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 Thread API (for both FTD and MTD).
32 */
33
34 #include "openthread-core-config.h"
35
36 #if OPENTHREAD_FTD || OPENTHREAD_MTD
37
38 #include "instance/instance.hpp"
39
40 using namespace ot;
41
otThreadGetChildTimeout(otInstance * aInstance)42 uint32_t otThreadGetChildTimeout(otInstance *aInstance)
43 {
44 return AsCoreType(aInstance).Get<Mle::MleRouter>().GetTimeout();
45 }
46
otThreadSetChildTimeout(otInstance * aInstance,uint32_t aTimeout)47 void otThreadSetChildTimeout(otInstance *aInstance, uint32_t aTimeout)
48 {
49 AsCoreType(aInstance).Get<Mle::MleRouter>().SetTimeout(aTimeout);
50 }
51
otThreadGetExtendedPanId(otInstance * aInstance)52 const otExtendedPanId *otThreadGetExtendedPanId(otInstance *aInstance)
53 {
54 return &AsCoreType(aInstance).Get<MeshCoP::ExtendedPanIdManager>().GetExtPanId();
55 }
56
otThreadSetExtendedPanId(otInstance * aInstance,const otExtendedPanId * aExtendedPanId)57 otError otThreadSetExtendedPanId(otInstance *aInstance, const otExtendedPanId *aExtendedPanId)
58 {
59 Error error = kErrorNone;
60 Instance &instance = AsCoreType(aInstance);
61 const MeshCoP::ExtendedPanId &extPanId = AsCoreType(aExtendedPanId);
62
63 VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
64
65 instance.Get<MeshCoP::ExtendedPanIdManager>().SetExtPanId(extPanId);
66
67 instance.Get<MeshCoP::ActiveDatasetManager>().Clear();
68 instance.Get<MeshCoP::PendingDatasetManager>().Clear();
69
70 exit:
71 return error;
72 }
73
otThreadGetLeaderRloc(otInstance * aInstance,otIp6Address * aLeaderRloc)74 otError otThreadGetLeaderRloc(otInstance *aInstance, otIp6Address *aLeaderRloc)
75 {
76 Error error = kErrorNone;
77
78 VerifyOrExit(!AsCoreType(aInstance).Get<Mle::Mle>().HasRloc16(Mle::kInvalidRloc16), error = kErrorDetached);
79 AsCoreType(aInstance).Get<Mle::Mle>().GetLeaderRloc(AsCoreType(aLeaderRloc));
80
81 exit:
82 return error;
83 }
84
otThreadGetLinkMode(otInstance * aInstance)85 otLinkModeConfig otThreadGetLinkMode(otInstance *aInstance)
86 {
87 otLinkModeConfig config;
88
89 AsCoreType(aInstance).Get<Mle::MleRouter>().GetDeviceMode().Get(config);
90
91 return config;
92 }
93
otThreadSetLinkMode(otInstance * aInstance,otLinkModeConfig aConfig)94 otError otThreadSetLinkMode(otInstance *aInstance, otLinkModeConfig aConfig)
95 {
96 return AsCoreType(aInstance).Get<Mle::MleRouter>().SetDeviceMode(Mle::DeviceMode(aConfig));
97 }
98
otThreadGetNetworkKey(otInstance * aInstance,otNetworkKey * aNetworkKey)99 void otThreadGetNetworkKey(otInstance *aInstance, otNetworkKey *aNetworkKey)
100 {
101 AsCoreType(aInstance).Get<KeyManager>().GetNetworkKey(AsCoreType(aNetworkKey));
102 }
103
104 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
otThreadGetNetworkKeyRef(otInstance * aInstance)105 otNetworkKeyRef otThreadGetNetworkKeyRef(otInstance *aInstance)
106 {
107 return AsCoreType(aInstance).Get<KeyManager>().GetNetworkKeyRef();
108 }
109 #endif
110
otThreadSetNetworkKey(otInstance * aInstance,const otNetworkKey * aKey)111 otError otThreadSetNetworkKey(otInstance *aInstance, const otNetworkKey *aKey)
112 {
113 Error error = kErrorNone;
114 Instance &instance = AsCoreType(aInstance);
115
116 VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
117
118 instance.Get<KeyManager>().SetNetworkKey(AsCoreType(aKey));
119
120 instance.Get<MeshCoP::ActiveDatasetManager>().Clear();
121 instance.Get<MeshCoP::PendingDatasetManager>().Clear();
122
123 exit:
124 return error;
125 }
126
127 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
otThreadSetNetworkKeyRef(otInstance * aInstance,otNetworkKeyRef aKeyRef)128 otError otThreadSetNetworkKeyRef(otInstance *aInstance, otNetworkKeyRef aKeyRef)
129 {
130 Error error = kErrorNone;
131 Instance &instance = AsCoreType(aInstance);
132
133 VerifyOrExit(aKeyRef != 0, error = kErrorInvalidArgs);
134
135 VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
136
137 instance.Get<KeyManager>().SetNetworkKeyRef((aKeyRef));
138 instance.Get<MeshCoP::ActiveDatasetManager>().Clear();
139 instance.Get<MeshCoP::PendingDatasetManager>().Clear();
140
141 exit:
142 return error;
143 }
144 #endif
145
otThreadGetRloc(otInstance * aInstance)146 const otIp6Address *otThreadGetRloc(otInstance *aInstance)
147 {
148 return &AsCoreType(aInstance).Get<Mle::MleRouter>().GetMeshLocalRloc();
149 }
150
otThreadGetMeshLocalEid(otInstance * aInstance)151 const otIp6Address *otThreadGetMeshLocalEid(otInstance *aInstance)
152 {
153 return &AsCoreType(aInstance).Get<Mle::MleRouter>().GetMeshLocalEid();
154 }
155
otThreadGetMeshLocalPrefix(otInstance * aInstance)156 const otMeshLocalPrefix *otThreadGetMeshLocalPrefix(otInstance *aInstance)
157 {
158 return &AsCoreType(aInstance).Get<Mle::MleRouter>().GetMeshLocalPrefix();
159 }
160
otThreadSetMeshLocalPrefix(otInstance * aInstance,const otMeshLocalPrefix * aMeshLocalPrefix)161 otError otThreadSetMeshLocalPrefix(otInstance *aInstance, const otMeshLocalPrefix *aMeshLocalPrefix)
162 {
163 Error error = kErrorNone;
164
165 VerifyOrExit(AsCoreType(aInstance).Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
166
167 AsCoreType(aInstance).Get<Mle::MleRouter>().SetMeshLocalPrefix(AsCoreType(aMeshLocalPrefix));
168 AsCoreType(aInstance).Get<MeshCoP::ActiveDatasetManager>().Clear();
169 AsCoreType(aInstance).Get<MeshCoP::PendingDatasetManager>().Clear();
170
171 exit:
172 return error;
173 }
174
otThreadGetLinkLocalIp6Address(otInstance * aInstance)175 const otIp6Address *otThreadGetLinkLocalIp6Address(otInstance *aInstance)
176 {
177 return &AsCoreType(aInstance).Get<Mle::MleRouter>().GetLinkLocalAddress();
178 }
179
otThreadGetLinkLocalAllThreadNodesMulticastAddress(otInstance * aInstance)180 const otIp6Address *otThreadGetLinkLocalAllThreadNodesMulticastAddress(otInstance *aInstance)
181 {
182 return &AsCoreType(aInstance).Get<Mle::MleRouter>().GetLinkLocalAllThreadNodesAddress();
183 }
184
otThreadGetRealmLocalAllThreadNodesMulticastAddress(otInstance * aInstance)185 const otIp6Address *otThreadGetRealmLocalAllThreadNodesMulticastAddress(otInstance *aInstance)
186 {
187 return &AsCoreType(aInstance).Get<Mle::MleRouter>().GetRealmLocalAllThreadNodesAddress();
188 }
189
otThreadGetServiceAloc(otInstance * aInstance,uint8_t aServiceId,otIp6Address * aServiceAloc)190 otError otThreadGetServiceAloc(otInstance *aInstance, uint8_t aServiceId, otIp6Address *aServiceAloc)
191 {
192 Error error = kErrorNone;
193
194 VerifyOrExit(!AsCoreType(aInstance).Get<Mle::Mle>().HasRloc16(Mle::kInvalidRloc16), error = kErrorDetached);
195 AsCoreType(aInstance).Get<Mle::Mle>().GetServiceAloc(aServiceId, AsCoreType(aServiceAloc));
196
197 exit:
198 return error;
199 }
200
otThreadGetNetworkName(otInstance * aInstance)201 const char *otThreadGetNetworkName(otInstance *aInstance)
202 {
203 return AsCoreType(aInstance).Get<MeshCoP::NetworkNameManager>().GetNetworkName().GetAsCString();
204 }
205
otThreadSetNetworkName(otInstance * aInstance,const char * aNetworkName)206 otError otThreadSetNetworkName(otInstance *aInstance, const char *aNetworkName)
207 {
208 Error error = kErrorNone;
209
210 VerifyOrExit(AsCoreType(aInstance).Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
211
212 #if !OPENTHREAD_CONFIG_ALLOW_EMPTY_NETWORK_NAME
213 // Thread interfaces support a zero length name internally for backwards compatibility, but new names
214 // must be at least one valid character long.
215 VerifyOrExit(nullptr != aNetworkName && aNetworkName[0] != '\0', error = kErrorInvalidArgs);
216 #endif
217
218 error = AsCoreType(aInstance).Get<MeshCoP::NetworkNameManager>().SetNetworkName(aNetworkName);
219 AsCoreType(aInstance).Get<MeshCoP::ActiveDatasetManager>().Clear();
220 AsCoreType(aInstance).Get<MeshCoP::PendingDatasetManager>().Clear();
221
222 exit:
223 return error;
224 }
225
226 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
otThreadGetDomainName(otInstance * aInstance)227 const char *otThreadGetDomainName(otInstance *aInstance)
228 {
229 return AsCoreType(aInstance).Get<MeshCoP::NetworkNameManager>().GetDomainName().GetAsCString();
230 }
231
otThreadSetDomainName(otInstance * aInstance,const char * aDomainName)232 otError otThreadSetDomainName(otInstance *aInstance, const char *aDomainName)
233 {
234 Error error = kErrorNone;
235
236 VerifyOrExit(AsCoreType(aInstance).Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
237
238 error = AsCoreType(aInstance).Get<MeshCoP::NetworkNameManager>().SetDomainName(aDomainName);
239
240 exit:
241 return error;
242 }
243
244 #if OPENTHREAD_CONFIG_DUA_ENABLE
otThreadSetFixedDuaInterfaceIdentifier(otInstance * aInstance,const otIp6InterfaceIdentifier * aIid)245 otError otThreadSetFixedDuaInterfaceIdentifier(otInstance *aInstance, const otIp6InterfaceIdentifier *aIid)
246 {
247 Error error = kErrorNone;
248
249 if (aIid)
250 {
251 error = AsCoreType(aInstance).Get<DuaManager>().SetFixedDuaInterfaceIdentifier(AsCoreType(aIid));
252 }
253 else
254 {
255 AsCoreType(aInstance).Get<DuaManager>().ClearFixedDuaInterfaceIdentifier();
256 }
257
258 return error;
259 }
260
otThreadGetFixedDuaInterfaceIdentifier(otInstance * aInstance)261 const otIp6InterfaceIdentifier *otThreadGetFixedDuaInterfaceIdentifier(otInstance *aInstance)
262 {
263 Instance &instance = AsCoreType(aInstance);
264 const otIp6InterfaceIdentifier *iid = nullptr;
265
266 if (instance.Get<DuaManager>().IsFixedDuaInterfaceIdentifierSet())
267 {
268 iid = &instance.Get<DuaManager>().GetFixedDuaInterfaceIdentifier();
269 }
270
271 return iid;
272 }
273 #endif // OPENTHREAD_CONFIG_DUA_ENABLE
274
275 #endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
276
otThreadGetKeySequenceCounter(otInstance * aInstance)277 uint32_t otThreadGetKeySequenceCounter(otInstance *aInstance)
278 {
279 return AsCoreType(aInstance).Get<KeyManager>().GetCurrentKeySequence();
280 }
281
otThreadSetKeySequenceCounter(otInstance * aInstance,uint32_t aKeySequenceCounter)282 void otThreadSetKeySequenceCounter(otInstance *aInstance, uint32_t aKeySequenceCounter)
283 {
284 AsCoreType(aInstance).Get<KeyManager>().SetCurrentKeySequence(
285 aKeySequenceCounter, KeyManager::kForceUpdate | KeyManager::kGuardTimerUnchanged);
286 }
287
otThreadGetKeySwitchGuardTime(otInstance * aInstance)288 uint16_t otThreadGetKeySwitchGuardTime(otInstance *aInstance)
289 {
290 return AsCoreType(aInstance).Get<KeyManager>().GetKeySwitchGuardTime();
291 }
292
otThreadSetKeySwitchGuardTime(otInstance * aInstance,uint16_t aKeySwitchGuardTime)293 void otThreadSetKeySwitchGuardTime(otInstance *aInstance, uint16_t aKeySwitchGuardTime)
294 {
295 AsCoreType(aInstance).Get<KeyManager>().SetKeySwitchGuardTime(aKeySwitchGuardTime);
296 }
297
otThreadBecomeDetached(otInstance * aInstance)298 otError otThreadBecomeDetached(otInstance *aInstance)
299 {
300 return AsCoreType(aInstance).Get<Mle::MleRouter>().BecomeDetached();
301 }
302
otThreadBecomeChild(otInstance * aInstance)303 otError otThreadBecomeChild(otInstance *aInstance) { return AsCoreType(aInstance).Get<Mle::MleRouter>().BecomeChild(); }
304
otThreadGetNextNeighborInfo(otInstance * aInstance,otNeighborInfoIterator * aIterator,otNeighborInfo * aInfo)305 otError otThreadGetNextNeighborInfo(otInstance *aInstance, otNeighborInfoIterator *aIterator, otNeighborInfo *aInfo)
306 {
307 AssertPointerIsNotNull(aIterator);
308
309 return AsCoreType(aInstance).Get<NeighborTable>().GetNextNeighborInfo(*aIterator, AsCoreType(aInfo));
310 }
311
otThreadGetDeviceRole(otInstance * aInstance)312 otDeviceRole otThreadGetDeviceRole(otInstance *aInstance)
313 {
314 return MapEnum(AsCoreType(aInstance).Get<Mle::MleRouter>().GetRole());
315 }
316
otThreadDeviceRoleToString(otDeviceRole aRole)317 const char *otThreadDeviceRoleToString(otDeviceRole aRole) { return Mle::RoleToString(MapEnum(aRole)); }
318
otThreadGetLeaderData(otInstance * aInstance,otLeaderData * aLeaderData)319 otError otThreadGetLeaderData(otInstance *aInstance, otLeaderData *aLeaderData)
320 {
321 Error error = kErrorNone;
322
323 AssertPointerIsNotNull(aLeaderData);
324
325 VerifyOrExit(AsCoreType(aInstance).Get<Mle::MleRouter>().IsAttached(), error = kErrorDetached);
326 *aLeaderData = AsCoreType(aInstance).Get<Mle::MleRouter>().GetLeaderData();
327
328 exit:
329 return error;
330 }
331
otThreadGetLeaderRouterId(otInstance * aInstance)332 uint8_t otThreadGetLeaderRouterId(otInstance *aInstance)
333 {
334 return AsCoreType(aInstance).Get<Mle::MleRouter>().GetLeaderId();
335 }
336
otThreadGetLeaderWeight(otInstance * aInstance)337 uint8_t otThreadGetLeaderWeight(otInstance *aInstance)
338 {
339 return AsCoreType(aInstance).Get<Mle::MleRouter>().GetLeaderData().GetWeighting();
340 }
341
otThreadGetPartitionId(otInstance * aInstance)342 uint32_t otThreadGetPartitionId(otInstance *aInstance)
343 {
344 return AsCoreType(aInstance).Get<Mle::MleRouter>().GetLeaderData().GetPartitionId();
345 }
346
otThreadGetRloc16(otInstance * aInstance)347 uint16_t otThreadGetRloc16(otInstance *aInstance) { return AsCoreType(aInstance).Get<Mle::MleRouter>().GetRloc16(); }
348
otThreadGetParentInfo(otInstance * aInstance,otRouterInfo * aParentInfo)349 otError otThreadGetParentInfo(otInstance *aInstance, otRouterInfo *aParentInfo)
350 {
351 return AsCoreType(aInstance).Get<Mle::Mle>().GetParentInfo(AsCoreType(aParentInfo));
352 }
353
otThreadGetParentAverageRssi(otInstance * aInstance,int8_t * aParentRssi)354 otError otThreadGetParentAverageRssi(otInstance *aInstance, int8_t *aParentRssi)
355 {
356 Error error = kErrorNone;
357
358 AssertPointerIsNotNull(aParentRssi);
359
360 *aParentRssi = AsCoreType(aInstance).Get<Mle::MleRouter>().GetParent().GetLinkInfo().GetAverageRss();
361
362 VerifyOrExit(*aParentRssi != Radio::kInvalidRssi, error = kErrorFailed);
363
364 exit:
365 return error;
366 }
367
otThreadGetParentLastRssi(otInstance * aInstance,int8_t * aLastRssi)368 otError otThreadGetParentLastRssi(otInstance *aInstance, int8_t *aLastRssi)
369 {
370 Error error = kErrorNone;
371
372 AssertPointerIsNotNull(aLastRssi);
373
374 *aLastRssi = AsCoreType(aInstance).Get<Mle::MleRouter>().GetParent().GetLinkInfo().GetLastRss();
375
376 VerifyOrExit(*aLastRssi != Radio::kInvalidRssi, error = kErrorFailed);
377
378 exit:
379 return error;
380 }
381
otThreadSearchForBetterParent(otInstance * aInstance)382 otError otThreadSearchForBetterParent(otInstance *aInstance)
383 {
384 return AsCoreType(aInstance).Get<Mle::Mle>().SearchForBetterParent();
385 }
386
otThreadSetEnabled(otInstance * aInstance,bool aEnabled)387 otError otThreadSetEnabled(otInstance *aInstance, bool aEnabled)
388 {
389 Error error = kErrorNone;
390
391 if (aEnabled)
392 {
393 error = AsCoreType(aInstance).Get<Mle::MleRouter>().Start();
394 }
395 else
396 {
397 AsCoreType(aInstance).Get<Mle::MleRouter>().Stop();
398 }
399
400 return error;
401 }
402
otThreadGetVersion(void)403 uint16_t otThreadGetVersion(void) { return kThreadVersion; }
404
otThreadIsSingleton(otInstance * aInstance)405 bool otThreadIsSingleton(otInstance *aInstance)
406 {
407 bool isSingleton = false;
408
409 #if OPENTHREAD_FTD
410 isSingleton = AsCoreType(aInstance).Get<Mle::MleRouter>().IsSingleton();
411 #else
412 OT_UNUSED_VARIABLE(aInstance);
413 #endif
414
415 return isSingleton;
416 }
417
otThreadDiscover(otInstance * aInstance,uint32_t aScanChannels,uint16_t aPanId,bool aJoiner,bool aEnableEui64Filtering,otHandleActiveScanResult aCallback,void * aCallbackContext)418 otError otThreadDiscover(otInstance *aInstance,
419 uint32_t aScanChannels,
420 uint16_t aPanId,
421 bool aJoiner,
422 bool aEnableEui64Filtering,
423 otHandleActiveScanResult aCallback,
424 void *aCallbackContext)
425 {
426 return AsCoreType(aInstance).Get<Mle::DiscoverScanner>().Discover(
427 Mac::ChannelMask(aScanChannels), aPanId, aJoiner, aEnableEui64Filtering,
428 /* aFilterIndexes (use hash of factory EUI64) */ nullptr, aCallback, aCallbackContext);
429 }
430
otThreadSetJoinerAdvertisement(otInstance * aInstance,uint32_t aOui,const uint8_t * aAdvData,uint8_t aAdvDataLength)431 otError otThreadSetJoinerAdvertisement(otInstance *aInstance,
432 uint32_t aOui,
433 const uint8_t *aAdvData,
434 uint8_t aAdvDataLength)
435 {
436 return AsCoreType(aInstance).Get<Mle::DiscoverScanner>().SetJoinerAdvertisement(aOui, aAdvData, aAdvDataLength);
437 }
438
otThreadIsDiscoverInProgress(otInstance * aInstance)439 bool otThreadIsDiscoverInProgress(otInstance *aInstance)
440 {
441 return AsCoreType(aInstance).Get<Mle::DiscoverScanner>().IsInProgress();
442 }
443
otThreadGetIp6Counters(otInstance * aInstance)444 const otIpCounters *otThreadGetIp6Counters(otInstance *aInstance)
445 {
446 return &AsCoreType(aInstance).Get<MeshForwarder>().GetCounters();
447 }
448
otThreadResetIp6Counters(otInstance * aInstance)449 void otThreadResetIp6Counters(otInstance *aInstance) { AsCoreType(aInstance).Get<MeshForwarder>().ResetCounters(); }
450
451 #if OPENTHREAD_CONFIG_TX_QUEUE_STATISTICS_ENABLE
otThreadGetTimeInQueueHistogram(otInstance * aInstance,uint16_t * aNumBins,uint32_t * aBinInterval)452 const uint32_t *otThreadGetTimeInQueueHistogram(otInstance *aInstance, uint16_t *aNumBins, uint32_t *aBinInterval)
453 {
454 AssertPointerIsNotNull(aNumBins);
455 AssertPointerIsNotNull(aBinInterval);
456
457 return AsCoreType(aInstance).Get<MeshForwarder>().GetTimeInQueueHistogram(*aNumBins, *aBinInterval);
458 }
459
otThreadGetMaxTimeInQueue(otInstance * aInstance)460 uint32_t otThreadGetMaxTimeInQueue(otInstance *aInstance)
461 {
462 return AsCoreType(aInstance).Get<MeshForwarder>().GetMaxTimeInQueue();
463 }
464
otThreadResetTimeInQueueStat(otInstance * aInstance)465 void otThreadResetTimeInQueueStat(otInstance *aInstance)
466 {
467 return AsCoreType(aInstance).Get<MeshForwarder>().ResetTimeInQueueStat();
468 }
469 #endif
470
otThreadGetMleCounters(otInstance * aInstance)471 const otMleCounters *otThreadGetMleCounters(otInstance *aInstance)
472 {
473 return &AsCoreType(aInstance).Get<Mle::MleRouter>().GetCounters();
474 }
475
otThreadResetMleCounters(otInstance * aInstance)476 void otThreadResetMleCounters(otInstance *aInstance) { AsCoreType(aInstance).Get<Mle::MleRouter>().ResetCounters(); }
477
478 #if OPENTHREAD_CONFIG_UPTIME_ENABLE
otThreadGetCurrentAttachDuration(otInstance * aInstance)479 uint32_t otThreadGetCurrentAttachDuration(otInstance *aInstance)
480 {
481 return AsCoreType(aInstance).Get<Mle::MleRouter>().GetCurrentAttachDuration();
482 }
483 #endif
484
485 #if OPENTHREAD_CONFIG_MLE_PARENT_RESPONSE_CALLBACK_API_ENABLE
otThreadRegisterParentResponseCallback(otInstance * aInstance,otThreadParentResponseCallback aCallback,void * aContext)486 void otThreadRegisterParentResponseCallback(otInstance *aInstance,
487 otThreadParentResponseCallback aCallback,
488 void *aContext)
489 {
490 AsCoreType(aInstance).Get<Mle::MleRouter>().RegisterParentResponseStatsCallback(aCallback, aContext);
491 }
492 #endif
493
494 #if OPENTHREAD_CONFIG_TMF_ANYCAST_LOCATOR_ENABLE
otThreadLocateAnycastDestination(otInstance * aInstance,const otIp6Address * aAnycastAddress,otThreadAnycastLocatorCallback aCallback,void * aContext)495 otError otThreadLocateAnycastDestination(otInstance *aInstance,
496 const otIp6Address *aAnycastAddress,
497 otThreadAnycastLocatorCallback aCallback,
498 void *aContext)
499 {
500 return AsCoreType(aInstance).Get<AnycastLocator>().Locate(AsCoreType(aAnycastAddress), aCallback, aContext);
501 }
502
otThreadIsAnycastLocateInProgress(otInstance * aInstance)503 bool otThreadIsAnycastLocateInProgress(otInstance *aInstance)
504 {
505 return AsCoreType(aInstance).Get<AnycastLocator>().IsInProgress();
506 }
507 #endif
508
otThreadDetachGracefully(otInstance * aInstance,otDetachGracefullyCallback aCallback,void * aContext)509 otError otThreadDetachGracefully(otInstance *aInstance, otDetachGracefullyCallback aCallback, void *aContext)
510 {
511 return AsCoreType(aInstance).Get<Mle::MleRouter>().DetachGracefully(aCallback, aContext);
512 }
513
514 #if OPENTHREAD_CONFIG_DYNAMIC_STORE_FRAME_AHEAD_COUNTER_ENABLE
otThreadSetStoreFrameCounterAhead(otInstance * aInstance,uint32_t aStoreFrameCounterAhead)515 void otThreadSetStoreFrameCounterAhead(otInstance *aInstance, uint32_t aStoreFrameCounterAhead)
516 {
517 return AsCoreType(aInstance).Get<Mle::Mle>().SetStoreFrameCounterAhead(aStoreFrameCounterAhead);
518 }
519
otThreadGetStoreFrameCounterAhead(otInstance * aInstance)520 uint32_t otThreadGetStoreFrameCounterAhead(otInstance *aInstance)
521 {
522 return AsCoreType(aInstance).Get<Mle::Mle>().GetStoreFrameCounterAhead();
523 }
524 #endif
525
526 #if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE
otThreadWakeup(otInstance * aInstance,const otExtAddress * aWedAddress,uint16_t aWakeupIntervalUs,uint16_t aWakeupDurationMs,otWakeupCallback aCallback,void * aCallbackContext)527 otError otThreadWakeup(otInstance *aInstance,
528 const otExtAddress *aWedAddress,
529 uint16_t aWakeupIntervalUs,
530 uint16_t aWakeupDurationMs,
531 otWakeupCallback aCallback,
532 void *aCallbackContext)
533 {
534 return AsCoreType(aInstance).Get<Mle::Mle>().Wakeup(AsCoreType(aWedAddress), aWakeupIntervalUs, aWakeupDurationMs,
535 aCallback, aCallbackContext);
536 }
537 #endif
538
539 #endif // OPENTHREAD_FTD || OPENTHREAD_MTD
540
541 #if OPENTHREAD_CONFIG_UPTIME_ENABLE
otConvertDurationInSecondsToString(uint32_t aDuration,char * aBuffer,uint16_t aSize)542 void otConvertDurationInSecondsToString(uint32_t aDuration, char *aBuffer, uint16_t aSize)
543 {
544 StringWriter writer(aBuffer, aSize);
545
546 Uptime::UptimeToString(Uptime::SecToMsec(aDuration), writer, /* aIncludeMsec */ false);
547 }
548 #endif
549