1 /*
2 * Copyright (c) 2016, The OpenThread Authors.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. Neither the name of the copyright holder nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /**
30 * @file
31 * This file implements the OpenThread Link API.
32 */
33
34 #include "openthread-core-config.h"
35
36 #include <openthread/link.h>
37
38 #include "common/instance.hpp"
39 #include "common/locator_getters.hpp"
40 #include "mac/mac.hpp"
41 #include "radio/radio.hpp"
42
43 using namespace ot;
44
otLinkGetChannel(otInstance * aInstance)45 uint8_t otLinkGetChannel(otInstance *aInstance)
46 {
47 Instance &instance = *static_cast<Instance *>(aInstance);
48 uint8_t channel;
49
50 #if OPENTHREAD_CONFIG_LINK_RAW_ENABLE
51 if (instance.Get<Mac::LinkRaw>().IsEnabled())
52 {
53 channel = instance.Get<Mac::LinkRaw>().GetChannel();
54 }
55 else
56 #endif
57 {
58 channel = instance.Get<Mac::Mac>().GetPanChannel();
59 }
60
61 return channel;
62 }
63
otLinkSetChannel(otInstance * aInstance,uint8_t aChannel)64 otError otLinkSetChannel(otInstance *aInstance, uint8_t aChannel)
65 {
66 Error error;
67 Instance &instance = *static_cast<Instance *>(aInstance);
68
69 #if OPENTHREAD_CONFIG_LINK_RAW_ENABLE
70 if (instance.Get<Mac::LinkRaw>().IsEnabled())
71 {
72 error = instance.Get<Mac::LinkRaw>().SetChannel(aChannel);
73 ExitNow();
74 }
75 #endif
76
77 VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
78
79 SuccessOrExit(error = instance.Get<Mac::Mac>().SetPanChannel(aChannel));
80 instance.Get<MeshCoP::ActiveDataset>().Clear();
81 instance.Get<MeshCoP::PendingDataset>().Clear();
82
83 exit:
84 return error;
85 }
86
otLinkGetSupportedChannelMask(otInstance * aInstance)87 uint32_t otLinkGetSupportedChannelMask(otInstance *aInstance)
88 {
89 Instance &instance = *static_cast<Instance *>(aInstance);
90
91 return instance.Get<Mac::Mac>().GetSupportedChannelMask().GetMask();
92 }
93
otLinkSetSupportedChannelMask(otInstance * aInstance,uint32_t aChannelMask)94 otError otLinkSetSupportedChannelMask(otInstance *aInstance, uint32_t aChannelMask)
95 {
96 Error error = kErrorNone;
97 Instance &instance = *static_cast<Instance *>(aInstance);
98
99 VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
100
101 instance.Get<Mac::Mac>().SetSupportedChannelMask(static_cast<Mac::ChannelMask>(aChannelMask));
102
103 exit:
104 return error;
105 }
106
otLinkGetExtendedAddress(otInstance * aInstance)107 const otExtAddress *otLinkGetExtendedAddress(otInstance *aInstance)
108 {
109 Instance &instance = *static_cast<Instance *>(aInstance);
110
111 return &instance.Get<Mac::Mac>().GetExtAddress();
112 }
113
otLinkSetExtendedAddress(otInstance * aInstance,const otExtAddress * aExtAddress)114 otError otLinkSetExtendedAddress(otInstance *aInstance, const otExtAddress *aExtAddress)
115 {
116 Error error = kErrorNone;
117 Instance &instance = *static_cast<Instance *>(aInstance);
118
119 OT_ASSERT(aExtAddress != nullptr);
120 VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
121
122 instance.Get<Mac::Mac>().SetExtAddress(*static_cast<const Mac::ExtAddress *>(aExtAddress));
123
124 instance.Get<Mle::MleRouter>().UpdateLinkLocalAddress();
125
126 exit:
127 return error;
128 }
129
otLinkGetFactoryAssignedIeeeEui64(otInstance * aInstance,otExtAddress * aEui64)130 void otLinkGetFactoryAssignedIeeeEui64(otInstance *aInstance, otExtAddress *aEui64)
131 {
132 Instance &instance = *static_cast<Instance *>(aInstance);
133
134 instance.Get<Radio>().GetIeeeEui64(*static_cast<Mac::ExtAddress *>(aEui64));
135 }
136
otLinkGetPanId(otInstance * aInstance)137 otPanId otLinkGetPanId(otInstance *aInstance)
138 {
139 Instance &instance = *static_cast<Instance *>(aInstance);
140
141 return instance.Get<Mac::Mac>().GetPanId();
142 }
143
otLinkSetPanId(otInstance * aInstance,otPanId aPanId)144 otError otLinkSetPanId(otInstance *aInstance, otPanId aPanId)
145 {
146 Error error = kErrorNone;
147 Instance &instance = *static_cast<Instance *>(aInstance);
148
149 VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
150
151 instance.Get<Mac::Mac>().SetPanId(aPanId);
152 instance.Get<MeshCoP::ActiveDataset>().Clear();
153 instance.Get<MeshCoP::PendingDataset>().Clear();
154
155 exit:
156 return error;
157 }
158
otLinkGetPollPeriod(otInstance * aInstance)159 uint32_t otLinkGetPollPeriod(otInstance *aInstance)
160 {
161 Instance &instance = *static_cast<Instance *>(aInstance);
162
163 return instance.Get<DataPollSender>().GetKeepAlivePollPeriod();
164 }
165
otLinkSetPollPeriod(otInstance * aInstance,uint32_t aPollPeriod)166 otError otLinkSetPollPeriod(otInstance *aInstance, uint32_t aPollPeriod)
167 {
168 Instance &instance = *static_cast<Instance *>(aInstance);
169
170 return instance.Get<DataPollSender>().SetExternalPollPeriod(aPollPeriod);
171 }
172
otLinkSendDataRequest(otInstance * aInstance)173 otError otLinkSendDataRequest(otInstance *aInstance)
174 {
175 Instance &instance = *static_cast<Instance *>(aInstance);
176
177 return instance.Get<DataPollSender>().SendDataPoll();
178 }
179
otLinkGetShortAddress(otInstance * aInstance)180 otShortAddress otLinkGetShortAddress(otInstance *aInstance)
181 {
182 Instance &instance = *static_cast<Instance *>(aInstance);
183
184 return instance.Get<Mac::Mac>().GetShortAddress();
185 }
186
otLinkGetMaxFrameRetriesDirect(otInstance * aInstance)187 uint8_t otLinkGetMaxFrameRetriesDirect(otInstance *aInstance)
188 {
189 Instance &instance = *static_cast<Instance *>(aInstance);
190
191 return instance.Get<Mac::Mac>().GetMaxFrameRetriesDirect();
192 }
193
otLinkSetMaxFrameRetriesDirect(otInstance * aInstance,uint8_t aMaxFrameRetriesDirect)194 void otLinkSetMaxFrameRetriesDirect(otInstance *aInstance, uint8_t aMaxFrameRetriesDirect)
195 {
196 Instance &instance = *static_cast<Instance *>(aInstance);
197
198 instance.Get<Mac::Mac>().SetMaxFrameRetriesDirect(aMaxFrameRetriesDirect);
199 }
200
201 #if OPENTHREAD_FTD
202
otLinkGetMaxFrameRetriesIndirect(otInstance * aInstance)203 uint8_t otLinkGetMaxFrameRetriesIndirect(otInstance *aInstance)
204 {
205 Instance &instance = *static_cast<Instance *>(aInstance);
206
207 return instance.Get<Mac::Mac>().GetMaxFrameRetriesIndirect();
208 }
209
otLinkSetMaxFrameRetriesIndirect(otInstance * aInstance,uint8_t aMaxFrameRetriesIndirect)210 void otLinkSetMaxFrameRetriesIndirect(otInstance *aInstance, uint8_t aMaxFrameRetriesIndirect)
211 {
212 Instance &instance = *static_cast<Instance *>(aInstance);
213
214 instance.Get<Mac::Mac>().SetMaxFrameRetriesIndirect(aMaxFrameRetriesIndirect);
215 }
216
217 #endif // OPENTHREAD_FTD
218
219 #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
220
otLinkFilterGetAddressMode(otInstance * aInstance)221 otMacFilterAddressMode otLinkFilterGetAddressMode(otInstance *aInstance)
222 {
223 Instance &instance = *static_cast<Instance *>(aInstance);
224
225 return static_cast<otMacFilterAddressMode>(instance.Get<Mac::Filter>().GetMode());
226 }
227
otLinkFilterSetAddressMode(otInstance * aInstance,otMacFilterAddressMode aMode)228 void otLinkFilterSetAddressMode(otInstance *aInstance, otMacFilterAddressMode aMode)
229 {
230 Instance &instance = *static_cast<Instance *>(aInstance);
231
232 instance.Get<Mac::Filter>().SetMode(static_cast<Mac::Filter::Mode>(aMode));
233 }
234
otLinkFilterAddAddress(otInstance * aInstance,const otExtAddress * aExtAddress)235 otError otLinkFilterAddAddress(otInstance *aInstance, const otExtAddress *aExtAddress)
236 {
237 Instance &instance = *static_cast<Instance *>(aInstance);
238
239 OT_ASSERT(aExtAddress != nullptr);
240
241 return instance.Get<Mac::Filter>().AddAddress(*static_cast<const Mac::ExtAddress *>(aExtAddress));
242 }
243
otLinkFilterRemoveAddress(otInstance * aInstance,const otExtAddress * aExtAddress)244 void otLinkFilterRemoveAddress(otInstance *aInstance, const otExtAddress *aExtAddress)
245 {
246 Instance &instance = *static_cast<Instance *>(aInstance);
247
248 OT_ASSERT(aExtAddress != nullptr);
249
250 instance.Get<Mac::Filter>().RemoveAddress(*static_cast<const Mac::ExtAddress *>(aExtAddress));
251 }
252
otLinkFilterClearAddresses(otInstance * aInstance)253 void otLinkFilterClearAddresses(otInstance *aInstance)
254 {
255 Instance &instance = *static_cast<Instance *>(aInstance);
256
257 return instance.Get<Mac::Filter>().ClearAddresses();
258 }
259
otLinkFilterGetNextAddress(otInstance * aInstance,otMacFilterIterator * aIterator,otMacFilterEntry * aEntry)260 otError otLinkFilterGetNextAddress(otInstance *aInstance, otMacFilterIterator *aIterator, otMacFilterEntry *aEntry)
261 {
262 Instance &instance = *static_cast<Instance *>(aInstance);
263
264 OT_ASSERT(aIterator != nullptr && aEntry != nullptr);
265
266 return instance.Get<Mac::Filter>().GetNextAddress(*aIterator, *aEntry);
267 }
268
otLinkFilterAddRssIn(otInstance * aInstance,const otExtAddress * aExtAddress,int8_t aRss)269 otError otLinkFilterAddRssIn(otInstance *aInstance, const otExtAddress *aExtAddress, int8_t aRss)
270 {
271 Instance &instance = *static_cast<Instance *>(aInstance);
272
273 OT_ASSERT(aExtAddress != nullptr);
274
275 return instance.Get<Mac::Filter>().AddRssIn(*static_cast<const Mac::ExtAddress *>(aExtAddress), aRss);
276 }
277
otLinkFilterRemoveRssIn(otInstance * aInstance,const otExtAddress * aExtAddress)278 void otLinkFilterRemoveRssIn(otInstance *aInstance, const otExtAddress *aExtAddress)
279 {
280 Instance &instance = *static_cast<Instance *>(aInstance);
281
282 OT_ASSERT(aExtAddress != nullptr);
283
284 instance.Get<Mac::Filter>().RemoveRssIn(*static_cast<const Mac::ExtAddress *>(aExtAddress));
285 }
286
otLinkFilterSetDefaultRssIn(otInstance * aInstance,int8_t aRss)287 void otLinkFilterSetDefaultRssIn(otInstance *aInstance, int8_t aRss)
288 {
289 Instance &instance = *static_cast<Instance *>(aInstance);
290
291 instance.Get<Mac::Filter>().SetDefaultRssIn(aRss);
292 }
293
otLinkFilterClearDefaultRssIn(otInstance * aInstance)294 void otLinkFilterClearDefaultRssIn(otInstance *aInstance)
295 {
296 Instance &instance = *static_cast<Instance *>(aInstance);
297
298 instance.Get<Mac::Filter>().ClearDefaultRssIn();
299 }
300
otLinkFilterClearAllRssIn(otInstance * aInstance)301 void otLinkFilterClearAllRssIn(otInstance *aInstance)
302 {
303 Instance &instance = *static_cast<Instance *>(aInstance);
304
305 instance.Get<Mac::Filter>().ClearAllRssIn();
306 }
307
otLinkFilterGetNextRssIn(otInstance * aInstance,otMacFilterIterator * aIterator,otMacFilterEntry * aEntry)308 otError otLinkFilterGetNextRssIn(otInstance *aInstance, otMacFilterIterator *aIterator, otMacFilterEntry *aEntry)
309 {
310 Instance &instance = *static_cast<Instance *>(aInstance);
311
312 OT_ASSERT(aIterator != nullptr && aEntry != nullptr);
313
314 return instance.Get<Mac::Filter>().GetNextRssIn(*aIterator, *aEntry);
315 }
316
otLinkConvertRssToLinkQuality(otInstance * aInstance,int8_t aRss)317 uint8_t otLinkConvertRssToLinkQuality(otInstance *aInstance, int8_t aRss)
318 {
319 Instance &instance = *static_cast<Instance *>(aInstance);
320
321 return LinkQualityInfo::ConvertRssToLinkQuality(instance.Get<Mac::Mac>().GetNoiseFloor(), aRss);
322 }
323
otLinkConvertLinkQualityToRss(otInstance * aInstance,uint8_t aLinkQuality)324 int8_t otLinkConvertLinkQualityToRss(otInstance *aInstance, uint8_t aLinkQuality)
325 {
326 Instance &instance = *static_cast<Instance *>(aInstance);
327
328 return LinkQualityInfo::ConvertLinkQualityToRss(instance.Get<Mac::Mac>().GetNoiseFloor(), aLinkQuality);
329 }
330
331 #endif // OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
332
333 #if OPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_ENABLE
otLinkGetTxDirectRetrySuccessHistogram(otInstance * aInstance,uint8_t * aNumberOfEntries)334 const uint32_t *otLinkGetTxDirectRetrySuccessHistogram(otInstance *aInstance, uint8_t *aNumberOfEntries)
335 {
336 Instance &instance = *static_cast<Instance *>(aInstance);
337
338 return instance.Get<Mac::Mac>().GetDirectRetrySuccessHistogram(*aNumberOfEntries);
339 }
340
otLinkGetTxIndirectRetrySuccessHistogram(otInstance * aInstance,uint8_t * aNumberOfEntries)341 const uint32_t *otLinkGetTxIndirectRetrySuccessHistogram(otInstance *aInstance, uint8_t *aNumberOfEntries)
342 {
343 const uint32_t *histogram = nullptr;
344
345 #if OPENTHREAD_FTD
346 Instance &instance = *static_cast<Instance *>(aInstance);
347
348 histogram = instance.Get<Mac::Mac>().GetIndirectRetrySuccessHistogram(*aNumberOfEntries);
349 #else
350 OT_UNUSED_VARIABLE(aInstance);
351 *aNumberOfEntries = 0;
352 #endif
353
354 return histogram;
355 }
356
otLinkResetTxRetrySuccessHistogram(otInstance * aInstance)357 void otLinkResetTxRetrySuccessHistogram(otInstance *aInstance)
358 {
359 Instance &instance = *static_cast<Instance *>(aInstance);
360
361 instance.Get<Mac::Mac>().ResetRetrySuccessHistogram();
362 }
363 #endif // OPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_ENABLE
364
otLinkSetPcapCallback(otInstance * aInstance,otLinkPcapCallback aPcapCallback,void * aCallbackContext)365 void otLinkSetPcapCallback(otInstance *aInstance, otLinkPcapCallback aPcapCallback, void *aCallbackContext)
366 {
367 Instance &instance = *static_cast<Instance *>(aInstance);
368
369 instance.Get<Mac::Mac>().SetPcapCallback(aPcapCallback, aCallbackContext);
370 }
371
otLinkIsPromiscuous(otInstance * aInstance)372 bool otLinkIsPromiscuous(otInstance *aInstance)
373 {
374 Instance &instance = *static_cast<Instance *>(aInstance);
375
376 return instance.Get<Mac::Mac>().IsPromiscuous();
377 }
378
otLinkSetPromiscuous(otInstance * aInstance,bool aPromiscuous)379 otError otLinkSetPromiscuous(otInstance *aInstance, bool aPromiscuous)
380 {
381 Error error = kErrorNone;
382 Instance &instance = *static_cast<Instance *>(aInstance);
383
384 // cannot enable IEEE 802.15.4 promiscuous mode if the Thread interface is enabled
385 VerifyOrExit(!instance.Get<ThreadNetif>().IsUp(), error = kErrorInvalidState);
386
387 instance.Get<Mac::Mac>().SetPromiscuous(aPromiscuous);
388
389 exit:
390 return error;
391 }
392
otLinkSetEnabled(otInstance * aInstance,bool aEnable)393 otError otLinkSetEnabled(otInstance *aInstance, bool aEnable)
394 {
395 Error error = kErrorNone;
396 Instance &instance = *static_cast<Instance *>(aInstance);
397
398 // cannot disable the link layer if the Thread interface is enabled
399 VerifyOrExit(!instance.Get<ThreadNetif>().IsUp(), error = kErrorInvalidState);
400
401 instance.Get<Mac::Mac>().SetEnabled(aEnable);
402
403 exit:
404 return error;
405 }
406
otLinkIsEnabled(otInstance * aInstance)407 bool otLinkIsEnabled(otInstance *aInstance)
408 {
409 Instance &instance = *static_cast<Instance *>(aInstance);
410
411 return instance.Get<Mac::Mac>().IsEnabled();
412 }
413
otLinkGetCounters(otInstance * aInstance)414 const otMacCounters *otLinkGetCounters(otInstance *aInstance)
415 {
416 Instance &instance = *static_cast<Instance *>(aInstance);
417
418 return &instance.Get<Mac::Mac>().GetCounters();
419 }
420
otLinkResetCounters(otInstance * aInstance)421 void otLinkResetCounters(otInstance *aInstance)
422 {
423 Instance &instance = *static_cast<Instance *>(aInstance);
424
425 instance.Get<Mac::Mac>().ResetCounters();
426 }
427
otLinkActiveScan(otInstance * aInstance,uint32_t aScanChannels,uint16_t aScanDuration,otHandleActiveScanResult aCallback,void * aCallbackContext)428 otError otLinkActiveScan(otInstance * aInstance,
429 uint32_t aScanChannels,
430 uint16_t aScanDuration,
431 otHandleActiveScanResult aCallback,
432 void * aCallbackContext)
433 {
434 Instance &instance = *static_cast<Instance *>(aInstance);
435
436 return instance.Get<Mac::Mac>().ActiveScan(aScanChannels, aScanDuration, aCallback, aCallbackContext);
437 }
438
otLinkIsActiveScanInProgress(otInstance * aInstance)439 bool otLinkIsActiveScanInProgress(otInstance *aInstance)
440 {
441 Instance &instance = *static_cast<Instance *>(aInstance);
442
443 return instance.Get<Mac::Mac>().IsActiveScanInProgress();
444 }
445
otLinkEnergyScan(otInstance * aInstance,uint32_t aScanChannels,uint16_t aScanDuration,otHandleEnergyScanResult aCallback,void * aCallbackContext)446 otError otLinkEnergyScan(otInstance * aInstance,
447 uint32_t aScanChannels,
448 uint16_t aScanDuration,
449 otHandleEnergyScanResult aCallback,
450 void * aCallbackContext)
451 {
452 Instance &instance = *static_cast<Instance *>(aInstance);
453
454 return instance.Get<Mac::Mac>().EnergyScan(aScanChannels, aScanDuration, aCallback, aCallbackContext);
455 }
456
otLinkIsEnergyScanInProgress(otInstance * aInstance)457 bool otLinkIsEnergyScanInProgress(otInstance *aInstance)
458 {
459 Instance &instance = *static_cast<Instance *>(aInstance);
460
461 return instance.Get<Mac::Mac>().IsEnergyScanInProgress();
462 }
463
otLinkIsInTransmitState(otInstance * aInstance)464 bool otLinkIsInTransmitState(otInstance *aInstance)
465 {
466 Instance &instance = *static_cast<Instance *>(aInstance);
467
468 return instance.Get<Mac::Mac>().IsInTransmitState();
469 }
470
otLinkGetCcaFailureRate(otInstance * aInstance)471 uint16_t otLinkGetCcaFailureRate(otInstance *aInstance)
472 {
473 Instance &instance = *static_cast<Instance *>(aInstance);
474
475 return instance.Get<Mac::Mac>().GetCcaFailureRate();
476 }
477
478 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
otLinkCslGetChannel(otInstance * aInstance)479 uint8_t otLinkCslGetChannel(otInstance *aInstance)
480 {
481 return static_cast<Instance *>(aInstance)->Get<Mac::Mac>().GetCslChannel();
482 }
483
otLinkCslSetChannel(otInstance * aInstance,uint8_t aChannel)484 otError otLinkCslSetChannel(otInstance *aInstance, uint8_t aChannel)
485 {
486 Error error = kErrorNone;
487 Instance &instance = *static_cast<Instance *>(aInstance);
488
489 VerifyOrExit(Radio::IsCslChannelValid(aChannel), error = kErrorInvalidArgs);
490
491 instance.Get<Mac::Mac>().SetCslChannel(aChannel);
492
493 exit:
494 return error;
495 }
496
otLinkCslGetPeriod(otInstance * aInstance)497 uint16_t otLinkCslGetPeriod(otInstance *aInstance)
498 {
499 return static_cast<Instance *>(aInstance)->Get<Mac::Mac>().GetCslPeriod();
500 }
501
otLinkCslSetPeriod(otInstance * aInstance,uint16_t aPeriod)502 otError otLinkCslSetPeriod(otInstance *aInstance, uint16_t aPeriod)
503 {
504 Error error = kErrorNone;
505 Instance &instance = *static_cast<Instance *>(aInstance);
506
507 VerifyOrExit((aPeriod == 0 || kMinCslPeriod <= aPeriod), error = kErrorInvalidArgs);
508 instance.Get<Mac::Mac>().SetCslPeriod(aPeriod);
509
510 exit:
511 return error;
512 }
513
otLinkCslGetTimeout(otInstance * aInstance)514 uint32_t otLinkCslGetTimeout(otInstance *aInstance)
515 {
516 return static_cast<Instance *>(aInstance)->Get<Mle::MleRouter>().GetCslTimeout();
517 }
518
otLinkCslSetTimeout(otInstance * aInstance,uint32_t aTimeout)519 otError otLinkCslSetTimeout(otInstance *aInstance, uint32_t aTimeout)
520 {
521 Error error = kErrorNone;
522 Instance &instance = *static_cast<Instance *>(aInstance);
523
524 VerifyOrExit(kMaxCslTimeout >= aTimeout, error = kErrorInvalidArgs);
525 instance.Get<Mle::MleRouter>().SetCslTimeout(aTimeout);
526
527 exit:
528 return error;
529 }
530
531 #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
532
533 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
otLinkSendEmptyData(otInstance * aInstance)534 otError otLinkSendEmptyData(otInstance *aInstance)
535 {
536 Instance &instance = *static_cast<Instance *>(aInstance);
537
538 return instance.Get<MeshForwarder>().SendEmptyMessage();
539 }
540 #endif
541