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