• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 includes definitions for a Thread `Child`.
32  */
33 
34 #ifndef CHILD_HPP_
35 #define CHILD_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include "common/bit_set.hpp"
40 #include "thread/neighbor.hpp"
41 
42 namespace ot {
43 
44 #if OPENTHREAD_FTD
45 
46 #if OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD < 2
47 #error OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD should be at least set to 2.
48 #endif
49 
50 /**
51  * Represents a Thread Child.
52  */
53 class Child : public CslNeighbor
54 {
55 public:
56     static constexpr uint8_t kMaxRequestTlvs = 6;
57 
58     /**
59      * Maximum number of registered IPv6 addresses per child (excluding the mesh-local EID).
60      */
61     static constexpr uint16_t kNumIp6Addresses = OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD - 1;
62 
63     /**
64      * Represents the iterator for registered IPv6 address list of an MTD child.
65      */
66     typedef otChildIp6AddressIterator AddressIterator;
67 
68     /**
69      * The initial value for an `AddressIterator`.
70      */
71     static constexpr AddressIterator kAddressIteratorInit = OT_CHILD_IP6_ADDRESS_ITERATOR_INIT;
72 
73     /**
74      * Represents diagnostic information for a Thread Child.
75      */
76     class Info : public otChildInfo, public Clearable<Info>
77     {
78     public:
79         /**
80          * Sets the `Info` instance from a given `Child`.
81          *
82          * @param[in] aChild   A neighbor.
83          */
84         void SetFrom(const Child &aChild);
85     };
86 
87     /**
88      * Represents an IPv6 address entry registered by an MTD child.
89      */
90     class Ip6AddrEntry : public Ip6::Address
91     {
92     public:
93         /**
94          * Indicates whether the entry matches a given IPv6 address.
95          *
96          * @param[in] aAddress   The IPv6 address.
97          *
98          * @retval TRUE   The entry matches @p aAddress.
99          * @retval FALSE  The entry does not match @p aAddress.
100          */
Matches(const Ip6::Address & aAddress) const101         bool Matches(const Ip6::Address &aAddress) const { return (*this == aAddress); }
102 
103 #if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
104         /**
105          * Gets the MLR state of the IPv6 address entry.
106          *
107          * @param[in] aChild  The child owning this address entry.
108          *
109          * @returns The MLR state of IPv6 address entry.
110          */
111         MlrState GetMlrState(const Child &aChild) const;
112 
113         /**
114          * Sets the MLR state of the IPv6 address entry.
115          *
116          * @param[in] aState    The MLR state.
117          * @param[in] aChild    The child owning this address entry.
118          */
119         void SetMlrState(MlrState aState, Child &aChild);
120 #endif
121     };
122 
123     /**
124      * Represents an array of IPv6 address entries registered by an MTD child.
125      *
126      * This array does not include the mesh-local EID.
127      */
128     typedef Array<Ip6AddrEntry, kNumIp6Addresses> Ip6AddressArray;
129 
130     /**
131      * Initializes the `Child` object.
132      *
133      * @param[in] aInstance  A reference to OpenThread instance.
134      */
Init(Instance & aInstance)135     void Init(Instance &aInstance) { Neighbor::Init(aInstance); }
136 
137     /**
138      * Clears the child entry.
139      */
140     void Clear(void);
141 
142     /**
143      * Clears the IPv6 address list for the child.
144      */
145     void ClearIp6Addresses(void);
146 
147     /**
148      * Sets the device mode flags.
149      *
150      * @param[in]  aMode  The device mode flags.
151      */
152     void SetDeviceMode(Mle::DeviceMode aMode);
153 
154     /**
155      * Gets the mesh-local IPv6 address.
156      *
157      * @param[out]   aAddress            A reference to an IPv6 address to provide address (if any).
158      *
159      * @retval kErrorNone      Successfully found the mesh-local address and updated @p aAddress.
160      * @retval kErrorNotFound  No mesh-local IPv6 address in the IPv6 address list.
161      */
162     Error GetMeshLocalIp6Address(Ip6::Address &aAddress) const;
163 
164     /**
165      * Returns the Mesh Local Interface Identifier.
166      *
167      * @returns The Mesh Local Interface Identifier.
168      */
GetMeshLocalIid(void) const169     const Ip6::InterfaceIdentifier &GetMeshLocalIid(void) const { return mMeshLocalIid; }
170 
171     /**
172      * Gets an array of registered IPv6 address entries by the child.
173      *
174      * The array does not include the mesh-local EID. The ML-EID can retrieved using  `GetMeshLocalIp6Address()`.
175      *
176      * @returns The array of registered IPv6 addresses by the child.
177      */
GetIp6Addresses(void) const178     const Ip6AddressArray &GetIp6Addresses(void) const { return mIp6Addresses; }
179 
180     /**
181      * Gets an array of registered IPv6 address entries by the child.
182      *
183      * The array does not include the mesh-local EID. The ML-EID can retrieved using  `GetMeshLocalIp6Address()`.
184      *
185      * @returns The array of registered IPv6 addresses by the child.
186      */
GetIp6Addresses(void)187     Ip6AddressArray &GetIp6Addresses(void) { return mIp6Addresses; }
188 
189     /**
190      * Iterates over all registered IPv6 addresses (using an iterator).
191      *
192      * @param[in,out]  aIterator  The iterator to use. On success the iterator will be updated.
193      *                            To get the first IPv6 address the iterator should be set to `kAddressIteratorInit`
194      * @param[out]     aAddress   A reference to an IPv6 address to return the address.
195      *
196      * @retval kErrorNone        Successfully got the next IPv6 address. @p aIterator and @p aAddress are updated.
197      * @retval kErrorNotFound    No more address.
198      */
199     Error GetNextIp6Address(AddressIterator &aIterator, Ip6::Address &aAddress) const;
200 
201     /**
202      * Adds an IPv6 address to the list.
203      *
204      * @param[in]  aAddress           A reference to IPv6 address to be added.
205      *
206      * @retval kErrorNone          Successfully added the new address.
207      * @retval kErrorAlready       Address is already in the list.
208      * @retval kErrorNoBufs        Already at maximum number of addresses. No entry available to add the new address.
209      * @retval kErrorInvalidArgs   Address is invalid (it is the Unspecified Address).
210      */
211     Error AddIp6Address(const Ip6::Address &aAddress);
212 
213     /**
214      * Removes an IPv6 address from the list.
215      *
216      * @param[in]  aAddress               A reference to IPv6 address to be removed.
217      *
218      * @retval kErrorNone             Successfully removed the address.
219      * @retval kErrorNotFound         Address was not found in the list.
220      * @retval kErrorInvalidArgs      Address is invalid (it is the Unspecified Address).
221      */
222     Error RemoveIp6Address(const Ip6::Address &aAddress);
223 
224     /**
225      * Indicates whether an IPv6 address is in the list of IPv6 addresses of the child.
226      *
227      * @param[in]  aAddress   A reference to IPv6 address.
228      *
229      * @retval TRUE           The address exists on the list.
230      * @retval FALSE          Address was not found in the list.
231      */
232     bool HasIp6Address(const Ip6::Address &aAddress) const;
233 
234 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE
235     /**
236      * Retrieves the Domain Unicast Address registered by the child.
237      *
238      * @param[out] aAddress    A reference to return the DUA address.
239      *
240      * @retval kErrorNone      Successfully retrieved the DUA address, @p aAddress is updated.
241      * @retval kErrorNotFound  Could not find any DUA address.
242      */
243     Error GetDomainUnicastAddress(Ip6::Address &aAddress) const;
244 #endif
245 
246     /**
247      * Gets the child timeout.
248      *
249      * @returns The child timeout.
250      */
GetTimeout(void) const251     uint32_t GetTimeout(void) const { return mTimeout; }
252 
253     /**
254      * Sets the child timeout.
255      *
256      * @param[in]  aTimeout  The child timeout.
257      */
SetTimeout(uint32_t aTimeout)258     void SetTimeout(uint32_t aTimeout) { mTimeout = aTimeout; }
259 
260     /**
261      * Gets the network data version.
262      *
263      * @returns The network data version.
264      */
GetNetworkDataVersion(void) const265     uint8_t GetNetworkDataVersion(void) const { return mNetworkDataVersion; }
266 
267     /**
268      * Sets the network data version.
269      *
270      * @param[in]  aVersion  The network data version.
271      */
SetNetworkDataVersion(uint8_t aVersion)272     void SetNetworkDataVersion(uint8_t aVersion) { mNetworkDataVersion = aVersion; }
273 
274     /**
275      * Generates a new challenge value to use during a child attach.
276      */
GenerateChallenge(void)277     void GenerateChallenge(void) { mAttachChallenge.GenerateRandom(); }
278 
279     /**
280      * Gets the current challenge value used during attach.
281      *
282      * @returns The current challenge value.
283      */
GetChallenge(void) const284     const Mle::TxChallenge &GetChallenge(void) const { return mAttachChallenge; }
285 
286     /**
287      * Clears the requested TLV list.
288      */
ClearRequestTlvs(void)289     void ClearRequestTlvs(void) { memset(mRequestTlvs, Mle::Tlv::kInvalid, sizeof(mRequestTlvs)); }
290 
291     /**
292      * Returns the requested TLV at index @p aIndex.
293      *
294      * @param[in]  aIndex  The index into the requested TLV list.
295      *
296      * @returns The requested TLV at index @p aIndex.
297      */
GetRequestTlv(uint8_t aIndex) const298     uint8_t GetRequestTlv(uint8_t aIndex) const { return mRequestTlvs[aIndex]; }
299 
300     /**
301      * Sets the requested TLV at index @p aIndex.
302      *
303      * @param[in]  aIndex  The index into the requested TLV list.
304      * @param[in]  aType   The TLV type.
305      */
SetRequestTlv(uint8_t aIndex,uint8_t aType)306     void SetRequestTlv(uint8_t aIndex, uint8_t aType) { mRequestTlvs[aIndex] = aType; }
307 
308     /**
309      * Returns the supervision interval (in seconds).
310      *
311      * @returns The supervision interval (in seconds).
312      */
GetSupervisionInterval(void) const313     uint16_t GetSupervisionInterval(void) const { return mSupervisionInterval; }
314 
315     /**
316      * Sets the supervision interval.
317      *
318      * @param[in] aInterval  The supervision interval (in seconds).
319      */
SetSupervisionInterval(uint16_t aInterval)320     void SetSupervisionInterval(uint16_t aInterval) { mSupervisionInterval = aInterval; }
321 
322     /**
323      * Increments the number of seconds since last supervision of the child.
324      */
IncrementSecondsSinceLastSupervision(void)325     void IncrementSecondsSinceLastSupervision(void) { mSecondsSinceSupervision++; }
326 
327     /**
328      * Returns the number of seconds since last supervision of the child (last message to the child)
329      *
330      * @returns Number of seconds since last supervision of the child.
331      */
GetSecondsSinceLastSupervision(void) const332     uint16_t GetSecondsSinceLastSupervision(void) const { return mSecondsSinceSupervision; }
333 
334     /**
335      * Resets the number of seconds since last supervision of the child to zero.
336      */
ResetSecondsSinceLastSupervision(void)337     void ResetSecondsSinceLastSupervision(void) { mSecondsSinceSupervision = 0; }
338 
339 #if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
340     /**
341      * Returns if the Child has IPv6 address @p aAddress of MLR state `kMlrStateRegistered`.
342      *
343      * @param[in] aAddress  The IPv6 address.
344      *
345      * @retval true   If the Child has IPv6 address @p aAddress of MLR state `kMlrStateRegistered`.
346      * @retval false  If the Child does not have IPv6 address @p aAddress of MLR state `kMlrStateRegistered`.
347      */
348     bool HasMlrRegisteredAddress(const Ip6::Address &aAddress) const;
349 
350     /**
351      * Returns if the Child has any IPv6 address of MLR state `kMlrStateRegistered`.
352      *
353      * @retval true   If the Child has any IPv6 address of MLR state `kMlrStateRegistered`.
354      * @retval false  If the Child does not have any IPv6 address of MLR state `kMlrStateRegistered`.
355      */
HasAnyMlrRegisteredAddress(void) const356     bool HasAnyMlrRegisteredAddress(void) const { return !mMlrRegisteredSet.IsEmpty(); }
357 
358     /**
359      * Returns if the Child has any IPv6 address of MLR state `kMlrStateToRegister`.
360      *
361      * @retval true   If the Child has any IPv6 address of MLR state `kMlrStateToRegister`.
362      * @retval false  If the Child does not have any IPv6 address of MLR state `kMlrStateToRegister`.
363      */
HasAnyMlrToRegisterAddress(void) const364     bool HasAnyMlrToRegisterAddress(void) const { return !mMlrToRegisterSet.IsEmpty(); }
365 #endif // OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
366 
367 private:
368     typedef BitSet<kNumIp6Addresses> ChildIp6AddressSet;
369 
370     uint32_t mTimeout;
371 
372     Ip6::InterfaceIdentifier mMeshLocalIid;
373     Ip6AddressArray          mIp6Addresses;
374 #if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
375     ChildIp6AddressSet mMlrToRegisterSet;
376     ChildIp6AddressSet mMlrRegisteredSet;
377 #endif
378 
379     uint8_t mNetworkDataVersion;
380 
381     union
382     {
383         uint8_t          mRequestTlvs[kMaxRequestTlvs];
384         Mle::TxChallenge mAttachChallenge;
385     };
386 
387     uint16_t mSupervisionInterval;
388     uint16_t mSecondsSinceSupervision;
389 };
390 
391 DefineCoreType(otChildInfo, Child::Info);
392 
393 #endif // OPENTHREAD_FTD
394 
395 } // namespace ot
396 
397 #endif // CHILD_HPP_
398