• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2016-2018, 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 Thread child table.
32  */
33 
34 #ifndef CHILD_TABLE_HPP_
35 #define CHILD_TABLE_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #if OPENTHREAD_FTD
40 
41 #include "common/const_cast.hpp"
42 #include "common/iterator_utils.hpp"
43 #include "common/locator.hpp"
44 #include "common/non_copyable.hpp"
45 #include "thread/child.hpp"
46 
47 namespace ot {
48 
49 /**
50  * Represents the Thread child table.
51  */
52 class ChildTable : public InstanceLocator, private NonCopyable
53 {
54     friend class NeighborTable;
55     class IteratorBuilder;
56 
57 public:
58     /**
59      * Represents an iterator for iterating through the child entries in the child table.
60      */
61     class Iterator : public InstanceLocator, public ItemPtrIterator<Child, Iterator>
62     {
63         friend class ItemPtrIterator<Child, Iterator>;
64         friend class IteratorBuilder;
65 
66     public:
67         /**
68          * Initializes an `Iterator` instance.
69          *
70          * @param[in] aInstance  A reference to the OpenThread instance.
71          * @param[in] aFilter    A child state filter.
72          */
73         Iterator(Instance &aInstance, Child::StateFilter aFilter);
74 
75         /**
76          * Resets the iterator to start over.
77          */
78         void Reset(void);
79 
80         /**
81          * Gets the `Child` entry to which the iterator is currently pointing.
82          *
83          * @returns A pointer to the `Child` entry, or `nullptr` if the iterator is done and/or empty.
84          */
GetChild(void)85         Child *GetChild(void) { return mItem; }
86 
87     private:
Iterator(Instance & aInstance)88         explicit Iterator(Instance &aInstance)
89             : InstanceLocator(aInstance)
90             , mFilter(Child::StateFilter::kInStateValid)
91         {
92         }
93 
94         void Advance(void);
95 
96         Child::StateFilter mFilter;
97     };
98 
99     /**
100      * Initializes a `ChildTable` instance.
101      *
102      * @param[in]  aInstance     A reference to the OpenThread instance.
103      */
104     explicit ChildTable(Instance &aInstance);
105 
106     /**
107      * Clears the child table.
108      */
109     void Clear(void);
110 
111     /**
112      * Returns the child table index for a given `Child` instance.
113      *
114      * @param[in]  aChild  A reference to a `Child`
115      *
116      * @returns The index corresponding to @p aChild.
117      */
GetChildIndex(const Child & aChild) const118     uint16_t GetChildIndex(const Child &aChild) const { return static_cast<uint16_t>(&aChild - mChildren); }
119 
120     /**
121      * Returns a pointer to a `Child` entry at a given index, or `nullptr` if the index is out of bounds,
122      * i.e., index is larger or equal to maximum number of children allowed (@sa GetMaxChildrenAllowed()).
123      *
124      * @param[in]  aChildIndex  A child index.
125      *
126      * @returns A pointer to the `Child` corresponding to the given index, or `nullptr` if the index is out of bounds.
127      */
128     Child *GetChildAtIndex(uint16_t aChildIndex);
129 
130     /**
131      * Gets a new/unused `Child` entry from the child table.
132      *
133      * @note The returned child entry will be cleared (`memset` to zero).
134      *
135      * @returns A pointer to a new `Child` entry, or `nullptr` if all `Child` entries are in use.
136      */
137     Child *GetNewChild(void);
138 
139     /**
140      * Searches the child table for a `Child` with a given RLOC16 also matching a given state filter.
141      *
142      * @param[in]  aRloc16  A RLOC16 address.
143      * @param[in]  aFilter  A child state filter.
144      *
145      * @returns  A pointer to the `Child` entry if one is found, or `nullptr` otherwise.
146      */
147     Child *FindChild(uint16_t aRloc16, Child::StateFilter aFilter);
148 
149     /**
150      * Searches the child table for a `Child` with a given extended address also matching a given state
151      * filter.
152      *
153      * @param[in]  aExtAddress A reference to an extended address.
154      * @param[in]  aFilter     A child state filter.
155      *
156      * @returns  A pointer to the `Child` entry if one is found, or `nullptr` otherwise.
157      */
158     Child *FindChild(const Mac::ExtAddress &aExtAddress, Child::StateFilter aFilter);
159 
160     /**
161      * Searches the child table for a `Child` with a given address also matching a given state filter.
162      *
163      * @param[in]  aMacAddress A reference to a MAC address.
164      * @param[in]  aFilter     A child state filter.
165      *
166      * @returns  A pointer to the `Child` entry if one is found, or `nullptr` otherwise.
167      */
168     Child *FindChild(const Mac::Address &aMacAddress, Child::StateFilter aFilter);
169 
170     /**
171      * Indicates whether the child table contains any child matching a given state filter.
172      *
173      * @param[in]  aFilter  A child state filter.
174      *
175      * @returns  TRUE if the table contains at least one child table matching the given filter, FALSE otherwise.
176      */
177     bool HasChildren(Child::StateFilter aFilter) const;
178 
179     /**
180      * Returns the number of children in the child table matching a given state filter.
181      *
182      * @param[in]  aFilter  A child state filter.
183      *
184      * @returns Number of children matching the given state filer.
185      */
186     uint16_t GetNumChildren(Child::StateFilter aFilter) const;
187 
188     /**
189      * Returns the maximum number of children that can be supported (build-time constant).
190      *
191      * @note Number of children allowed (from `GetMaxChildrenAllowed()`) can be less than maximum number of supported
192      * children.
193      *
194      * @returns  The maximum number of children supported
195      */
GetMaxChildren(void) const196     uint16_t GetMaxChildren(void) const { return kMaxChildren; }
197 
198     /**
199      * Get the maximum number of children allowed.
200      *
201      * @returns  The maximum number of children allowed.
202      */
GetMaxChildrenAllowed(void) const203     uint16_t GetMaxChildrenAllowed(void) const { return mMaxChildrenAllowed; }
204 
205     /**
206      * Sets the maximum number of children allowed.
207      *
208      * The number of children allowed must be at least one and at most same as maximum supported children (@sa
209      * GetMaxChildren()). It can be changed only if the child table is empty.
210      *
211      * @param[in]  aMaxChildren  Maximum number of children allowed.
212      *
213      * @retval kErrorNone         The number of allowed children changed successfully.
214      * @retval kErrorInvalidArgs  If @p aMaxChildren is not in the range [1, Max supported children].
215      * @retval kErrorInvalidState The child table is not empty.
216      */
217     Error SetMaxChildrenAllowed(uint16_t aMaxChildren);
218 
219     /**
220      * Enables range-based `for` loop iteration over all child entries in the child table matching a given
221      * state filter.
222      *
223      * Should be used as follows:
224      *
225      *     for (Child &child : aChildTable.Iterate(aFilter)) { ... }
226      *
227      * @param[in] aFilter  A child state filter.
228      *
229      * @returns An IteratorBuilder instance.
230      */
Iterate(Child::StateFilter aFilter)231     IteratorBuilder Iterate(Child::StateFilter aFilter) { return IteratorBuilder(GetInstance(), aFilter); }
232 
233     /**
234      * Retains diagnostic information for an attached child by Child ID or RLOC16.
235      *
236      * @param[in]   aChildId    The Child ID or RLOC16 for an attached child.
237      * @param[out]  aChildInfo  A reference to a `Child::Info` to populate with the child information.
238      */
239     Error GetChildInfoById(uint16_t aChildId, Child::Info &aChildInfo);
240 
241     /**
242      * Retains diagnostic information for an attached child by the internal table index.
243      *
244      * @param[in]   aChildIndex  The table index.
245      * @param[out]  aChildInfo   A reference to a `Child::Info` to populate with the child information.
246      */
247     Error GetChildInfoByIndex(uint16_t aChildIndex, Child::Info &aChildInfo);
248 
249     /**
250      * Restores child table from non-volatile memory.
251      */
252     void Restore(void);
253 
254     /**
255      * Removes a stored child information from non-volatile memory.
256      *
257      * @param[in]  aChild     A reference to the child to remove from non-volatile memory.
258      */
259     void RemoveStoredChild(const Child &aChild);
260 
261     /**
262      * Store a child information into non-volatile memory.
263      *
264      * @param[in]  aChild          A reference to the child to store.
265      *
266      * @retval  kErrorNone     Successfully store child.
267      * @retval  kErrorNoBufs   Insufficient available buffers to store child.
268      */
269     Error StoreChild(const Child &aChild);
270 
271     /**
272      * Indicates whether or not the child table contains an MTD child with a given @p aRloc16.
273      *
274      * Only children in `kInStateValidOrRestoring` are considered.
275      *
276      * @param[in]  aRloc16  The RLOC16 to check.
277      *
278      * @retval TRUE  If the child table contains an MTD child with @p aRloc16.
279      * @retval FALSE If the child table does not contain an MTD child with @p aRloc16.
280      */
281     bool HasMinimalChild(uint16_t aRloc16) const;
282 
283     /**
284      * Indicates whether the child table contains any sleepy child (in states valid or restoring) with a
285      * given IPv6 address.
286      *
287      * @param[in]  aIp6Address  An IPv6 address.
288      *
289      * @retval TRUE   If the child table contains any sleepy child with @p aIp6Address.
290      * @retval FALSE  If the child table does not contain any sleepy child with @p aIp6Address.
291      */
292     bool HasSleepyChildWithAddress(const Ip6::Address &aIp6Address) const;
293 
294     /**
295      * Indicates whether the child table contains a given `Neighbor` instance.
296      *
297      * @param[in]  aNeighbor  A reference to a `Neighbor`.
298      *
299      * @retval TRUE  if @p aNeighbor is a `Child` in the child table.
300      * @retval FALSE if @p aNeighbor is not a `Child` in the child table.
301      */
Contains(const Neighbor & aNeighbor) const302     bool Contains(const Neighbor &aNeighbor) const
303     {
304         const Child *child = static_cast<const Child *>(&aNeighbor);
305 
306         return (mChildren <= child) && (child < GetArrayEnd(mChildren));
307     }
308 
309 private:
310     static constexpr uint16_t kMaxChildren = OPENTHREAD_CONFIG_MLE_MAX_CHILDREN;
311 
312     class IteratorBuilder : public InstanceLocator
313     {
314     public:
IteratorBuilder(Instance & aInstance,Child::StateFilter aFilter)315         IteratorBuilder(Instance &aInstance, Child::StateFilter aFilter)
316             : InstanceLocator(aInstance)
317             , mFilter(aFilter)
318         {
319         }
320 
begin(void)321         Iterator begin(void) { return Iterator(GetInstance(), mFilter); }
end(void)322         Iterator end(void) { return Iterator(GetInstance()); }
323 
324     private:
325         Child::StateFilter mFilter;
326     };
327 
FindChild(const Child::AddressMatcher & aMatcher)328     Child *FindChild(const Child::AddressMatcher &aMatcher) { return AsNonConst(AsConst(this)->FindChild(aMatcher)); }
329 
330     const Child *FindChild(const Child::AddressMatcher &aMatcher) const;
331     void         RefreshStoredChildren(void);
332 
333     uint16_t mMaxChildrenAllowed;
334     Child    mChildren[kMaxChildren];
335 };
336 
337 } // namespace ot
338 
339 #endif // OPENTHREAD_FTD
340 
341 #endif // CHILD_TABLE_HPP_
342