1 /*
2 * Copyright (c) 2016-2017, 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 (FTD only).
32 */
33
34 #include "openthread-core-config.h"
35
36 #if OPENTHREAD_FTD
37
38 #include "instance/instance.hpp"
39
40 using namespace ot;
41
otThreadGetMaxAllowedChildren(otInstance * aInstance)42 uint16_t otThreadGetMaxAllowedChildren(otInstance *aInstance)
43 {
44 return AsCoreType(aInstance).Get<ChildTable>().GetMaxChildrenAllowed();
45 }
46
otThreadSetMaxAllowedChildren(otInstance * aInstance,uint16_t aMaxChildren)47 otError otThreadSetMaxAllowedChildren(otInstance *aInstance, uint16_t aMaxChildren)
48 {
49 return AsCoreType(aInstance).Get<ChildTable>().SetMaxChildrenAllowed(aMaxChildren);
50 }
51
otThreadGetMaxChildIpAddresses(otInstance * aInstance)52 uint8_t otThreadGetMaxChildIpAddresses(otInstance *aInstance)
53 {
54 return AsCoreType(aInstance).Get<Mle::MleRouter>().GetMaxChildIpAddresses();
55 }
56
57 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
otThreadSetMaxChildIpAddresses(otInstance * aInstance,uint8_t aMaxIpAddresses)58 otError otThreadSetMaxChildIpAddresses(otInstance *aInstance, uint8_t aMaxIpAddresses)
59 {
60 return AsCoreType(aInstance).Get<Mle::MleRouter>().SetMaxChildIpAddresses(aMaxIpAddresses);
61 }
62 #endif
63
otThreadIsRouterEligible(otInstance * aInstance)64 bool otThreadIsRouterEligible(otInstance *aInstance)
65 {
66 return AsCoreType(aInstance).Get<Mle::MleRouter>().IsRouterEligible();
67 }
68
otThreadSetRouterEligible(otInstance * aInstance,bool aEligible)69 otError otThreadSetRouterEligible(otInstance *aInstance, bool aEligible)
70 {
71 return AsCoreType(aInstance).Get<Mle::MleRouter>().SetRouterEligible(aEligible);
72 }
73
otThreadSetPreferredRouterId(otInstance * aInstance,uint8_t aRouterId)74 otError otThreadSetPreferredRouterId(otInstance *aInstance, uint8_t aRouterId)
75 {
76 return AsCoreType(aInstance).Get<Mle::MleRouter>().SetPreferredRouterId(aRouterId);
77 }
78
79 #if OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE
otThreadGetDeviceProperties(otInstance * aInstance)80 const otDeviceProperties *otThreadGetDeviceProperties(otInstance *aInstance)
81 {
82 return &AsCoreType(aInstance).Get<Mle::MleRouter>().GetDeviceProperties();
83 }
84
otThreadSetDeviceProperties(otInstance * aInstance,const otDeviceProperties * aDeviceProperties)85 void otThreadSetDeviceProperties(otInstance *aInstance, const otDeviceProperties *aDeviceProperties)
86 {
87 AsCoreType(aInstance).Get<Mle::MleRouter>().SetDeviceProperties(AsCoreType(aDeviceProperties));
88 }
89 #endif
90
otThreadGetLocalLeaderWeight(otInstance * aInstance)91 uint8_t otThreadGetLocalLeaderWeight(otInstance *aInstance)
92 {
93 return AsCoreType(aInstance).Get<Mle::MleRouter>().GetLeaderWeight();
94 }
95
otThreadSetLocalLeaderWeight(otInstance * aInstance,uint8_t aWeight)96 void otThreadSetLocalLeaderWeight(otInstance *aInstance, uint8_t aWeight)
97 {
98 AsCoreType(aInstance).Get<Mle::MleRouter>().SetLeaderWeight(aWeight);
99 }
100
101 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
otThreadGetPreferredLeaderPartitionId(otInstance * aInstance)102 uint32_t otThreadGetPreferredLeaderPartitionId(otInstance *aInstance)
103 {
104 return AsCoreType(aInstance).Get<Mle::MleRouter>().GetPreferredLeaderPartitionId();
105 }
106
otThreadSetPreferredLeaderPartitionId(otInstance * aInstance,uint32_t aPartitionId)107 void otThreadSetPreferredLeaderPartitionId(otInstance *aInstance, uint32_t aPartitionId)
108 {
109 AsCoreType(aInstance).Get<Mle::MleRouter>().SetPreferredLeaderPartitionId(aPartitionId);
110 }
111 #endif
112
otThreadGetJoinerUdpPort(otInstance * aInstance)113 uint16_t otThreadGetJoinerUdpPort(otInstance *aInstance)
114 {
115 return AsCoreType(aInstance).Get<MeshCoP::JoinerRouter>().GetJoinerUdpPort();
116 }
117
otThreadSetJoinerUdpPort(otInstance * aInstance,uint16_t aJoinerUdpPort)118 otError otThreadSetJoinerUdpPort(otInstance *aInstance, uint16_t aJoinerUdpPort)
119 {
120 AsCoreType(aInstance).Get<MeshCoP::JoinerRouter>().SetJoinerUdpPort(aJoinerUdpPort);
121
122 return kErrorNone;
123 }
124
otThreadGetContextIdReuseDelay(otInstance * aInstance)125 uint32_t otThreadGetContextIdReuseDelay(otInstance *aInstance)
126 {
127 return AsCoreType(aInstance).Get<NetworkData::Leader>().GetContextIdReuseDelay();
128 }
129
otThreadSetContextIdReuseDelay(otInstance * aInstance,uint32_t aDelay)130 void otThreadSetContextIdReuseDelay(otInstance *aInstance, uint32_t aDelay)
131 {
132 AsCoreType(aInstance).Get<NetworkData::Leader>().SetContextIdReuseDelay(aDelay);
133 }
134
otThreadGetNetworkIdTimeout(otInstance * aInstance)135 uint8_t otThreadGetNetworkIdTimeout(otInstance *aInstance)
136 {
137 return AsCoreType(aInstance).Get<Mle::MleRouter>().GetNetworkIdTimeout();
138 }
139
otThreadSetNetworkIdTimeout(otInstance * aInstance,uint8_t aTimeout)140 void otThreadSetNetworkIdTimeout(otInstance *aInstance, uint8_t aTimeout)
141 {
142 AsCoreType(aInstance).Get<Mle::MleRouter>().SetNetworkIdTimeout(aTimeout);
143 }
144
otThreadGetRouterUpgradeThreshold(otInstance * aInstance)145 uint8_t otThreadGetRouterUpgradeThreshold(otInstance *aInstance)
146 {
147 return AsCoreType(aInstance).Get<Mle::MleRouter>().GetRouterUpgradeThreshold();
148 }
149
otThreadSetRouterUpgradeThreshold(otInstance * aInstance,uint8_t aThreshold)150 void otThreadSetRouterUpgradeThreshold(otInstance *aInstance, uint8_t aThreshold)
151 {
152 AsCoreType(aInstance).Get<Mle::MleRouter>().SetRouterUpgradeThreshold(aThreshold);
153 }
154
otThreadGetChildRouterLinks(otInstance * aInstance)155 uint8_t otThreadGetChildRouterLinks(otInstance *aInstance)
156 {
157 return AsCoreType(aInstance).Get<Mle::MleRouter>().GetChildRouterLinks();
158 }
159
otThreadSetChildRouterLinks(otInstance * aInstance,uint8_t aChildRouterLinks)160 otError otThreadSetChildRouterLinks(otInstance *aInstance, uint8_t aChildRouterLinks)
161 {
162 return AsCoreType(aInstance).Get<Mle::MleRouter>().SetChildRouterLinks(aChildRouterLinks);
163 }
164
otThreadReleaseRouterId(otInstance * aInstance,uint8_t aRouterId)165 otError otThreadReleaseRouterId(otInstance *aInstance, uint8_t aRouterId)
166 {
167 Error error = kErrorNone;
168
169 VerifyOrExit(aRouterId <= Mle::kMaxRouterId, error = kErrorInvalidArgs);
170
171 error = AsCoreType(aInstance).Get<RouterTable>().Release(aRouterId);
172
173 exit:
174 return error;
175 }
176
otThreadBecomeRouter(otInstance * aInstance)177 otError otThreadBecomeRouter(otInstance *aInstance)
178 {
179 return AsCoreType(aInstance).Get<Mle::MleRouter>().BecomeRouter(ThreadStatusTlv::kHaveChildIdRequest);
180 }
181
otThreadBecomeLeader(otInstance * aInstance)182 otError otThreadBecomeLeader(otInstance *aInstance)
183 {
184 return AsCoreType(aInstance).Get<Mle::MleRouter>().BecomeLeader(/* aCheckWeight */ true);
185 }
186
otThreadGetRouterDowngradeThreshold(otInstance * aInstance)187 uint8_t otThreadGetRouterDowngradeThreshold(otInstance *aInstance)
188 {
189 return AsCoreType(aInstance).Get<Mle::MleRouter>().GetRouterDowngradeThreshold();
190 }
191
otThreadSetRouterDowngradeThreshold(otInstance * aInstance,uint8_t aThreshold)192 void otThreadSetRouterDowngradeThreshold(otInstance *aInstance, uint8_t aThreshold)
193 {
194 AsCoreType(aInstance).Get<Mle::MleRouter>().SetRouterDowngradeThreshold(aThreshold);
195 }
196
otThreadGetRouterSelectionJitter(otInstance * aInstance)197 uint8_t otThreadGetRouterSelectionJitter(otInstance *aInstance)
198 {
199 return AsCoreType(aInstance).Get<Mle::MleRouter>().GetRouterSelectionJitter();
200 }
201
otThreadSetRouterSelectionJitter(otInstance * aInstance,uint8_t aRouterJitter)202 void otThreadSetRouterSelectionJitter(otInstance *aInstance, uint8_t aRouterJitter)
203 {
204 AsCoreType(aInstance).Get<Mle::MleRouter>().SetRouterSelectionJitter(aRouterJitter);
205 }
206
otThreadGetChildInfoById(otInstance * aInstance,uint16_t aChildId,otChildInfo * aChildInfo)207 otError otThreadGetChildInfoById(otInstance *aInstance, uint16_t aChildId, otChildInfo *aChildInfo)
208 {
209 return AsCoreType(aInstance).Get<ChildTable>().GetChildInfoById(aChildId, AsCoreType(aChildInfo));
210 }
211
otThreadGetChildInfoByIndex(otInstance * aInstance,uint16_t aChildIndex,otChildInfo * aChildInfo)212 otError otThreadGetChildInfoByIndex(otInstance *aInstance, uint16_t aChildIndex, otChildInfo *aChildInfo)
213 {
214 return AsCoreType(aInstance).Get<ChildTable>().GetChildInfoByIndex(aChildIndex, AsCoreType(aChildInfo));
215 }
216
otThreadGetChildNextIp6Address(otInstance * aInstance,uint16_t aChildIndex,otChildIp6AddressIterator * aIterator,otIp6Address * aAddress)217 otError otThreadGetChildNextIp6Address(otInstance *aInstance,
218 uint16_t aChildIndex,
219 otChildIp6AddressIterator *aIterator,
220 otIp6Address *aAddress)
221 {
222 Error error = kErrorNone;
223 const Child *child;
224
225 AssertPointerIsNotNull(aIterator);
226 AssertPointerIsNotNull(aAddress);
227
228 child = AsCoreType(aInstance).Get<ChildTable>().GetChildAtIndex(aChildIndex);
229 VerifyOrExit(child != nullptr, error = kErrorInvalidArgs);
230 VerifyOrExit(child->IsStateValidOrRestoring(), error = kErrorInvalidArgs);
231
232 error = child->GetNextIp6Address(*aIterator, AsCoreType(aAddress));
233
234 exit:
235 return error;
236 }
237
otThreadGetRouterIdSequence(otInstance * aInstance)238 uint8_t otThreadGetRouterIdSequence(otInstance *aInstance)
239 {
240 return AsCoreType(aInstance).Get<RouterTable>().GetRouterIdSequence();
241 }
242
otThreadGetMaxRouterId(otInstance * aInstance)243 uint8_t otThreadGetMaxRouterId(otInstance *aInstance)
244 {
245 OT_UNUSED_VARIABLE(aInstance);
246 return Mle::kMaxRouterId;
247 }
248
otThreadGetRouterInfo(otInstance * aInstance,uint16_t aRouterId,otRouterInfo * aRouterInfo)249 otError otThreadGetRouterInfo(otInstance *aInstance, uint16_t aRouterId, otRouterInfo *aRouterInfo)
250 {
251 return AsCoreType(aInstance).Get<RouterTable>().GetRouterInfo(aRouterId, AsCoreType(aRouterInfo));
252 }
253
otThreadGetNextCacheEntry(otInstance * aInstance,otCacheEntryInfo * aEntryInfo,otCacheEntryIterator * aIterator)254 otError otThreadGetNextCacheEntry(otInstance *aInstance, otCacheEntryInfo *aEntryInfo, otCacheEntryIterator *aIterator)
255 {
256 return AsCoreType(aInstance).Get<AddressResolver>().GetNextCacheEntry(AsCoreType(aEntryInfo),
257 AsCoreType(aIterator));
258 }
259
260 #if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
otThreadSetSteeringData(otInstance * aInstance,const otExtAddress * aExtAddress)261 void otThreadSetSteeringData(otInstance *aInstance, const otExtAddress *aExtAddress)
262 {
263 AsCoreType(aInstance).Get<Mle::MleRouter>().SetSteeringData(AsCoreTypePtr(aExtAddress));
264 }
265 #endif
266
otThreadGetPskc(otInstance * aInstance,otPskc * aPskc)267 void otThreadGetPskc(otInstance *aInstance, otPskc *aPskc)
268 {
269 AsCoreType(aInstance).Get<KeyManager>().GetPskc(AsCoreType(aPskc));
270 }
271
272 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
otThreadGetPskcRef(otInstance * aInstance)273 otPskcRef otThreadGetPskcRef(otInstance *aInstance) { return AsCoreType(aInstance).Get<KeyManager>().GetPskcRef(); }
274 #endif
275
otThreadSetPskc(otInstance * aInstance,const otPskc * aPskc)276 otError otThreadSetPskc(otInstance *aInstance, const otPskc *aPskc)
277 {
278 Error error = kErrorNone;
279
280 VerifyOrExit(AsCoreType(aInstance).Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
281
282 AsCoreType(aInstance).Get<KeyManager>().SetPskc(AsCoreType(aPskc));
283 AsCoreType(aInstance).Get<MeshCoP::ActiveDatasetManager>().Clear();
284 AsCoreType(aInstance).Get<MeshCoP::PendingDatasetManager>().Clear();
285
286 exit:
287 return error;
288 }
289
290 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
otThreadSetPskcRef(otInstance * aInstance,otPskcRef aKeyRef)291 otError otThreadSetPskcRef(otInstance *aInstance, otPskcRef aKeyRef)
292 {
293 Error error = kErrorNone;
294 Instance &instance = AsCoreType(aInstance);
295
296 VerifyOrExit(aKeyRef != 0, error = kErrorInvalidArgs);
297 VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
298
299 instance.Get<KeyManager>().SetPskcRef(aKeyRef);
300 instance.Get<MeshCoP::ActiveDatasetManager>().Clear();
301 instance.Get<MeshCoP::PendingDatasetManager>().Clear();
302
303 exit:
304 return error;
305 }
306 #endif
307
otThreadGetParentPriority(otInstance * aInstance)308 int8_t otThreadGetParentPriority(otInstance *aInstance)
309 {
310 return AsCoreType(aInstance).Get<Mle::MleRouter>().GetAssignParentPriority();
311 }
312
otThreadSetParentPriority(otInstance * aInstance,int8_t aParentPriority)313 otError otThreadSetParentPriority(otInstance *aInstance, int8_t aParentPriority)
314 {
315 return AsCoreType(aInstance).Get<Mle::MleRouter>().SetAssignParentPriority(aParentPriority);
316 }
317
otThreadRegisterNeighborTableCallback(otInstance * aInstance,otNeighborTableCallback aCallback)318 void otThreadRegisterNeighborTableCallback(otInstance *aInstance, otNeighborTableCallback aCallback)
319 {
320 AsCoreType(aInstance).Get<NeighborTable>().RegisterCallback(aCallback);
321 }
322
otThreadSetDiscoveryRequestCallback(otInstance * aInstance,otThreadDiscoveryRequestCallback aCallback,void * aContext)323 void otThreadSetDiscoveryRequestCallback(otInstance *aInstance,
324 otThreadDiscoveryRequestCallback aCallback,
325 void *aContext)
326 {
327 AsCoreType(aInstance).Get<Mle::MleRouter>().SetDiscoveryRequestCallback(aCallback, aContext);
328 }
329
330 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
331
otThreadSendAddressNotification(otInstance * aInstance,otIp6Address * aDestination,otIp6Address * aTarget,otIp6InterfaceIdentifier * aMlIid)332 void otThreadSendAddressNotification(otInstance *aInstance,
333 otIp6Address *aDestination,
334 otIp6Address *aTarget,
335 otIp6InterfaceIdentifier *aMlIid)
336 {
337 AsCoreType(aInstance).Get<AddressResolver>().SendAddressQueryResponse(AsCoreType(aTarget), AsCoreType(aMlIid),
338 nullptr, AsCoreType(aDestination));
339 }
340
341 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
otThreadSendProactiveBackboneNotification(otInstance * aInstance,otIp6Address * aTarget,otIp6InterfaceIdentifier * aMlIid,uint32_t aTimeSinceLastTransaction)342 otError otThreadSendProactiveBackboneNotification(otInstance *aInstance,
343 otIp6Address *aTarget,
344 otIp6InterfaceIdentifier *aMlIid,
345 uint32_t aTimeSinceLastTransaction)
346 {
347 return AsCoreType(aInstance).Get<BackboneRouter::Manager>().SendProactiveBackboneNotification(
348 AsCoreType(aTarget), AsCoreType(aMlIid), aTimeSinceLastTransaction);
349 }
350 #endif
351
otThreadSetCcmEnabled(otInstance * aInstance,bool aEnabled)352 void otThreadSetCcmEnabled(otInstance *aInstance, bool aEnabled)
353 {
354 AsCoreType(aInstance).Get<Mle::MleRouter>().SetCcmEnabled(aEnabled);
355 }
356
otThreadSetThreadVersionCheckEnabled(otInstance * aInstance,bool aEnabled)357 void otThreadSetThreadVersionCheckEnabled(otInstance *aInstance, bool aEnabled)
358 {
359 AsCoreType(aInstance).Get<Mle::MleRouter>().SetThreadVersionCheckEnabled(aEnabled);
360 }
361
otThreadSetTmfOriginFilterEnabled(otInstance * aInstance,bool aEnabled)362 void otThreadSetTmfOriginFilterEnabled(otInstance *aInstance, bool aEnabled)
363 {
364 AsCoreType(aInstance).Get<Ip6::Ip6>().SetTmfOriginFilterEnabled(aEnabled);
365 }
366
otThreadIsTmfOriginFilterEnabled(otInstance * aInstance)367 bool otThreadIsTmfOriginFilterEnabled(otInstance *aInstance)
368 {
369 return AsCoreType(aInstance).Get<Ip6::Ip6>().IsTmfOriginFilterEnabled();
370 }
371
otThreadGetRouterIdRange(otInstance * aInstance,uint8_t * aMinRouterId,uint8_t * aMaxRouterId)372 void otThreadGetRouterIdRange(otInstance *aInstance, uint8_t *aMinRouterId, uint8_t *aMaxRouterId)
373 {
374 AssertPointerIsNotNull(aMinRouterId);
375 AssertPointerIsNotNull(aMaxRouterId);
376
377 AsCoreType(aInstance).Get<RouterTable>().GetRouterIdRange(*aMinRouterId, *aMaxRouterId);
378 }
379
otThreadSetRouterIdRange(otInstance * aInstance,uint8_t aMinRouterId,uint8_t aMaxRouterId)380 otError otThreadSetRouterIdRange(otInstance *aInstance, uint8_t aMinRouterId, uint8_t aMaxRouterId)
381 {
382 return AsCoreType(aInstance).Get<RouterTable>().SetRouterIdRange(aMinRouterId, aMaxRouterId);
383 }
384
otThreadGetAdvertisementTrickleIntervalMax(otInstance * aInstance)385 uint32_t otThreadGetAdvertisementTrickleIntervalMax(otInstance *aInstance)
386 {
387 return AsCoreType(aInstance).Get<Mle::MleRouter>().GetAdvertisementTrickleIntervalMax();
388 }
389
390 #endif // OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
391
otThreadIsRouterIdAllocated(otInstance * aInstance,uint8_t aRouterId)392 bool otThreadIsRouterIdAllocated(otInstance *aInstance, uint8_t aRouterId)
393 {
394 return AsCoreType(aInstance).Get<RouterTable>().IsAllocated(aRouterId);
395 }
396
otThreadGetNextHopAndPathCost(otInstance * aInstance,uint16_t aDestRloc16,uint16_t * aNextHopRloc16,uint8_t * aPathCost)397 void otThreadGetNextHopAndPathCost(otInstance *aInstance,
398 uint16_t aDestRloc16,
399 uint16_t *aNextHopRloc16,
400 uint8_t *aPathCost)
401 {
402 uint8_t pathcost;
403 uint16_t nextHopRloc16;
404
405 AsCoreType(aInstance).Get<RouterTable>().GetNextHopAndPathCost(
406 aDestRloc16, (aNextHopRloc16 != nullptr) ? *aNextHopRloc16 : nextHopRloc16,
407 (aPathCost != nullptr) ? *aPathCost : pathcost);
408 }
409
410 #endif // OPENTHREAD_FTD
411