mirror of
https://github.com/espressif/openthread.git
synced 2026-09-06 01:00:09 +00:00
[netdata] enhance and simplify NetworkData class (#7004)
This commit updates the `NetworkData` implementation to simplify it and make it more flexible. It changes `NetworkData` class such that it delegates providing the buffer space to store the TLVs to its sub-classes (`Local`/`Leader`) or its users. This allow us to remove many `static` methods that expect inputs of `(aTlvs, aTlvsLength)` and instead the use the `NetworkData` methods directly. Basically, the `NetworkData` class can now be considered as a wrapper over a pointer to a buffer containing a sequence of TLVs which provides methods to parse and process the TLVs. `NetworkData` class assumes that the TLVs (buffer content) is immutable and we have a new class `MutableNetworkData` which provides methods to update (add, remove, or modify) the TLVs.
This commit is contained in:
@@ -68,9 +68,7 @@ otError otBorderRoutingGetOnLinkPrefix(otInstance *aInstance, otIp6Prefix *aPref
|
||||
|
||||
otError otBorderRouterGetNetData(otInstance *aInstance, bool aStable, uint8_t *aData, uint8_t *aDataLength)
|
||||
{
|
||||
OT_ASSERT(aData != nullptr && aDataLength != nullptr);
|
||||
|
||||
return AsCoreType(aInstance).Get<NetworkData::Local>().GetNetworkData(aStable, aData, *aDataLength);
|
||||
return AsCoreType(aInstance).Get<NetworkData::Local>().CopyNetworkData(aStable, aData, *aDataLength);
|
||||
}
|
||||
|
||||
otError otBorderRouterAddOnMeshPrefix(otInstance *aInstance, const otBorderRouterConfig *aConfig)
|
||||
|
||||
@@ -42,9 +42,7 @@ using namespace ot;
|
||||
|
||||
otError otNetDataGet(otInstance *aInstance, bool aStable, uint8_t *aData, uint8_t *aDataLength)
|
||||
{
|
||||
OT_ASSERT(aData != nullptr && aDataLength != nullptr);
|
||||
|
||||
return AsCoreType(aInstance).Get<NetworkData::Leader>().GetNetworkData(aStable, aData, *aDataLength);
|
||||
return AsCoreType(aInstance).Get<NetworkData::Leader>().CopyNetworkData(aStable, aData, *aDataLength);
|
||||
}
|
||||
|
||||
otError otNetDataGetNextOnMeshPrefix(otInstance * aInstance,
|
||||
|
||||
@@ -44,9 +44,7 @@ using namespace ot;
|
||||
|
||||
otError otServerGetNetDataLocal(otInstance *aInstance, bool aStable, uint8_t *aData, uint8_t *aDataLength)
|
||||
{
|
||||
OT_ASSERT(aData != nullptr && aDataLength != nullptr);
|
||||
|
||||
return AsCoreType(aInstance).Get<NetworkData::Local>().GetNetworkData(aStable, aData, *aDataLength);
|
||||
return AsCoreType(aInstance).Get<NetworkData::Local>().CopyNetworkData(aStable, aData, *aDataLength);
|
||||
}
|
||||
|
||||
otError otServerAddService(otInstance *aInstance, const otServiceConfig *aConfig)
|
||||
|
||||
@@ -1199,7 +1199,7 @@ Error Mle::AppendNetworkData(Message &aMessage, bool aStableOnly)
|
||||
VerifyOrExit(!mRetrieveNewNetworkData, error = kErrorInvalidState);
|
||||
|
||||
length = sizeof(networkData);
|
||||
IgnoreError(Get<NetworkData::Leader>().GetNetworkData(aStableOnly, networkData, length));
|
||||
IgnoreError(Get<NetworkData::Leader>().CopyNetworkData(aStableOnly, networkData, length));
|
||||
|
||||
error = Tlv::Append<NetworkDataTlv>(aMessage, networkData, length);
|
||||
|
||||
|
||||
@@ -47,19 +47,30 @@
|
||||
namespace ot {
|
||||
namespace NetworkData {
|
||||
|
||||
Error NetworkData::GetNetworkData(bool aStable, uint8_t *aData, uint8_t &aDataLength) const
|
||||
Error NetworkData::CopyNetworkData(bool aStable, uint8_t *aData, uint8_t &aDataLength) const
|
||||
{
|
||||
Error error;
|
||||
MutableNetworkData netDataCopy(GetInstance(), aData, 0, aDataLength);
|
||||
|
||||
SuccessOrExit(error = CopyNetworkData(aStable, netDataCopy));
|
||||
aDataLength = netDataCopy.GetLength();
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error NetworkData::CopyNetworkData(bool aStable, MutableNetworkData &aNetworkData) const
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
OT_ASSERT(aData != nullptr);
|
||||
VerifyOrExit(aDataLength >= mLength, error = kErrorNoBufs);
|
||||
VerifyOrExit(aNetworkData.GetSize() >= mLength, error = kErrorNoBufs);
|
||||
|
||||
memcpy(aData, mTlvs, mLength);
|
||||
aDataLength = mLength;
|
||||
memcpy(aNetworkData.GetBytes(), mTlvs, mLength);
|
||||
aNetworkData.SetLength(mLength);
|
||||
|
||||
if (aStable)
|
||||
{
|
||||
RemoveTemporaryData(aData, aDataLength);
|
||||
aNetworkData.RemoveTemporaryData();
|
||||
}
|
||||
|
||||
exit:
|
||||
@@ -381,11 +392,11 @@ exit:
|
||||
return rval;
|
||||
}
|
||||
|
||||
void NetworkData::RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength)
|
||||
void MutableNetworkData::RemoveTemporaryData(void)
|
||||
{
|
||||
NetworkDataTlv *cur = reinterpret_cast<NetworkDataTlv *>(aData);
|
||||
NetworkDataTlv *cur = GetTlvsStart();
|
||||
|
||||
while (cur < reinterpret_cast<NetworkDataTlv *>(aData + aDataLength))
|
||||
while (cur < GetTlvsEnd())
|
||||
{
|
||||
switch (cur->GetType())
|
||||
{
|
||||
@@ -393,30 +404,28 @@ void NetworkData::RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength)
|
||||
{
|
||||
PrefixTlv *prefix = static_cast<PrefixTlv *>(cur);
|
||||
|
||||
RemoveTemporaryData(aData, aDataLength, *prefix);
|
||||
RemoveTemporaryDataIn(*prefix);
|
||||
|
||||
if (prefix->GetSubTlvsLength() == 0)
|
||||
{
|
||||
RemoveTlv(aData, aDataLength, cur);
|
||||
RemoveTlv(cur);
|
||||
continue;
|
||||
}
|
||||
|
||||
otDumpDebgNetData("remove prefix done", aData, aDataLength);
|
||||
break;
|
||||
}
|
||||
|
||||
case NetworkDataTlv::kTypeService:
|
||||
{
|
||||
ServiceTlv *service = static_cast<ServiceTlv *>(cur);
|
||||
RemoveTemporaryData(aData, aDataLength, *service);
|
||||
RemoveTemporaryDataIn(*service);
|
||||
|
||||
if (service->GetSubTlvsLength() == 0)
|
||||
{
|
||||
RemoveTlv(aData, aDataLength, cur);
|
||||
RemoveTlv(cur);
|
||||
continue;
|
||||
}
|
||||
|
||||
otDumpDebgNetData("remove service done", aData, aDataLength);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -424,7 +433,7 @@ void NetworkData::RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength)
|
||||
// remove temporary tlv
|
||||
if (!cur->IsStable())
|
||||
{
|
||||
RemoveTlv(aData, aDataLength, cur);
|
||||
RemoveTlv(cur);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -433,11 +442,9 @@ void NetworkData::RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength)
|
||||
|
||||
cur = cur->GetNext();
|
||||
}
|
||||
|
||||
otDumpDebgNetData("remove done", aData, aDataLength);
|
||||
}
|
||||
|
||||
void NetworkData::RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, PrefixTlv &aPrefix)
|
||||
void MutableNetworkData::RemoveTemporaryDataIn(PrefixTlv &aPrefix)
|
||||
{
|
||||
NetworkDataTlv *cur = aPrefix.GetSubTlvs();
|
||||
|
||||
@@ -494,13 +501,13 @@ void NetworkData::RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, Pref
|
||||
{
|
||||
// remove temporary tlv
|
||||
uint8_t subTlvSize = cur->GetSize();
|
||||
RemoveTlv(aData, aDataLength, cur);
|
||||
RemoveTlv(cur);
|
||||
aPrefix.SetSubTlvsLength(aPrefix.GetSubTlvsLength() - subTlvSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkData::RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, ServiceTlv &aService)
|
||||
void MutableNetworkData::RemoveTemporaryDataIn(ServiceTlv &aService)
|
||||
{
|
||||
NetworkDataTlv *cur = aService.GetSubTlvs();
|
||||
|
||||
@@ -528,7 +535,7 @@ void NetworkData::RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, Serv
|
||||
{
|
||||
// remove temporary tlv
|
||||
uint8_t subTlvSize = cur->GetSize();
|
||||
RemoveTlv(aData, aDataLength, cur);
|
||||
RemoveTlv(cur);
|
||||
aService.SetSubTlvsLength(aService.GetSubTlvsLength() - subTlvSize);
|
||||
}
|
||||
}
|
||||
@@ -536,15 +543,7 @@ void NetworkData::RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, Serv
|
||||
|
||||
const PrefixTlv *NetworkData::FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) const
|
||||
{
|
||||
return FindPrefix(aPrefix, aPrefixLength, mTlvs, mLength);
|
||||
}
|
||||
|
||||
const PrefixTlv *NetworkData::FindPrefix(const uint8_t *aPrefix,
|
||||
uint8_t aPrefixLength,
|
||||
const uint8_t *aTlvs,
|
||||
uint8_t aTlvsLength)
|
||||
{
|
||||
TlvIterator tlvIterator(aTlvs, aTlvsLength);
|
||||
TlvIterator tlvIterator(mTlvs, mLength);
|
||||
const PrefixTlv *prefixTlv;
|
||||
|
||||
while ((prefixTlv = tlvIterator.Iterate<PrefixTlv>()) != nullptr)
|
||||
@@ -562,16 +561,7 @@ const ServiceTlv *NetworkData::FindService(uint32_t aEnterpriseNumber,
|
||||
const ServiceData &aServiceData,
|
||||
ServiceMatchMode aServiceMatchMode) const
|
||||
{
|
||||
return FindService(aEnterpriseNumber, aServiceData, aServiceMatchMode, mTlvs, mLength);
|
||||
}
|
||||
|
||||
const ServiceTlv *NetworkData::FindService(uint32_t aEnterpriseNumber,
|
||||
const ServiceData &aServiceData,
|
||||
ServiceMatchMode aServiceMatchMode,
|
||||
const uint8_t * aTlvs,
|
||||
uint8_t aTlvsLength)
|
||||
{
|
||||
TlvIterator tlvIterator(aTlvs, aTlvsLength);
|
||||
TlvIterator tlvIterator(mTlvs, mLength);
|
||||
const ServiceTlv *serviceTlv;
|
||||
|
||||
while ((serviceTlv = tlvIterator.Iterate<ServiceTlv>()) != nullptr)
|
||||
@@ -604,7 +594,7 @@ const ServiceTlv *NetworkData::FindNextService(const ServiceTlv * aPrevServiceTl
|
||||
length = static_cast<uint8_t>((mTlvs + mLength) - tlvs);
|
||||
}
|
||||
|
||||
return FindService(aEnterpriseNumber, aServiceData, aServiceMatchMode, tlvs, length);
|
||||
return NetworkData(GetInstance(), tlvs, length).FindService(aEnterpriseNumber, aServiceData, aServiceMatchMode);
|
||||
}
|
||||
|
||||
const ServiceTlv *NetworkData::FindNextThreadService(const ServiceTlv * aPrevServiceTlv,
|
||||
@@ -641,7 +631,7 @@ exit:
|
||||
return match;
|
||||
}
|
||||
|
||||
NetworkDataTlv *NetworkData::AppendTlv(uint16_t aTlvSize)
|
||||
NetworkDataTlv *MutableNetworkData::AppendTlv(uint16_t aTlvSize)
|
||||
{
|
||||
NetworkDataTlv *tlv;
|
||||
|
||||
@@ -654,7 +644,7 @@ exit:
|
||||
return tlv;
|
||||
}
|
||||
|
||||
void NetworkData::Insert(void *aStart, uint8_t aLength)
|
||||
void MutableNetworkData::Insert(void *aStart, uint8_t aLength)
|
||||
{
|
||||
uint8_t *start = reinterpret_cast<uint8_t *>(aStart);
|
||||
|
||||
@@ -663,36 +653,27 @@ void NetworkData::Insert(void *aStart, uint8_t aLength)
|
||||
mLength += aLength;
|
||||
}
|
||||
|
||||
void NetworkData::Remove(uint8_t *aData, uint8_t &aDataLength, uint8_t *aRemoveStart, uint8_t aRemoveLength)
|
||||
void MutableNetworkData::Remove(void *aRemoveStart, uint8_t aRemoveLength)
|
||||
{
|
||||
uint8_t *dataEnd = aData + aDataLength;
|
||||
uint8_t *removeEnd = aRemoveStart + aRemoveLength;
|
||||
uint8_t *end = GetBytes() + mLength;
|
||||
uint8_t *removeStart = reinterpret_cast<uint8_t *>(aRemoveStart);
|
||||
uint8_t *removeEnd = removeStart + aRemoveLength;
|
||||
|
||||
OT_ASSERT((aRemoveLength <= aDataLength) && (aData <= aRemoveStart) && (removeEnd <= dataEnd));
|
||||
OT_ASSERT((aRemoveLength <= mLength) && (GetBytes() <= removeStart) && (removeEnd <= end));
|
||||
|
||||
memmove(aRemoveStart, removeEnd, static_cast<uint8_t>(dataEnd - removeEnd));
|
||||
aDataLength -= aRemoveLength;
|
||||
memmove(removeStart, removeEnd, static_cast<uint8_t>(end - removeEnd));
|
||||
mLength -= aRemoveLength;
|
||||
}
|
||||
|
||||
void NetworkData::RemoveTlv(uint8_t *aData, uint8_t &aDataLength, NetworkDataTlv *aTlv)
|
||||
void MutableNetworkData::RemoveTlv(NetworkDataTlv *aTlv)
|
||||
{
|
||||
Remove(aData, aDataLength, reinterpret_cast<uint8_t *>(aTlv), aTlv->GetSize());
|
||||
}
|
||||
|
||||
void NetworkData::Remove(void *aRemoveStart, uint8_t aRemoveLength)
|
||||
{
|
||||
NetworkData::Remove(mTlvs, mLength, reinterpret_cast<uint8_t *>(aRemoveStart), aRemoveLength);
|
||||
}
|
||||
|
||||
void NetworkData::RemoveTlv(NetworkDataTlv *aTlv)
|
||||
{
|
||||
NetworkData::RemoveTlv(mTlvs, mLength, aTlv);
|
||||
Remove(aTlv, aTlv->GetSize());
|
||||
}
|
||||
|
||||
Error NetworkData::SendServerDataNotification(uint16_t aRloc16,
|
||||
bool aAppendNetDataTlv,
|
||||
Coap::ResponseHandler aHandler,
|
||||
void * aContext)
|
||||
void * aContext) const
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Coap::Message * message = nullptr;
|
||||
|
||||
+258
-217
@@ -92,6 +92,10 @@ class Manager;
|
||||
*
|
||||
*/
|
||||
|
||||
class Leader;
|
||||
class Publisher;
|
||||
class MutableNetworkData;
|
||||
|
||||
/**
|
||||
* This type represents a Iterator used to iterate through Network Data info (e.g., see `GetNextOnMeshPrefix()`)
|
||||
*
|
||||
@@ -101,48 +105,91 @@ typedef otNetworkDataIterator Iterator;
|
||||
constexpr Iterator kIteratorInit = OT_NETWORK_DATA_ITERATOR_INIT; ///< Initializer for `Iterator` type.
|
||||
|
||||
/**
|
||||
* This class implements Network Data processing.
|
||||
* This class represents an immutable Network Data.
|
||||
*
|
||||
*/
|
||||
class NetworkData : public InstanceLocator
|
||||
{
|
||||
friend class Service::Manager;
|
||||
friend class Leader;
|
||||
friend class Publisher;
|
||||
friend class MutableNetworkData;
|
||||
friend class Service::Manager;
|
||||
|
||||
public:
|
||||
static constexpr uint8_t kMaxSize = 254; ///< Maximum size of Thread Network Data in bytes.
|
||||
|
||||
/**
|
||||
* This constructor initializes the object.
|
||||
* This constructor initializes the `NetworkData` from a given pointer to a buffer and length.
|
||||
*
|
||||
* @param[in] aInstance A reference to the OpenThread instance.
|
||||
* @param[in] aInstance A reference to the OpenThread instance.
|
||||
* @param[in] aTlvs A pointer to the buffer containing the TLVs.
|
||||
* @param[in] aLength The length (number of bytes) of @p aTlvs buffer.
|
||||
*
|
||||
*/
|
||||
explicit NetworkData(Instance &aInstance)
|
||||
explicit NetworkData(Instance &aInstance, const uint8_t *aTlvs = nullptr, uint8_t aLength = 0)
|
||||
: InstanceLocator(aInstance)
|
||||
, mLength(0)
|
||||
, mTlvs(aTlvs)
|
||||
, mLength(aLength)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method clears the network data.
|
||||
* This constructor initializes the `NetworkData` from a range of TLVs (given as pair of start and end pointers).
|
||||
*
|
||||
* @param[in] aInstance A reference to the OpenThread instance.
|
||||
* @param[in] aStartTlv A pointer to the start of the TLVs buffer.
|
||||
* @param[in] aEndTlv A pointer to the end of the TLVs buffer.
|
||||
*
|
||||
*/
|
||||
void Clear(void) { mLength = 0; }
|
||||
NetworkData(Instance &aInstance, const NetworkDataTlv *aStartTlv, const NetworkDataTlv *aEndTlv)
|
||||
: InstanceLocator(aInstance)
|
||||
, mTlvs(reinterpret_cast<const uint8_t *>(aStartTlv))
|
||||
, mLength(static_cast<uint8_t>(reinterpret_cast<const uint8_t *>(aEndTlv) -
|
||||
reinterpret_cast<const uint8_t *>(aStartTlv)))
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method provides a full or stable copy of the Thread Network Data.
|
||||
* This method returns the length of `NetworkData` (number of bytes).
|
||||
*
|
||||
* @param[in] aStable TRUE when copying the stable version, FALSE when copying the full version.
|
||||
* @param[out] aData A pointer to the data buffer.
|
||||
* @param[inout] aDataLength On entry, size of the data buffer pointed to by @p aData.
|
||||
* On exit, number of copied bytes.
|
||||
*
|
||||
* @retval kErrorNone Successfully copied full Thread Network Data.
|
||||
* @retval kErrorNoBufs Not enough space to fully copy Thread Network Data.
|
||||
* @returns The length of `NetworkData` (number of bytes).
|
||||
*
|
||||
*/
|
||||
Error GetNetworkData(bool aStable, uint8_t *aData, uint8_t &aDataLength) const;
|
||||
uint8_t GetLength(void) const { return mLength; }
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the start of the TLVs in `NetworkData`.
|
||||
*
|
||||
* @returns A pointer to the start of the TLVs.
|
||||
*
|
||||
*/
|
||||
const uint8_t *GetBytes(void) const { return mTlvs; }
|
||||
|
||||
/**
|
||||
* This method provides full or stable copy of the Thread Network Data.
|
||||
*
|
||||
* @param[in] aStable TRUE when copying the stable version, FALSE when copying the full version.
|
||||
* @param[out] aData A pointer to the data buffer to copy the Network Data into.
|
||||
* @param[inout] aDataLength On entry, size of the data buffer pointed to by @p aData.
|
||||
* On exit, number of copied bytes.
|
||||
*
|
||||
* @retval kErrorNone Successfully copied full Thread Network Data.
|
||||
* @retval kErrorNoBufs Not enough space in @p aData to fully copy Thread Network Data.
|
||||
*
|
||||
*/
|
||||
Error CopyNetworkData(bool aStable, uint8_t *aData, uint8_t &aDataLength) const;
|
||||
|
||||
/**
|
||||
* This method provides full or stable copy of the Thread Network Data.
|
||||
*
|
||||
* @param[in] aStable TRUE when copying the stable version, FALSE when copying the full version.
|
||||
* @param[out] aNetworkData A reference to a `MutableNetworkData` to copy the Network Data into.
|
||||
*
|
||||
* @retval kErrorNone Successfully copied full Thread Network Data.
|
||||
* @retval kErrorNoBufs Not enough space in @p aNetworkData to fully copy Thread Network Data.
|
||||
*
|
||||
*/
|
||||
Error CopyNetworkData(bool aStable, MutableNetworkData &aNetworkData) const;
|
||||
|
||||
/**
|
||||
* This method provides the next On Mesh prefix in the Thread Network Data.
|
||||
@@ -307,14 +354,6 @@ protected:
|
||||
kServiceExactMatch, ///< Match the full Service Data exactly.
|
||||
};
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the start of Network Data TLV sequence.
|
||||
*
|
||||
* @returns A pointer to the start of Network Data TLV sequence.
|
||||
*
|
||||
*/
|
||||
NetworkDataTlv *GetTlvsStart(void) { return reinterpret_cast<NetworkDataTlv *>(mTlvs); }
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the start of Network Data TLV sequence.
|
||||
*
|
||||
@@ -323,14 +362,6 @@ protected:
|
||||
*/
|
||||
const NetworkDataTlv *GetTlvsStart(void) const { return reinterpret_cast<const NetworkDataTlv *>(mTlvs); }
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the end of Network Data TLV sequence.
|
||||
*
|
||||
* @returns A pointer to the end of Network Data TLV sequence.
|
||||
*
|
||||
*/
|
||||
NetworkDataTlv *GetTlvsEnd(void) { return reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength); }
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the end of Network Data TLV sequence.
|
||||
*
|
||||
@@ -339,20 +370,6 @@ protected:
|
||||
*/
|
||||
const NetworkDataTlv *GetTlvsEnd(void) const { return reinterpret_cast<const NetworkDataTlv *>(mTlvs + mLength); }
|
||||
|
||||
/**
|
||||
* This method returns a pointer to a Prefix TLV.
|
||||
*
|
||||
* @param[in] aPrefix A pointer to an IPv6 prefix.
|
||||
* @param[in] aPrefixLength The prefix length pointed to by @p aPrefix (in bits).
|
||||
*
|
||||
* @returns A pointer to the Prefix TLV if one is found or nullptr if no matching Prefix TLV exists.
|
||||
*
|
||||
*/
|
||||
PrefixTlv *FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength)
|
||||
{
|
||||
return AsNonConst(AsConst(this)->FindPrefix(aPrefix, aPrefixLength));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a pointer to a Prefix TLV.
|
||||
*
|
||||
@@ -364,16 +381,6 @@ protected:
|
||||
*/
|
||||
const PrefixTlv *FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) const;
|
||||
|
||||
/**
|
||||
* This method returns a pointer to a Prefix TLV.
|
||||
*
|
||||
* @param[in] aPrefix An IPv6 prefix.
|
||||
*
|
||||
* @returns A pointer to the Prefix TLV if one is found or nullptr if no matching Prefix TLV exists.
|
||||
*
|
||||
*/
|
||||
PrefixTlv *FindPrefix(const Ip6::Prefix &aPrefix) { return FindPrefix(aPrefix.GetBytes(), aPrefix.GetLength()); }
|
||||
|
||||
/**
|
||||
* This method returns a pointer to a Prefix TLV.
|
||||
*
|
||||
@@ -387,55 +394,6 @@ protected:
|
||||
return FindPrefix(aPrefix.GetBytes(), aPrefix.GetLength());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a pointer to a Prefix TLV in a specified tlvs buffer.
|
||||
*
|
||||
* @param[in] aPrefix A pointer to an IPv6 prefix.
|
||||
* @param[in] aPrefixLength The prefix length pointed to by @p aPrefix (in bits).
|
||||
* @param[in] aTlvs A pointer to a specified tlvs buffer.
|
||||
* @param[in] aTlvsLength The specified tlvs buffer length pointed to by @p aTlvs.
|
||||
*
|
||||
* @returns A pointer to the Prefix TLV if one is found or nullptr if no matching Prefix TLV exists.
|
||||
*
|
||||
*/
|
||||
static PrefixTlv *FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, uint8_t *aTlvs, uint8_t aTlvsLength)
|
||||
{
|
||||
return AsNonConst(FindPrefix(aPrefix, aPrefixLength, AsConst(aTlvs), aTlvsLength));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a pointer to a Prefix TLV in a specified tlvs buffer.
|
||||
*
|
||||
* @param[in] aPrefix A pointer to an IPv6 prefix.
|
||||
* @param[in] aPrefixLength The prefix length pointed to by @p aPrefix (in bits).
|
||||
* @param[in] aTlvs A pointer to a specified tlvs buffer.
|
||||
* @param[in] aTlvsLength The specified tlvs buffer length pointed to by @p aTlvs.
|
||||
*
|
||||
* @returns A pointer to the Prefix TLV if one is found or nullptr if no matching Prefix TLV exists.
|
||||
*
|
||||
*/
|
||||
static const PrefixTlv *FindPrefix(const uint8_t *aPrefix,
|
||||
uint8_t aPrefixLength,
|
||||
const uint8_t *aTlvs,
|
||||
uint8_t aTlvsLength);
|
||||
|
||||
/**
|
||||
* This method returns a pointer to a matching Service TLV.
|
||||
*
|
||||
* @param[in] aEnterpriseNumber Enterprise Number.
|
||||
* @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 ServiceData &aServiceData,
|
||||
ServiceMatchMode aServiceMatchMode)
|
||||
{
|
||||
return AsNonConst(AsConst(this)->FindService(aEnterpriseNumber, aServiceData, aServiceMatchMode));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a pointer to a matching Service TLV.
|
||||
*
|
||||
@@ -450,45 +408,6 @@ protected:
|
||||
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 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.
|
||||
*
|
||||
* @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 ServiceData &aServiceData,
|
||||
ServiceMatchMode aServiceMatchMode,
|
||||
uint8_t * aTlvs,
|
||||
uint8_t 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 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.
|
||||
*
|
||||
* @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 ServiceData &aServiceData,
|
||||
ServiceMatchMode aServiceMatchMode,
|
||||
const uint8_t * aTlvs,
|
||||
uint8_t aTlvsLength);
|
||||
|
||||
/**
|
||||
* This method returns the next pointer to a matching Service TLV.
|
||||
*
|
||||
@@ -527,68 +446,6 @@ protected:
|
||||
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
|
||||
* 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.
|
||||
*
|
||||
* On success, the returned TLV is not initialized (i.e., the TLV Length field is not set) but the requested
|
||||
* size for it (@p aTlvSize number of bytes) is reserved in the Network Data.
|
||||
*
|
||||
* @param[in] aTlvSize The size of TLV (total number of bytes including Type, Length, and Value fields)
|
||||
*
|
||||
* @returns A pointer to the TLV if there is space to grow Network Data, or nullptr if no space to grow the Network
|
||||
* Data with requested @p aTlvSize number of bytes.
|
||||
*
|
||||
*/
|
||||
NetworkDataTlv *AppendTlv(uint16_t aTlvSize);
|
||||
|
||||
/**
|
||||
* This method inserts bytes into the Network Data.
|
||||
*
|
||||
* @param[in] aStart A pointer to the beginning of the insertion.
|
||||
* @param[in] aLength The number of bytes to insert.
|
||||
*
|
||||
*/
|
||||
void Insert(void *aStart, uint8_t aLength);
|
||||
|
||||
/**
|
||||
* This method removes bytes from the Network Data.
|
||||
*
|
||||
* @param[in] aRemoveStart A pointer to the beginning of the removal.
|
||||
* @param[in] aRemoveLength The number of bytes to remove.
|
||||
*
|
||||
*/
|
||||
void Remove(void *aRemoveStart, uint8_t aRemoveLength);
|
||||
|
||||
/**
|
||||
* This method removes a TLV from the Network Data.
|
||||
*
|
||||
* @param[in] aTlv The TLV to remove.
|
||||
*
|
||||
*/
|
||||
void RemoveTlv(NetworkDataTlv *aTlv);
|
||||
|
||||
/**
|
||||
* This method strips non-stable data from the Thread Network Data.
|
||||
*
|
||||
* @param[inout] aData A pointer to the Network Data to modify.
|
||||
* @param[inout] aDataLength On entry, the size of the Network Data in bytes. On exit, the size of the
|
||||
* resulting Network Data in bytes.
|
||||
*
|
||||
*/
|
||||
static void RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength);
|
||||
|
||||
/**
|
||||
* This method sends a Server Data Notification message to the Leader.
|
||||
*
|
||||
@@ -604,10 +461,7 @@ protected:
|
||||
Error SendServerDataNotification(uint16_t aRloc16,
|
||||
bool aAppendNetDataTlv,
|
||||
Coap::ResponseHandler aHandler,
|
||||
void * aContext);
|
||||
|
||||
uint8_t mTlvs[kMaxSize]; ///< The Network Data buffer.
|
||||
uint8_t mLength; ///< The number of valid bytes in @var mTlvs.
|
||||
void * aContext) const;
|
||||
|
||||
private:
|
||||
class NetworkDataIterator
|
||||
@@ -682,16 +536,203 @@ private:
|
||||
|
||||
Error Iterate(Iterator &aIterator, uint16_t aRloc16, Config &aConfig) const;
|
||||
|
||||
static void RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, PrefixTlv &aPrefix);
|
||||
static void RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, ServiceTlv &aService);
|
||||
|
||||
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 ServiceData &aServiceData,
|
||||
ServiceMatchMode aServiceMatchMode);
|
||||
|
||||
const uint8_t *mTlvs;
|
||||
uint8_t mLength;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class represents mutable Network Data.
|
||||
*
|
||||
*/
|
||||
class MutableNetworkData : public NetworkData
|
||||
{
|
||||
friend class NetworkData;
|
||||
friend class Service::Manager;
|
||||
friend class Publisher;
|
||||
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes the `MutableNetworkData`
|
||||
*
|
||||
* @param[in] aInstance A reference to the OpenThread instance.
|
||||
* @param[in] aTlvs A pointer to the buffer to store the TLVs.
|
||||
* @param[in] aLength The current length of the Network Data.
|
||||
* @param[in] aSize Size of the buffer @p aTlvs (maximum length).
|
||||
*
|
||||
*/
|
||||
MutableNetworkData(Instance &aInstance, uint8_t *aTlvs, uint8_t aLength, uint8_t aSize)
|
||||
: NetworkData(aInstance, aTlvs, aLength)
|
||||
, mSize(aSize)
|
||||
{
|
||||
}
|
||||
|
||||
using NetworkData::GetBytes;
|
||||
using NetworkData::GetLength;
|
||||
|
||||
/**
|
||||
* This method returns the size of the buffer to store the mutable Network Data.
|
||||
*
|
||||
* @returns The size of the buffer.
|
||||
*
|
||||
*/
|
||||
uint8_t GetSize(void) const { return mSize; }
|
||||
|
||||
/**
|
||||
* This method returns a pointer to start of the TLVs in `NetworkData`.
|
||||
*
|
||||
* @returns A pointer to start of the TLVs.
|
||||
*
|
||||
*/
|
||||
uint8_t *GetBytes(void) { return AsNonConst(AsConst(this)->GetBytes()); }
|
||||
|
||||
/**
|
||||
* This method clears the network data.
|
||||
*
|
||||
*/
|
||||
void Clear(void) { mLength = 0; }
|
||||
|
||||
protected:
|
||||
/**
|
||||
* This method sets the Network Data length.
|
||||
*
|
||||
* @param[in] aLength The length.
|
||||
*
|
||||
*/
|
||||
void SetLength(uint8_t aLength) { mLength = aLength; }
|
||||
|
||||
using NetworkData::GetTlvsStart;
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the start of Network Data TLV sequence.
|
||||
*
|
||||
* @returns A pointer to the start of Network Data TLV sequence.
|
||||
*
|
||||
*/
|
||||
NetworkDataTlv *GetTlvsStart(void) { return AsNonConst(AsConst(this)->GetTlvsStart()); }
|
||||
|
||||
using NetworkData::GetTlvsEnd;
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the end of Network Data TLV sequence.
|
||||
*
|
||||
* @returns A pointer to the end of Network Data TLV sequence.
|
||||
*
|
||||
*/
|
||||
NetworkDataTlv *GetTlvsEnd(void) { return AsNonConst(AsConst(this)->GetTlvsEnd()); }
|
||||
|
||||
using NetworkData::FindPrefix;
|
||||
|
||||
/**
|
||||
* This method returns a pointer to a Prefix TLV.
|
||||
*
|
||||
* @param[in] aPrefix A pointer to an IPv6 prefix.
|
||||
* @param[in] aPrefixLength The prefix length pointed to by @p aPrefix (in bits).
|
||||
*
|
||||
* @returns A pointer to the Prefix TLV if one is found or nullptr if no matching Prefix TLV exists.
|
||||
*
|
||||
*/
|
||||
PrefixTlv *FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength)
|
||||
{
|
||||
return AsNonConst(AsConst(this)->FindPrefix(aPrefix, aPrefixLength));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a pointer to a Prefix TLV.
|
||||
*
|
||||
* @param[in] aPrefix An IPv6 prefix.
|
||||
*
|
||||
* @returns A pointer to the Prefix TLV if one is found or nullptr if no matching Prefix TLV exists.
|
||||
*
|
||||
*/
|
||||
PrefixTlv *FindPrefix(const Ip6::Prefix &aPrefix) { return FindPrefix(aPrefix.GetBytes(), aPrefix.GetLength()); }
|
||||
|
||||
using NetworkData::FindService;
|
||||
|
||||
/**
|
||||
* This method returns a pointer to a matching Service TLV.
|
||||
*
|
||||
* @param[in] aEnterpriseNumber Enterprise Number.
|
||||
* @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 ServiceData &aServiceData,
|
||||
ServiceMatchMode aServiceMatchMode)
|
||||
{
|
||||
return AsNonConst(AsConst(this)->FindService(aEnterpriseNumber, aServiceData, aServiceMatchMode));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 <= mSize); }
|
||||
|
||||
/**
|
||||
* This method grows the Network Data to append a TLV with a requested size.
|
||||
*
|
||||
* On success, the returned TLV is not initialized (i.e., the TLV Length field is not set) but the requested
|
||||
* size for it (@p aTlvSize number of bytes) is reserved in the Network Data.
|
||||
*
|
||||
* @param[in] aTlvSize The size of TLV (total number of bytes including Type, Length, and Value fields)
|
||||
*
|
||||
* @returns A pointer to the TLV if there is space to grow Network Data, or nullptr if no space to grow the Network
|
||||
* Data with requested @p aTlvSize number of bytes.
|
||||
*
|
||||
*/
|
||||
NetworkDataTlv *AppendTlv(uint16_t aTlvSize);
|
||||
|
||||
/**
|
||||
* This method inserts bytes into the Network Data.
|
||||
*
|
||||
* @param[in] aStart A pointer to the beginning of the insertion.
|
||||
* @param[in] aLength The number of bytes to insert.
|
||||
*
|
||||
*/
|
||||
void Insert(void *aStart, uint8_t aLength);
|
||||
|
||||
/**
|
||||
* This method removes bytes from the Network Data.
|
||||
*
|
||||
* @param[in] aRemoveStart A pointer to the beginning of the removal.
|
||||
* @param[in] aRemoveLength The number of bytes to remove.
|
||||
*
|
||||
*/
|
||||
void Remove(void *aRemoveStart, uint8_t aRemoveLength);
|
||||
|
||||
/**
|
||||
* This method removes a TLV from the Network Data.
|
||||
*
|
||||
* @param[in] aTlv The TLV to remove.
|
||||
*
|
||||
*/
|
||||
void RemoveTlv(NetworkDataTlv *aTlv);
|
||||
|
||||
/**
|
||||
* This method strips non-stable data from the Thread Network Data.
|
||||
*
|
||||
*/
|
||||
void RemoveTemporaryData(void);
|
||||
|
||||
private:
|
||||
void RemoveTemporaryDataIn(PrefixTlv &aPrefix);
|
||||
void RemoveTemporaryDataIn(ServiceTlv &aService);
|
||||
|
||||
uint8_t mSize;
|
||||
};
|
||||
|
||||
} // namespace NetworkData
|
||||
|
||||
@@ -57,7 +57,7 @@ void LeaderBase::Reset(void)
|
||||
{
|
||||
mVersion = Random::NonCrypto::GetUint8();
|
||||
mStableVersion = Random::NonCrypto::GetUint8();
|
||||
mLength = 0;
|
||||
SetLength(0);
|
||||
Get<ot::Notifier>().Signal(kEventThreadNetdataChanged);
|
||||
}
|
||||
|
||||
@@ -356,16 +356,16 @@ Error LeaderBase::SetNetworkData(uint8_t aVersion,
|
||||
|
||||
SuccessOrExit(error = aMessage.Read(aMessageOffset, tlv));
|
||||
|
||||
length = aMessage.ReadBytes(aMessageOffset + sizeof(tlv), mTlvs, tlv.GetLength());
|
||||
length = aMessage.ReadBytes(aMessageOffset + sizeof(tlv), GetBytes(), tlv.GetLength());
|
||||
VerifyOrExit(length == tlv.GetLength(), error = kErrorParse);
|
||||
|
||||
mLength = tlv.GetLength();
|
||||
SetLength(tlv.GetLength());
|
||||
mVersion = aVersion;
|
||||
mStableVersion = aStableVersion;
|
||||
|
||||
if (aStableOnly)
|
||||
{
|
||||
RemoveTemporaryData(mTlvs, mLength);
|
||||
RemoveTemporaryData();
|
||||
}
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
@@ -376,7 +376,7 @@ Error LeaderBase::SetNetworkData(uint8_t aVersion,
|
||||
}
|
||||
#endif
|
||||
|
||||
otDumpDebgNetData("set network data", mTlvs, mLength);
|
||||
otDumpDebgNetData("SetNetworkData", GetBytes(), GetLength());
|
||||
|
||||
Get<ot::Notifier>().Signal(kEventThreadNetdataChanged);
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace NetworkData {
|
||||
* This class implements the Thread Network Data maintained by the Leader.
|
||||
*
|
||||
*/
|
||||
class LeaderBase : public NetworkData
|
||||
class LeaderBase : public MutableNetworkData
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
*
|
||||
*/
|
||||
explicit LeaderBase(Instance &aInstance)
|
||||
: NetworkData(aInstance)
|
||||
: MutableNetworkData(aInstance, mTlvBuffer, 0, sizeof(mTlvBuffer))
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
@@ -290,6 +290,8 @@ private:
|
||||
uint16_t * aRloc16) const;
|
||||
Error DefaultRouteLookup(const PrefixTlv &aPrefix, uint16_t *aRloc16) const;
|
||||
Error SteeringDataCheck(const FilterIndexes &aFilterIndexes) const;
|
||||
|
||||
uint8_t mTlvBuffer[kMaxSize];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -302,7 +304,11 @@ private:
|
||||
#if OPENTHREAD_MTD
|
||||
namespace ot {
|
||||
namespace NetworkData {
|
||||
typedef class LeaderBase Leader;
|
||||
class Leader : public LeaderBase
|
||||
{
|
||||
public:
|
||||
using LeaderBase::LeaderBase;
|
||||
};
|
||||
} // namespace NetworkData
|
||||
} // namespace ot
|
||||
#elif OPENTHREAD_FTD
|
||||
|
||||
@@ -139,7 +139,7 @@ void Leader::HandleServerData(void *aContext, otMessage *aMessage, const otMessa
|
||||
|
||||
void Leader::HandleServerData(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
ThreadNetworkDataTlv networkData;
|
||||
ThreadNetworkDataTlv networkDataTlv;
|
||||
uint16_t rloc16;
|
||||
|
||||
otLogInfoNetData("Received network data registration");
|
||||
@@ -157,11 +157,15 @@ void Leader::HandleServerData(Coap::Message &aMessage, const Ip6::MessageInfo &a
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
if (Tlv::FindTlv(aMessage, networkData) == kErrorNone)
|
||||
if (Tlv::FindTlv(aMessage, networkDataTlv) == kErrorNone)
|
||||
{
|
||||
VerifyOrExit(networkData.IsValid());
|
||||
RegisterNetworkData(aMessageInfo.GetPeerAddr().GetIid().GetLocator(), networkData.GetTlvs(),
|
||||
networkData.GetLength());
|
||||
VerifyOrExit(networkDataTlv.IsValid());
|
||||
|
||||
{
|
||||
NetworkData networkData(GetInstance(), networkDataTlv.GetTlvs(), networkDataTlv.GetLength());
|
||||
|
||||
RegisterNetworkData(aMessageInfo.GetPeerAddr().GetIid().GetLocator(), networkData);
|
||||
}
|
||||
}
|
||||
|
||||
SuccessOrExit(Get<Tmf::Agent>().SendEmptyAck(aMessage, aMessageInfo));
|
||||
@@ -391,23 +395,21 @@ bool Leader::RlocMatch(uint16_t aFirstRloc16, uint16_t aSecondRloc16, MatchMode
|
||||
return matched;
|
||||
}
|
||||
|
||||
Error Leader::Validate(const uint8_t *aTlvs, uint8_t aTlvsLength, uint16_t aRloc16)
|
||||
Error Leader::Validate(const NetworkData &aNetworkData, uint16_t aRloc16)
|
||||
{
|
||||
// Validate that the `aTlvs` contains well-formed TLVs, sub-TLVs,
|
||||
// and entries all matching `aRloc16` (no other entry for other
|
||||
// RLOCs and no duplicates TLVs).
|
||||
|
||||
Error error = kErrorNone;
|
||||
const NetworkDataTlv *end = reinterpret_cast<const NetworkDataTlv *>(aTlvs + aTlvsLength);
|
||||
const NetworkDataTlv *end = aNetworkData.GetTlvsEnd();
|
||||
|
||||
for (const NetworkDataTlv *cur = reinterpret_cast<const NetworkDataTlv *>(aTlvs); cur < end; cur = cur->GetNext())
|
||||
for (const NetworkDataTlv *cur = aNetworkData.GetTlvsStart(); cur < end; cur = cur->GetNext())
|
||||
{
|
||||
uint8_t offset;
|
||||
NetworkData validatedSegment(aNetworkData.GetInstance(), aNetworkData.GetTlvsStart(), cur);
|
||||
|
||||
VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end, error = kErrorParse);
|
||||
|
||||
offset = static_cast<uint8_t>(reinterpret_cast<const uint8_t *>(cur) - aTlvs);
|
||||
|
||||
switch (cur->GetType())
|
||||
{
|
||||
case NetworkDataTlv::kTypePrefix:
|
||||
@@ -417,7 +419,7 @@ Error Leader::Validate(const uint8_t *aTlvs, uint8_t aTlvsLength, uint16_t aRloc
|
||||
VerifyOrExit(prefix->IsValid(), error = kErrorParse);
|
||||
|
||||
// Ensure there is no duplicate Prefix TLVs with same prefix.
|
||||
VerifyOrExit(FindPrefix(prefix->GetPrefix(), prefix->GetPrefixLength(), aTlvs, offset) == nullptr,
|
||||
VerifyOrExit(validatedSegment.FindPrefix(prefix->GetPrefix(), prefix->GetPrefixLength()) == nullptr,
|
||||
error = kErrorParse);
|
||||
|
||||
SuccessOrExit(error = ValidatePrefix(*prefix, aRloc16));
|
||||
@@ -435,8 +437,8 @@ Error Leader::Validate(const uint8_t *aTlvs, uint8_t aTlvsLength, uint16_t aRloc
|
||||
|
||||
// Ensure there is no duplicate Service TLV with same
|
||||
// Enterprise Number and Service Data.
|
||||
VerifyOrExit(FindService(service->GetEnterpriseNumber(), serviceData, kServiceExactMatch, aTlvs, offset) ==
|
||||
nullptr,
|
||||
VerifyOrExit(validatedSegment.FindService(service->GetEnterpriseNumber(), serviceData,
|
||||
kServiceExactMatch) == nullptr,
|
||||
error = kErrorParse);
|
||||
|
||||
SuccessOrExit(error = ValidateService(*service, aRloc16));
|
||||
@@ -695,24 +697,23 @@ exit:
|
||||
return status;
|
||||
}
|
||||
|
||||
void Leader::RegisterNetworkData(uint16_t aRloc16, const uint8_t *aTlvs, uint8_t aTlvsLength)
|
||||
void Leader::RegisterNetworkData(uint16_t aRloc16, const NetworkData &aNetworkData)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
const NetworkDataTlv *end = reinterpret_cast<const NetworkDataTlv *>(aTlvs + aTlvsLength);
|
||||
ChangedFlags flags;
|
||||
Error error = kErrorNone;
|
||||
ChangedFlags flags;
|
||||
|
||||
VerifyOrExit(Get<RouterTable>().IsAllocated(Mle::Mle::RouterIdFromRloc16(aRloc16)), error = kErrorNoRoute);
|
||||
|
||||
// Validate that the `aTlvs` contains well-formed TLVs, sub-TLVs,
|
||||
// Validate that the `aNetworkData` contains well-formed TLVs, sub-TLVs,
|
||||
// and entries all matching `aRloc16` (no other RLOCs).
|
||||
SuccessOrExit(error = Validate(aTlvs, aTlvsLength, aRloc16));
|
||||
SuccessOrExit(error = Validate(aNetworkData, aRloc16));
|
||||
|
||||
// Remove all entries matching `aRloc16` excluding entries that are
|
||||
// present in `aTlvs`
|
||||
RemoveRloc(aRloc16, kMatchModeRloc16, aTlvs, aTlvsLength, flags);
|
||||
// present in `aNetworkData`
|
||||
RemoveRloc(aRloc16, kMatchModeRloc16, aNetworkData, flags);
|
||||
|
||||
// Now add all new entries in `aTlvs` to Network Data.
|
||||
for (const NetworkDataTlv *cur = reinterpret_cast<const NetworkDataTlv *>(aTlvs); cur < end; cur = cur->GetNext())
|
||||
for (const NetworkDataTlv *cur = aNetworkData.GetTlvsStart(); cur < aNetworkData.GetTlvsEnd(); cur = cur->GetNext())
|
||||
{
|
||||
switch (cur->GetType())
|
||||
{
|
||||
@@ -731,7 +732,7 @@ void Leader::RegisterNetworkData(uint16_t aRloc16, const uint8_t *aTlvs, uint8_t
|
||||
|
||||
IncrementVersions(flags);
|
||||
|
||||
otDumpDebgNetData("add done", mTlvs, mLength);
|
||||
otDumpDebgNetData("Register", GetBytes(), GetLength());
|
||||
|
||||
exit:
|
||||
|
||||
@@ -1045,20 +1046,21 @@ void Leader::StopContextReuseTimer(uint8_t aContextId)
|
||||
|
||||
void Leader::RemoveRloc(uint16_t aRloc16, MatchMode aMatchMode, ChangedFlags &aChangedFlags)
|
||||
{
|
||||
RemoveRloc(aRloc16, aMatchMode, nullptr, 0, aChangedFlags);
|
||||
NetworkData excludeNetworkData(GetInstance()); // Empty network data.
|
||||
|
||||
RemoveRloc(aRloc16, aMatchMode, excludeNetworkData, aChangedFlags);
|
||||
}
|
||||
|
||||
void Leader::RemoveRloc(uint16_t aRloc16,
|
||||
MatchMode aMatchMode,
|
||||
const uint8_t *aExcludeTlvs,
|
||||
uint8_t aExcludeTlvsLength,
|
||||
ChangedFlags & aChangedFlags)
|
||||
void Leader::RemoveRloc(uint16_t aRloc16,
|
||||
MatchMode aMatchMode,
|
||||
const NetworkData &aExcludeNetworkData,
|
||||
ChangedFlags & aChangedFlags)
|
||||
{
|
||||
// Remove entries from Network Data matching `aRloc16` (using
|
||||
// `aMatchMode` to determine the match) but exclude any entries
|
||||
// that are present in `aExcludeTlvs`. As entries are removed
|
||||
// update `aChangedFlags` to indicate if Network Data (stable or
|
||||
// not) got changed.
|
||||
// that are present in `aExcludeNetworkData`. As entries are
|
||||
// removed update `aChangedFlags` to indicate if Network Data
|
||||
// (stable or not) got changed.
|
||||
|
||||
NetworkDataTlv *cur = GetTlvsStart();
|
||||
|
||||
@@ -1070,7 +1072,7 @@ void Leader::RemoveRloc(uint16_t aRloc16,
|
||||
{
|
||||
PrefixTlv * prefix = static_cast<PrefixTlv *>(cur);
|
||||
const PrefixTlv *excludePrefix =
|
||||
FindPrefix(prefix->GetPrefix(), prefix->GetPrefixLength(), aExcludeTlvs, aExcludeTlvsLength);
|
||||
aExcludeNetworkData.FindPrefix(prefix->GetPrefix(), prefix->GetPrefixLength());
|
||||
|
||||
RemoveRlocInPrefix(*prefix, aRloc16, aMatchMode, excludePrefix, aChangedFlags);
|
||||
|
||||
@@ -1091,8 +1093,8 @@ void Leader::RemoveRloc(uint16_t aRloc16,
|
||||
|
||||
service->GetServiceData(serviceData);
|
||||
|
||||
excludeService = FindService(service->GetEnterpriseNumber(), serviceData, kServiceExactMatch, aExcludeTlvs,
|
||||
aExcludeTlvsLength);
|
||||
excludeService =
|
||||
aExcludeNetworkData.FindService(service->GetEnterpriseNumber(), serviceData, kServiceExactMatch);
|
||||
|
||||
RemoveRlocInService(*service, aRloc16, aMatchMode, excludeService, aChangedFlags);
|
||||
|
||||
@@ -1111,8 +1113,6 @@ void Leader::RemoveRloc(uint16_t aRloc16,
|
||||
|
||||
cur = cur->GetNext();
|
||||
}
|
||||
|
||||
otDumpDebgNetData("remove done", mTlvs, mLength);
|
||||
}
|
||||
|
||||
void Leader::RemoveRlocInPrefix(PrefixTlv & aPrefix,
|
||||
|
||||
@@ -209,7 +209,7 @@ private:
|
||||
static void HandleTimer(Timer &aTimer);
|
||||
void HandleTimer(void);
|
||||
|
||||
void RegisterNetworkData(uint16_t aRloc16, const uint8_t *aTlvs, uint8_t aTlvsLength);
|
||||
void RegisterNetworkData(uint16_t aRloc16, const NetworkData &aNetworkData);
|
||||
|
||||
Error AddPrefix(const PrefixTlv &aPrefix, ChangedFlags &aChangedFlags);
|
||||
Error AddHasRoute(const HasRouteTlv &aHasRoute, PrefixTlv &aDstPrefix, ChangedFlags &aChangedFlags);
|
||||
@@ -230,11 +230,10 @@ private:
|
||||
void RemoveCommissioningData(void);
|
||||
|
||||
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 RemoveRloc(uint16_t aRloc16,
|
||||
MatchMode aMatchMode,
|
||||
const NetworkData &aExcludeNetworkData,
|
||||
ChangedFlags & aChangedFlags);
|
||||
void RemoveRlocInPrefix(PrefixTlv & aPrefix,
|
||||
uint16_t aRloc16,
|
||||
MatchMode aMatchMode,
|
||||
@@ -260,7 +259,7 @@ private:
|
||||
|
||||
static bool RlocMatch(uint16_t aFirstRloc16, uint16_t aSecondRloc16, MatchMode aMatchMode);
|
||||
|
||||
static Error Validate(const uint8_t *aTlvs, uint8_t aTlvsLength, uint16_t aRloc16);
|
||||
static Error Validate(const NetworkData &aNetworkData, uint16_t aRloc16);
|
||||
static Error ValidatePrefix(const PrefixTlv &aPrefix, uint16_t aRloc16);
|
||||
static Error ValidateService(const ServiceTlv &aService, uint16_t aRloc16);
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ Error Local::AddPrefix(const Ip6::Prefix &aPrefix, NetworkDataTlv::Type aSubTlvT
|
||||
prefixTlv->GetSubTlvs()->SetStable();
|
||||
}
|
||||
|
||||
otDumpDebgNetData("add prefix done", mTlvs, mLength);
|
||||
otDumpDebgNetData("AddPrefix", GetBytes(), GetLength());
|
||||
|
||||
exit:
|
||||
return error;
|
||||
@@ -141,7 +141,7 @@ Error Local::RemovePrefix(const Ip6::Prefix &aPrefix, NetworkDataTlv::Type aSubT
|
||||
RemoveTlv(tlv);
|
||||
|
||||
exit:
|
||||
otDumpDebgNetData("remove done", mTlvs, mLength);
|
||||
otDumpDebgNetData("RmvPrefix", GetBytes(), GetLength());
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ Error Local::AddService(uint32_t aEnterpriseNumber,
|
||||
serverTlv->SetStable();
|
||||
}
|
||||
|
||||
otDumpDebgNetData("add service done", mTlvs, mLength);
|
||||
otDumpDebgNetData("AddService", GetBytes(), GetLength());
|
||||
|
||||
exit:
|
||||
return error;
|
||||
@@ -232,7 +232,7 @@ Error Local::RemoveService(uint32_t aEnterpriseNumber, const ServiceData &aServi
|
||||
RemoveTlv(tlv);
|
||||
|
||||
exit:
|
||||
otDumpDebgNetData("remove service done", mTlvs, mLength);
|
||||
otDumpDebgNetData("RmvService", GetBytes(), GetLength());
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace NetworkData {
|
||||
* This class implements the Thread Network Data contributed by the local device.
|
||||
*
|
||||
*/
|
||||
class Local : public NetworkData, private NonCopyable
|
||||
class Local : public MutableNetworkData, private NonCopyable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
*
|
||||
*/
|
||||
explicit Local(Instance &aInstance)
|
||||
: NetworkData(aInstance)
|
||||
: MutableNetworkData(aInstance, mTlvBuffer, 0, sizeof(mTlvBuffer))
|
||||
, mOldRloc(Mac::kShortAddrInvalid)
|
||||
{
|
||||
}
|
||||
@@ -181,6 +181,7 @@ private:
|
||||
bool IsServiceConsistent(void) const;
|
||||
#endif
|
||||
|
||||
uint8_t mTlvBuffer[kMaxSize];
|
||||
uint16_t mOldRloc;
|
||||
};
|
||||
|
||||
|
||||
@@ -355,11 +355,9 @@ Error NetworkDiagnostic::FillRequestedTlvs(const Message & aRequest,
|
||||
|
||||
case NetworkDiagnosticTlv::kNetworkData:
|
||||
{
|
||||
uint8_t netData[NetworkData::NetworkData::kMaxSize];
|
||||
uint8_t length = sizeof(netData);
|
||||
NetworkData::NetworkData &netData = Get<NetworkData::Leader>();
|
||||
|
||||
IgnoreError(Get<NetworkData::Leader>().GetNetworkData(/* aStableOnly */ false, netData, length));
|
||||
SuccessOrExit(error = Tlv::Append<NetworkDataTlv>(aResponse, netData, length));
|
||||
SuccessOrExit(error = Tlv::Append<NetworkDataTlv>(aResponse, netData.GetBytes(), netData.GetLength()));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,17 +64,6 @@ bool CompareExternalRouteConfig(const otExternalRouteConfig &aConfig1, const otE
|
||||
|
||||
void TestNetworkDataIterator(void)
|
||||
{
|
||||
class TestNetworkData : public NetworkData
|
||||
{
|
||||
public:
|
||||
TestNetworkData(ot::Instance *aInstance, const uint8_t *aTlvs, uint8_t aTlvsLength)
|
||||
: NetworkData(*aInstance)
|
||||
{
|
||||
memcpy(mTlvs, aTlvs, aTlvsLength);
|
||||
mLength = aTlvsLength;
|
||||
}
|
||||
};
|
||||
|
||||
ot::Instance * instance;
|
||||
Iterator iter = kIteratorInit;
|
||||
ExternalRouteConfig config;
|
||||
@@ -115,7 +104,7 @@ void TestNetworkDataIterator(void)
|
||||
},
|
||||
};
|
||||
|
||||
TestNetworkData netData(instance, kNetworkData, sizeof(kNetworkData));
|
||||
NetworkData netData(*instance, kNetworkData, sizeof(kNetworkData));
|
||||
|
||||
iter = OT_NETWORK_DATA_ITERATOR_INIT;
|
||||
|
||||
@@ -201,7 +190,7 @@ void TestNetworkDataIterator(void)
|
||||
},
|
||||
};
|
||||
|
||||
TestNetworkData netData(instance, kNetworkData, sizeof(kNetworkData));
|
||||
NetworkData netData(*instance, kNetworkData, sizeof(kNetworkData));
|
||||
|
||||
iter = OT_NETWORK_DATA_ITERATOR_INIT;
|
||||
|
||||
@@ -276,7 +265,7 @@ public:
|
||||
SuccessOrQuit(AddService(serviceData4));
|
||||
SuccessOrQuit(AddService(serviceData5));
|
||||
|
||||
DumpBuffer("netdata", mTlvs, mLength);
|
||||
DumpBuffer("netdata", GetBytes(), GetLength());
|
||||
|
||||
// Iterate through all entries that start with { 0x02 } (kServiceData1)
|
||||
tlv = nullptr;
|
||||
@@ -334,8 +323,8 @@ void TestNetworkDataDsnSrpServices(void)
|
||||
public:
|
||||
void Populate(const uint8_t *aTlvs, uint8_t aTlvsLength)
|
||||
{
|
||||
memcpy(mTlvs, aTlvs, aTlvsLength);
|
||||
mLength = aTlvsLength;
|
||||
memcpy(GetBytes(), aTlvs, aTlvsLength);
|
||||
SetLength(aTlvsLength);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user