mirror of
https://github.com/espressif/openthread.git
synced 2026-07-28 22:57:47 +00:00
[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:
committed by
Jonathan Hui
parent
ca35753a1e
commit
063d7a1514
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user