diff --git a/src/core/thread/key_manager.cpp b/src/core/thread/key_manager.cpp index bcb0c6aee..1c96cd0cd 100644 --- a/src/core/thread/key_manager.cpp +++ b/src/core/thread/key_manager.cpp @@ -122,11 +122,11 @@ otError KeyManager::SetMasterKey(const MasterKey &aKey) #if OPENTHREAD_FTD // reset router frame counters - for (RouterTable::Iterator iter(GetInstance()); !iter.IsDone(); iter++) + for (Router &router : Get().Iterate()) { - iter.GetRouter()->SetKeySequence(0); - iter.GetRouter()->SetLinkFrameCounter(0); - iter.GetRouter()->SetMleFrameCounter(0); + router.SetKeySequence(0); + router.SetLinkFrameCounter(0); + router.SetMleFrameCounter(0); } // reset child frame counters diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index d87896b37..609633cde 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -1541,10 +1541,8 @@ void MleRouter::UpdateRoutes(const RouteTlv &aRoute, uint8_t aRouterId) VerifyOrExit(changed, OT_NOOP); otLogInfoMle("Route table updated"); - for (RouterTable::Iterator iter(GetInstance()); !iter.IsDone(); iter++) + for (Router &router : Get().Iterate()) { - Router &router = *iter.GetRouter(); - otLogInfoMle(" %04x -> %04x, cost:%d %d, lqin:%d, lqout:%d, link:%s", router.GetRloc16(), (router.GetNextHop() == kInvalidRouterId) ? 0xffff : Rloc16FromRouterId(router.GetNextHop()), router.GetCost(), mRouterTable.GetLinkCost(router), router.GetLinkInfo().GetLinkQuality(), @@ -1870,9 +1868,8 @@ void MleRouter::HandleStateUpdateTimer(void) } // update router state - for (RouterTable::Iterator iter(GetInstance()); !iter.IsDone(); iter++) + for (Router &router : Get().Iterate()) { - Router & router = *iter.GetRouter(); uint32_t age; if (router.GetRloc16() == GetRloc16()) @@ -4372,9 +4369,8 @@ void MleRouter::FillConnectivityTlv(ConnectivityTlv &aTlv) aTlv.SetActiveRouters(mRouterTable.GetActiveRouterCount()); - for (RouterTable::Iterator iter(GetInstance()); !iter.IsDone(); iter++) + for (Router &router : Get().Iterate()) { - Router &router = *iter.GetRouter(); uint8_t linkQuality; if (router.GetRloc16() == GetRloc16()) @@ -4479,10 +4475,8 @@ void MleRouter::FillRouteTlv(RouteTlv &aTlv) aTlv.SetRouterIdSequence(mRouterTable.GetRouterIdSequence()); aTlv.SetRouterIdMask(mRouterTable.GetRouterIdSet()); - for (RouterTable::Iterator iter(GetInstance()); !iter.IsDone(); iter++, routerCount++) + for (Router &router : Get().Iterate()) { - Router &router = *iter.GetRouter(); - if (router.GetRloc16() == GetRloc16()) { aTlv.SetLinkQualityIn(routerCount, 0); @@ -4521,6 +4515,8 @@ void MleRouter::FillRouteTlv(RouteTlv &aTlv) aTlv.SetLinkQualityOut(routerCount, router.GetLinkQualityOut()); aTlv.SetLinkQualityIn(routerCount, router.GetLinkInfo().GetLinkQuality()); } + + routerCount++; } aTlv.SetRouteDataLength(routerCount); @@ -4551,10 +4547,8 @@ bool MleRouter::HasMinDowngradeNeighborRouters(void) uint8_t linkQuality; uint8_t routerCount = 0; - for (RouterTable::Iterator iter(GetInstance()); !iter.IsDone(); iter++) + for (Router &router : Get().Iterate()) { - Router &router = *iter.GetRouter(); - if (!router.IsStateValid()) { continue; @@ -4581,9 +4575,8 @@ bool MleRouter::HasOneNeighborWithComparableConnectivity(const RouteTlv &aRoute, bool rval = true; // process local neighbor routers - for (RouterTable::Iterator iter(GetInstance()); !iter.IsDone(); iter++) + for (Router &router : Get().Iterate()) { - Router &router = *iter.GetRouter(); uint8_t localLinkQuality = 0; uint8_t peerLinkQuality = 0; uint8_t routerCount = 0; diff --git a/src/core/thread/router_table.cpp b/src/core/thread/router_table.cpp index 3eecdcf10..d44bcb392 100644 --- a/src/core/thread/router_table.cpp +++ b/src/core/thread/router_table.cpp @@ -44,14 +44,8 @@ namespace ot { RouterTable::Iterator::Iterator(Instance &aInstance) : InstanceLocator(aInstance) - , mRouter(nullptr) + , mRouter(Get().GetFirstEntry()) { - Reset(); -} - -void RouterTable::Iterator::Reset(void) -{ - mRouter = Get().GetFirstEntry(); } void RouterTable::Iterator::Advance(void) diff --git a/src/core/thread/router_table.hpp b/src/core/thread/router_table.hpp index 1709f992c..66aaba3ff 100644 --- a/src/core/thread/router_table.hpp +++ b/src/core/thread/router_table.hpp @@ -44,6 +44,8 @@ namespace ot { class RouterTable : public InstanceLocator { + class IteratorBuilder; + public: /** * This class represents an iterator for iterating through entries in the router table. @@ -51,6 +53,8 @@ public: */ class Iterator : public InstanceLocator { + friend class IteratorBuilder; + public: /** * This constructor initializes an `Iterator` instance to start from beginning of the router table. @@ -61,13 +65,7 @@ public: 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. + * This method indicates if the iterator has reached the end of the list, i.e., iterator is empty. * * @retval TRUE The iterator has reached the end of the list. * @retval FALSE The iterator currently points to a valid entry. @@ -75,20 +73,11 @@ public: */ bool IsDone(void) const { return (mRouter == nullptr); } - /** - * 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 `nullptr` 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 `nullptr` and `IsDone()` returns `true`). + * becomes empty (i.e., `IsDone()` returns `true`). * */ void operator++(void) { Advance(); } @@ -97,20 +86,70 @@ public: * 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 `nullptr` and `IsDone()` returns `true`). + * becomes empty (i.e., `IsDone()` returns `true`). * */ void operator++(int) { Advance(); } /** - * This method gets the entry to which the iterator is currently pointing. + * This method overloads the `*` dereference operator and gets a reference to `Router` entry to which the + * iterator is currently pointing. * - * @returns A pointer to the current entry, or `nullptr` if the iterator is done/empty. + * This method MUST be used when the iterator is not empty/finished (i.e., `IsDone()` returns `false`). + * + * @returns A reference to the `Router` entry currently pointed by the iterator. * */ - Router *GetRouter(void) { return mRouter; } + Router &operator*(void) { return *mRouter; } + + /** + * This method overloads the `->` dereference operator and gets a pointer to `Router` entry to which the + * iterator is currently pointing. + * + * @returns A pointer to the `Router` entry associated with the iterator, or `nullptr` if iterator is + * empty/done. + * + */ + Router *operator->(void) { return mRouter; } + + /** + * This method overloads operator `==` to evaluate whether or not two `Iterator` instances point to the same + * router entry. + * + * @param[in] aOther The other `Iterator` to compare with. + * + * @retval TRUE If the two `Iterator` objects point to the same router entry or both are done. + * @retval FALSE If the two `Iterator` objects do not point to the same router entry. + * + */ + bool operator==(const Iterator &aOther) { return mRouter == aOther.mRouter; } + + /** + * This method overloads operator `!=` to evaluate whether or not two `Iterator` instances point to the same + * router entry. + * + * @param[in] aOther The other `Iterator` to compare with. + * + * @retval TRUE If the two `Iterator` objects do not point to the same router entry. + * @retval FALSE If the two `Iterator` objects point to the same router entry or both are done. + * + */ + bool operator!=(const Iterator &aOther) { return mRouter != aOther.mRouter; } private: + enum IteratorType + { + kEndIterator, + }; + + Iterator(Instance &aInstance, IteratorType) + : InstanceLocator(aInstance) + , mRouter(nullptr) + { + } + + void Advance(void); + Router *mRouter; }; @@ -350,7 +389,21 @@ public: */ void ProcessTimerTick(void); + IteratorBuilder Iterate(void) { return IteratorBuilder(GetInstance()); } + private: + class IteratorBuilder : public InstanceLocator + { + public: + IteratorBuilder(Instance &aInstance) + : InstanceLocator(aInstance) + { + } + + Iterator begin(void) { return Iterator(GetInstance()); } + Iterator end(void) { return Iterator(GetInstance(), Iterator::kEndIterator); } + }; + void UpdateAllocation(void); const Router *GetFirstEntry(void) const; const Router *GetNextEntry(const Router *aRouter) const;