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