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