mirror of
https://github.com/espressif/openthread.git
synced 2025-08-06 14:52:18 +08:00
[trel] use LinkedList
for TREL peer tracking (#11476)
This commit updates the internal data structure used for tracking TREL peers. Peer tracking now uses a `LinkedList` of `Peer` objects allocated from a pre-allocated `Pool<Peer>`, instead of using a fixed-size `Array<Peer>`. This change allows for future enhancements, such as using heap-allocated `Peer` entries and/or extending the `Peer` object to track additional (dynamically allocated) information.
This commit is contained in:

committed by
GitHub

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