• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 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 #ifndef ROUTER_TABLE_HPP_
30 #define ROUTER_TABLE_HPP_
31 
32 #include "openthread-core-config.h"
33 
34 #if OPENTHREAD_FTD
35 
36 #include "common/const_cast.hpp"
37 #include "common/encoding.hpp"
38 #include "common/iterator_utils.hpp"
39 #include "common/locator.hpp"
40 #include "common/non_copyable.hpp"
41 #include "mac/mac_types.hpp"
42 #include "thread/mle_types.hpp"
43 #include "thread/thread_tlvs.hpp"
44 #include "thread/topology.hpp"
45 
46 namespace ot {
47 
48 class RouterTable : public InstanceLocator, private NonCopyable
49 {
50     friend class NeighborTable;
51     class IteratorBuilder;
52 
53 public:
54     /**
55      * This class represents an iterator for iterating through entries in the router table.
56      *
57      */
58     class Iterator : public InstanceLocator, public ItemPtrIterator<Router, Iterator>
59     {
60         friend class ItemPtrIterator<Router, Iterator>;
61         friend class IteratorBuilder;
62 
63     public:
64         /**
65          * This constructor initializes an `Iterator` instance to start from beginning of the router table.
66          *
67          * @param[in] aInstance  A reference to the OpenThread instance.
68          *
69          */
70         explicit Iterator(Instance &aInstance);
71 
72     private:
73         enum IteratorType : uint8_t
74         {
75             kEndIterator,
76         };
77 
Iterator(Instance & aInstance,IteratorType)78         Iterator(Instance &aInstance, IteratorType)
79             : InstanceLocator(aInstance)
80         {
81         }
82 
83         void Advance(void);
84     };
85 
86     /**
87      * Constructor.
88      *
89      * @param[in]  aInstance  A reference to the OpenThread instance.
90      *
91      */
92     explicit RouterTable(Instance &aInstance);
93 
94     /**
95      * This method clears the router table.
96      *
97      */
98     void Clear(void);
99 
100     /**
101      * This method removes all neighbor links to routers.
102      *
103      */
104     void ClearNeighbors(void);
105 
106     /**
107      * This method allocates a router with a random router id.
108      *
109      * @returns A pointer to the allocated router or `nullptr` if a router ID is not available.
110      *
111      */
112     Router *Allocate(void);
113 
114     /**
115      * This method allocates a router with a specified router id.
116      *
117      * @returns A pointer to the allocated router or `nullptr` if the router id could not be allocated.
118      *
119      */
120     Router *Allocate(uint8_t aRouterId);
121 
122     /**
123      * This method releases a router id.
124      *
125      * @param[in]  aRouterId  The router id.
126      *
127      * @retval kErrorNone          Successfully released the router id.
128      * @retval kErrorInvalidState  The device is not currently operating as a leader.
129      * @retval kErrorNotFound      The router id is not currently allocated.
130      *
131      */
132     Error Release(uint8_t aRouterId);
133 
134     /**
135      * This method removes a router link.
136      *
137      * @param[in]  aRouter  A reference to the router.
138      *
139      */
140     void RemoveRouterLink(Router &aRouter);
141 
142     /**
143      * This method returns the number of active routers in the Thread network.
144      *
145      * @returns The number of active routers in the Thread network.
146      *
147      */
GetActiveRouterCount(void) const148     uint8_t GetActiveRouterCount(void) const { return mActiveRouterCount; }
149 
150     /**
151      * This method returns the number of active links with neighboring routers.
152      *
153      * @returns The number of active links with neighboring routers.
154      *
155      */
156     uint8_t GetActiveLinkCount(void) const;
157 
158     /**
159      * This method returns the leader in the Thread network.
160      *
161      * @returns A pointer to the Leader in the Thread network.
162      *
163      */
164     Router *GetLeader(void);
165 
166     /**
167      * This method returns the time in seconds since the last Router ID Sequence update.
168      *
169      * @returns The time in seconds since the last Router ID Sequence update.
170      *
171      */
172     uint32_t GetLeaderAge(void) const;
173 
174     /**
175      * This method returns the link cost for a neighboring router.
176      *
177      * @param[in]  aRouter  A reference to the router.
178      *
179      * @returns The link cost.
180      *
181      */
182     uint8_t GetLinkCost(Router &aRouter);
183 
184     /**
185      * This method returns the neighbor for a given RLOC16.
186      *
187      * @param[in]  aRloc16  The RLOC16 value.
188      *
189      * @returns A pointer to the router or `nullptr` if the router could not be found.
190      *
191      */
192     Router *GetNeighbor(uint16_t aRloc16);
193 
194     /**
195      * This method returns the neighbor for a given IEEE Extended Address.
196      *
197      * @param[in]  aExtAddress  A reference to the IEEE Extended Address.
198      *
199      * @returns A pointer to the router or `nullptr` if the router could not be found.
200      *
201      */
202     Router *GetNeighbor(const Mac::ExtAddress &aExtAddress);
203 
204     /**
205      * This method returns the neighbor for a given MAC address.
206      *
207      * @param[in]  aMacAddress  A MAC address
208      *
209      * @returns A pointer to the router or `nullptr` if the router could not be found.
210      *
211      */
212     Router *GetNeighbor(const Mac::Address &aMacAddress);
213 
214     /**
215      * This method returns the router for a given router id.
216      *
217      * @param[in]  aRouterId  The router id.
218      *
219      * @returns A pointer to the router or `nullptr` if the router could not be found.
220      *
221      */
GetRouter(uint8_t aRouterId)222     Router *GetRouter(uint8_t aRouterId) { return AsNonConst(AsConst(this)->GetRouter(aRouterId)); }
223 
224     /**
225      * This method returns the router for a given router id.
226      *
227      * @param[in]  aRouterId  The router id.
228      *
229      * @returns A pointer to the router or `nullptr` if the router could not be found.
230      *
231      */
232     const Router *GetRouter(uint8_t aRouterId) const;
233 
234     /**
235      * This method returns the router for a given IEEE Extended Address.
236      *
237      * @param[in]  aExtAddress  A reference to the IEEE Extended Address.
238      *
239      * @returns A pointer to the router or `nullptr` if the router could not be found.
240      *
241      */
242     Router *GetRouter(const Mac::ExtAddress &aExtAddress);
243 
244     /**
245      * This method returns if the router table contains a given `Neighbor` instance.
246      *
247      * @param[in]  aNeighbor  A reference to a `Neighbor`.
248      *
249      * @retval TRUE  if @p aNeighbor is a `Router` in the router table.
250      * @retval FALSE if @p aNeighbor is not a `Router` in the router table
251      *               (i.e. mParent, mParentCandidate, a `Child` of the child table).
252      *
253      */
Contains(const Neighbor & aNeighbor) const254     bool Contains(const Neighbor &aNeighbor) const
255     {
256         return mRouters <= &static_cast<const Router &>(aNeighbor) &&
257                &static_cast<const Router &>(aNeighbor) < mRouters + Mle::kMaxRouters;
258     }
259 
260     /**
261      * This method retains diagnostic information for a given router.
262      *
263      * @param[in]   aRouterId    The router ID or RLOC16 for a given router.
264      * @param[out]  aRouterInfo  The router information.
265      *
266      * @retval kErrorNone          Successfully retrieved the router info for given id.
267      * @retval kErrorInvalidArgs   @p aRouterId is not a valid value for a router.
268      * @retval kErrorNotFound      No router entry with the given id.
269      *
270      */
271     Error GetRouterInfo(uint16_t aRouterId, Router::Info &aRouterInfo);
272 
273     /**
274      * This method returns the Router ID Sequence.
275      *
276      * @returns The Router ID Sequence.
277      *
278      */
GetRouterIdSequence(void) const279     uint8_t GetRouterIdSequence(void) const { return mRouterIdSequence; }
280 
281     /**
282      * This method returns the local time when the Router ID Sequence was last updated.
283      *
284      * @returns The local time when the Router ID Sequence was last updated.
285      *
286      */
GetRouterIdSequenceLastUpdated(void) const287     TimeMilli GetRouterIdSequenceLastUpdated(void) const { return mRouterIdSequenceLastUpdated; }
288 
289     /**
290      * This method returns the number of neighbor links.
291      *
292      * @returns The number of neighbor links.
293      *
294      */
295     uint8_t GetNeighborCount(void) const;
296 
297     /**
298      * This method indicates whether or not @p aRouterId is allocated.
299      *
300      * @retval TRUE if @p aRouterId is allocated.
301      * @retval FALSE if @p aRouterId is not allocated.
302      *
303      */
304     bool IsAllocated(uint8_t aRouterId) const;
305 
306     /**
307      * This method updates the Router ID allocation.
308      *
309      * @param[in]  aRouterIdSequence  The Router Id Sequence.
310      * @param[in]  aRouterIdSet       A reference to the Router Id Set.
311      *
312      */
313     void UpdateRouterIdSet(uint8_t aRouterIdSequence, const Mle::RouterIdSet &aRouterIdSet);
314 
315     /**
316      * This method gets the allocated Router ID set.
317      *
318      * @returns The allocated Router ID set.
319      *
320      */
GetRouterIdSet(void) const321     const Mle::RouterIdSet &GetRouterIdSet(void) const { return mAllocatedRouterIds; }
322 
323     /**
324      * This method updates the router table and must be called with a one second period.
325      *
326      */
327     void HandleTimeTick(void);
328 
329     /**
330      * This method enables range-based `for` loop iteration over all Router entries in the Router table.
331      *
332      * This method should be used as follows:
333      *
334      *     for (Router &router : Get<RouterTable>().Iterate()) { ... }
335      *
336      * @returns An `IteratorBuilder` instance.
337      *
338      */
Iterate(void)339     IteratorBuilder Iterate(void) { return IteratorBuilder(GetInstance()); }
340 
341 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
342     void GetRouterIdRange(uint8_t &aMinRouterId, uint8_t &aMaxRouterId) const;
343 
344     Error SetRouterIdRange(uint8_t aMinRouterId, uint8_t aMaxRouterId);
345 #endif
346 
347 private:
348     class IteratorBuilder : public InstanceLocator
349     {
350     public:
IteratorBuilder(Instance & aInstance)351         explicit IteratorBuilder(Instance &aInstance)
352             : InstanceLocator(aInstance)
353         {
354         }
355 
begin(void)356         Iterator begin(void) { return Iterator(GetInstance()); }
end(void)357         Iterator end(void) { return Iterator(GetInstance(), Iterator::kEndIterator); }
358     };
359 
360     void          UpdateAllocation(void);
361     const Router *GetFirstEntry(void) const;
362     const Router *GetNextEntry(const Router *aRouter) const;
GetFirstEntry(void)363     Router *      GetFirstEntry(void) { return AsNonConst(AsConst(this)->GetFirstEntry()); }
GetNextEntry(Router * aRouter)364     Router *      GetNextEntry(Router *aRouter) { return AsNonConst(AsConst(this)->GetNextEntry(aRouter)); }
365 
366     const Router *FindRouter(const Router::AddressMatcher &aMatcher) const;
FindRouter(const Router::AddressMatcher & aMatcher)367     Router *      FindRouter(const Router::AddressMatcher &aMatcher)
368     {
369         return AsNonConst(AsConst(this)->FindRouter(aMatcher));
370     }
371 
372     Router           mRouters[Mle::kMaxRouters];
373     Mle::RouterIdSet mAllocatedRouterIds;
374     uint8_t          mRouterIdReuseDelay[Mle::kMaxRouterId + 1];
375     TimeMilli        mRouterIdSequenceLastUpdated;
376     uint8_t          mRouterIdSequence;
377     uint8_t          mActiveRouterCount;
378 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
379     uint8_t mMinRouterId;
380     uint8_t mMaxRouterId;
381 #endif
382 };
383 
384 } // namespace ot
385 
386 #endif // OPENTHREAD_FTD
387 
388 #endif // ROUTER_TABLE_HPP_
389