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 <openthread/thread.h>
39
40 #include "common/as_core_type.hpp"
41 #include "common/debug.hpp"
42 #include "common/locator_getters.hpp"
43
44 using namespace ot;
45
otThreadGetChildTimeout(otInstance * aInstance)46 uint32_t otThreadGetChildTimeout(otInstance *aInstance)
47 {
48 return AsCoreType(aInstance).Get<Mle::MleRouter>().GetTimeout();
49 }
50
otThreadSetChildTimeout(otInstance * aInstance,uint32_t aTimeout)51 void otThreadSetChildTimeout(otInstance *aInstance, uint32_t aTimeout)
52 {
53 AsCoreType(aInstance).Get<Mle::MleRouter>().SetTimeout(aTimeout);
54 }
55
otThreadGetExtendedPanId(otInstance * aInstance)56 const otExtendedPanId *otThreadGetExtendedPanId(otInstance *aInstance)
57 {
58 return &AsCoreType(aInstance).Get<MeshCoP::ExtendedPanIdManager>().GetExtPanId();
59 }
60
otThreadSetExtendedPanId(otInstance * aInstance,const otExtendedPanId * aExtendedPanId)61 otError otThreadSetExtendedPanId(otInstance *aInstance, const otExtendedPanId *aExtendedPanId)
62 {
63 Error error = kErrorNone;
64 Instance & instance = AsCoreType(aInstance);
65 const MeshCoP::ExtendedPanId &extPanId = AsCoreType(aExtendedPanId);
66
67 VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
68
69 instance.Get<MeshCoP::ExtendedPanIdManager>().SetExtPanId(extPanId);
70
71 instance.Get<MeshCoP::ActiveDatasetManager>().Clear();
72 instance.Get<MeshCoP::PendingDatasetManager>().Clear();
73
74 exit:
75 return error;
76 }
77
otThreadGetLeaderRloc(otInstance * aInstance,otIp6Address * aLeaderRloc)78 otError otThreadGetLeaderRloc(otInstance *aInstance, otIp6Address *aLeaderRloc)
79 {
80 OT_ASSERT(aLeaderRloc != nullptr);
81
82 return AsCoreType(aInstance).Get<Mle::MleRouter>().GetLeaderAddress(AsCoreType(aLeaderRloc));
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 OT_ASSERT(aKey != nullptr);
117
118 VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
119
120 instance.Get<KeyManager>().SetNetworkKey(AsCoreType(aKey));
121
122 instance.Get<MeshCoP::ActiveDatasetManager>().Clear();
123 instance.Get<MeshCoP::PendingDatasetManager>().Clear();
124
125 exit:
126 return error;
127 }
128
129 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
otThreadSetNetworkKeyRef(otInstance * aInstance,otNetworkKeyRef aKeyRef)130 otError otThreadSetNetworkKeyRef(otInstance *aInstance, otNetworkKeyRef aKeyRef)
131 {
132 Error error = kErrorNone;
133 Instance &instance = AsCoreType(aInstance);
134
135 VerifyOrExit(aKeyRef != 0, error = kErrorInvalidArgs);
136
137 VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
138
139 instance.Get<KeyManager>().SetNetworkKeyRef((aKeyRef));
140 instance.Get<MeshCoP::ActiveDatasetManager>().Clear();
141 instance.Get<MeshCoP::PendingDatasetManager>().Clear();
142
143 exit:
144 return error;
145 }
146 #endif
147
otThreadGetRloc(otInstance * aInstance)148 const otIp6Address *otThreadGetRloc(otInstance *aInstance)
149 {
150 return &AsCoreType(aInstance).Get<Mle::MleRouter>().GetMeshLocal16();
151 }
152
otThreadGetMeshLocalEid(otInstance * aInstance)153 const otIp6Address *otThreadGetMeshLocalEid(otInstance *aInstance)
154 {
155 return &AsCoreType(aInstance).Get<Mle::MleRouter>().GetMeshLocal64();
156 }
157
otThreadGetMeshLocalPrefix(otInstance * aInstance)158 const otMeshLocalPrefix *otThreadGetMeshLocalPrefix(otInstance *aInstance)
159 {
160 return &AsCoreType(aInstance).Get<Mle::MleRouter>().GetMeshLocalPrefix();
161 }
162
otThreadSetMeshLocalPrefix(otInstance * aInstance,const otMeshLocalPrefix * aMeshLocalPrefix)163 otError otThreadSetMeshLocalPrefix(otInstance *aInstance, const otMeshLocalPrefix *aMeshLocalPrefix)
164 {
165 Error error = kErrorNone;
166
167 VerifyOrExit(AsCoreType(aInstance).Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
168
169 AsCoreType(aInstance).Get<Mle::MleRouter>().SetMeshLocalPrefix(AsCoreType(aMeshLocalPrefix));
170 AsCoreType(aInstance).Get<MeshCoP::ActiveDatasetManager>().Clear();
171 AsCoreType(aInstance).Get<MeshCoP::PendingDatasetManager>().Clear();
172
173 exit:
174 return error;
175 }
176
otThreadGetLinkLocalIp6Address(otInstance * aInstance)177 const otIp6Address *otThreadGetLinkLocalIp6Address(otInstance *aInstance)
178 {
179 return &AsCoreType(aInstance).Get<Mle::MleRouter>().GetLinkLocalAddress();
180 }
181
otThreadGetLinkLocalAllThreadNodesMulticastAddress(otInstance * aInstance)182 const otIp6Address *otThreadGetLinkLocalAllThreadNodesMulticastAddress(otInstance *aInstance)
183 {
184 return &AsCoreType(aInstance).Get<Mle::MleRouter>().GetLinkLocalAllThreadNodesAddress();
185 }
186
otThreadGetRealmLocalAllThreadNodesMulticastAddress(otInstance * aInstance)187 const otIp6Address *otThreadGetRealmLocalAllThreadNodesMulticastAddress(otInstance *aInstance)
188 {
189 return &AsCoreType(aInstance).Get<Mle::MleRouter>().GetRealmLocalAllThreadNodesAddress();
190 }
191
otThreadGetServiceAloc(otInstance * aInstance,uint8_t aServiceId,otIp6Address * aServiceAloc)192 otError otThreadGetServiceAloc(otInstance *aInstance, uint8_t aServiceId, otIp6Address *aServiceAloc)
193 {
194 return AsCoreType(aInstance).Get<Mle::MleRouter>().GetServiceAloc(aServiceId, AsCoreType(aServiceAloc));
195 }
196
otThreadGetNetworkName(otInstance * aInstance)197 const char *otThreadGetNetworkName(otInstance *aInstance)
198 {
199 return AsCoreType(aInstance).Get<MeshCoP::NetworkNameManager>().GetNetworkName().GetAsCString();
200 }
201
otThreadSetNetworkName(otInstance * aInstance,const char * aNetworkName)202 otError otThreadSetNetworkName(otInstance *aInstance, const char *aNetworkName)
203 {
204 Error error = kErrorNone;
205
206 VerifyOrExit(AsCoreType(aInstance).Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
207
208 error = AsCoreType(aInstance).Get<MeshCoP::NetworkNameManager>().SetNetworkName(aNetworkName);
209 AsCoreType(aInstance).Get<MeshCoP::ActiveDatasetManager>().Clear();
210 AsCoreType(aInstance).Get<MeshCoP::PendingDatasetManager>().Clear();
211
212 exit:
213 return error;
214 }
215
216 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
otThreadGetDomainName(otInstance * aInstance)217 const char *otThreadGetDomainName(otInstance *aInstance)
218 {
219 return AsCoreType(aInstance).Get<MeshCoP::NetworkNameManager>().GetDomainName().GetAsCString();
220 }
221
otThreadSetDomainName(otInstance * aInstance,const char * aDomainName)222 otError otThreadSetDomainName(otInstance *aInstance, const char *aDomainName)
223 {
224 Error error = kErrorNone;
225
226 VerifyOrExit(AsCoreType(aInstance).Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
227
228 error = AsCoreType(aInstance).Get<MeshCoP::NetworkNameManager>().SetDomainName(aDomainName);
229
230 exit:
231 return error;
232 }
233
234 #if OPENTHREAD_CONFIG_DUA_ENABLE
otThreadSetFixedDuaInterfaceIdentifier(otInstance * aInstance,const otIp6InterfaceIdentifier * aIid)235 otError otThreadSetFixedDuaInterfaceIdentifier(otInstance *aInstance, const otIp6InterfaceIdentifier *aIid)
236 {
237 Error error = kErrorNone;
238
239 if (aIid)
240 {
241 error = AsCoreType(aInstance).Get<DuaManager>().SetFixedDuaInterfaceIdentifier(AsCoreType(aIid));
242 }
243 else
244 {
245 AsCoreType(aInstance).Get<DuaManager>().ClearFixedDuaInterfaceIdentifier();
246 }
247
248 return error;
249 }
250
otThreadGetFixedDuaInterfaceIdentifier(otInstance * aInstance)251 const otIp6InterfaceIdentifier *otThreadGetFixedDuaInterfaceIdentifier(otInstance *aInstance)
252 {
253 Instance & instance = AsCoreType(aInstance);
254 const otIp6InterfaceIdentifier *iid = nullptr;
255
256 if (instance.Get<DuaManager>().IsFixedDuaInterfaceIdentifierSet())
257 {
258 iid = &instance.Get<DuaManager>().GetFixedDuaInterfaceIdentifier();
259 }
260
261 return iid;
262 }
263 #endif // OPENTHREAD_CONFIG_DUA_ENABLE
264
265 #endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
266
otThreadGetKeySequenceCounter(otInstance * aInstance)267 uint32_t otThreadGetKeySequenceCounter(otInstance *aInstance)
268 {
269 return AsCoreType(aInstance).Get<KeyManager>().GetCurrentKeySequence();
270 }
271
otThreadSetKeySequenceCounter(otInstance * aInstance,uint32_t aKeySequenceCounter)272 void otThreadSetKeySequenceCounter(otInstance *aInstance, uint32_t aKeySequenceCounter)
273 {
274 AsCoreType(aInstance).Get<KeyManager>().SetCurrentKeySequence(aKeySequenceCounter);
275 }
276
otThreadGetKeySwitchGuardTime(otInstance * aInstance)277 uint32_t otThreadGetKeySwitchGuardTime(otInstance *aInstance)
278 {
279 return AsCoreType(aInstance).Get<KeyManager>().GetKeySwitchGuardTime();
280 }
281
otThreadSetKeySwitchGuardTime(otInstance * aInstance,uint32_t aKeySwitchGuardTime)282 void otThreadSetKeySwitchGuardTime(otInstance *aInstance, uint32_t aKeySwitchGuardTime)
283 {
284 AsCoreType(aInstance).Get<KeyManager>().SetKeySwitchGuardTime(aKeySwitchGuardTime);
285 }
286
otThreadBecomeDetached(otInstance * aInstance)287 otError otThreadBecomeDetached(otInstance *aInstance)
288 {
289 return AsCoreType(aInstance).Get<Mle::MleRouter>().BecomeDetached();
290 }
291
otThreadBecomeChild(otInstance * aInstance)292 otError otThreadBecomeChild(otInstance *aInstance)
293 {
294 return AsCoreType(aInstance).Get<Mle::MleRouter>().BecomeChild();
295 }
296
otThreadGetNextNeighborInfo(otInstance * aInstance,otNeighborInfoIterator * aIterator,otNeighborInfo * aInfo)297 otError otThreadGetNextNeighborInfo(otInstance *aInstance, otNeighborInfoIterator *aIterator, otNeighborInfo *aInfo)
298 {
299 OT_ASSERT((aInfo != nullptr) && (aIterator != nullptr));
300
301 return AsCoreType(aInstance).Get<NeighborTable>().GetNextNeighborInfo(*aIterator, AsCoreType(aInfo));
302 }
303
otThreadGetDeviceRole(otInstance * aInstance)304 otDeviceRole otThreadGetDeviceRole(otInstance *aInstance)
305 {
306 return MapEnum(AsCoreType(aInstance).Get<Mle::MleRouter>().GetRole());
307 }
308
otThreadDeviceRoleToString(otDeviceRole aRole)309 const char *otThreadDeviceRoleToString(otDeviceRole aRole)
310 {
311 return Mle::Mle::RoleToString(MapEnum(aRole));
312 }
313
otThreadGetLeaderData(otInstance * aInstance,otLeaderData * aLeaderData)314 otError otThreadGetLeaderData(otInstance *aInstance, otLeaderData *aLeaderData)
315 {
316 Error error = kErrorNone;
317
318 OT_ASSERT(aLeaderData != nullptr);
319
320 VerifyOrExit(AsCoreType(aInstance).Get<Mle::MleRouter>().IsAttached(), error = kErrorDetached);
321 *aLeaderData = AsCoreType(aInstance).Get<Mle::MleRouter>().GetLeaderData();
322
323 exit:
324 return error;
325 }
326
otThreadGetLeaderRouterId(otInstance * aInstance)327 uint8_t otThreadGetLeaderRouterId(otInstance *aInstance)
328 {
329 return AsCoreType(aInstance).Get<Mle::MleRouter>().GetLeaderId();
330 }
331
otThreadGetLeaderWeight(otInstance * aInstance)332 uint8_t otThreadGetLeaderWeight(otInstance *aInstance)
333 {
334 return AsCoreType(aInstance).Get<Mle::MleRouter>().GetLeaderData().GetWeighting();
335 }
336
otThreadGetPartitionId(otInstance * aInstance)337 uint32_t otThreadGetPartitionId(otInstance *aInstance)
338 {
339 return AsCoreType(aInstance).Get<Mle::MleRouter>().GetLeaderData().GetPartitionId();
340 }
341
otThreadGetRloc16(otInstance * aInstance)342 uint16_t otThreadGetRloc16(otInstance *aInstance)
343 {
344 return AsCoreType(aInstance).Get<Mle::MleRouter>().GetRloc16();
345 }
346
otThreadGetParentInfo(otInstance * aInstance,otRouterInfo * aParentInfo)347 otError otThreadGetParentInfo(otInstance *aInstance, otRouterInfo *aParentInfo)
348 {
349 Error error = kErrorNone;
350 Router *parent;
351
352 OT_ASSERT(aParentInfo != nullptr);
353
354 // Reference device needs get the original parent's info even after the node state changed.
355 #if !OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
356 VerifyOrExit(AsCoreType(aInstance).Get<Mle::MleRouter>().IsChild(), error = kErrorInvalidState);
357 #endif
358
359 parent = &AsCoreType(aInstance).Get<Mle::MleRouter>().GetParent();
360
361 aParentInfo->mExtAddress = parent->GetExtAddress();
362 aParentInfo->mRloc16 = parent->GetRloc16();
363 aParentInfo->mRouterId = Mle::Mle::RouterIdFromRloc16(parent->GetRloc16());
364 aParentInfo->mNextHop = parent->GetNextHop();
365 aParentInfo->mPathCost = parent->GetCost();
366 aParentInfo->mLinkQualityIn = parent->GetLinkInfo().GetLinkQuality();
367 aParentInfo->mLinkQualityOut = parent->GetLinkQualityOut();
368 aParentInfo->mAge = static_cast<uint8_t>(Time::MsecToSec(TimerMilli::GetNow() - parent->GetLastHeard()));
369 aParentInfo->mAllocated = true;
370 aParentInfo->mLinkEstablished = parent->IsStateValid();
371
372 #if !OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
373 exit:
374 #endif
375 return error;
376 }
377
otThreadGetParentAverageRssi(otInstance * aInstance,int8_t * aParentRssi)378 otError otThreadGetParentAverageRssi(otInstance *aInstance, int8_t *aParentRssi)
379 {
380 Error error = kErrorNone;
381
382 OT_ASSERT(aParentRssi != nullptr);
383
384 *aParentRssi = AsCoreType(aInstance).Get<Mle::MleRouter>().GetParent().GetLinkInfo().GetAverageRss();
385
386 VerifyOrExit(*aParentRssi != OT_RADIO_RSSI_INVALID, error = kErrorFailed);
387
388 exit:
389 return error;
390 }
391
otThreadGetParentLastRssi(otInstance * aInstance,int8_t * aLastRssi)392 otError otThreadGetParentLastRssi(otInstance *aInstance, int8_t *aLastRssi)
393 {
394 Error error = kErrorNone;
395
396 OT_ASSERT(aLastRssi != nullptr);
397
398 *aLastRssi = AsCoreType(aInstance).Get<Mle::MleRouter>().GetParent().GetLinkInfo().GetLastRss();
399
400 VerifyOrExit(*aLastRssi != OT_RADIO_RSSI_INVALID, error = kErrorFailed);
401
402 exit:
403 return error;
404 }
405
otThreadSetEnabled(otInstance * aInstance,bool aEnabled)406 otError otThreadSetEnabled(otInstance *aInstance, bool aEnabled)
407 {
408 Error error = kErrorNone;
409
410 if (aEnabled)
411 {
412 error = AsCoreType(aInstance).Get<Mle::MleRouter>().Start();
413 }
414 else
415 {
416 AsCoreType(aInstance).Get<Mle::MleRouter>().Stop();
417 }
418
419 return error;
420 }
421
otThreadGetVersion(void)422 uint16_t otThreadGetVersion(void)
423 {
424 return OPENTHREAD_CONFIG_THREAD_VERSION;
425 }
426
otThreadIsSingleton(otInstance * aInstance)427 bool otThreadIsSingleton(otInstance *aInstance)
428 {
429 return AsCoreType(aInstance).Get<Mle::MleRouter>().IsSingleton();
430 }
431
otThreadDiscover(otInstance * aInstance,uint32_t aScanChannels,uint16_t aPanId,bool aJoiner,bool aEnableEui64Filtering,otHandleActiveScanResult aCallback,void * aCallbackContext)432 otError otThreadDiscover(otInstance * aInstance,
433 uint32_t aScanChannels,
434 uint16_t aPanId,
435 bool aJoiner,
436 bool aEnableEui64Filtering,
437 otHandleActiveScanResult aCallback,
438 void * aCallbackContext)
439 {
440 return AsCoreType(aInstance).Get<Mle::DiscoverScanner>().Discover(
441 Mac::ChannelMask(aScanChannels), aPanId, aJoiner, aEnableEui64Filtering,
442 /* aFilterIndexes (use hash of factory EUI64) */ nullptr, aCallback, aCallbackContext);
443 }
444
otThreadSetJoinerAdvertisement(otInstance * aInstance,uint32_t aOui,const uint8_t * aAdvData,uint8_t aAdvDataLength)445 otError otThreadSetJoinerAdvertisement(otInstance * aInstance,
446 uint32_t aOui,
447 const uint8_t *aAdvData,
448 uint8_t aAdvDataLength)
449 {
450 return AsCoreType(aInstance).Get<Mle::DiscoverScanner>().SetJoinerAdvertisement(aOui, aAdvData, aAdvDataLength);
451 }
452
otThreadIsDiscoverInProgress(otInstance * aInstance)453 bool otThreadIsDiscoverInProgress(otInstance *aInstance)
454 {
455 return AsCoreType(aInstance).Get<Mle::DiscoverScanner>().IsInProgress();
456 }
457
otThreadGetIp6Counters(otInstance * aInstance)458 const otIpCounters *otThreadGetIp6Counters(otInstance *aInstance)
459 {
460 return &AsCoreType(aInstance).Get<MeshForwarder>().GetCounters();
461 }
462
otThreadResetIp6Counters(otInstance * aInstance)463 void otThreadResetIp6Counters(otInstance *aInstance)
464 {
465 AsCoreType(aInstance).Get<MeshForwarder>().ResetCounters();
466 }
467
otThreadGetMleCounters(otInstance * aInstance)468 const otMleCounters *otThreadGetMleCounters(otInstance *aInstance)
469 {
470 return &AsCoreType(aInstance).Get<Mle::MleRouter>().GetCounters();
471 }
472
otThreadResetMleCounters(otInstance * aInstance)473 void otThreadResetMleCounters(otInstance *aInstance)
474 {
475 AsCoreType(aInstance).Get<Mle::MleRouter>().ResetCounters();
476 }
477
otThreadRegisterParentResponseCallback(otInstance * aInstance,otThreadParentResponseCallback aCallback,void * aContext)478 void otThreadRegisterParentResponseCallback(otInstance * aInstance,
479 otThreadParentResponseCallback aCallback,
480 void * aContext)
481 {
482 AsCoreType(aInstance).Get<Mle::MleRouter>().RegisterParentResponseStatsCallback(aCallback, aContext);
483 }
484
485 #if OPENTHREAD_CONFIG_TMF_ANYCAST_LOCATOR_ENABLE
otThreadLocateAnycastDestination(otInstance * aInstance,const otIp6Address * aAnycastAddress,otThreadAnycastLocatorCallback aCallback,void * aContext)486 otError otThreadLocateAnycastDestination(otInstance * aInstance,
487 const otIp6Address * aAnycastAddress,
488 otThreadAnycastLocatorCallback aCallback,
489 void * aContext)
490 {
491 return AsCoreType(aInstance).Get<AnycastLocator>().Locate(AsCoreType(aAnycastAddress), aCallback, aContext);
492 }
493
otThreadIsAnycastLocateInProgress(otInstance * aInstance)494 bool otThreadIsAnycastLocateInProgress(otInstance *aInstance)
495 {
496 return AsCoreType(aInstance).Get<AnycastLocator>().IsInProgress();
497 }
498 #endif
499
otThreadDetachGracefully(otInstance * aInstance,otDetachGracefullyCallback aCallback,void * aContext)500 otError otThreadDetachGracefully(otInstance *aInstance, otDetachGracefullyCallback aCallback, void *aContext)
501 {
502 return AsCoreType(aInstance).Get<Mle::MleRouter>().DetachGracefully(aCallback, aContext);
503 }
504
505 #endif // OPENTHREAD_FTD || OPENTHREAD_MTD
506