• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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