| /* |
| * Copyright (c) 2018, The OpenThread Authors. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * 3. Neither the name of the copyright holder nor the |
| * names of its contributors may be used to endorse or promote products |
| * derived from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef ROUTER_TABLE_HPP_ |
| #define ROUTER_TABLE_HPP_ |
| |
| #include "common/encoding.hpp" |
| #include "common/locator.hpp" |
| #include "mac/mac_types.hpp" |
| #include "thread/mle_constants.hpp" |
| #include "thread/thread_tlvs.hpp" |
| #include "thread/topology.hpp" |
| |
| namespace ot { |
| |
| #if OPENTHREAD_FTD |
| |
| class RouterTable : public InstanceLocator |
| { |
| public: |
| /** |
| * This class represents an iterator for iterating through entries in the router table. |
| * |
| */ |
| class Iterator : public InstanceLocator |
| { |
| public: |
| /** |
| * This constructor initializes an `Iterator` instance to start from beginning of the router table. |
| * |
| * @param[in] aInstance A reference to the OpenThread instance. |
| * |
| */ |
| explicit Iterator(Instance &aInstance); |
| |
| /** |
| * This method resets the iterator to start over. |
| * |
| */ |
| void Reset(void); |
| |
| /** |
| * This method indicates if the iterator has reached the end of the list. |
| * |
| * @retval TRUE The iterator has reached the end of the list. |
| * @retval FALSE The iterator currently points to a valid entry. |
| * |
| */ |
| bool IsDone(void) const { return (mRouter == NULL); } |
| |
| /** |
| * This method advances the iterator. |
| * |
| * The iterator is moved to point to the next entry. If there are no more entries matching the iterator |
| * becomes empty (i.e., `GetRouter()` returns `NULL` and `IsDone()` returns `true`). |
| * |
| */ |
| void Advance(void); |
| |
| /** |
| * This method overloads `++` operator (pre-increment) to advance the iterator. |
| * |
| * The iterator is moved to point to the next entry. If there are no more entries matching the iterator |
| * becomes empty (i.e., `GetRouter()` returns `NULL` and `IsDone()` returns `true`). |
| * |
| */ |
| void operator++(void) { Advance(); } |
| |
| /** |
| * This method overloads `++` operator (post-increment) to advance the iterator. |
| * |
| * The iterator is moved to point to the next entry. If there are no more entries matching the iterator |
| * becomes empty (i.e., `GetRouter()` returns `NULL` and `IsDone()` returns `true`). |
| * |
| */ |
| void operator++(int) { Advance(); } |
| |
| /** |
| * This method gets the entry to which the iterator is currently pointing. |
| * |
| * @returns A pointer to the current entry, or `NULL` if the iterator is done/empty. |
| * |
| */ |
| Router *GetRouter(void) { return mRouter; } |
| |
| private: |
| Router *mRouter; |
| }; |
| |
| /** |
| * Constructor. |
| * |
| * @param[in] aInstance A reference to the OpenThread instance. |
| * |
| */ |
| explicit RouterTable(Instance &aInstance); |
| |
| /** |
| * This method clears the router table. |
| * |
| */ |
| void Clear(void); |
| |
| /** |
| * This method removes all neighbor links to routers. |
| * |
| */ |
| void ClearNeighbors(void); |
| |
| /** |
| * This method allocates a router with a random router id. |
| * |
| * @returns A pointer to the allocated router or NULL if a router ID is not available. |
| * |
| */ |
| Router *Allocate(void); |
| |
| /** |
| * This method allocates a router with a specified router id. |
| * |
| * @returns A pointer to the allocated router or NULL if the router id could not be allocated. |
| * |
| */ |
| Router *Allocate(uint8_t aRouterId); |
| |
| /** |
| * This method releases a router id. |
| * |
| * @param[in] aRouterId The router id. |
| * |
| * @retval OT_ERROR_NONE Successfully released the router id. |
| * @retval OT_ERROR_INVALID_STATE The device is not currently operating as a leader. |
| * @retval OT_ERROR_NOT_FOUND The router id is not currently allocated. |
| * |
| */ |
| otError Release(uint8_t aRouterId); |
| |
| /** |
| * This method removes a neighboring router link. |
| * |
| * @param[in] aRouter A reference to the router. |
| * |
| */ |
| void RemoveNeighbor(Router &aRouter); |
| |
| /** |
| * This method returns the number of active routers in the Thread network. |
| * |
| * @returns The number of active routers in the Thread network. |
| * |
| */ |
| uint8_t GetActiveRouterCount(void) const { return mActiveRouterCount; } |
| |
| /** |
| * This method returns the number of active links with neighboring routers. |
| * |
| * @returns The number of active links with neighboring routers. |
| * |
| */ |
| uint8_t GetActiveLinkCount(void) const; |
| |
| /** |
| * This method returns the leader in the Thread network. |
| * |
| * @returns A pointer to the Leader in the Thread network. |
| * |
| */ |
| Router *GetLeader(void); |
| |
| /** |
| * This method returns the time in seconds since the last Router ID Sequence update. |
| * |
| * @returns The time in seconds since the last Router ID Sequence update. |
| * |
| */ |
| uint32_t GetLeaderAge(void) const; |
| |
| /** |
| * This method returns the link cost for a neighboring router. |
| * |
| * @param[in] aRouter A reference to the router. |
| * |
| * @returns The link cost. |
| * |
| */ |
| uint8_t GetLinkCost(Router &aRouter); |
| |
| /** |
| * This method returns the neighbor for a given RLOC16. |
| * |
| * @param[in] aRloc16 The RLOC16 value. |
| * |
| * @returns A pointer to the router or NULL if the router could not be found. |
| * |
| */ |
| Router *GetNeighbor(uint16_t aRloc16); |
| |
| /** |
| * This method returns the neighbor for a given IEEE Extended Address. |
| * |
| * @param[in] aExtAddress A reference to the IEEE Extended Address. |
| * |
| * @returns A pointer to the router or NULL if the router could not be found. |
| * |
| */ |
| Router *GetNeighbor(const Mac::ExtAddress &aExtAddress); |
| |
| /** |
| * This method returns the router for a given router id. |
| * |
| * @param[in] aRouterId The router id. |
| * |
| * @returns A pointer to the router or NULL if the router could not be found. |
| * |
| */ |
| Router *GetRouter(uint8_t aRouterId) |
| { |
| return const_cast<Router *>(const_cast<const RouterTable *>(this)->GetRouter(aRouterId)); |
| } |
| |
| /** |
| * This method returns the router for a given router id. |
| * |
| * @param[in] aRouterId The router id. |
| * |
| * @returns A pointer to the router or NULL if the router could not be found. |
| * |
| */ |
| const Router *GetRouter(uint8_t aRouterId) const; |
| |
| /** |
| * This method returns the router for a given IEEE Extended Address. |
| * |
| * @param[in] aExtAddress A reference to the IEEE Extended Address. |
| * |
| * @returns A pointer to the router or NULL if the router could not be found. |
| * |
| */ |
| Router *GetRouter(const Mac::ExtAddress &aExtAddress); |
| |
| /** |
| * This method retains diagnostic information for a given router. |
| * |
| * @param[in] aRouterId The router ID or RLOC16 for a given router. |
| * @param[out] aRouterInfo The router information. |
| * |
| * @retval OT_ERROR_NONE Successfully retrieved the router info for given id. |
| * @retval OT_ERROR_INVALID_ARGS @p aRouterId is not a valid value for a router. |
| * @retval OT_ERROR_NOT_FOUND No router entry with the given id. |
| * |
| */ |
| otError GetRouterInfo(uint16_t aRouterId, otRouterInfo &aRouterInfo); |
| |
| /** |
| * This method returns the Router ID Sequence. |
| * |
| * @returns The Router ID Sequence. |
| * |
| */ |
| uint8_t GetRouterIdSequence(void) const { return mRouterIdSequence; } |
| |
| /** |
| * This method returns the local time when the Router ID Sequence was last updated. |
| * |
| * @returns The local time when the Router ID Sequence was last updated. |
| * |
| */ |
| TimeMilli GetRouterIdSequenceLastUpdated(void) const { return mRouterIdSequenceLastUpdated; } |
| |
| /** |
| * This method returns the number of neighbor links. |
| * |
| * @returns The number of neighbor links. |
| * |
| */ |
| uint8_t GetNeighborCount(void) const; |
| |
| /** |
| * This method indicates whether or not @p aRouterId is allocated. |
| * |
| * @retval TRUE if @p aRouterId is allocated. |
| * @retval FALSE if @p aRouterId is not allocated. |
| * |
| */ |
| bool IsAllocated(uint8_t aRouterId) const; |
| |
| /** |
| * This method updates the router table with a received Route TLV. |
| * |
| * @param[in] aTlv A reference to the Route TLV. |
| * |
| */ |
| void ProcessTlv(const Mle::RouteTlv &aTlv); |
| |
| /** |
| * This method updates the router table with a received Router Mask TLV. |
| * |
| * @param[in] aTlv A reference to the Router Mask TLV. |
| * |
| */ |
| void ProcessTlv(const ThreadRouterMaskTlv &aTlv); |
| |
| /** |
| * This method updates the router table and must be called with a one second period. |
| * |
| */ |
| void ProcessTimerTick(void); |
| |
| private: |
| class RouterIdSet |
| { |
| public: |
| void Clear(void) { memset(mRouterIdSet, 0, sizeof(mRouterIdSet)); } |
| bool Contains(uint8_t aRouterId) const { return (mRouterIdSet[aRouterId / 8] & (1 << (aRouterId % 8))) != 0; } |
| void Add(uint8_t aRouterId) { mRouterIdSet[aRouterId / 8] |= 1 << (aRouterId % 8); } |
| void Remove(uint8_t aRouterId) { mRouterIdSet[aRouterId / 8] &= ~(1 << (aRouterId % 8)); } |
| |
| private: |
| uint8_t mRouterIdSet[BitVectorBytes(Mle::kMaxRouterId + 1)]; |
| }; |
| |
| void UpdateAllocation(void); |
| const Router *GetFirstEntry(void) const; |
| const Router *GetNextEntry(const Router *aRouter) const; |
| Router *GetFirstEntry(void) { return const_cast<Router *>(const_cast<const RouterTable *>(this)->GetFirstEntry()); } |
| Router *GetNextEntry(Router *aRouter) |
| { |
| return const_cast<Router *>(const_cast<const RouterTable *>(this)->GetNextEntry(aRouter)); |
| } |
| |
| Router mRouters[Mle::kMaxRouters]; |
| RouterIdSet mAllocatedRouterIds; |
| uint8_t mRouterIdReuseDelay[Mle::kMaxRouterId + 1]; |
| TimeMilli mRouterIdSequenceLastUpdated; |
| uint8_t mRouterIdSequence; |
| uint8_t mActiveRouterCount; |
| }; |
| |
| #endif // OPENTHREAD_FTD |
| |
| #if OPENTHREAD_MTD |
| |
| class RouterTable |
| { |
| public: |
| class Iterator |
| { |
| public: |
| explicit Iterator(Instance &) {} |
| void Reset(void) {} |
| bool IsDone(void) const { return true; } |
| void Advance(void) {} |
| void operator++(void) {} |
| void operator++(int) {} |
| Router *GetRouter(void) { return NULL; } |
| }; |
| |
| explicit RouterTable(Instance &) {} |
| |
| uint8_t GetNeighborCount(void) const { return 0; } |
| }; |
| |
| #endif // OPENTHREAD_MTD |
| |
| } // namespace ot |
| |
| #endif // ROUTER_TABLE_HPP_ |