mirror of
https://github.com/espressif/openthread.git
synced 2026-08-09 20:27:47 +00:00
[network-data] enhance/simplify updating of network data on leader (#4817)
This commit changes the model for updating Network Data on a leader. It adds `ChangedFlags` type which is used to track whether full or stable version of Network Data gets changed as TLVs/sub-TLVs are being added or removed. This is then used to update version and stable version accordingly. When registering new received Network Data on the leader, the new model updates the Network Data in place. First, newly added `Validate()` method is called to verify that the received Network Data contains well-formed TLVs and sub-TLVs (e.g., no duplicate Prefix/Service TLVs) and all sub-TLVs/entries match the sender's RLOC16. Then, all entries in the current Network Data associated with the sender's RLOC16 which are not present in the newly received data are removed. Afterwards, any new entry in the received Network Data is added. This approach helps simplify the code and ensures existing TLVs/sub-TLVs remain as before (e.g., no need to keep a copy of previous data to ensure same Service IDs are used when adding/removing Service TLVs). This commit also adds `UpdatePrefix()` and `UpdateService()` methods which ensure a Prefix or Service TLV is marked correctly as stable or not depending on its sub-TLVs (e.g., if all stable sub-TLVs are removed the enclosing TLV is marked as not stable).
This commit is contained in:
committed by
Jonathan Hui
parent
bfef9c6a03
commit
4c7ec29e6d
@@ -240,7 +240,7 @@ enum AlocAllocation
|
||||
* Service IDs
|
||||
*
|
||||
*/
|
||||
enum ServiceId
|
||||
enum
|
||||
{
|
||||
kServiceMinId = 0x00, ///< Minimal Service ID.
|
||||
kServiceMaxId = 0x0f, ///< Maximal Service ID.
|
||||
|
||||
@@ -712,14 +712,14 @@ exit:
|
||||
return serviceTlv;
|
||||
}
|
||||
|
||||
NetworkDataTlv *NetworkData::AppendTlv(uint8_t aTlvSize)
|
||||
NetworkDataTlv *NetworkData::AppendTlv(uint16_t aTlvSize)
|
||||
{
|
||||
NetworkDataTlv *tlv;
|
||||
|
||||
VerifyOrExit(mLength + aTlvSize <= kMaxSize, tlv = NULL);
|
||||
VerifyOrExit(CanInsert(aTlvSize), tlv = NULL);
|
||||
|
||||
tlv = GetTlvsEnd();
|
||||
mLength += aTlvSize;
|
||||
mLength += static_cast<uint8_t>(aTlvSize);
|
||||
|
||||
exit:
|
||||
return tlv;
|
||||
@@ -729,7 +729,7 @@ void NetworkData::Insert(void *aStart, uint8_t aLength)
|
||||
{
|
||||
uint8_t *start = reinterpret_cast<uint8_t *>(aStart);
|
||||
|
||||
OT_ASSERT(aLength + mLength <= sizeof(mTlvs) && mTlvs <= start && start <= mTlvs + mLength);
|
||||
OT_ASSERT(CanInsert(aLength) && mTlvs <= start && start <= mTlvs + mLength);
|
||||
memmove(start + aLength, start, mLength - static_cast<size_t>(start - mTlvs));
|
||||
mLength += aLength;
|
||||
}
|
||||
|
||||
@@ -596,6 +596,18 @@ protected:
|
||||
const uint8_t *aTlvs,
|
||||
uint8_t aTlvsLength);
|
||||
|
||||
/**
|
||||
* This method indicates whether there is space in Network Data to insert/append new info and grow it by a given
|
||||
* number of bytes.
|
||||
*
|
||||
* @param[in] aSize The number of bytes to grow the Network Data.
|
||||
*
|
||||
* @retval TRUE There is space to grow Network Data by @p aSize bytes.
|
||||
* @retval FALSE There is no space left to grow Network Data by @p aSize bytes.
|
||||
*
|
||||
*/
|
||||
bool CanInsert(uint16_t aSize) const { return (mLength + aSize <= kMaxSize); }
|
||||
|
||||
/**
|
||||
* This method grows the Network Data to append a TLV with a requested size.
|
||||
*
|
||||
@@ -608,7 +620,7 @@ protected:
|
||||
* Data with requested @p aTlvSize number of bytes.
|
||||
*
|
||||
*/
|
||||
NetworkDataTlv *AppendTlv(uint8_t aTlvSize);
|
||||
NetworkDataTlv *AppendTlv(uint16_t aTlvSize);
|
||||
|
||||
/**
|
||||
* This method inserts bytes into the Network Data.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -171,51 +171,105 @@ public:
|
||||
otError RemoveStaleChildEntries(Coap::ResponseHandler aHandler, void *aContext);
|
||||
|
||||
private:
|
||||
class ChangedFlags
|
||||
{
|
||||
public:
|
||||
ChangedFlags(void)
|
||||
: mChanged(false)
|
||||
, mStableChanged(false)
|
||||
{
|
||||
}
|
||||
|
||||
void Update(const NetworkDataTlv &aTlv)
|
||||
{
|
||||
mChanged = true;
|
||||
mStableChanged = (mStableChanged || aTlv.IsStable());
|
||||
}
|
||||
|
||||
bool DidChange(void) const { return mChanged; }
|
||||
bool DidStableChange(void) const { return mStableChanged; }
|
||||
|
||||
private:
|
||||
bool mChanged; // Any (stable or not) network data change (add/remove).
|
||||
bool mStableChanged; // Stable network data change (add/remove).
|
||||
};
|
||||
|
||||
enum UpdateStatus
|
||||
{
|
||||
kTlvRemoved, // TLV contained no sub TLVs and therefore is removed.
|
||||
kTlvUpdated, // TLV stable flag is updated based on its sub TLVs.
|
||||
};
|
||||
|
||||
static void HandleServerData(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
|
||||
void HandleServerData(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
static void HandleTimer(Timer &aTimer);
|
||||
void HandleTimer(void);
|
||||
|
||||
otError RegisterNetworkData(uint16_t aRloc16, uint8_t *aTlvs, uint8_t aTlvsLength);
|
||||
otError RegisterNetworkData(uint16_t aRloc16, const uint8_t *aTlvs, uint8_t aTlvsLength);
|
||||
|
||||
otError AddHasRoute(PrefixTlv &aPrefix, HasRouteTlv &aHasRoute);
|
||||
otError AddBorderRouter(PrefixTlv &aPrefix, BorderRouterTlv &aBorderRouter);
|
||||
otError AddNetworkData(uint8_t *aTlvs, uint8_t aTlvsLength, uint8_t *aOldTlvs, uint8_t aOldTlvsLength);
|
||||
otError AddPrefix(PrefixTlv &aPrefix);
|
||||
otError AddServer(ServiceTlv &aService, ServerTlv &aServer, uint8_t *aOldTlvs, uint8_t aOldTlvsLength);
|
||||
otError AddService(ServiceTlv &aService, uint8_t *aOldTlvs, uint8_t aOldTlvsLength);
|
||||
otError AddPrefix(const PrefixTlv &aPrefix, ChangedFlags &aChangedFlags);
|
||||
otError AddHasRoute(const HasRouteTlv &aHasRoute, PrefixTlv &aDstPrefix, ChangedFlags &aChangedFlags);
|
||||
otError AddBorderRouter(const BorderRouterTlv &aBorderRouter, PrefixTlv &aDstPrefix, ChangedFlags &aFlags);
|
||||
otError AddService(const ServiceTlv &aService, ChangedFlags &aChangedFlags);
|
||||
otError AddServer(const ServerTlv &aServer, ServiceTlv &aDstService, ChangedFlags &aChangedFlags);
|
||||
|
||||
int AllocateContext(void);
|
||||
void FreeContext(uint8_t aContextId);
|
||||
void StartContextReuseTimer(uint8_t aContextId);
|
||||
void StopContextReuseTimer(uint8_t aContextId);
|
||||
otError AllocateServiceId(uint8_t &aServiceId);
|
||||
|
||||
otError AllocateContextId(uint8_t &aConextId);
|
||||
void FreeContextId(uint8_t aContextId);
|
||||
void StartContextReuseTimer(uint8_t aContextId);
|
||||
void StopContextReuseTimer(uint8_t aContextId);
|
||||
|
||||
void RemoveContext(uint8_t aContextId);
|
||||
void RemoveContext(PrefixTlv &aPrefix, uint8_t aContextId);
|
||||
|
||||
void RemoveCommissioningData(void);
|
||||
|
||||
void RemoveRloc(uint16_t aRloc16, MatchMode aMatchMode);
|
||||
void RemoveRloc(PrefixTlv &aPrefix, uint16_t aRloc16, MatchMode aMatchMode);
|
||||
void RemoveRloc(ServiceTlv &aService, uint16_t aRloc16, MatchMode aMatchMode);
|
||||
void RemoveRloc(PrefixTlv &aPrefix, HasRouteTlv &aHasRoute, uint16_t aRloc16, MatchMode aMatchMode);
|
||||
void RemoveRloc(PrefixTlv &aPrefix, BorderRouterTlv &aBorderRouter, uint16_t aRloc16, MatchMode aMatchMode);
|
||||
void RemoveRloc(uint16_t aRloc16, MatchMode aMatchMode, ChangedFlags &aChangedFlags);
|
||||
void RemoveRloc(uint16_t aRloc16,
|
||||
MatchMode aMatchMode,
|
||||
const uint8_t *aExcludeTlvs,
|
||||
uint8_t aExcludeTlvsLength,
|
||||
ChangedFlags & aChangedFlags);
|
||||
void RemoveRlocInPrefix(PrefixTlv & aPrefix,
|
||||
uint16_t aRloc16,
|
||||
MatchMode aMatchMode,
|
||||
const PrefixTlv *aExcludePrefix,
|
||||
ChangedFlags & aChangedFlags);
|
||||
void RemoveRlocInService(ServiceTlv & aService,
|
||||
uint16_t aRloc16,
|
||||
MatchMode aMatchMode,
|
||||
const ServiceTlv *aExcludeService,
|
||||
ChangedFlags & aChangedFlags);
|
||||
void RemoveRlocInHasRoute(PrefixTlv & aPrefix,
|
||||
HasRouteTlv & aHasRoute,
|
||||
uint16_t aRloc16,
|
||||
MatchMode aMatchMode,
|
||||
const PrefixTlv *aExcludePrefix,
|
||||
ChangedFlags & aChangedFlags);
|
||||
void RemoveRlocInBorderRouter(PrefixTlv & aPrefix,
|
||||
BorderRouterTlv &aBorderRouter,
|
||||
uint16_t aRloc16,
|
||||
MatchMode aMatchMode,
|
||||
const PrefixTlv *aExcludePrefix,
|
||||
ChangedFlags & aChangedFlags);
|
||||
|
||||
static bool RlocMatch(uint16_t aFirstRloc16, uint16_t aSecondRloc16, MatchMode aMatchMode);
|
||||
|
||||
static otError RlocLookup(uint16_t aRloc16,
|
||||
bool & aIn,
|
||||
bool & aStable,
|
||||
const uint8_t *aTlvs,
|
||||
uint8_t aTlvsLength,
|
||||
MatchMode aMatchMode,
|
||||
bool aAllowOtherEntries = true);
|
||||
static otError Validate(const uint8_t *aTlvs, uint8_t aTlvsLength, uint16_t aRloc16);
|
||||
static otError ValidatePrefix(const PrefixTlv &aPrefix, uint16_t aRloc16);
|
||||
static otError ValidateService(const ServiceTlv &aService, uint16_t aRloc16);
|
||||
|
||||
static bool IsStableUpdated(const uint8_t *aTlvs,
|
||||
uint8_t aTlvsLength,
|
||||
const uint8_t *aTlvsBase,
|
||||
uint8_t aTlvsBaseLength);
|
||||
static bool ContainsMatchingEntry(const PrefixTlv *aPrefix, bool aStable, const HasRouteEntry &aEntry);
|
||||
static bool ContainsMatchingEntry(const HasRouteTlv *aHasRoute, const HasRouteEntry &aEntry);
|
||||
static bool ContainsMatchingEntry(const PrefixTlv *aPrefix, bool aStable, const BorderRouterEntry &aEntry);
|
||||
static bool ContainsMatchingEntry(const BorderRouterTlv *aBorderRouter, const BorderRouterEntry &aEntry);
|
||||
static bool ContainsMatchingServer(const ServiceTlv *aService, const ServerTlv &aServer);
|
||||
|
||||
UpdateStatus UpdatePrefix(PrefixTlv &aPrefix);
|
||||
UpdateStatus UpdateService(ServiceTlv &aService);
|
||||
UpdateStatus UpdateTlv(NetworkDataTlv &aTlv, const NetworkDataTlv *aSubTlvs);
|
||||
|
||||
static void HandleCommissioningSet(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
|
||||
void HandleCommissioningSet(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
@@ -230,6 +284,7 @@ private:
|
||||
const Ip6::MessageInfo & aMessageInfo,
|
||||
MeshCoP::StateTlv::State aState);
|
||||
void IncrementVersions(bool aIncludeStable);
|
||||
void IncrementVersions(const ChangedFlags &aFlags);
|
||||
|
||||
/**
|
||||
* Thread Specification Constants.
|
||||
|
||||
@@ -251,21 +251,22 @@ otError Local::AddService(uint32_t aEnterpriseNumber,
|
||||
otError error = OT_ERROR_NONE;
|
||||
ServiceTlv *serviceTlv;
|
||||
ServerTlv * serverTlv;
|
||||
size_t serviceTlvSize =
|
||||
ServiceTlv::GetSize(aEnterpriseNumber, aServiceDataLength) + sizeof(ServerTlv) + aServerDataLength;
|
||||
uint16_t serviceTlvSize =
|
||||
ServiceTlv::CalculateSize(aEnterpriseNumber, aServiceDataLength) + sizeof(ServerTlv) + aServerDataLength;
|
||||
|
||||
RemoveService(aEnterpriseNumber, aServiceData, aServiceDataLength);
|
||||
|
||||
VerifyOrExit(serviceTlvSize <= kMaxSize, error = OT_ERROR_NO_BUFS);
|
||||
|
||||
serviceTlv = static_cast<ServiceTlv *>(AppendTlv(static_cast<uint8_t>(serviceTlvSize)));
|
||||
serviceTlv = static_cast<ServiceTlv *>(AppendTlv(serviceTlvSize));
|
||||
VerifyOrExit(serviceTlv != NULL, error = OT_ERROR_NO_BUFS);
|
||||
|
||||
serviceTlv->Init(/* aServiceId */ 0, aEnterpriseNumber, aServiceData, aServiceDataLength);
|
||||
serviceTlv->SetSubTlvsLength(sizeof(ServerTlv) + aServerDataLength);
|
||||
|
||||
serverTlv = static_cast<ServerTlv *>(serviceTlv->GetSubTlvs());
|
||||
serverTlv->Init();
|
||||
|
||||
serverTlv->Init(Get<Mle::MleRouter>().GetRloc16(), aServerData, aServerDataLength);
|
||||
|
||||
// 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."
|
||||
@@ -276,9 +277,6 @@ otError Local::AddService(uint32_t aEnterpriseNumber,
|
||||
serverTlv->SetStable();
|
||||
}
|
||||
|
||||
serverTlv->SetServer16(Get<Mle::MleRouter>().GetRloc16());
|
||||
serverTlv->SetServerData(aServerData, aServerDataLength);
|
||||
|
||||
otDumpDebgNetData("add service done", mTlvs, mLength);
|
||||
|
||||
exit:
|
||||
|
||||
@@ -123,6 +123,22 @@ public:
|
||||
*/
|
||||
void SetLength(uint8_t aLength) { mLength = aLength; }
|
||||
|
||||
/**
|
||||
* This methods increases the Length value by a given amount.
|
||||
*
|
||||
* @param[in] aIncrement The increment amount to increase the length.
|
||||
*
|
||||
*/
|
||||
void IncreaseLength(uint8_t aIncrement) { mLength += aIncrement; }
|
||||
|
||||
/**
|
||||
* This methods decreases the Length value by a given amount.
|
||||
*
|
||||
* @param[in] aDecrement The decrement amount to decrease the length.
|
||||
*
|
||||
*/
|
||||
void DecreaseLength(uint8_t aDecrement) { mLength -= aDecrement; }
|
||||
|
||||
/**
|
||||
* This method returns the TLV's total size (number of bytes) including Type, Length, and Value fields.
|
||||
*
|
||||
@@ -272,6 +288,20 @@ public:
|
||||
*/
|
||||
const HasRouteEntry *GetNext(void) const { return (this + 1); }
|
||||
|
||||
/**
|
||||
* This method indicates whether two entries fully match.
|
||||
*
|
||||
* @param[in] aOtherEntry Another entry to compare with it.
|
||||
*
|
||||
* @retval TRUE The two entries are equal.
|
||||
* @retval FALSE The two entries are not equal.
|
||||
*
|
||||
*/
|
||||
bool operator==(const HasRouteEntry &aOtherEntry) const
|
||||
{
|
||||
return (memcmp(this, &aOtherEntry, sizeof(HasRouteEntry)) == 0);
|
||||
}
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
@@ -506,6 +536,19 @@ public:
|
||||
SetLength(sizeof(*this) - sizeof(NetworkDataTlv) + BitVectorBytes(mPrefixLength) + aLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* This static method calculates the total size (number of bytes) of a Prefix TLV with a given Prefix Length value.
|
||||
*
|
||||
* Note that the returned size does include the Type and Length fields in the TLV, but does not account for any
|
||||
* sub TLVs of the Prefix TLV.
|
||||
*
|
||||
* @param[in] aPrefixLength A Prefix Length in bits.
|
||||
|
||||
* @returns The size (number of bytes) of the Prefix TLV.
|
||||
*
|
||||
*/
|
||||
static uint16_t CalculateSize(uint8_t aPrefixLength) { return sizeof(PrefixTlv) + BitVectorBytes(aPrefixLength); }
|
||||
|
||||
private:
|
||||
uint8_t mDomainId;
|
||||
uint8_t mPrefixLength;
|
||||
@@ -687,6 +730,20 @@ public:
|
||||
*/
|
||||
const BorderRouterEntry *GetNext(void) const { return (this + 1); }
|
||||
|
||||
/**
|
||||
* This method indicates whether two entries fully match.
|
||||
*
|
||||
* @param[in] aOtherEntry Another entry to compare with it.
|
||||
*
|
||||
* @retval TRUE The two entries are equal.
|
||||
* @retval FALSE The two entries are not equal.
|
||||
*
|
||||
*/
|
||||
bool operator==(const BorderRouterEntry &aOtherEntry) const
|
||||
{
|
||||
return (memcmp(this, &aOtherEntry, sizeof(BorderRouterEntry)) == 0);
|
||||
}
|
||||
|
||||
private:
|
||||
uint16_t mRloc;
|
||||
uint16_t mFlags;
|
||||
@@ -811,16 +868,19 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* This method initializes the TLV.
|
||||
* This method initializes the Context TLV.
|
||||
*
|
||||
* @param[in] aConextId The Context ID value.
|
||||
* @param[in] aLength The Context Length value.
|
||||
*
|
||||
*/
|
||||
void Init(void)
|
||||
void Init(uint8_t aContextId, uint8_t aConextLength)
|
||||
{
|
||||
NetworkDataTlv::Init();
|
||||
SetType(kTypeContext);
|
||||
SetLength(2);
|
||||
mFlags = 0;
|
||||
mContextLength = 0;
|
||||
SetLength(sizeof(ContextTlv) - sizeof(NetworkDataTlv));
|
||||
mFlags = ((aContextId << kContextIdOffset) & kContextIdMask);
|
||||
mContextLength = aConextLength;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -852,17 +912,6 @@ public:
|
||||
*/
|
||||
uint8_t GetContextId(void) const { return mFlags & kContextIdMask; }
|
||||
|
||||
/**
|
||||
* This method sets the Context ID value.
|
||||
*
|
||||
* @param[in] aContextId The Context ID value.
|
||||
*
|
||||
*/
|
||||
void SetContextId(uint8_t aContextId)
|
||||
{
|
||||
mFlags = (mFlags & ~kContextIdMask) | ((aContextId << kContextIdOffset) & kContextIdMask);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the Context Length value.
|
||||
*
|
||||
@@ -871,14 +920,6 @@ public:
|
||||
*/
|
||||
uint8_t GetContextLength(void) const { return mContextLength; }
|
||||
|
||||
/**
|
||||
* This method sets the Context Length value.
|
||||
*
|
||||
* @param[in] aLength The Context Length value.
|
||||
*
|
||||
*/
|
||||
void SetContextLength(uint8_t aLength) { mContextLength = aLength; }
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
@@ -1080,7 +1121,7 @@ public:
|
||||
* @returns The size (number of bytes) of the Service TLV.
|
||||
*
|
||||
*/
|
||||
static uint16_t GetSize(uint32_t aEnterpriseNumber, uint8_t aServiceDataLength)
|
||||
static uint16_t CalculateSize(uint32_t aEnterpriseNumber, uint8_t aServiceDataLength)
|
||||
{
|
||||
return sizeof(NetworkDataTlv) + kMinLength + aServiceDataLength +
|
||||
((aEnterpriseNumber == kThreadEnterpriseNumber) ? 0 : sizeof(uint32_t) /* mEnterpriseNumber */);
|
||||
@@ -1133,14 +1174,20 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* This method initializes the TLV.
|
||||
* This method initializes the Server TLV.
|
||||
*
|
||||
* @param[in] aServer16 The Server16 value.
|
||||
* @param[in] aServerData The Server Data.
|
||||
* @param[in] aServerDataLength Server Data length in bytes.
|
||||
*
|
||||
*/
|
||||
void Init(void)
|
||||
void Init(uint16_t aServer16, const uint8_t *aServerData, uint8_t aServerDataLength)
|
||||
{
|
||||
NetworkDataTlv::Init();
|
||||
SetType(kTypeServer);
|
||||
SetLength(sizeof(*this) - sizeof(NetworkDataTlv));
|
||||
SetServer16(aServer16);
|
||||
memcpy(reinterpret_cast<uint8_t *>(this) + sizeof(*this), aServerData, aServerDataLength);
|
||||
SetLength(sizeof(*this) - sizeof(NetworkDataTlv) + aServerDataLength);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1153,43 +1200,29 @@ public:
|
||||
bool IsValid(void) const { return GetLength() >= (sizeof(*this) - sizeof(NetworkDataTlv)); }
|
||||
|
||||
/**
|
||||
* This method returns the S_server_16 value.
|
||||
* This method returns the Server16 value.
|
||||
*
|
||||
* @returns The S_server_16 value.
|
||||
* @returns The Server16 value.
|
||||
*
|
||||
*/
|
||||
uint16_t GetServer16(void) const { return HostSwap16(mServer16); }
|
||||
|
||||
/**
|
||||
* This method sets the S_server_16 value.
|
||||
/*
|
||||
* This method sets the Server16 value.
|
||||
*
|
||||
* @param[in] aServer16 The S_server_16 value.
|
||||
* @param[in] aServer16 The Server16 value.
|
||||
*
|
||||
*/
|
||||
void SetServer16(uint16_t aServer16) { mServer16 = HostSwap16(aServer16); }
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the Server Data.
|
||||
* This method returns the Server Data.
|
||||
*
|
||||
* @returns A pointer to the Server Data.
|
||||
*
|
||||
*/
|
||||
const uint8_t *GetServerData(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(*this); }
|
||||
|
||||
/**
|
||||
* This method sets Server Data to the given values.
|
||||
*
|
||||
* Caller must ensure that there is enough memory allocated.
|
||||
*
|
||||
* @param aServerData pointer to the server data to use
|
||||
* @param aServerDataLength length of the provided server data in bytes
|
||||
*/
|
||||
void SetServerData(const uint8_t *aServerData, uint8_t aServerDataLength)
|
||||
{
|
||||
SetLength(sizeof(*this) - sizeof(NetworkDataTlv) + aServerDataLength);
|
||||
memcpy(reinterpret_cast<uint8_t *>(this) + sizeof(*this), aServerData, aServerDataLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the Server Data length in bytes.
|
||||
*
|
||||
@@ -1198,6 +1231,32 @@ public:
|
||||
*/
|
||||
uint8_t GetServerDataLength(void) const { return GetLength() - (sizeof(*this) - sizeof(NetworkDataTlv)); }
|
||||
|
||||
/**
|
||||
* This method indicates whether two Server TLVs fully match.
|
||||
*
|
||||
* @param[in] aOther Another Server TLV to compare with it.
|
||||
*
|
||||
* @retval TRUE The two TLVs are equal.
|
||||
* @retval FALSE The two TLVs are not equal.
|
||||
*
|
||||
*/
|
||||
bool operator==(const ServerTlv &aOther) const
|
||||
{
|
||||
return (GetLength() == aOther.GetLength()) && (memcmp(GetValue(), aOther.GetValue(), GetLength()) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* This static method calculates the total size (number of bytes) of a Service TLV with a given Server Data length.
|
||||
*
|
||||
* Note that the returned size does include the Type and Length fields in the TLV.
|
||||
*
|
||||
* @param[in] aServerDataLength Server Data length in bytes.
|
||||
*
|
||||
* @returns The size (number of bytes) of the Server TLV.
|
||||
*
|
||||
*/
|
||||
static uint16_t CalculateSize(uint8_t aServerDataLength) { return sizeof(ServerTlv) + aServerDataLength; }
|
||||
|
||||
private:
|
||||
uint16_t mServer16;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
Reference in New Issue
Block a user