From 6c55d53a504e52a074cd9be168b8b1da51968184 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Tue, 29 Jul 2025 17:03:02 -0700 Subject: [PATCH] [mle] move child ID allocation logic to `ChildTable` (#11764) This commit moves the child ID allocation logic from `Mle` to `ChildTable`. A new `AllocateNewChildRloc16()` method is added to `ChildTable` to contain the allocation logic, and the `mNextChildId` counter is moved to `ChildTable`. `Mle` is updated to use this new method. This refactoring improves code encapsulation by making the `ChildTable` responsible for managing all aspects of the children it contains, including ID allocation. --- src/core/thread/child_table.cpp | 27 +++++++++++++++++++++++++++ src/core/thread/child_table.hpp | 8 ++++++++ src/core/thread/mle.cpp | 1 - src/core/thread/mle.hpp | 1 - src/core/thread/mle_ftd.cpp | 18 +----------------- 5 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/core/thread/child_table.cpp b/src/core/thread/child_table.cpp index 57a7c6c37..e8360491d 100644 --- a/src/core/thread/child_table.cpp +++ b/src/core/thread/child_table.cpp @@ -39,6 +39,9 @@ namespace ot { +//--------------------------------------------------------------------------------------------------------------------- +// `ChildTable::Iterator` + ChildTable::Iterator::Iterator(Instance &aInstance, Child::StateFilter aFilter) : InstanceLocator(aInstance) , ItemPtrIterator(nullptr) @@ -71,8 +74,12 @@ exit: return; } +//--------------------------------------------------------------------------------------------------------------------- +// `ChildTable` + ChildTable::ChildTable(Instance &aInstance) : InstanceLocator(aInstance) + , mNextChildId(Mle::kMaxChildId) , mMaxChildrenAllowed(kMaxChildren) { for (Child &child : mChildren) @@ -112,6 +119,26 @@ exit: return child; } +uint16_t ChildTable::AllocateNewChildRloc16(void) +{ + uint16_t rloc16; + + do + { + mNextChildId++; + + if (mNextChildId > Mle::kMaxChildId) + { + mNextChildId = Mle::kMinChildId; + } + + rloc16 = Get().GetRloc16() | mNextChildId; + + } while (FindChild(rloc16, Child::kInStateAnyExceptInvalid) != nullptr); + + return rloc16; +} + const Child *ChildTable::FindChild(const Child::AddressMatcher &aMatcher) const { const Child *child = mChildren; diff --git a/src/core/thread/child_table.hpp b/src/core/thread/child_table.hpp index 88fb6b051..3a3b3e1e1 100644 --- a/src/core/thread/child_table.hpp +++ b/src/core/thread/child_table.hpp @@ -136,6 +136,13 @@ public: */ Child *GetNewChild(void); + /** + * Allocates a new child ID and returns the corresponding RLOC16. + * + * @returns The allocated child RLOC16. + */ + uint16_t AllocateNewChildRloc16(void); + /** * Searches the child table for a `Child` with a given RLOC16 also matching a given state filter. * @@ -330,6 +337,7 @@ private: const Child *FindChild(const Child::AddressMatcher &aMatcher) const; void RefreshStoredChildren(void); + uint16_t mNextChildId; uint16_t mMaxChildrenAllowed; Child mChildren[kMaxChildren]; }; diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index f057d18f8..0cc98f991 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -106,7 +106,6 @@ Mle::Mle(Instance &aInstance) , mMaxChildIpAddresses(0) #endif , mParentPriority(kParentPriorityUnspecified) - , mNextChildId(kMaxChildId) , mPreviousPartitionIdRouter(0) , mPreviousPartitionId(0) #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index 25b40e206..a94941907 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -2324,7 +2324,6 @@ private: uint8_t mMaxChildIpAddresses; #endif int8_t mParentPriority; - uint16_t mNextChildId; uint32_t mPreviousPartitionIdRouter; uint32_t mPreviousPartitionId; #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE diff --git a/src/core/thread/mle_ftd.cpp b/src/core/thread/mle_ftd.cpp index ce2089d05..91eca92a9 100644 --- a/src/core/thread/mle_ftd.cpp +++ b/src/core/thread/mle_ftd.cpp @@ -2855,23 +2855,7 @@ Error Mle::SendChildIdResponse(Child &aChild) if ((aChild.GetRloc16() == 0) || !HasMatchingRouterIdWith(aChild.GetRloc16())) { - uint16_t rloc16; - - // Pick next Child ID that is not being used - do - { - mNextChildId++; - - if (mNextChildId > kMaxChildId) - { - mNextChildId = kMinChildId; - } - - rloc16 = Get().GetShortAddress() | mNextChildId; - - } while (mChildTable.FindChild(rloc16, Child::kInStateAnyExceptInvalid) != nullptr); - - aChild.SetRloc16(rloc16); + aChild.SetRloc16(mChildTable.AllocateNewChildRloc16()); } SuccessOrExit(error = message->AppendAddress16Tlv(aChild.GetRloc16()));