Skip to content

Commit ec2b0d4

Browse files
authored
[trel] use LinkedList for TREL peer tracking (openthread#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.
1 parent 2591b58 commit ec2b0d4

File tree

4 files changed

+59
-40
lines changed

4 files changed

+59
-40
lines changed

include/openthread/instance.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ extern "C" {
5252
*
5353
* @note This number versions both OpenThread platform and user APIs.
5454
*/
55-
#define OPENTHREAD_API_VERSION (504)
55+
#define OPENTHREAD_API_VERSION (505)
5656

5757
/**
5858
* @addtogroup api-instance

include/openthread/trel.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ typedef struct otTrelPeer
6868
/**
6969
* Represents an iterator for iterating over TREL peer table entries.
7070
*/
71-
typedef uint16_t otTrelPeerIterator;
71+
typedef const void *otTrelPeerIterator;
7272

7373
/**
7474
* Enables or disables TREL operation.

src/core/radio/trel_interface.cpp

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -102,18 +102,21 @@ void Interface::Disable(void)
102102
VerifyOrExit(mInitialized);
103103

104104
otPlatTrelDisable(&GetInstance());
105-
mPeerTable.Clear();
105+
ClearPeerList();
106106
LogDebg("Disabled interface");
107107

108108
exit:
109109
return;
110110
}
111111

112-
Interface::Peer *Interface::FindPeer(const Mac::ExtAddress &aExtAddress)
112+
void Interface::ClearPeerList(void)
113113
{
114-
return mPeerTable.FindMatching(aExtAddress);
114+
mPeerList.Clear();
115+
mPeerPool.FreeAll();
115116
}
116117

118+
Interface::Peer *Interface::FindPeer(const Mac::ExtAddress &aExtAddress) { return mPeerList.FindMatching(aExtAddress); }
119+
117120
void Interface::NotifyPeerSocketAddressDifference(const Ip6::SockAddr &aPeerSockAddr, const Ip6::SockAddr &aRxSockAddr)
118121
{
119122
otPlatTrelNotifyPeerSocketAddressDifference(&GetInstance(), &aPeerSockAddr, &aRxSockAddr);
@@ -205,7 +208,7 @@ void Interface::HandleDiscoveredPeerInfo(const Peer::Info &aInfo)
205208
// different Extended MAC address. This ensures that we do not
206209
// keep stale entries in the peer table.
207210

208-
entry = mPeerTable.FindMatching(aInfo.GetSockAddr());
211+
entry = mPeerList.FindMatching(aInfo.GetSockAddr());
209212

210213
if ((entry != nullptr) && !entry->Matches(extAddress))
211214
{
@@ -215,7 +218,7 @@ void Interface::HandleDiscoveredPeerInfo(const Peer::Info &aInfo)
215218

216219
if (entry == nullptr)
217220
{
218-
entry = mPeerTable.FindMatching(extAddress);
221+
entry = mPeerList.FindMatching(extAddress);
219222
}
220223

221224
if (entry == nullptr)
@@ -297,18 +300,23 @@ Interface::Peer *Interface::GetNewPeerEntry(void)
297300
{
298301
Peer *peerEntry;
299302

300-
peerEntry = mPeerTable.PushBack();
301-
VerifyOrExit(peerEntry == nullptr);
303+
peerEntry = mPeerPool.Allocate();
304+
305+
if (peerEntry != nullptr)
306+
{
307+
mPeerList.Push(*peerEntry);
308+
ExitNow();
309+
}
302310

303-
for (Peer &entry : mPeerTable)
311+
for (Peer &entry : mPeerList)
304312
{
305313
if (entry.GetExtPanId() != Get<MeshCoP::ExtendedPanIdManager>().GetExtPanId())
306314
{
307315
ExitNow(peerEntry = &entry);
308316
}
309317
}
310318

311-
for (Peer &entry : mPeerTable)
319+
for (Peer &entry : mPeerList)
312320
{
313321
// We skip over any existing entry in neighbor table (even if the
314322
// entry is in invalid state).
@@ -336,15 +344,10 @@ void Interface::RemovePeerEntry(Peer &aEntry)
336344
{
337345
aEntry.Log("Removing");
338346

339-
// Replace the entry being removed with the last entry (if not the
340-
// last one already) and then pop the last entry from array.
341-
342-
if (&aEntry != mPeerTable.Back())
347+
if (mPeerList.Remove(aEntry) == kErrorNone)
343348
{
344-
aEntry = *mPeerTable.Back();
349+
mPeerPool.Free(aEntry);
345350
}
346-
347-
mPeerTable.PopBack();
348351
}
349352

350353
const Counters *Interface::GetCounters(void) const { return otPlatTrelGetCounters(&GetInstance()); }
@@ -362,7 +365,7 @@ Error Interface::Send(const Packet &aPacket, bool aIsDiscovery)
362365
switch (aPacket.GetHeader().GetType())
363366
{
364367
case Header::kTypeBroadcast:
365-
for (Peer &entry : mPeerTable)
368+
for (Peer &entry : mPeerList)
366369
{
367370
if (!aIsDiscovery && (entry.GetExtPanId() != Get<MeshCoP::ExtendedPanIdManager>().GetExtPanId()))
368371
{
@@ -375,7 +378,7 @@ Error Interface::Send(const Packet &aPacket, bool aIsDiscovery)
375378

376379
case Header::kTypeUnicast:
377380
case Header::kTypeAck:
378-
peerEntry = mPeerTable.FindMatching(aPacket.GetHeader().GetDestination());
381+
peerEntry = mPeerList.FindMatching(aPacket.GetHeader().GetDestination());
379382
VerifyOrExit(peerEntry != nullptr, error = kErrorAbort);
380383
otPlatTrelSend(&GetInstance(), aPacket.GetBuffer(), aPacket.GetLength(), &peerEntry->mSockAddr);
381384
break;
@@ -414,14 +417,26 @@ void Interface::HandleReceived(uint8_t *aBuffer, uint16_t aLength, const Ip6::So
414417

415418
const Interface::Peer *Interface::GetNextPeer(PeerIterator &aIterator) const
416419
{
417-
const Peer *entry = mPeerTable.At(aIterator);
420+
const Peer *entry = static_cast<const Peer *>(aIterator);
421+
422+
VerifyOrExit(entry != nullptr);
423+
aIterator = entry->GetNext();
418424

419-
if (entry != nullptr)
425+
exit:
426+
return entry;
427+
}
428+
429+
uint16_t Interface::GetNumberOfPeers(void) const
430+
{
431+
uint16_t count = 0;
432+
433+
for (const Peer &peer : mPeerList)
420434
{
421-
aIterator++;
435+
OT_UNUSED_VARIABLE(peer);
436+
count++;
422437
}
423438

424-
return entry;
439+
return count;
425440
}
426441

427442
void Interface::Peer::Log(const char *aAction) const

src/core/radio/trel_interface.hpp

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@
4141
#include <openthread/trel.h>
4242
#include <openthread/platform/trel.h>
4343

44-
#include "common/array.hpp"
44+
#include "common/linked_list.hpp"
4545
#include "common/locator.hpp"
46+
#include "common/pool.hpp"
4647
#include "common/tasklet.hpp"
4748
#include "common/time.hpp"
4849
#include "mac/mac_types.hpp"
@@ -83,9 +84,10 @@ class Interface : public InstanceLocator
8384
/**
8485
* Represents information about a discovered TREL peer.
8586
*/
86-
class Peer : public otTrelPeer
87+
class Peer : public otTrelPeer, public LinkedListEntry<Peer>
8788
{
8889
friend class Interface;
90+
friend class LinkedListEntry<Peer>;
8991
friend void otPlatTrelHandleDiscoveredPeerInfo(otInstance *aInstance, const otPlatTrelPeerInfo *aInfo);
9092

9193
public:
@@ -153,6 +155,8 @@ class Interface : public InstanceLocator
153155
void SetExtAddress(const Mac::ExtAddress &aExtAddress) { mExtAddress = aExtAddress; }
154156
void SetExtPanId(const MeshCoP::ExtendedPanId &aExtPanId) { mExtPanId = aExtPanId; }
155157
void Log(const char *aAction) const;
158+
159+
Peer *mNext;
156160
};
157161

158162
/**
@@ -198,7 +202,7 @@ class Interface : public InstanceLocator
198202
*
199203
* @param[in] aIterator The iterator to initialize.
200204
*/
201-
void InitIterator(PeerIterator &aIterator) const { aIterator = 0; }
205+
void InitIterator(PeerIterator &aIterator) const { aIterator = mPeerList.GetHead(); }
202206

203207
/**
204208
* Iterates over the peer table entries.
@@ -214,7 +218,7 @@ class Interface : public InstanceLocator
214218
*
215219
* @returns The number of TREL peers.
216220
*/
217-
uint16_t GetNumberOfPeers(void) const { return mPeerTable.GetLength(); }
221+
uint16_t GetNumberOfPeers(void) const;
218222

219223
/**
220224
* Sets the filter mode (enables/disables filtering).
@@ -276,16 +280,14 @@ class Interface : public InstanceLocator
276280

277281
private:
278282
#if OPENTHREAD_CONFIG_TREL_PEER_TABLE_SIZE != 0
279-
static constexpr uint16_t kPeerTableSize = OPENTHREAD_CONFIG_TREL_PEER_TABLE_SIZE;
283+
static constexpr uint16_t kPeerPoolSize = OPENTHREAD_CONFIG_TREL_PEER_TABLE_SIZE;
280284
#else
281-
static constexpr uint16_t kPeerTableExtraEntries = 32;
282-
static constexpr uint16_t kPeerTableSize = Mle::kMaxRouters + Mle::kMaxChildren + kPeerTableExtraEntries;
285+
static constexpr uint16_t kExtraEntries = 32;
286+
static constexpr uint16_t kPeerPoolSize = Mle::kMaxRouters + Mle::kMaxChildren + kExtraEntries;
283287
#endif
284288
static const char kTxtRecordExtAddressKey[];
285289
static const char kTxtRecordExtPanIdKey[];
286290

287-
typedef Array<Peer, kPeerTableSize, uint16_t> PeerTable;
288-
289291
explicit Interface(Instance &aInstance);
290292

291293
// Methods used by `Trel::Link`.
@@ -304,16 +306,18 @@ class Interface : public InstanceLocator
304306
MeshCoP::ExtendedPanId &aExtPanId) const;
305307
Peer *GetNewPeerEntry(void);
306308
void RemovePeerEntry(Peer &aEntry);
309+
void ClearPeerList(void);
307310

308311
using RegisterServiceTask = TaskletIn<Interface, &Interface::RegisterService>;
309312

310-
bool mInitialized : 1;
311-
bool mEnabled : 1;
312-
bool mFiltered : 1;
313-
RegisterServiceTask mRegisterServiceTask;
314-
uint16_t mUdpPort;
315-
Packet mRxPacket;
316-
PeerTable mPeerTable;
313+
bool mInitialized : 1;
314+
bool mEnabled : 1;
315+
bool mFiltered : 1;
316+
RegisterServiceTask mRegisterServiceTask;
317+
uint16_t mUdpPort;
318+
Packet mRxPacket;
319+
LinkedList<Peer> mPeerList;
320+
Pool<Peer, kPeerPoolSize> mPeerPool;
317321
};
318322

319323
} // namespace Trel

0 commit comments

Comments
 (0)