[trel] introduce TxtData and TxtDataEncoder in PeerDiscoverer (#11496)

This commit introduces `TxtData` and `TxtDataEncoder` as nested types
in `Trel::PeerDiscoverer`. These classes handle the decoding and
encoding of TXT data for the TREL service, separating this TXT
data-related logic from the rest of the code. This helps simplify the
code and enables future extensions, allowing the TXT data logic to be
used irrespective of how services are registered or discovered.
This commit is contained in:
Abtin Keshavarzian
2025-05-13 21:49:00 -07:00
committed by GitHub
parent 6961ad183a
commit 718a27e8f2
2 changed files with 96 additions and 43 deletions

View File

@ -41,9 +41,6 @@ namespace Trel {
RegisterLogModule("TrelDiscoverer");
const char PeerDiscoverer::kTxtRecordExtAddressKey[] = "xa";
const char PeerDiscoverer::kTxtRecordExtPanIdKey[] = "xp";
PeerDiscoverer::PeerDiscoverer(Instance &aInstance)
: InstanceLocator(aInstance)
, mIsRunning(false)
@ -89,30 +86,17 @@ void PeerDiscoverer::PostRegisterServiceTask(void)
void PeerDiscoverer::RegisterService(void)
{
// TXT data consists of two entries: the length fields, the
// "key" string, "=" char, and binary representation of the MAC
// or Extended PAN ID values.
static constexpr uint8_t kTxtDataSize =
/* ExtAddr */ sizeof(uint8_t) + sizeof(kTxtRecordExtAddressKey) - 1 + sizeof(char) + sizeof(Mac::ExtAddress) +
/* ExtPanId */ sizeof(uint8_t) + sizeof(kTxtRecordExtPanIdKey) - 1 + sizeof(char) +
sizeof(MeshCoP::ExtendedPanId);
uint8_t txtData[kTxtDataSize];
Dns::TxtDataEncoder encoder(txtData, sizeof(txtData));
TxtDataEncoder txtData(GetInstance());
uint16_t port;
VerifyOrExit(mIsRunning);
port = Get<Interface>().GetUdpPort();
SuccessOrAssert(encoder.AppendEntry(kTxtRecordExtAddressKey, Get<Mac::Mac>().GetExtAddress()));
SuccessOrAssert(encoder.AppendEntry(kTxtRecordExtPanIdKey, Get<MeshCoP::ExtendedPanIdManager>().GetExtPanId()));
txtData.Encode();
LogInfo("Registering DNS-SD service: port:%u, txt:\"%s=%s, %s=%s\"", port, kTxtRecordExtAddressKey,
Get<Mac::Mac>().GetExtAddress().ToString().AsCString(), kTxtRecordExtPanIdKey,
Get<MeshCoP::ExtendedPanIdManager>().GetExtPanId().ToString().AsCString());
otPlatTrelRegisterService(&GetInstance(), port, txtData, static_cast<uint8_t>(encoder.GetLength()));
LogInfo("Registering DNS-SD service: port:%u", port);
otPlatTrelRegisterService(&GetInstance(), port, txtData.GetBytes(), static_cast<uint8_t>(txtData.GetLength()));
exit:
return;
@ -132,19 +116,20 @@ exit:
void PeerDiscoverer::HandleDiscoveredPeerInfo(const PeerInfo &aInfo)
{
Peer *peer;
Mac::ExtAddress extAddress;
MeshCoP::ExtendedPanId extPanId;
TxtData txtData;
TxtData::Info txtInfo;
bool isNew = false;
VerifyOrExit(mIsRunning);
SuccessOrExit(aInfo.ParseTxtData(extAddress, extPanId));
txtData.Init(aInfo.mTxtData, aInfo.mTxtLength);
SuccessOrExit(txtData.Decode(txtInfo));
VerifyOrExit(extAddress != Get<Mac::Mac>().GetExtAddress());
VerifyOrExit(txtInfo.mExtAddress != Get<Mac::Mac>().GetExtAddress());
if (aInfo.IsRemoved())
{
Get<PeerTable>().RemoveAndFreeAllMatching(extAddress);
Get<PeerTable>().RemoveAndFreeAllMatching(txtInfo.mExtAddress);
ExitNow();
}
@ -156,7 +141,7 @@ void PeerDiscoverer::HandleDiscoveredPeerInfo(const PeerInfo &aInfo)
peer = Get<PeerTable>().FindMatching(aInfo.GetSockAddr());
if ((peer != nullptr) && !peer->Matches(extAddress))
if ((peer != nullptr) && !peer->Matches(txtInfo.mExtAddress))
{
Get<PeerTable>().RemoveMatching(aInfo.GetSockAddr());
peer = nullptr;
@ -164,7 +149,7 @@ void PeerDiscoverer::HandleDiscoveredPeerInfo(const PeerInfo &aInfo)
if (peer == nullptr)
{
peer = Get<PeerTable>().FindMatching(extAddress);
peer = Get<PeerTable>().FindMatching(txtInfo.mExtAddress);
}
if (peer == nullptr)
@ -172,16 +157,16 @@ void PeerDiscoverer::HandleDiscoveredPeerInfo(const PeerInfo &aInfo)
peer = Get<PeerTable>().AllocateAndAddNewPeer();
VerifyOrExit(peer != nullptr);
peer->SetExtAddress(extAddress);
peer->SetExtAddress(txtInfo.mExtAddress);
isNew = true;
}
if (!isNew)
{
VerifyOrExit((peer->GetExtPanId() != extPanId) || (peer->GetSockAddr() != aInfo.GetSockAddr()));
VerifyOrExit((peer->GetExtPanId() != txtInfo.mExtPanId) || (peer->GetSockAddr() != aInfo.GetSockAddr()));
}
peer->SetExtPanId(extPanId);
peer->SetExtPanId(txtInfo.mExtPanId);
peer->SetSockAddr(aInfo.GetSockAddr());
peer->Log(isNew ? Peer::kAdded : Peer::kUpdated);
@ -190,7 +175,19 @@ exit:
return;
}
Error PeerDiscoverer::PeerInfo::ParseTxtData(Mac::ExtAddress &aExtAddress, MeshCoP::ExtendedPanId &aExtPanId) const
//----------------------------------------------------------------------------------------------------------------------
// PeerDiscoverer::TxtData
const char PeerDiscoverer::TxtData::kExtAddressKey[] = "xa";
const char PeerDiscoverer::TxtData::kExtPanIdKey[] = "xp";
void PeerDiscoverer::TxtData::Init(const uint8_t *aData, uint16_t aLength)
{
mData = aData;
mLength = aLength;
}
Error PeerDiscoverer::TxtData::Decode(Info &aInfo)
{
Error error;
Dns::TxtEntry entry;
@ -198,9 +195,9 @@ Error PeerDiscoverer::PeerInfo::ParseTxtData(Mac::ExtAddress &aExtAddress, MeshC
bool parsedExtAddress = false;
bool parsedExtPanId = false;
aExtPanId.Clear();
aInfo.Clear();
iterator.Init(mTxtData, mTxtLength);
iterator.Init(mData, mLength);
while ((error = iterator.GetNextEntry(entry)) == kErrorNone)
{
@ -213,18 +210,18 @@ Error PeerDiscoverer::PeerInfo::ParseTxtData(Mac::ExtAddress &aExtAddress, MeshC
continue;
}
if (StringMatch(entry.mKey, kTxtRecordExtAddressKey))
if (StringMatch(entry.mKey, kExtAddressKey))
{
VerifyOrExit(!parsedExtAddress, error = kErrorParse);
VerifyOrExit(entry.mValueLength >= sizeof(Mac::ExtAddress), error = kErrorParse);
aExtAddress.Set(entry.mValue);
aInfo.mExtAddress.Set(entry.mValue);
parsedExtAddress = true;
}
else if (StringMatch(entry.mKey, kTxtRecordExtPanIdKey))
else if (StringMatch(entry.mKey, kExtPanIdKey))
{
VerifyOrExit(!parsedExtPanId, error = kErrorParse);
VerifyOrExit(entry.mValueLength >= sizeof(MeshCoP::ExtendedPanId), error = kErrorParse);
memcpy(aExtPanId.m8, entry.mValue, sizeof(MeshCoP::ExtendedPanId));
memcpy(aInfo.mExtPanId.m8, entry.mValue, sizeof(MeshCoP::ExtendedPanId));
parsedExtPanId = true;
}
@ -240,6 +237,25 @@ exit:
return error;
}
//----------------------------------------------------------------------------------------------------------------------
// PeerDiscoverer::TxtDataEncoder
PeerDiscoverer::TxtDataEncoder::TxtDataEncoder(Instance &aInstance)
: InstanceLocator(aInstance)
{
}
void PeerDiscoverer::TxtDataEncoder::Encode(void)
{
Dns::TxtDataEncoder encoder(mBuffer, sizeof(mBuffer));
SuccessOrAssert(encoder.AppendEntry(kExtAddressKey, Get<Mac::Mac>().GetExtAddress()));
SuccessOrAssert(encoder.AppendEntry(kExtPanIdKey, Get<MeshCoP::ExtendedPanIdManager>().GetExtPanId()));
mData = mBuffer;
mLength = encoder.GetLength();
}
} // namespace Trel
} // namespace ot

View File

@ -40,6 +40,7 @@
#include <openthread/platform/trel.h>
#include "common/clearable.hpp"
#include "common/locator.hpp"
#include "common/tasklet.hpp"
#include "radio/trel_peer.hpp"
@ -90,14 +91,50 @@ public:
void NotifyPeerSocketAddressDifference(const Ip6::SockAddr &aPeerSockAddr, const Ip6::SockAddr &aRxSockAddr);
private:
static const char kTxtRecordExtAddressKey[];
static const char kTxtRecordExtPanIdKey[];
class TxtData
{
public:
struct Info : public Clearable<Info>
{
Mac::ExtAddress mExtAddress;
MeshCoP::ExtendedPanId mExtPanId;
};
void Init(const uint8_t *aData, uint16_t aLength);
const uint8_t *GetBytes(void) const { return mData; }
uint16_t GetLength(void) const { return mLength; }
Error Decode(Info &aInfo);
protected:
static const char kExtAddressKey[]; // "xa"
static const char kExtPanIdKey[]; // "xp"
const uint8_t *mData;
uint16_t mLength;
};
class TxtDataEncoder : public InstanceLocator, public TxtData
{
public:
explicit TxtDataEncoder(Instance &aInstance);
void Encode(void);
private:
// TXT data consists of two entries: `xa` for extended address
// and `xp` for extended PAN ID. Each entry starts with one
// byte for length, then the two-character key, followed by
// an `=` character, and then the value. This adds up to
// (4 + 8 [value]) = 12 bytes total per entry. The value of
// 32 accommodates these two entries and more.
static constexpr uint8_t kMaxSize = 32;
uint8_t mBuffer[kMaxSize];
};
struct PeerInfo : public otPlatTrelPeerInfo
{
bool IsRemoved(void) const { return mRemoved; }
const Ip6::SockAddr &GetSockAddr(void) const { return AsCoreType(&mSockAddr); }
Error ParseTxtData(Mac::ExtAddress &aExtAddress, MeshCoP::ExtendedPanId &aExtPanId) const;
};
explicit PeerDiscoverer(Instance &aInstance);