Skip to content

Commit 19203d3

Browse files
authored
[dns] add common TxtDataEncoder (openthread#11469)
This commit moves and enhances the `TxtDataEncoder` class, relocating it to the common `dns_types.hpp` header file. The new `TxtDataEncoder` provides helper methods to append TXT entries with a variety of value types, including `NameData`, C-strings, or an unsigned integer (in big-endian format). This enhanced encoder is then used by the `BorderAgent` when preparing MeshCoP TXT data and also by the TREL module.
1 parent c231648 commit 19203d3

5 files changed

Lines changed: 204 additions & 133 deletions

File tree

src/core/meshcop/border_agent.cpp

Lines changed: 44 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -181,13 +181,6 @@ void BorderAgent::SetServiceChangedCallback(ServiceChangedCallback aCallback, vo
181181
PostServiceTask();
182182
}
183183

184-
Error BorderAgent::PrepareServiceTxtData(ServiceTxtData &aTxtData) const
185-
{
186-
TxtEncoder encoder(GetInstance(), aTxtData);
187-
188-
return encoder.EncodeTxtData();
189-
}
190-
191184
void BorderAgent::HandleNotifierEvents(Events aEvents)
192185
{
193186
if (aEvents.Contains(kEventThreadRoleChanged))
@@ -390,150 +383,113 @@ void BorderAgent::PostServiceTask(void)
390383
}
391384
}
392385

393-
//----------------------------------------------------------------------------------------------------------------------
394-
// BorderAgent::TxtEncoder
395-
396-
Error BorderAgent::TxtEncoder::AppendTxtEntry(const char *aKey, const void *aValue, uint16_t aValueLength)
386+
Error BorderAgent::PrepareServiceTxtData(ServiceTxtData &aTxtData)
397387
{
398-
Dns::TxtEntry txtEntry;
399-
400-
txtEntry.Init(aKey, reinterpret_cast<const uint8_t *>(aValue), aValueLength);
401-
return txtEntry.AppendTo(mAppender);
402-
}
403-
404-
template <> Error BorderAgent::TxtEncoder::AppendTxtEntry<NameData>(const char *aKey, const NameData &aObject)
405-
{
406-
return AppendTxtEntry(aKey, aObject.GetBuffer(), aObject.GetLength());
407-
}
408-
409-
Error BorderAgent::TxtEncoder::EncodeTxtData(void)
410-
{
411-
Error error = kErrorNone;
388+
Error error = kErrorNone;
389+
Dns::TxtDataEncoder encoder(aTxtData.mData, sizeof(aTxtData.mData));
412390

413391
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
414392
{
415393
Id id;
416394

417-
if (Get<BorderAgent>().GetId(id) == kErrorNone)
395+
if (GetId(id) == kErrorNone)
418396
{
419-
SuccessOrExit(error = AppendTxtEntry("id", id));
397+
SuccessOrExit(error = encoder.AppendEntry("id", id));
420398
}
421399
}
422400
#endif
423-
SuccessOrExit(error = AppendTxtEntry("nn", Get<NetworkNameManager>().GetNetworkName().GetAsData()));
424-
SuccessOrExit(error = AppendTxtEntry("xp", Get<ExtendedPanIdManager>().GetExtPanId()));
425-
SuccessOrExit(error = AppendTxtEntry("tv", NameData(kThreadVersionString, strlen(kThreadVersionString))));
426-
SuccessOrExit(error = AppendTxtEntry("xa", Get<Mac::Mac>().GetExtAddress()));
427-
SuccessOrExit(error = AppendTxtEntry("sb", BigEndian::HostSwap32(DetermineStateBitmap())));
401+
SuccessOrExit(error = encoder.AppendNameEntry("nn", Get<NetworkNameManager>().GetNetworkName().GetAsData()));
402+
SuccessOrExit(error = encoder.AppendEntry("xp", Get<ExtendedPanIdManager>().GetExtPanId()));
403+
SuccessOrExit(error = encoder.AppendStringEntry("tv", kThreadVersionString));
404+
SuccessOrExit(error = encoder.AppendEntry("xa", Get<Mac::Mac>().GetExtAddress()));
405+
SuccessOrExit(error = encoder.AppendBigEndianUintEntry("sb", DetermineStateBitmap()));
428406

429407
if (Get<Mle::Mle>().IsAttached())
430408
{
431-
SuccessOrExit(
432-
error = AppendTxtEntry("pt", BigEndian::HostSwap32(Get<Mle::Mle>().GetLeaderData().GetPartitionId())));
409+
SuccessOrExit(error = encoder.AppendBigEndianUintEntry("pt", Get<Mle::Mle>().GetLeaderData().GetPartitionId()));
410+
433411
if (Get<MeshCoP::ActiveDatasetManager>().GetTimestamp().IsValid())
434412
{
435-
SuccessOrExit(error = AppendTxtEntry("at", Get<MeshCoP::ActiveDatasetManager>().GetTimestamp()));
413+
SuccessOrExit(error = encoder.AppendEntry("at", Get<MeshCoP::ActiveDatasetManager>().GetTimestamp()));
436414
}
437415
}
438416

439417
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
440-
SuccessOrExit(error = AppendBbrTxtEntry());
441-
#endif
442-
443-
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
444-
SuccessOrExit(error = AppendOmrTxtEntry());
445-
#endif
446-
447-
mTxtData.mLength = mAppender.GetAppendedLength();
448-
449-
exit:
450-
return error;
451-
}
452-
453-
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
454-
Error BorderAgent::TxtEncoder::AppendBbrTxtEntry(void)
455-
{
456-
Error error = kErrorNone;
457-
const DomainName &domainName = Get<MeshCoP::NetworkNameManager>().GetDomainName();
458-
459418
if (Get<Mle::Mle>().IsAttached() && Get<BackboneRouter::Local>().IsEnabled())
460419
{
461420
BackboneRouter::Config bbrConfig;
462421

463422
Get<BackboneRouter::Local>().GetConfig(bbrConfig);
464-
SuccessOrExit(error = AppendTxtEntry("sq", bbrConfig.mSequenceNumber));
465-
SuccessOrExit(error = AppendTxtEntry("bb", BigEndian::HostSwap16(BackboneRouter::kBackboneUdpPort)));
423+
SuccessOrExit(error = encoder.AppendEntry("sq", bbrConfig.mSequenceNumber));
424+
SuccessOrExit(error = encoder.AppendBigEndianUintEntry("bb", BackboneRouter::kBackboneUdpPort));
466425
}
467426

468-
error = AppendTxtEntry(
469-
"dn", NameData(domainName.GetAsCString(), StringLength(domainName.GetAsCString(), sizeof(domainName))));
470-
471-
exit:
472-
return error;
473-
}
474-
#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
427+
SuccessOrExit(error =
428+
encoder.AppendNameEntry("dn", Get<MeshCoP::NetworkNameManager>().GetDomainName().GetAsData()));
429+
#endif
475430

476431
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
477-
Error BorderAgent::TxtEncoder::AppendOmrTxtEntry(void)
478-
{
479-
Error error = kErrorNone;
480-
Ip6::Prefix prefix;
481-
BorderRouter::RoutingManager::RoutePreference preference;
482-
483-
if (Get<BorderRouter::RoutingManager>().GetFavoredOmrPrefix(prefix, preference) == kErrorNone &&
484-
prefix.GetLength() > 0)
485432
{
486-
uint8_t omrData[Ip6::NetworkPrefix::kSize + 1];
433+
Ip6::Prefix prefix;
434+
BorderRouter::RoutingManager::RoutePreference preference;
435+
436+
if (Get<BorderRouter::RoutingManager>().GetFavoredOmrPrefix(prefix, preference) == kErrorNone &&
437+
prefix.GetLength() > 0)
438+
{
439+
uint8_t omrData[Ip6::NetworkPrefix::kSize + 1];
487440

488-
omrData[0] = prefix.GetLength();
489-
memcpy(omrData + 1, prefix.GetBytes(), prefix.GetBytesSize());
441+
omrData[0] = prefix.GetLength();
442+
memcpy(omrData + 1, prefix.GetBytes(), prefix.GetBytesSize());
490443

491-
SuccessOrExit(error = AppendTxtEntry("omr", omrData));
444+
SuccessOrExit(error = encoder.AppendEntry("omr", omrData));
445+
}
492446
}
447+
#endif
448+
449+
aTxtData.mLength = encoder.GetLength();
493450

494451
exit:
495452
return error;
496453
}
497-
#endif
498454

499-
uint32_t BorderAgent::TxtEncoder::DetermineStateBitmap(void)
455+
uint32_t BorderAgent::DetermineStateBitmap(void) const
500456
{
501457
uint32_t bitmap = 0;
502458

503-
bitmap |= (Get<BorderAgent>().IsRunning() ? kConnectionModePskc : kConnectionModeDisabled);
504-
bitmap |= kAvailabilityHigh;
459+
bitmap |= (IsRunning() ? StateBitmap::kConnectionModePskc : StateBitmap::kConnectionModeDisabled);
460+
bitmap |= StateBitmap::kAvailabilityHigh;
505461

506462
switch (Get<Mle::Mle>().GetRole())
507463
{
508464
case Mle::DeviceRole::kRoleDisabled:
509-
bitmap |= (kThreadIfStatusNotInitialized | kThreadRoleDisabledOrDetached);
465+
bitmap |= (StateBitmap::kThreadIfStatusNotInitialized | StateBitmap::kThreadRoleDisabledOrDetached);
510466
break;
511467
case Mle::DeviceRole::kRoleDetached:
512-
bitmap |= (kThreadIfStatusInitialized | kThreadRoleDisabledOrDetached);
468+
bitmap |= (StateBitmap::kThreadIfStatusInitialized | StateBitmap::kThreadRoleDisabledOrDetached);
513469
break;
514470
case Mle::DeviceRole::kRoleChild:
515-
bitmap |= (kThreadIfStatusActive | kThreadRoleChild);
471+
bitmap |= (StateBitmap::kThreadIfStatusActive | StateBitmap::kThreadRoleChild);
516472
break;
517473
case Mle::DeviceRole::kRoleRouter:
518-
bitmap |= (kThreadIfStatusActive | kThreadRoleRouter);
474+
bitmap |= (StateBitmap::kThreadIfStatusActive | StateBitmap::kThreadRoleRouter);
519475
break;
520476
case Mle::DeviceRole::kRoleLeader:
521-
bitmap |= (kThreadIfStatusActive | kThreadRoleLeader);
477+
bitmap |= (StateBitmap::kThreadIfStatusActive | StateBitmap::kThreadRoleLeader);
522478
break;
523479
}
524480

525481
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
526482
if (Get<Mle::Mle>().IsAttached())
527483
{
528-
bitmap |= (Get<BackboneRouter::Local>().IsEnabled() ? kFlagBbrIsActive : 0);
529-
bitmap |= (Get<BackboneRouter::Local>().IsPrimary() ? kFlagBbrIsPrimary : 0);
484+
bitmap |= (Get<BackboneRouter::Local>().IsEnabled() ? StateBitmap::kFlagBbrIsActive : 0);
485+
bitmap |= (Get<BackboneRouter::Local>().IsPrimary() ? StateBitmap::kFlagBbrIsPrimary : 0);
530486
}
531487
#endif
532488

533489
#if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
534-
if (Get<BorderAgent::EphemeralKeyManager>().GetState() != EphemeralKeyManager::kStateDisabled)
490+
if (mEphemeralKeyManager.GetState() != EphemeralKeyManager::kStateDisabled)
535491
{
536-
bitmap |= kFlagEpskcSupported;
492+
bitmap |= StateBitmap::kFlagEpskcSupported;
537493
}
538494
#endif
539495

src/core/meshcop/border_agent.hpp

Lines changed: 4 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ class BorderAgent : public InstanceLocator, private NonCopyable
227227
* @retval kErrorNone If successfully retrieved the Border Agent MeshCoP Service TXT data.
228228
* @retval kErrorNoBufs If the buffer in @p aTxtData doesn't have enough size.
229229
*/
230-
Error PrepareServiceTxtData(ServiceTxtData &aTxtData) const;
230+
Error PrepareServiceTxtData(ServiceTxtData &aTxtData);
231231

232232
#if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
233233
/**
@@ -471,19 +471,8 @@ class BorderAgent : public InstanceLocator, private NonCopyable
471471
uint64_t mAllocationTime;
472472
};
473473

474-
class TxtEncoder : public InstanceLocator
474+
struct StateBitmap
475475
{
476-
public:
477-
TxtEncoder(Instance &aInstance, ServiceTxtData &aTxtData)
478-
: InstanceLocator(aInstance)
479-
, mTxtData(aTxtData)
480-
, mAppender(mTxtData.mData, sizeof(mTxtData.mData))
481-
{
482-
}
483-
484-
Error EncodeTxtData(void);
485-
486-
private:
487476
// --- State Bitmap ConnectionMode ---
488477
static constexpr uint8_t kOffsetConnectionMode = 0;
489478
static constexpr uint32_t kMaskConnectionMode = 7 << kOffsetConnectionMode;
@@ -525,28 +514,6 @@ class BorderAgent : public InstanceLocator, private NonCopyable
525514
// --- State Bitmap EpskcSupported ---
526515
static constexpr uint8_t kOffsetEpskcSupported = 11;
527516
static constexpr uint32_t kFlagEpskcSupported = 1 << kOffsetEpskcSupported;
528-
529-
uint32_t DetermineStateBitmap(void);
530-
531-
Error AppendTxtEntry(const char *aKey, const void *aValue, uint16_t aValueLength);
532-
533-
template <typename ObjectType> Error AppendTxtEntry(const char *aKey, const ObjectType &aObject)
534-
{
535-
static_assert(!TypeTraits::IsPointer<ObjectType>::kValue, "ObjectType must not be a pointer");
536-
static_assert(!TypeTraits::IsSame<ObjectType, NameData>::kValue, "ObjectType must not be `NameData`");
537-
538-
return AppendTxtEntry(aKey, &aObject, sizeof(ObjectType));
539-
}
540-
541-
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
542-
Error AppendBbrTxtEntry(void);
543-
#endif
544-
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
545-
Error AppendOmrTxtEntry(void);
546-
#endif
547-
548-
ServiceTxtData &mTxtData;
549-
Appender mAppender;
550517
};
551518

552519
void UpdateState(void);
@@ -568,6 +535,8 @@ class BorderAgent : public InstanceLocator, private NonCopyable
568535

569536
static Coap::Message::Code CoapCodeFromError(Error aError);
570537

538+
uint32_t DetermineStateBitmap(void) const;
539+
571540
void PostServiceTask(void);
572541
void HandleServiceTask(void);
573542
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE

src/core/net/dns_types.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,6 +1390,24 @@ Error TxtEntry::AppendEntries(const TxtEntry *aEntries, uint16_t aNumEntries, Ap
13901390
return error;
13911391
}
13921392

1393+
Error TxtDataEncoder::AppendBytesEntry(const char *aKey, const void *aBuffer, uint16_t aLength)
1394+
{
1395+
return TxtEntry(aKey, reinterpret_cast<const uint8_t *>(aBuffer), aLength).AppendTo(mAppender);
1396+
}
1397+
1398+
Error TxtDataEncoder::AppendStringEntry(const char *aKey, const char *aStringValue)
1399+
{
1400+
Error error;
1401+
uint16_t length = StringLength(aStringValue, kMaxStringEntryLength + 1);
1402+
1403+
VerifyOrExit(length <= kMaxStringEntryLength, error = kErrorInvalidArgs);
1404+
1405+
error = AppendBytesEntry(aKey, aStringValue, length);
1406+
1407+
exit:
1408+
return error;
1409+
}
1410+
13931411
bool AaaaRecord::IsValid(void) const
13941412
{
13951413
return GetType() == Dns::ResourceRecord::kTypeAaaa && GetSize() == sizeof(*this);

0 commit comments

Comments
 (0)