[netdata] add ServiceData and ServerData types (#6984)

This commit adds new types `NetworkData::ServiceData/ServerData`
(which use the `ot::Data` class) which help simplify different
`NetworkData` methods dealing with Service and Server TLVs.
This commit is contained in:
Abtin Keshavarzian
2021-09-16 14:50:23 -07:00
committed by Jonathan Hui
parent ca35753a1e
commit 063d7a1514
16 changed files with 372 additions and 277 deletions
+13 -7
View File
@@ -53,12 +53,15 @@ otError otServerGetNetDataLocal(otInstance *aInstance, bool aStable, uint8_t *aD
otError otServerAddService(otInstance *aInstance, const otServiceConfig *aConfig)
{
Instance &instance = *static_cast<Instance *>(aInstance);
Instance & instance = *static_cast<Instance *>(aInstance);
NetworkData::ServiceData serviceData;
NetworkData::ServerData serverData;
return instance.Get<NetworkData::Local>().AddService(aConfig->mEnterpriseNumber, &aConfig->mServiceData[0],
aConfig->mServiceDataLength, aConfig->mServerConfig.mStable,
&aConfig->mServerConfig.mServerData[0],
aConfig->mServerConfig.mServerDataLength);
serviceData.Init(&aConfig->mServiceData[0], aConfig->mServiceDataLength);
serverData.Init(&aConfig->mServerConfig.mServerData[0], aConfig->mServerConfig.mServerDataLength);
return instance.Get<NetworkData::Local>().AddService(aConfig->mEnterpriseNumber, serviceData,
aConfig->mServerConfig.mStable, serverData);
}
otError otServerRemoveService(otInstance * aInstance,
@@ -66,9 +69,12 @@ otError otServerRemoveService(otInstance * aInstance,
const uint8_t *aServiceData,
uint8_t aServiceDataLength)
{
Instance &instance = *static_cast<Instance *>(aInstance);
Instance & instance = *static_cast<Instance *>(aInstance);
NetworkData::ServiceData serviceData;
return instance.Get<NetworkData::Local>().RemoveService(aEnterpriseNumber, aServiceData, aServiceDataLength);
serviceData.Init(aServiceData, aServiceDataLength);
return instance.Get<NetworkData::Local>().RemoveService(aEnterpriseNumber, serviceData);
}
otError otServerGetNextService(otInstance *aInstance, otNetworkDataIterator *aIterator, otServiceConfig *aConfig)
+34 -31
View File
@@ -558,27 +558,25 @@ const PrefixTlv *NetworkData::FindPrefix(const uint8_t *aPrefix,
return prefixTlv;
}
const ServiceTlv *NetworkData::FindService(uint32_t aEnterpriseNumber,
const uint8_t * aServiceData,
uint8_t aServiceDataLength,
ServiceMatchMode aServiceMatchMode) const
const ServiceTlv *NetworkData::FindService(uint32_t aEnterpriseNumber,
const ServiceData &aServiceData,
ServiceMatchMode aServiceMatchMode) const
{
return FindService(aEnterpriseNumber, aServiceData, aServiceDataLength, aServiceMatchMode, mTlvs, mLength);
return FindService(aEnterpriseNumber, aServiceData, aServiceMatchMode, mTlvs, mLength);
}
const ServiceTlv *NetworkData::FindService(uint32_t aEnterpriseNumber,
const uint8_t * aServiceData,
uint8_t aServiceDataLength,
ServiceMatchMode aServiceMatchMode,
const uint8_t * aTlvs,
uint8_t aTlvsLength)
const ServiceTlv *NetworkData::FindService(uint32_t aEnterpriseNumber,
const ServiceData &aServiceData,
ServiceMatchMode aServiceMatchMode,
const uint8_t * aTlvs,
uint8_t aTlvsLength)
{
TlvIterator tlvIterator(aTlvs, aTlvsLength);
const ServiceTlv *serviceTlv;
while ((serviceTlv = tlvIterator.Iterate<ServiceTlv>()) != nullptr)
{
if (MatchService(*serviceTlv, aEnterpriseNumber, aServiceData, aServiceDataLength, aServiceMatchMode))
if (MatchService(*serviceTlv, aEnterpriseNumber, aServiceData, aServiceMatchMode))
{
break;
}
@@ -587,11 +585,10 @@ const ServiceTlv *NetworkData::FindService(uint32_t aEnterpriseNumber,
return serviceTlv;
}
const ServiceTlv *NetworkData::FindNextService(const ServiceTlv *aPrevServiceTlv,
uint32_t aEnterpriseNumber,
const uint8_t * aServiceData,
uint8_t aServiceDataLength,
ServiceMatchMode aServiceMatchMode) const
const ServiceTlv *NetworkData::FindNextService(const ServiceTlv * aPrevServiceTlv,
uint32_t aEnterpriseNumber,
const ServiceData &aServiceData,
ServiceMatchMode aServiceMatchMode) const
{
const uint8_t *tlvs;
uint8_t length;
@@ -607,33 +604,39 @@ const ServiceTlv *NetworkData::FindNextService(const ServiceTlv *aPrevServiceTlv
length = static_cast<uint8_t>((mTlvs + mLength) - tlvs);
}
return FindService(aEnterpriseNumber, aServiceData, aServiceDataLength, aServiceMatchMode, tlvs, length);
return FindService(aEnterpriseNumber, aServiceData, aServiceMatchMode, tlvs, length);
}
bool NetworkData::MatchService(const ServiceTlv &aServiceTlv,
uint32_t aEnterpriseNumber,
const uint8_t * aServiceData,
uint8_t aServiceDataLength,
ServiceMatchMode aServiceMatchMode)
const ServiceTlv *NetworkData::FindNextThreadService(const ServiceTlv * aPrevServiceTlv,
const ServiceData &aServiceData,
ServiceMatchMode aServiceMatchMode) const
{
bool match = false;
return FindNextService(aPrevServiceTlv, ServiceTlv::kThreadEnterpriseNumber, aServiceData, aServiceMatchMode);
}
VerifyOrExit(aServiceTlv.GetEnterpriseNumber() == aEnterpriseNumber &&
aServiceTlv.GetServiceDataLength() >= aServiceDataLength);
bool NetworkData::MatchService(const ServiceTlv & aServiceTlv,
uint32_t aEnterpriseNumber,
const ServiceData &aServiceData,
ServiceMatchMode aServiceMatchMode)
{
bool match = false;
ServiceData serviceData;
VerifyOrExit(aServiceTlv.GetEnterpriseNumber() == aEnterpriseNumber);
aServiceTlv.GetServiceData(serviceData);
switch (aServiceMatchMode)
{
case kServiceExactMatch:
VerifyOrExit(aServiceTlv.GetServiceDataLength() == aServiceDataLength);
OT_FALL_THROUGH;
match = (serviceData == aServiceData);
break;
case kServicePrefixMatch:
VerifyOrExit(memcmp(aServiceTlv.GetServiceData(), aServiceData, aServiceDataLength) == 0);
match = serviceData.StartsWith(aServiceData);
break;
}
match = true;
exit:
return match;
}
+49 -44
View File
@@ -423,44 +423,38 @@ protected:
* This method returns a pointer to a matching Service TLV.
*
* @param[in] aEnterpriseNumber Enterprise Number.
* @param[in] aServiceData A pointer to a Service Data.
* @param[in] aServiceDataLength The Service Data length pointed to by @p aServiceData.
* @param[in] aServiceData A Service Data.
* @param[in] aServiceMatchMode The Service Data match mode.
*
* @returns A pointer to the Service TLV if one is found or nullptr if no matching Service TLV exists.
*
*/
ServiceTlv *FindService(uint32_t aEnterpriseNumber,
const uint8_t * aServiceData,
uint8_t aServiceDataLength,
ServiceMatchMode aServiceMatchMode)
ServiceTlv *FindService(uint32_t aEnterpriseNumber,
const ServiceData &aServiceData,
ServiceMatchMode aServiceMatchMode)
{
return AsNonConst(
AsConst(this)->FindService(aEnterpriseNumber, aServiceData, aServiceDataLength, aServiceMatchMode));
return AsNonConst(AsConst(this)->FindService(aEnterpriseNumber, aServiceData, aServiceMatchMode));
}
/**
* This method returns a pointer to a matching Service TLV.
*
* @param[in] aEnterpriseNumber Enterprise Number.
* @param[in] aServiceData A pointer to a Service Data.
* @param[in] aServiceDataLength The Service Data length pointed to by @p aServiceData.
* @param[in] aServiceData A Service Data.
* @param[in] aServiceMatchMode The Service Data match mode.
*
* @returns A pointer to the Service TLV if one is found or nullptr if no matching Service TLV exists.
*
*/
const ServiceTlv *FindService(uint32_t aEnterpriseNumber,
const uint8_t * aServiceData,
uint8_t aServiceDataLength,
ServiceMatchMode aServiceMatchMode) const;
const ServiceTlv *FindService(uint32_t aEnterpriseNumber,
const ServiceData &aServiceData,
ServiceMatchMode aServiceMatchMode) const;
/**
* This method returns a pointer to a Service TLV in a specified tlvs buffer.
*
* @param[in] aEnterpriseNumber Enterprise Number.
* @param[in] aServiceData A pointer to a Service Data.
* @param[in] aServiceDataLength The Service Data length pointed to by @p aServiceData.
* @param[in] aServiceData A Service Data.
* @param[in] aServiceMatchMode The Service Data match mode.
* @param[in] aTlvs A pointer to a specified tlvs buffer.
* @param[in] aTlvsLength The specified tlvs buffer length pointed to by @p aTlvs.
@@ -468,23 +462,20 @@ protected:
* @returns A pointer to the Service TLV if one is found or nullptr if no matching Service TLV exists.
*
*/
static ServiceTlv *FindService(uint32_t aEnterpriseNumber,
const uint8_t * aServiceData,
uint8_t aServiceDataLength,
ServiceMatchMode aServiceMatchMode,
uint8_t * aTlvs,
uint8_t aTlvsLength)
static ServiceTlv *FindService(uint32_t aEnterpriseNumber,
const ServiceData &aServiceData,
ServiceMatchMode aServiceMatchMode,
uint8_t * aTlvs,
uint8_t aTlvsLength)
{
return AsNonConst(FindService(aEnterpriseNumber, aServiceData, aServiceDataLength, aServiceMatchMode,
AsConst(aTlvs), aTlvsLength));
return AsNonConst(FindService(aEnterpriseNumber, aServiceData, aServiceMatchMode, AsConst(aTlvs), aTlvsLength));
}
/**
* This method returns a pointer to a Service TLV in a specified tlvs buffer.
*
* @param[in] aEnterpriseNumber Enterprise Number.
* @param[in] aServiceData A pointer to a Service Data.
* @param[in] aServiceDataLength The Service Data length pointed to by @p aServiceData.
* @param[in] aServiceData A Service Data.
* @param[in] aServiceMatchMode The Service Data match mode.
* @param[in] aTlvs A pointer to a specified tlvs buffer.
* @param[in] aTlvsLength The specified tlvs buffer length pointed to by @p aTlvs.
@@ -492,12 +483,11 @@ protected:
* @returns A pointer to the Service TLV if one is found or nullptr if no matching Service TLV exists.
*
*/
static const ServiceTlv *FindService(uint32_t aEnterpriseNumber,
const uint8_t * aServiceData,
uint8_t aServiceDataLength,
ServiceMatchMode aServiceMatchMode,
const uint8_t * aTlvs,
uint8_t aTlvsLength);
static const ServiceTlv *FindService(uint32_t aEnterpriseNumber,
const ServiceData &aServiceData,
ServiceMatchMode aServiceMatchMode,
const uint8_t * aTlvs,
uint8_t aTlvsLength);
/**
* This method returns the next pointer to a matching Service TLV.
@@ -508,18 +498,34 @@ protected:
* Service TLV), or a pointer to the previous Service TLV returned from this method
* to iterate to the next matching Service TLV.
* @param[in] aEnterpriseNumber Enterprise Number.
* @param[in] aServiceData A pointer to a Service Data to match with Service TLVs.
* @param[in] aServiceDataLength The Service Data length pointed to by @p aServiceData.
* @param[in] aServiceData A Service Data to match with Service TLVs.
* @param[in] aServiceMatchMode The Service Data match mode.
*
* @returns A pointer to the next matching Service TLV if one is found or nullptr if it cannot be found.
*
*/
const ServiceTlv *FindNextService(const ServiceTlv *aPrevServiceTlv,
uint32_t aEnterpriseNumber,
const uint8_t * aServiceData,
uint8_t aServiceDataLength,
ServiceMatchMode aServiceMatchMode) const;
const ServiceTlv *FindNextService(const ServiceTlv * aPrevServiceTlv,
uint32_t aEnterpriseNumber,
const ServiceData &aServiceData,
ServiceMatchMode aServiceMatchMode) const;
/**
* This method returns the next pointer to a matching Thread Service TLV (with Thread Enterprise number).
*
* This method can be used to iterate over all Thread Service TLVs that start with a given Service Data.
*
* @param[in] aPrevServiceTlv Set to nullptr to start from the beginning of the TLVs (finding the first matching
* Service TLV), or a pointer to the previous Service TLV returned from this method
* to iterate to the next matching Service TLV.
* @param[in] aServiceData A Service Data to match with Service TLVs.
* @param[in] aServiceMatchMode The Service Data match mode.
*
* @returns A pointer to the next matching Thread Service TLV if one is found or nullptr if it cannot be found.
*
*/
const ServiceTlv *FindNextThreadService(const ServiceTlv * aPrevServiceTlv,
const ServiceData &aServiceData,
ServiceMatchMode aServiceMatchMode) const;
/**
* This method indicates whether there is space in Network Data to insert/append new info and grow it by a given
@@ -682,11 +688,10 @@ private:
static void Remove(uint8_t *aData, uint8_t &aDataLength, uint8_t *aRemoveStart, uint8_t aRemoveLength);
static void RemoveTlv(uint8_t *aData, uint8_t &aDataLength, NetworkDataTlv *aTlv);
static bool MatchService(const ServiceTlv &aServiceTlv,
uint32_t aEnterpriseNumber,
const uint8_t * aServiceData,
uint8_t aServiceDataLength,
ServiceMatchMode aServiceMatchMode);
static bool MatchService(const ServiceTlv & aServiceTlv,
uint32_t aEnterpriseNumber,
const ServiceData &aServiceData,
ServiceMatchMode aServiceMatchMode);
};
} // namespace NetworkData
+8 -8
View File
@@ -61,21 +61,21 @@ void LeaderBase::Reset(void)
Get<ot::Notifier>().Signal(kEventThreadNetdataChanged);
}
Error LeaderBase::GetServiceId(uint32_t aEnterpriseNumber,
const uint8_t *aServiceData,
uint8_t aServiceDataLength,
bool aServerStable,
uint8_t & aServiceId) const
Error LeaderBase::GetServiceId(uint32_t aEnterpriseNumber,
const ServiceData &aServiceData,
bool aServerStable,
uint8_t & aServiceId) const
{
Error error = kErrorNotFound;
Iterator iterator = kIteratorInit;
ServiceConfig serviceConfig;
ServiceData serviceData;
while (GetNextService(iterator, serviceConfig) == kErrorNone)
{
if (aEnterpriseNumber == serviceConfig.mEnterpriseNumber &&
aServiceDataLength == serviceConfig.mServiceDataLength &&
memcmp(aServiceData, serviceConfig.mServiceData, aServiceDataLength) == 0 &&
serviceConfig.GetServiceData(serviceData);
if (aEnterpriseNumber == serviceConfig.mEnterpriseNumber && aServiceData == serviceData &&
aServerStable == serviceConfig.mServerConfig.mStable)
{
aServiceId = serviceConfig.mServiceId;
+6 -8
View File
@@ -260,20 +260,18 @@ public:
* This method gets the Service ID for the specified service.
*
* @param[in] aEnterpriseNumber Enterprise Number (IANA-assigned) for Service TLV
* @param[in] aServiceData A pointer to the Service Data
* @param[in] aServiceDataLength The length of @p aServiceData in bytes.
* @param[in] aServerStable The Stable flag value for Server TLV
* @param[in] aServiceData The Service Data.
* @param[in] aServerStable The Stable flag value for Server TLV.
* @param[out] aServiceId A reference where to put the Service ID.
*
* @retval kErrorNone Successfully got the Service ID.
* @retval kErrorNotFound The specified service was not found.
*
*/
Error GetServiceId(uint32_t aEnterpriseNumber,
const uint8_t *aServiceData,
uint8_t aServiceDataLength,
bool aServerStable,
uint8_t & aServiceId) const;
Error GetServiceId(uint32_t aEnterpriseNumber,
const ServiceData &aServiceData,
bool aServerStable,
uint8_t & aServiceId) const;
protected:
uint8_t mStableVersion;
+24 -12
View File
@@ -427,13 +427,16 @@ Error Leader::Validate(const uint8_t *aTlvs, uint8_t aTlvsLength, uint16_t aRloc
case NetworkDataTlv::kTypeService:
{
const ServiceTlv *service = static_cast<const ServiceTlv *>(cur);
ServiceData serviceData;
VerifyOrExit(service->IsValid(), error = kErrorParse);
service->GetServiceData(serviceData);
// Ensure there is no duplicate Service TLV with same
// Enterprise Number and Service Data.
VerifyOrExit(FindService(service->GetEnterpriseNumber(), service->GetServiceData(),
service->GetServiceDataLength(), kServiceExactMatch, aTlvs, offset) == nullptr,
VerifyOrExit(FindService(service->GetEnterpriseNumber(), serviceData, kServiceExactMatch, aTlvs, offset) ==
nullptr,
error = kErrorParse);
SuccessOrExit(error = ValidateService(*service, aRloc16));
@@ -786,11 +789,14 @@ exit:
Error Leader::AddService(const ServiceTlv &aService, ChangedFlags &aChangedFlags)
{
Error error = kErrorNone;
ServiceTlv * dstService = FindService(aService.GetEnterpriseNumber(), aService.GetServiceData(),
aService.GetServiceDataLength(), kServiceExactMatch);
Error error = kErrorNone;
ServiceTlv * dstService;
ServiceData serviceData;
const ServerTlv *server;
aService.GetServiceData(serviceData);
dstService = FindService(aService.GetEnterpriseNumber(), serviceData, kServiceExactMatch);
if (dstService == nullptr)
{
uint8_t serviceId;
@@ -798,11 +804,10 @@ Error Leader::AddService(const ServiceTlv &aService, ChangedFlags &aChangedFlags
SuccessOrExit(error = AllocateServiceId(serviceId));
dstService = static_cast<ServiceTlv *>(
AppendTlv(ServiceTlv::CalculateSize(aService.GetEnterpriseNumber(), aService.GetServiceDataLength())));
AppendTlv(ServiceTlv::CalculateSize(aService.GetEnterpriseNumber(), serviceData.GetLength())));
VerifyOrExit(dstService != nullptr, error = kErrorNoBufs);
dstService->Init(serviceId, aService.GetEnterpriseNumber(), aService.GetServiceData(),
aService.GetServiceDataLength());
dstService->Init(serviceId, aService.GetEnterpriseNumber(), serviceData);
}
server = NetworkDataTlv::Find<ServerTlv>(aService.GetSubTlvs(), aService.GetNext());
@@ -934,15 +939,18 @@ Error Leader::AddServer(const ServerTlv &aServer, ServiceTlv &aDstService, Chang
{
Error error = kErrorNone;
ServerTlv *dstServer;
ServerData serverData;
uint8_t tlvSize = aServer.GetSize();
VerifyOrExit(!ContainsMatchingServer(&aDstService, aServer));
VerifyOrExit(CanInsert(tlvSize), error = kErrorNoBufs);
aServer.GetServerData(serverData);
dstServer = static_cast<ServerTlv *>(aDstService.GetNext());
Insert(dstServer, tlvSize);
dstServer->Init(aServer.GetServer16(), aServer.GetServerData(), aServer.GetServerDataLength());
dstServer->Init(aServer.GetServer16(), serverData);
if (aServer.IsStable())
{
@@ -1078,9 +1086,13 @@ void Leader::RemoveRloc(uint16_t aRloc16,
case NetworkDataTlv::kTypeService:
{
ServiceTlv * service = static_cast<ServiceTlv *>(cur);
const ServiceTlv *excludeService =
FindService(service->GetEnterpriseNumber(), service->GetServiceData(), service->GetServiceDataLength(),
kServiceExactMatch, aExcludeTlvs, aExcludeTlvsLength);
ServiceData serviceData;
const ServiceTlv *excludeService;
service->GetServiceData(serviceData);
excludeService = FindService(service->GetEnterpriseNumber(), serviceData, kServiceExactMatch, aExcludeTlvs,
aExcludeTlvsLength);
RemoveRlocInService(*service, aRloc16, aMatchMode, excludeService, aChangedFlags);
+12 -16
View File
@@ -183,32 +183,29 @@ bool Local::IsExternalRouteConsistent(void) const
#endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
Error Local::AddService(uint32_t aEnterpriseNumber,
const uint8_t *aServiceData,
uint8_t aServiceDataLength,
bool aServerStable,
const uint8_t *aServerData,
uint8_t aServerDataLength)
Error Local::AddService(uint32_t aEnterpriseNumber,
const ServiceData &aServiceData,
bool aServerStable,
const ServerData & aServerData)
{
Error error = kErrorNone;
ServiceTlv *serviceTlv;
ServerTlv * serverTlv;
uint16_t serviceTlvSize =
ServiceTlv::CalculateSize(aEnterpriseNumber, aServiceDataLength) + sizeof(ServerTlv) + aServerDataLength;
uint16_t serviceTlvSize = ServiceTlv::CalculateSize(aEnterpriseNumber, aServiceData.GetLength()) +
sizeof(ServerTlv) + aServerData.GetLength();
IgnoreError(RemoveService(aEnterpriseNumber, aServiceData, aServiceDataLength));
IgnoreError(RemoveService(aEnterpriseNumber, aServiceData));
VerifyOrExit(serviceTlvSize <= kMaxSize, error = kErrorNoBufs);
serviceTlv = static_cast<ServiceTlv *>(AppendTlv(serviceTlvSize));
VerifyOrExit(serviceTlv != nullptr, error = kErrorNoBufs);
serviceTlv->Init(/* aServiceId */ 0, aEnterpriseNumber, aServiceData, aServiceDataLength);
serviceTlv->SetSubTlvsLength(sizeof(ServerTlv) + aServerDataLength);
serviceTlv->Init(/* aServiceId */ 0, aEnterpriseNumber, aServiceData);
serviceTlv->SetSubTlvsLength(sizeof(ServerTlv) + aServerData.GetLength());
serverTlv = static_cast<ServerTlv *>(serviceTlv->GetSubTlvs());
serverTlv->Init(Get<Mle::MleRouter>().GetRloc16(), aServerData, aServerDataLength);
serverTlv->Init(Get<Mle::MleRouter>().GetRloc16(), aServerData);
// According to Thread spec 1.1.1, section 5.18.6 Service TLV:
// "The Stable flag is set if any of the included sub-TLVs have their Stable flag set."
@@ -225,13 +222,12 @@ exit:
return error;
}
Error Local::RemoveService(uint32_t aEnterpriseNumber, const uint8_t *aServiceData, uint8_t aServiceDataLength)
Error Local::RemoveService(uint32_t aEnterpriseNumber, const ServiceData &aServiceData)
{
Error error = kErrorNone;
ServiceTlv *tlv;
VerifyOrExit((tlv = FindService(aEnterpriseNumber, aServiceData, aServiceDataLength, kServiceExactMatch)) !=
nullptr,
VerifyOrExit((tlv = FindService(aEnterpriseNumber, aServiceData, kServiceExactMatch)) != nullptr,
error = kErrorNotFound);
RemoveTlv(tlv);
+10 -15
View File
@@ -125,36 +125,31 @@ public:
/**
* This method adds a Service entry to the Thread Network local data.
*
* @param[in] aEnterpriseNumber Enterprise Number (IANA-assigned) for Service TLV
* @param[in] aServiceData A pointer to the Service Data
* @param[in] aServiceDataLength The length of @p aServiceData in bytes.
* @param[in] aServerStable The Stable flag value for Server TLV
* @param[in] aServerData A pointer to the Server Data
* @param[in] aServerDataLength The length of @p aServerData in bytes.
* @param[in] aEnterpriseNumber Enterprise Number (IANA-assigned) for Service TLV.
* @param[in] aServiceData The Service Data.
* @param[in] aServerStable The Stable flag value for Server TLV.
* @param[in] aServerData The Server Data.
*
* @retval kErrorNone Successfully added the Service entry.
* @retval kErrorNoBufs Insufficient space to add the Service entry.
*
*/
Error AddService(uint32_t aEnterpriseNumber,
const uint8_t *aServiceData,
uint8_t aServiceDataLength,
bool aServerStable,
const uint8_t *aServerData,
uint8_t aServerDataLength);
Error AddService(uint32_t aEnterpriseNumber,
const ServiceData &aServiceData,
bool aServerStable,
const ServerData & aServerData);
/**
* This method removes a Service entry from the Thread Network local data.
*
* @param[in] aEnterpriseNumber Enterprise Number of the service to be deleted.
* @param[in] aServiceData A pointer to the service data.
* @param[in] aServiceDataLength The length of @p aServiceData in bytes.
* @param[in] aServiceData The service data.
*
* @retval kErrorNone Successfully removed the Service entry.
* @retval kErrorNotFound Could not find the Service entry.
*
*/
Error RemoveService(uint32_t aEnterpriseNumber, const uint8_t *aServiceData, uint8_t aServiceDataLength);
Error RemoveService(uint32_t aEnterpriseNumber, const ServiceData &aServiceData);
#endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
/**
+10 -6
View File
@@ -731,10 +731,12 @@ void Publisher::DnsSrpServiceEntry::CountAnycastEntries(uint8_t &aNumEntries, ui
Service::DnsSrpAnycast::ServiceData serviceData(mInfo.GetSequenceNumber());
const ServiceTlv * serviceTlv = nullptr;
ServiceData data;
while ((serviceTlv = Get<Leader>().FindNextService(
serviceTlv, Service::kThreadEnterpriseNumber, reinterpret_cast<const uint8_t *>(&serviceData),
serviceData.GetLength(), NetworkData::kServicePrefixMatch)) != nullptr)
data.Init(&serviceData, serviceData.GetLength());
while ((serviceTlv = Get<Leader>().FindNextThreadService(serviceTlv, data, NetworkData::kServicePrefixMatch)) !=
nullptr)
{
TlvIterator subTlvIterator(*serviceTlv);
const ServerTlv *serverSubTlv;
@@ -757,10 +759,12 @@ void Publisher::DnsSrpServiceEntry::CountUnicastEntries(uint8_t &aNumEntries, ui
// the Network Data.
const ServiceTlv *serviceTlv = nullptr;
ServiceData data;
while ((serviceTlv = Get<Leader>().FindNextService(
serviceTlv, Service::kThreadEnterpriseNumber, &Service::DnsSrpUnicast::kServiceData,
sizeof(Service::DnsSrpUnicast::kServiceData), NetworkData::kServicePrefixMatch)) != nullptr)
data.InitFrom(Service::DnsSrpUnicast::kServiceData);
while ((serviceTlv = Get<Leader>().FindNextThreadService(serviceTlv, data, NetworkData::kServicePrefixMatch)) !=
nullptr)
{
TlvIterator subTlvIterator(*serviceTlv);
const ServerTlv *serverSubTlv;
+54 -29
View File
@@ -49,6 +49,7 @@ namespace Service {
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
const uint8_t BackboneRouter::kServiceData;
#endif
const uint8_t DnsSrpAnycast::kServiceData;
const uint8_t DnsSrpUnicast::kServiceData;
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
@@ -59,15 +60,22 @@ Error Manager::AddService(const void *aServiceData,
const void *aServerData,
uint8_t aServerDataLength)
{
return Get<Local>().AddService(kThreadEnterpriseNumber, reinterpret_cast<const uint8_t *>(aServiceData),
aServiceDataLength, aServerStable, reinterpret_cast<const uint8_t *>(aServerData),
aServerDataLength);
ServiceData serviceData;
ServerData serverData;
serviceData.Init(aServiceData, aServiceDataLength);
serverData.Init(aServerData, aServerDataLength);
return Get<Local>().AddService(kThreadEnterpriseNumber, serviceData, aServerStable, serverData);
}
Error Manager::RemoveService(const void *aServiceData, uint8_t aServiceDataLength)
{
return Get<Local>().RemoveService(kThreadEnterpriseNumber, reinterpret_cast<const uint8_t *>(aServiceData),
aServiceDataLength);
ServiceData serviceData;
serviceData.Init(aServiceData, aServiceDataLength);
return Get<Local>().RemoveService(kThreadEnterpriseNumber, serviceData);
}
#endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
@@ -77,8 +85,11 @@ Error Manager::GetServiceId(const void *aServiceData,
bool aServerStable,
uint8_t & aServiceId) const
{
return Get<Leader>().GetServiceId(kThreadEnterpriseNumber, reinterpret_cast<const uint8_t *>(aServiceData),
aServiceDataLength, aServerStable, aServiceId);
ServiceData serviceData;
serviceData.Init(aServiceData, aServiceDataLength);
return Get<Leader>().GetServiceId(kThreadEnterpriseNumber, serviceData, aServerStable, aServiceId);
}
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
@@ -88,12 +99,14 @@ void Manager::GetBackboneRouterPrimary(ot::BackboneRouter::BackboneRouterConfig
const ServerTlv * rvalServerTlv = nullptr;
const BackboneRouter::ServerData *rvalServerData = nullptr;
const ServiceTlv * serviceTlv = nullptr;
ServiceData serviceData;
serviceData.Init(&BackboneRouter::kServiceData, BackboneRouter::kServiceDataMinSize);
aConfig.mServer16 = Mac::kShortAddrInvalid;
while ((serviceTlv = Get<Leader>().FindNextService(
serviceTlv, kThreadEnterpriseNumber, &BackboneRouter::kServiceData, BackboneRouter::kServiceDataMinSize,
NetworkData::kServicePrefixMatch)) != nullptr)
while ((serviceTlv = Get<Leader>().FindNextThreadService(serviceTlv, serviceData,
NetworkData::kServicePrefixMatch)) != nullptr)
{
Iterator iterator;
@@ -101,14 +114,17 @@ void Manager::GetBackboneRouterPrimary(ot::BackboneRouter::BackboneRouterConfig
while (IterateToNextServer(iterator) == kErrorNone)
{
ServerData data;
const BackboneRouter::ServerData *serverData;
if (iterator.mServerSubTlv->GetServerDataLength() < sizeof(BackboneRouter::ServerData))
iterator.mServerSubTlv->GetServerData(data);
if (data.GetLength() < sizeof(BackboneRouter::ServerData))
{
continue;
}
serverData = reinterpret_cast<const BackboneRouter::ServerData *>(iterator.mServerSubTlv->GetServerData());
serverData = reinterpret_cast<const BackboneRouter::ServerData *>(data.GetBytes());
if (rvalServerTlv == nullptr ||
IsBackboneRouterPreferredTo(*iterator.mServerSubTlv, *serverData, *rvalServerTlv, *rvalServerData))
@@ -152,22 +168,24 @@ exit:
Error Manager::GetNextDnsSrpAnycastInfo(Iterator &aIterator, DnsSrpAnycast::Info &aInfo) const
{
Error error = kErrorNone;
uint8_t serviceData = DnsSrpAnycast::kServiceNumber;
const ServiceTlv *tlv = aIterator.mServiceTlv;
Error error = kErrorNone;
ServiceData serviceData;
const ServiceTlv *tlv = aIterator.mServiceTlv;
serviceData.InitFrom(DnsSrpAnycast::kServiceData);
do
{
tlv = Get<Leader>().FindNextService(tlv, kThreadEnterpriseNumber, &serviceData, sizeof(serviceData),
NetworkData::kServicePrefixMatch);
tlv = Get<Leader>().FindNextThreadService(tlv, serviceData, NetworkData::kServicePrefixMatch);
VerifyOrExit(tlv != nullptr, error = kErrorNotFound);
} while (tlv->GetServiceDataLength() < sizeof(DnsSrpAnycast::ServiceData));
tlv->GetServiceData(serviceData);
aInfo.mAnycastAddress.SetToAnycastLocator(Get<Mle::Mle>().GetMeshLocalPrefix(),
Mle::Mle::ServiceAlocFromId(tlv->GetServiceId()));
aInfo.mSequenceNumber =
reinterpret_cast<const DnsSrpAnycast::ServiceData *>(tlv->GetServiceData())->GetSequenceNumber();
reinterpret_cast<const DnsSrpAnycast::ServiceData *>(serviceData.GetBytes())->GetSequenceNumber();
aIterator.mServiceTlv = tlv;
@@ -195,7 +213,10 @@ Error Manager::FindPreferredDnsSrpAnycastInfo(DnsSrpAnycast::Info &aInfo) const
Error Manager::GetNextDnsSrpUnicastInfo(Iterator &aIterator, DnsSrpUnicast::Info &aInfo) const
{
Error error = kErrorNone;
Error error = kErrorNone;
ServiceData serviceData;
serviceData.InitFrom(DnsSrpUnicast::kServiceData);
while (true)
{
@@ -203,28 +224,32 @@ Error Manager::GetNextDnsSrpUnicastInfo(Iterator &aIterator, DnsSrpUnicast::Info
while (IterateToNextServer(aIterator) == kErrorNone)
{
ServerData data;
// Server sub-TLV can contain address and port info
// (then we parse and return the info), or it can be
// empty (then we skip over it).
if (aIterator.mServerSubTlv->GetServerDataLength() >= sizeof(DnsSrpUnicast::ServerData))
aIterator.mServerSubTlv->GetServerData(data);
if (data.GetLength() >= sizeof(DnsSrpUnicast::ServerData))
{
const DnsSrpUnicast::ServerData *serverData =
reinterpret_cast<const DnsSrpUnicast::ServerData *>(aIterator.mServerSubTlv->GetServerData());
reinterpret_cast<const DnsSrpUnicast::ServerData *>(data.GetBytes());
aInfo.mSockAddr.SetAddress(serverData->GetAddress());
aInfo.mSockAddr.SetPort(serverData->GetPort());
ExitNow();
}
if (aIterator.mServerSubTlv->GetServerDataLength() == sizeof(uint16_t))
if (data.GetLength() == sizeof(uint16_t))
{
// Handle the case where the server TLV data only
// contains a port number and use the RLOC as the
// IPv6 address.
aInfo.mSockAddr.GetAddress().SetToRoutingLocator(Get<Mle::Mle>().GetMeshLocalPrefix(),
aIterator.mServerSubTlv->GetServer16());
aInfo.mSockAddr.SetPort(Encoding::BigEndian::ReadUint16(aIterator.mServerSubTlv->GetServerData()));
aInfo.mSockAddr.SetPort(Encoding::BigEndian::ReadUint16(data.GetBytes()));
ExitNow();
}
}
@@ -232,8 +257,7 @@ Error Manager::GetNextDnsSrpUnicastInfo(Iterator &aIterator, DnsSrpUnicast::Info
// Find the next matching Service TLV.
aIterator.mServiceTlv =
Get<Leader>().FindNextService(aIterator.mServiceTlv, kThreadEnterpriseNumber, &DnsSrpUnicast::kServiceData,
sizeof(DnsSrpUnicast::kServiceData), NetworkData::kServicePrefixMatch);
Get<Leader>().FindNextThreadService(aIterator.mServiceTlv, serviceData, NetworkData::kServicePrefixMatch);
VerifyOrExit(aIterator.mServiceTlv != nullptr, error = kErrorNotFound);
@@ -241,11 +265,12 @@ Error Manager::GetNextDnsSrpUnicastInfo(Iterator &aIterator, DnsSrpUnicast::Info
{
// The Service TLV data contains the address and port info.
const DnsSrpUnicast::ServiceData *serviceData;
const DnsSrpUnicast::ServiceData *dnsServiceData;
serviceData = reinterpret_cast<const DnsSrpUnicast::ServiceData *>(aIterator.mServiceTlv->GetServiceData());
aInfo.mSockAddr.SetAddress(serviceData->GetAddress());
aInfo.mSockAddr.SetPort(serviceData->GetPort());
aIterator.mServiceTlv->GetServiceData(serviceData);
dnsServiceData = reinterpret_cast<const DnsSrpUnicast::ServiceData *>(serviceData.GetBytes());
aInfo.mSockAddr.SetAddress(dnsServiceData->GetAddress());
aInfo.mSockAddr.SetPort(dnsServiceData->GetPort());
ExitNow();
}
+8
View File
@@ -159,6 +159,14 @@ class DnsSrpAnycast
public:
static constexpr uint8_t kServiceNumber = 0x5c; ///< The service number of a `DnsSrpAnycast` entry.
/**
* This constant variable represents the short version of service data.
*
* The short version of service data contains only service number as a single byte.
*
*/
static const uint8_t kServiceData = kServiceNumber;
/**
* This structure represents information about an DNS/SRP server parsed from related Network Data service entries.
*
+26
View File
@@ -91,6 +91,32 @@ const NetworkDataTlv *PrefixTlv::FindSubTlv(Type aType, bool aStable) const
return Find(GetSubTlvs(), GetNext(), aType, aStable);
}
//---------------------------------------------------------------------------------------------------------------------
// ServiceTlv
void ServiceTlv::Init(uint8_t aServiceId, uint32_t aEnterpriseNumber, const ServiceData &aServiceData)
{
NetworkDataTlv::Init();
SetType(kTypeService);
mFlagsServiceId = (aEnterpriseNumber == kThreadEnterpriseNumber) ? kThreadEnterpriseFlag : 0;
mFlagsServiceId |= (aServiceId & kServiceIdMask);
if (aEnterpriseNumber != kThreadEnterpriseNumber)
{
mShared.mEnterpriseNumber = HostSwap32(aEnterpriseNumber);
mServiceDataLength = aServiceData.GetLength();
aServiceData.CopyBytesTo(&mServiceDataLength + sizeof(uint8_t));
}
else
{
mShared.mServiceDataLengthThreadEnterprise = aServiceData.GetLength();
aServiceData.CopyBytesTo(&mShared.mServiceDataLengthThreadEnterprise + sizeof(uint8_t));
}
SetLength(GetFieldsLength());
}
//---------------------------------------------------------------------------------------------------------------------
// TlvIterator
+27 -54
View File
@@ -1251,31 +1251,9 @@ public:
* @param[in] aServiceId The Service Id value.
* @param[in] aEnterpriseNumber The Enterprise Number.
* @param[in] aServiceData The Service Data.
* @param[in] aServiceDataLength The Service Data length (number of bytes).
*
*/
void Init(uint8_t aServiceId, uint32_t aEnterpriseNumber, const uint8_t *aServiceData, uint8_t aServiceDataLength)
{
NetworkDataTlv::Init();
SetType(kTypeService);
mFlagsServiceId = (aEnterpriseNumber == kThreadEnterpriseNumber) ? kThreadEnterpriseFlag : 0;
mFlagsServiceId |= (aServiceId & kServiceIdMask);
if (aEnterpriseNumber != kThreadEnterpriseNumber)
{
mShared.mEnterpriseNumber = HostSwap32(aEnterpriseNumber);
mServiceDataLength = aServiceDataLength;
memcpy(&mServiceDataLength + sizeof(uint8_t), aServiceData, aServiceDataLength);
}
else
{
mShared.mServiceDataLengthThreadEnterprise = aServiceDataLength;
memcpy(&mShared.mServiceDataLengthThreadEnterprise + sizeof(uint8_t), aServiceData, aServiceDataLength);
}
SetLength(GetFieldsLength());
}
void Init(uint8_t aServiceId, uint32_t aEnterpriseNumber, const ServiceData &aServiceData);
/**
* This method indicates whether or not the TLV appears to be well-formed.
@@ -1314,6 +1292,17 @@ public:
: HostSwap32(mShared.mEnterpriseNumber);
}
/**
* This method gets the Service Data.
*
* @param[out] aServiceData A reference to a`ServiceData` to return the data.
*
*/
void GetServiceData(ServiceData &aServiceData) const
{
aServiceData.Init(GetServiceData(), GetServiceDataLength());
}
/**
* This method gets Service Data length.
*
@@ -1325,30 +1314,6 @@ public:
return IsThreadEnterprise() ? mShared.mServiceDataLengthThreadEnterprise : mServiceDataLength;
}
/**
* This method returns a pointer to the Service Data.
*
* @returns A pointer to the Service Data.
*
*/
uint8_t *GetServiceData(void)
{
return (IsThreadEnterprise() ? &mShared.mServiceDataLengthThreadEnterprise : &mServiceDataLength) +
sizeof(uint8_t);
}
/**
* This method returns a pointer to the Service Data.
*
* @returns A pointer to the Service Data.
*
*/
const uint8_t *GetServiceData(void) const
{
return (IsThreadEnterprise() ? &mShared.mServiceDataLengthThreadEnterprise : &mServiceDataLength) +
sizeof(uint8_t);
}
/**
* This method returns the Sub-TLVs length in bytes.
*
@@ -1406,6 +1371,12 @@ public:
private:
bool IsThreadEnterprise(void) const { return (mFlagsServiceId & kThreadEnterpriseFlag) != 0; }
const uint8_t *GetServiceData(void) const
{
return (IsThreadEnterprise() ? &mShared.mServiceDataLengthThreadEnterprise : &mServiceDataLength) +
sizeof(uint8_t);
}
uint8_t GetFieldsLength(void) const
{
// Returns the length of TLV value's common fields (flags, enterprise
@@ -1448,16 +1419,15 @@ public:
*
* @param[in] aServer16 The Server16 value.
* @param[in] aServerData The Server Data.
* @param[in] aServerDataLength Server Data length in bytes.
*
*/
void Init(uint16_t aServer16, const uint8_t *aServerData, uint8_t aServerDataLength)
void Init(uint16_t aServer16, const ServerData &aServerData)
{
NetworkDataTlv::Init();
SetType(kTypeServer);
SetServer16(aServer16);
memcpy(reinterpret_cast<uint8_t *>(this) + sizeof(*this), aServerData, aServerDataLength);
SetLength(sizeof(*this) - sizeof(NetworkDataTlv) + aServerDataLength);
aServerData.CopyBytesTo(GetServerData());
SetLength(sizeof(*this) - sizeof(NetworkDataTlv) + aServerData.GetLength());
}
/**
@@ -1486,12 +1456,12 @@ public:
void SetServer16(uint16_t aServer16) { mServer16 = HostSwap16(aServer16); }
/**
* This method returns the Server Data.
* This method gets the Server Data.
*
* @returns A pointer to the Server Data.
* @param[out] aServerData A reference to a`ServerData` to return the data.
*
*/
const uint8_t *GetServerData(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(*this); }
void GetServerData(ServerData &aServerData) const { aServerData.Init(GetServerData(), GetServerDataLength()); }
/**
* This method returns the Server Data length in bytes.
@@ -1528,6 +1498,9 @@ public:
static uint16_t CalculateSize(uint8_t aServerDataLength) { return sizeof(ServerTlv) + aServerDataLength; }
private:
const uint8_t *GetServerData(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(*this); }
uint8_t * GetServerData(void) { return AsNonConst(AsConst(this)->GetServerData()); }
uint16_t mServer16;
} OT_TOOL_PACKED_END;
+10 -4
View File
@@ -219,10 +219,13 @@ bool ServiceConfig::ServerConfig::operator==(const ServerConfig &aOther) const
void ServiceConfig::ServerConfig::SetFrom(const ServerTlv &aServerTlv)
{
ServerData serverData;
aServerTlv.GetServerData(serverData);
mStable = aServerTlv.IsStable();
mRloc16 = aServerTlv.GetServer16();
mServerDataLength = aServerTlv.GetServerDataLength();
memcpy(&mServerData, aServerTlv.GetServerData(), mServerDataLength);
mServerDataLength = serverData.GetLength();
serverData.CopyBytesTo(mServerData);
}
bool ServiceConfig::operator==(const ServiceConfig &aOther) const
@@ -234,12 +237,15 @@ bool ServiceConfig::operator==(const ServiceConfig &aOther) const
void ServiceConfig::SetFrom(const ServiceTlv &aServiceTlv, const ServerTlv &aServerTlv)
{
ServiceData serviceData;
Clear();
aServiceTlv.GetServiceData(serviceData);
mServiceId = aServiceTlv.GetServiceId();
mEnterpriseNumber = aServiceTlv.GetEnterpriseNumber();
mServiceDataLength = aServiceTlv.GetServiceDataLength();
memcpy(&mServiceData, aServiceTlv.GetServiceData(), mServiceDataLength);
mServiceDataLength = serviceData.GetLength();
serviceData.CopyBytesTo(mServiceData);
GetServerConfig().SetFrom(aServerTlv);
}
+33
View File
@@ -39,6 +39,7 @@
#include <openthread/netdata.h>
#include "common/clearable.hpp"
#include "common/data.hpp"
#include "common/debug.hpp"
#include "common/equatable.hpp"
#include "net/ip6_address.hpp"
@@ -249,6 +250,22 @@ private:
void SetFromTlvFlags(uint8_t aFlags);
};
/**
* This class represents a Service Data.
*
*/
class ServiceData : public Data<kWithUint8Length>
{
};
/**
* This class represents a Server Data.
*
*/
class ServerData : public Data<kWithUint8Length>
{
};
/**
* This type represents a Service configuration.
*
@@ -267,6 +284,14 @@ public:
friend class ServiceConfig;
public:
/**
* This method gets the Server Data.
*
* @param[out] aServerData A reference to a`ServerData` to return the data.
*
*/
void GetServerData(ServerData &aServerData) const { aServerData.Init(mServerData, mServerDataLength); }
/**
* This method overloads operator `==` to evaluate whether or not two `ServerConfig` instances are equal.
*
@@ -282,6 +307,14 @@ public:
void SetFrom(const ServerTlv &aServerTlv);
};
/**
* This method gets the Service Data.
*
* @param[out] aServiceData A reference to a `ServiceData` to return the data.
*
*/
void GetServiceData(ServiceData &aServiceData) const { aServiceData.Init(mServiceData, mServiceDataLength); }
/**
* This method gets the Server configuration.
*
+48 -43
View File
@@ -229,20 +229,24 @@ public:
{
}
template <uint8_t kSize> Error AddService(const uint8_t (&aServiceData)[kSize])
Error AddService(const ServiceData &aServiceData)
{
return Local::AddService(ServiceTlv::kThreadEnterpriseNumber, aServiceData, kSize, true, nullptr, 0);
return Local::AddService(ServiceTlv::kThreadEnterpriseNumber, aServiceData, true, ServerData());
}
template <uint8_t kSize>
Error ValidateServiceData(const ServiceTlv *aServiceTlv, const uint8_t (&aServiceData)[kSize]) const
Error ValidateServiceData(const ServiceTlv *aServiceTlv, const ServiceData &aServiceData) const
{
return
Error error = kErrorFailed;
ServiceData serviceData;
((aServiceTlv != nullptr) && (aServiceTlv->GetServiceDataLength() == kSize) &&
(memcmp(aServiceTlv->GetServiceData(), aServiceData, kSize) == 0))
? kErrorNone
: kErrorFailed;
VerifyOrExit(aServiceTlv != nullptr);
aServiceTlv->GetServiceData(serviceData);
VerifyOrExit(aServiceData == serviceData);
error = kErrorNone;
exit:
return error;
}
void Test(void)
@@ -254,52 +258,53 @@ public:
const uint8_t kServiceData5[] = {0x02, 0xab, 0xcd};
const ServiceTlv *tlv;
ServiceData serviceData1;
ServiceData serviceData2;
ServiceData serviceData3;
ServiceData serviceData4;
ServiceData serviceData5;
SuccessOrQuit(AddService(kServiceData1));
SuccessOrQuit(AddService(kServiceData2));
SuccessOrQuit(AddService(kServiceData3));
SuccessOrQuit(AddService(kServiceData4));
SuccessOrQuit(AddService(kServiceData5));
serviceData1.InitFrom(kServiceData1);
serviceData2.InitFrom(kServiceData2);
serviceData3.InitFrom(kServiceData3);
serviceData4.InitFrom(kServiceData4);
serviceData5.InitFrom(kServiceData5);
SuccessOrQuit(AddService(serviceData1));
SuccessOrQuit(AddService(serviceData2));
SuccessOrQuit(AddService(serviceData3));
SuccessOrQuit(AddService(serviceData4));
SuccessOrQuit(AddService(serviceData5));
DumpBuffer("netdata", mTlvs, mLength);
// Iterate through all entries that start with { 0x02 } (kServiceData1)
tlv = nullptr;
tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, kServiceData1, sizeof(kServiceData1),
kServicePrefixMatch);
SuccessOrQuit(ValidateServiceData(tlv, kServiceData1));
tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, kServiceData1, sizeof(kServiceData1),
kServicePrefixMatch);
SuccessOrQuit(ValidateServiceData(tlv, kServiceData4));
tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, kServiceData1, sizeof(kServiceData1),
kServicePrefixMatch);
SuccessOrQuit(ValidateServiceData(tlv, kServiceData5));
tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, kServiceData1, sizeof(kServiceData1),
kServicePrefixMatch);
tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData1, kServicePrefixMatch);
SuccessOrQuit(ValidateServiceData(tlv, serviceData1));
tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData1, kServicePrefixMatch);
SuccessOrQuit(ValidateServiceData(tlv, serviceData4));
tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData1, kServicePrefixMatch);
SuccessOrQuit(ValidateServiceData(tlv, serviceData5));
tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData1, kServicePrefixMatch);
VerifyOrQuit(tlv == nullptr, "FindNextService() returned extra TLV");
// Iterate through all entries that start with { 0xab } (kServiceData2)
// Iterate through all entries that start with { 0xab } (serviceData2)
tlv = nullptr;
tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, kServiceData2, sizeof(kServiceData2),
kServicePrefixMatch);
SuccessOrQuit(ValidateServiceData(tlv, kServiceData2));
tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, kServiceData2, sizeof(kServiceData2),
kServicePrefixMatch);
SuccessOrQuit(ValidateServiceData(tlv, kServiceData3));
tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, kServiceData2, sizeof(kServiceData2),
kServicePrefixMatch);
tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData2, kServicePrefixMatch);
SuccessOrQuit(ValidateServiceData(tlv, serviceData2));
tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData2, kServicePrefixMatch);
SuccessOrQuit(ValidateServiceData(tlv, serviceData3));
tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData2, kServicePrefixMatch);
VerifyOrQuit(tlv == nullptr, "FindNextService() returned extra TLV");
// Iterate through all entries that start with kServiceData5
// Iterate through all entries that start with serviceData5
tlv = nullptr;
tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, kServiceData5, sizeof(kServiceData5),
kServicePrefixMatch);
SuccessOrQuit(ValidateServiceData(tlv, kServiceData4));
tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, kServiceData5, sizeof(kServiceData5),
kServicePrefixMatch);
SuccessOrQuit(ValidateServiceData(tlv, kServiceData5));
tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, kServiceData5, sizeof(kServiceData5),
kServicePrefixMatch);
tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData5, kServicePrefixMatch);
SuccessOrQuit(ValidateServiceData(tlv, serviceData4));
tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData5, kServicePrefixMatch);
SuccessOrQuit(ValidateServiceData(tlv, serviceData5));
tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData5, kServicePrefixMatch);
VerifyOrQuit(tlv == nullptr, "FindNextService() returned extra TLV");
}
};