diff --git a/include/openthread/instance.h b/include/openthread/instance.h index 08a3203ea..29f30be69 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -52,7 +52,7 @@ extern "C" { * * @note This number versions both OpenThread platform and user APIs. */ -#define OPENTHREAD_API_VERSION (504) +#define OPENTHREAD_API_VERSION (505) /** * @addtogroup api-instance diff --git a/include/openthread/trel.h b/include/openthread/trel.h index 271d68677..23e4c47e6 100644 --- a/include/openthread/trel.h +++ b/include/openthread/trel.h @@ -68,7 +68,7 @@ typedef struct otTrelPeer /** * Represents an iterator for iterating over TREL peer table entries. */ -typedef uint16_t otTrelPeerIterator; +typedef const void *otTrelPeerIterator; /** * Enables or disables TREL operation. diff --git a/src/core/radio/trel_interface.cpp b/src/core/radio/trel_interface.cpp index bfa0ae4de..696138b88 100644 --- a/src/core/radio/trel_interface.cpp +++ b/src/core/radio/trel_interface.cpp @@ -102,18 +102,21 @@ void Interface::Disable(void) VerifyOrExit(mInitialized); otPlatTrelDisable(&GetInstance()); - mPeerTable.Clear(); + ClearPeerList(); LogDebg("Disabled interface"); exit: return; } -Interface::Peer *Interface::FindPeer(const Mac::ExtAddress &aExtAddress) +void Interface::ClearPeerList(void) { - return mPeerTable.FindMatching(aExtAddress); + mPeerList.Clear(); + mPeerPool.FreeAll(); } +Interface::Peer *Interface::FindPeer(const Mac::ExtAddress &aExtAddress) { return mPeerList.FindMatching(aExtAddress); } + void Interface::NotifyPeerSocketAddressDifference(const Ip6::SockAddr &aPeerSockAddr, const Ip6::SockAddr &aRxSockAddr) { otPlatTrelNotifyPeerSocketAddressDifference(&GetInstance(), &aPeerSockAddr, &aRxSockAddr); @@ -205,7 +208,7 @@ void Interface::HandleDiscoveredPeerInfo(const Peer::Info &aInfo) // different Extended MAC address. This ensures that we do not // keep stale entries in the peer table. - entry = mPeerTable.FindMatching(aInfo.GetSockAddr()); + entry = mPeerList.FindMatching(aInfo.GetSockAddr()); if ((entry != nullptr) && !entry->Matches(extAddress)) { @@ -215,7 +218,7 @@ void Interface::HandleDiscoveredPeerInfo(const Peer::Info &aInfo) if (entry == nullptr) { - entry = mPeerTable.FindMatching(extAddress); + entry = mPeerList.FindMatching(extAddress); } if (entry == nullptr) @@ -297,10 +300,15 @@ Interface::Peer *Interface::GetNewPeerEntry(void) { Peer *peerEntry; - peerEntry = mPeerTable.PushBack(); - VerifyOrExit(peerEntry == nullptr); + peerEntry = mPeerPool.Allocate(); - for (Peer &entry : mPeerTable) + if (peerEntry != nullptr) + { + mPeerList.Push(*peerEntry); + ExitNow(); + } + + for (Peer &entry : mPeerList) { if (entry.GetExtPanId() != Get().GetExtPanId()) { @@ -308,7 +316,7 @@ Interface::Peer *Interface::GetNewPeerEntry(void) } } - for (Peer &entry : mPeerTable) + for (Peer &entry : mPeerList) { // We skip over any existing entry in neighbor table (even if the // entry is in invalid state). @@ -336,15 +344,10 @@ void Interface::RemovePeerEntry(Peer &aEntry) { aEntry.Log("Removing"); - // Replace the entry being removed with the last entry (if not the - // last one already) and then pop the last entry from array. - - if (&aEntry != mPeerTable.Back()) + if (mPeerList.Remove(aEntry) == kErrorNone) { - aEntry = *mPeerTable.Back(); + mPeerPool.Free(aEntry); } - - mPeerTable.PopBack(); } const Counters *Interface::GetCounters(void) const { return otPlatTrelGetCounters(&GetInstance()); } @@ -362,7 +365,7 @@ Error Interface::Send(const Packet &aPacket, bool aIsDiscovery) switch (aPacket.GetHeader().GetType()) { case Header::kTypeBroadcast: - for (Peer &entry : mPeerTable) + for (Peer &entry : mPeerList) { if (!aIsDiscovery && (entry.GetExtPanId() != Get().GetExtPanId())) { @@ -375,7 +378,7 @@ Error Interface::Send(const Packet &aPacket, bool aIsDiscovery) case Header::kTypeUnicast: case Header::kTypeAck: - peerEntry = mPeerTable.FindMatching(aPacket.GetHeader().GetDestination()); + peerEntry = mPeerList.FindMatching(aPacket.GetHeader().GetDestination()); VerifyOrExit(peerEntry != nullptr, error = kErrorAbort); otPlatTrelSend(&GetInstance(), aPacket.GetBuffer(), aPacket.GetLength(), &peerEntry->mSockAddr); break; @@ -414,14 +417,26 @@ exit: const Interface::Peer *Interface::GetNextPeer(PeerIterator &aIterator) const { - const Peer *entry = mPeerTable.At(aIterator); + const Peer *entry = static_cast(aIterator); - if (entry != nullptr) + VerifyOrExit(entry != nullptr); + aIterator = entry->GetNext(); + +exit: + return entry; +} + +uint16_t Interface::GetNumberOfPeers(void) const +{ + uint16_t count = 0; + + for (const Peer &peer : mPeerList) { - aIterator++; + OT_UNUSED_VARIABLE(peer); + count++; } - return entry; + return count; } void Interface::Peer::Log(const char *aAction) const diff --git a/src/core/radio/trel_interface.hpp b/src/core/radio/trel_interface.hpp index c87e14897..1f9a7ce95 100644 --- a/src/core/radio/trel_interface.hpp +++ b/src/core/radio/trel_interface.hpp @@ -41,8 +41,9 @@ #include #include -#include "common/array.hpp" +#include "common/linked_list.hpp" #include "common/locator.hpp" +#include "common/pool.hpp" #include "common/tasklet.hpp" #include "common/time.hpp" #include "mac/mac_types.hpp" @@ -83,9 +84,10 @@ public: /** * Represents information about a discovered TREL peer. */ - class Peer : public otTrelPeer + class Peer : public otTrelPeer, public LinkedListEntry { friend class Interface; + friend class LinkedListEntry; friend void otPlatTrelHandleDiscoveredPeerInfo(otInstance *aInstance, const otPlatTrelPeerInfo *aInfo); public: @@ -153,6 +155,8 @@ public: void SetExtAddress(const Mac::ExtAddress &aExtAddress) { mExtAddress = aExtAddress; } void SetExtPanId(const MeshCoP::ExtendedPanId &aExtPanId) { mExtPanId = aExtPanId; } void Log(const char *aAction) const; + + Peer *mNext; }; /** @@ -198,7 +202,7 @@ public: * * @param[in] aIterator The iterator to initialize. */ - void InitIterator(PeerIterator &aIterator) const { aIterator = 0; } + void InitIterator(PeerIterator &aIterator) const { aIterator = mPeerList.GetHead(); } /** * Iterates over the peer table entries. @@ -214,7 +218,7 @@ public: * * @returns The number of TREL peers. */ - uint16_t GetNumberOfPeers(void) const { return mPeerTable.GetLength(); } + uint16_t GetNumberOfPeers(void) const; /** * Sets the filter mode (enables/disables filtering). @@ -276,16 +280,14 @@ public: private: #if OPENTHREAD_CONFIG_TREL_PEER_TABLE_SIZE != 0 - static constexpr uint16_t kPeerTableSize = OPENTHREAD_CONFIG_TREL_PEER_TABLE_SIZE; + static constexpr uint16_t kPeerPoolSize = OPENTHREAD_CONFIG_TREL_PEER_TABLE_SIZE; #else - static constexpr uint16_t kPeerTableExtraEntries = 32; - static constexpr uint16_t kPeerTableSize = Mle::kMaxRouters + Mle::kMaxChildren + kPeerTableExtraEntries; + static constexpr uint16_t kExtraEntries = 32; + static constexpr uint16_t kPeerPoolSize = Mle::kMaxRouters + Mle::kMaxChildren + kExtraEntries; #endif static const char kTxtRecordExtAddressKey[]; static const char kTxtRecordExtPanIdKey[]; - typedef Array PeerTable; - explicit Interface(Instance &aInstance); // Methods used by `Trel::Link`. @@ -304,16 +306,18 @@ private: MeshCoP::ExtendedPanId &aExtPanId) const; Peer *GetNewPeerEntry(void); void RemovePeerEntry(Peer &aEntry); + void ClearPeerList(void); using RegisterServiceTask = TaskletIn; - bool mInitialized : 1; - bool mEnabled : 1; - bool mFiltered : 1; - RegisterServiceTask mRegisterServiceTask; - uint16_t mUdpPort; - Packet mRxPacket; - PeerTable mPeerTable; + bool mInitialized : 1; + bool mEnabled : 1; + bool mFiltered : 1; + RegisterServiceTask mRegisterServiceTask; + uint16_t mUdpPort; + Packet mRxPacket; + LinkedList mPeerList; + Pool mPeerPool; }; } // namespace Trel