From 5b8ee97450408c19100c411e0ef972692d8560a9 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Mon, 20 Sep 2021 22:47:11 -0700 Subject: [PATCH] [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. --- src/core/api/border_router_api.cpp | 4 +- src/core/api/netdata_api.cpp | 4 +- src/core/api/server_api.cpp | 4 +- src/core/thread/mle.cpp | 2 +- src/core/thread/network_data.cpp | 107 ++--- src/core/thread/network_data.hpp | 475 +++++++++++--------- src/core/thread/network_data_leader.cpp | 10 +- src/core/thread/network_data_leader.hpp | 12 +- src/core/thread/network_data_leader_ftd.cpp | 76 ++-- src/core/thread/network_data_leader_ftd.hpp | 13 +- src/core/thread/network_data_local.cpp | 8 +- src/core/thread/network_data_local.hpp | 5 +- src/core/thread/network_diagnostic.cpp | 6 +- tests/unit/test_network_data.cpp | 21 +- 14 files changed, 378 insertions(+), 369 deletions(-) diff --git a/src/core/api/border_router_api.cpp b/src/core/api/border_router_api.cpp index 9fb24cd07..69fd09701 100644 --- a/src/core/api/border_router_api.cpp +++ b/src/core/api/border_router_api.cpp @@ -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().GetNetworkData(aStable, aData, *aDataLength); + return AsCoreType(aInstance).Get().CopyNetworkData(aStable, aData, *aDataLength); } otError otBorderRouterAddOnMeshPrefix(otInstance *aInstance, const otBorderRouterConfig *aConfig) diff --git a/src/core/api/netdata_api.cpp b/src/core/api/netdata_api.cpp index d42ce20a1..de2424250 100644 --- a/src/core/api/netdata_api.cpp +++ b/src/core/api/netdata_api.cpp @@ -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().GetNetworkData(aStable, aData, *aDataLength); + return AsCoreType(aInstance).Get().CopyNetworkData(aStable, aData, *aDataLength); } otError otNetDataGetNextOnMeshPrefix(otInstance * aInstance, diff --git a/src/core/api/server_api.cpp b/src/core/api/server_api.cpp index 1e0576fe3..bf08e9c86 100644 --- a/src/core/api/server_api.cpp +++ b/src/core/api/server_api.cpp @@ -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().GetNetworkData(aStable, aData, *aDataLength); + return AsCoreType(aInstance).Get().CopyNetworkData(aStable, aData, *aDataLength); } otError otServerAddService(otInstance *aInstance, const otServiceConfig *aConfig) diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 2aaa809f0..8e9cc28d8 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -1199,7 +1199,7 @@ Error Mle::AppendNetworkData(Message &aMessage, bool aStableOnly) VerifyOrExit(!mRetrieveNewNetworkData, error = kErrorInvalidState); length = sizeof(networkData); - IgnoreError(Get().GetNetworkData(aStableOnly, networkData, length)); + IgnoreError(Get().CopyNetworkData(aStableOnly, networkData, length)); error = Tlv::Append(aMessage, networkData, length); diff --git a/src/core/thread/network_data.cpp b/src/core/thread/network_data.cpp index 7d54d74a0..e950357b6 100644 --- a/src/core/thread/network_data.cpp +++ b/src/core/thread/network_data.cpp @@ -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(aData); + NetworkDataTlv *cur = GetTlvsStart(); - while (cur < reinterpret_cast(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(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(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()) != 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()) != nullptr) @@ -604,7 +594,7 @@ const ServiceTlv *NetworkData::FindNextService(const ServiceTlv * aPrevServiceTl length = static_cast((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(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(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(dataEnd - removeEnd)); - aDataLength -= aRemoveLength; + memmove(removeStart, removeEnd, static_cast(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(aTlv), aTlv->GetSize()); -} - -void NetworkData::Remove(void *aRemoveStart, uint8_t aRemoveLength) -{ - NetworkData::Remove(mTlvs, mLength, reinterpret_cast(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; diff --git a/src/core/thread/network_data.hpp b/src/core/thread/network_data.hpp index c5e304ea4..61a85156a 100644 --- a/src/core/thread/network_data.hpp +++ b/src/core/thread/network_data.hpp @@ -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(aStartTlv)) + , mLength(static_cast(reinterpret_cast(aEndTlv) - + reinterpret_cast(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(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(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(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(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 diff --git a/src/core/thread/network_data_leader.cpp b/src/core/thread/network_data_leader.cpp index 60447eb39..fec66ce3d 100644 --- a/src/core/thread/network_data_leader.cpp +++ b/src/core/thread/network_data_leader.cpp @@ -57,7 +57,7 @@ void LeaderBase::Reset(void) { mVersion = Random::NonCrypto::GetUint8(); mStableVersion = Random::NonCrypto::GetUint8(); - mLength = 0; + SetLength(0); Get().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().Signal(kEventThreadNetdataChanged); diff --git a/src/core/thread/network_data_leader.hpp b/src/core/thread/network_data_leader.hpp index aeeb5b0a2..e5c6ee736 100644 --- a/src/core/thread/network_data_leader.hpp +++ b/src/core/thread/network_data_leader.hpp @@ -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 diff --git a/src/core/thread/network_data_leader_ftd.cpp b/src/core/thread/network_data_leader_ftd.cpp index 5f5f47acc..3c2840938 100644 --- a/src/core/thread/network_data_leader_ftd.cpp +++ b/src/core/thread/network_data_leader_ftd.cpp @@ -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().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(aTlvs + aTlvsLength); + const NetworkDataTlv *end = aNetworkData.GetTlvsEnd(); - for (const NetworkDataTlv *cur = reinterpret_cast(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(reinterpret_cast(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(aTlvs + aTlvsLength); - ChangedFlags flags; + Error error = kErrorNone; + ChangedFlags flags; VerifyOrExit(Get().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(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(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, diff --git a/src/core/thread/network_data_leader_ftd.hpp b/src/core/thread/network_data_leader_ftd.hpp index 5ce0afc7d..2fecf38ed 100644 --- a/src/core/thread/network_data_leader_ftd.hpp +++ b/src/core/thread/network_data_leader_ftd.hpp @@ -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); diff --git a/src/core/thread/network_data_local.cpp b/src/core/thread/network_data_local.cpp index 7b3b9ef59..9cc7c5752 100644 --- a/src/core/thread/network_data_local.cpp +++ b/src/core/thread/network_data_local.cpp @@ -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; } diff --git a/src/core/thread/network_data_local.hpp b/src/core/thread/network_data_local.hpp index c62b60bac..de82f6896 100644 --- a/src/core/thread/network_data_local.hpp +++ b/src/core/thread/network_data_local.hpp @@ -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; }; diff --git a/src/core/thread/network_diagnostic.cpp b/src/core/thread/network_diagnostic.cpp index 14a4b2652..37aaf7963 100644 --- a/src/core/thread/network_diagnostic.cpp +++ b/src/core/thread/network_diagnostic.cpp @@ -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(); - IgnoreError(Get().GetNetworkData(/* aStableOnly */ false, netData, length)); - SuccessOrExit(error = Tlv::Append(aResponse, netData, length)); + SuccessOrExit(error = Tlv::Append(aResponse, netData.GetBytes(), netData.GetLength())); break; } diff --git a/tests/unit/test_network_data.cpp b/tests/unit/test_network_data.cpp index 143d80ce7..31438a1d1 100644 --- a/tests/unit/test_network_data.cpp +++ b/tests/unit/test_network_data.cpp @@ -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); } };