From c661791e87cb308bb8e6f45197cbf5efe1d653ec Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Tue, 7 Mar 2023 10:10:02 -0800 Subject: [PATCH] [netdata] mechanism to track max Network Data length since start/reset (#8826) This commit adds new mechanism in `NetworkData::Leader` to track the the maximum observed length of the Thread Network Data since OT stack initialization or since the last time user reset the tracking mechanism by calling `otNetDataResetMaxLength()`. This commit also adds public OT API and CLI commands for this. --- include/openthread/instance.h | 2 +- include/openthread/netdata.h | 45 ++++++++++++-- src/cli/README_NETDATA.md | 40 ++++++++++++- src/cli/cli_network_data.cpp | 65 ++++++++++++++++++++- src/core/api/netdata_api.cpp | 15 +++++ src/core/thread/network_data_leader.cpp | 12 +++- src/core/thread/network_data_leader.hpp | 21 +++++++ src/core/thread/network_data_leader_ftd.cpp | 2 +- 8 files changed, 189 insertions(+), 13 deletions(-) diff --git a/include/openthread/instance.h b/include/openthread/instance.h index 2e137bc94..5ad1b256a 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -53,7 +53,7 @@ extern "C" { * @note This number versions both OpenThread platform and user APIs. * */ -#define OPENTHREAD_API_VERSION (294) +#define OPENTHREAD_API_VERSION (295) /** * @addtogroup api-instance diff --git a/include/openthread/netdata.h b/include/openthread/netdata.h index 12c48e817..c3c22c6c8 100644 --- a/include/openthread/netdata.h +++ b/include/openthread/netdata.h @@ -125,7 +125,7 @@ typedef struct otServiceConfig } otServiceConfig; /** - * This method provides a full or stable copy of the Partition's Thread Network Data. + * Provide full or stable copy of the Partition's Thread Network Data. * * @param[in] aInstance A pointer to an OpenThread instance. * @param[in] aStable TRUE when copying the stable version, FALSE when copying the full version. @@ -133,11 +133,45 @@ typedef struct otServiceConfig * @param[in,out] aDataLength On entry, size of the data buffer pointed to by @p aData. * On exit, number of copied bytes. * + * @retval OT_ERROR_NONE Successfully copied the Thread Network Data into @p aData and updated @p aDataLength. + * @retval OT_ERROR_NO_BUFS Not enough space in @p aData to fully copy the Thread Network Data. + * */ otError otNetDataGet(otInstance *aInstance, bool aStable, uint8_t *aData, uint8_t *aDataLength); /** - * This function gets the next On Mesh Prefix in the partition's Network Data. + * Get the current length (number of bytes) of Partition's Thread Network Data. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * + * @return The length of the Network Data. + * + */ +uint8_t otNetDataGetLength(otInstance *aInstance); + +/** + * Get the maximum observed length of the Thread Network Data since OT stack initialization or since the last call to + * `otNetDataResetMaxLength()`. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * + * @return The maximum length of the Network Data (high water mark for Network Data length). + * + */ +uint8_t otNetDataGetMaxLength(otInstance *aInstance); + +/** + * Reset the tracked maximum length of the Thread Network Data. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * + * @sa otNetDataGetMaxLength + * + */ +void otNetDataResetMaxLength(otInstance *aInstance); + +/** + * Get the next On Mesh Prefix in the partition's Network Data. * * @param[in] aInstance A pointer to an OpenThread instance. * @param[in,out] aIterator A pointer to the Network Data iterator context. To get the first on-mesh entry @@ -153,7 +187,7 @@ otError otNetDataGetNextOnMeshPrefix(otInstance *aInstance, otBorderRouterConfig *aConfig); /** - * This function gets the next external route in the partition's Network Data. + * Get the next external route in the partition's Network Data. * * @param[in] aInstance A pointer to an OpenThread instance. * @param[in,out] aIterator A pointer to the Network Data iterator context. To get the first external route entry @@ -167,7 +201,7 @@ otError otNetDataGetNextOnMeshPrefix(otInstance *aInstance, otError otNetDataGetNextRoute(otInstance *aInstance, otNetworkDataIterator *aIterator, otExternalRouteConfig *aConfig); /** - * This function gets the next service in the partition's Network Data. + * Get the next service in the partition's Network Data. * * @param[in] aInstance A pointer to an OpenThread instance. * @param[in,out] aIterator A pointer to the Network Data iterator context. To get the first service entry @@ -231,8 +265,7 @@ otError otNetDataSteeringDataCheckJoinerWithDiscerner(otInstance const struct otJoinerDiscerner *aDiscerner); /** - * This function checks whether a given Prefix can act as a valid OMR prefix and also the Leader's Network Data contains - * this prefix. + * Check whether a given Prefix can act as a valid OMR prefix and also the Leader's Network Data contains this prefix. * * @param[in] aInstance A pointer to an OpenThread instance. * @param[in] aPrefix A pointer to the IPv6 prefix. diff --git a/src/cli/README_NETDATA.md b/src/cli/README_NETDATA.md index 68c3b43f7..ecef75e24 100644 --- a/src/cli/README_NETDATA.md +++ b/src/cli/README_NETDATA.md @@ -142,6 +142,8 @@ After the device successfully attaches to a Thread network, the device will retr ## Command List - [help](#help) +- [length](#length) +- [maxlength](#maxlength) - [publish](#publish) - [register](#register) - [show](#show) @@ -158,7 +160,8 @@ Print netdata help menu. ```bash > netdata help -help +length +maxlength publish register show @@ -167,6 +170,41 @@ unpublish Done ``` +### length + +Usage: `netdata length` + +Get the current length of (number of bytes) Partition's Thread Network Data. + +```bash +> netdata length +23 +Done +``` + +### maxlength + +Usage: `netdata maxlength` + +Get the maximum observed length of the Thread Network Data since OT stack initialization or since the last call to `netdata maxlength reset`. + +```bash +> netdata maxlength +40 +Done +``` + +### maxlength reset + +Usage: `netdata maxlength reset` + +Reset the tracked maximum length of the Thread Network Data. + +```bash +> netdata maxlength reset +Done +``` + ### publish The Network Data Publisher provides mechanisms to limit the number of similar Service and/or Prefix (on-mesh prefix or external route) entries in the Thread Network Data by monitoring the Network Data and managing if or when to add or remove entries. diff --git a/src/cli/cli_network_data.cpp b/src/cli/cli_network_data.cpp index dd62395f3..c28deb71a 100644 --- a/src/cli/cli_network_data.cpp +++ b/src/cli/cli_network_data.cpp @@ -159,6 +159,66 @@ void NetworkData::OutputService(const otServiceConfig &aConfig) OutputLine(" %04x", aConfig.mServerConfig.mRloc16); } +/** + * @cli netdata length + * @code + * netdata length + * 23 + * Done + * @endcode + * @par api_copy + * #otNetDataGetLength + */ +template <> otError NetworkData::Process(Arg aArgs[]) +{ + otError error = OT_ERROR_NONE; + + VerifyOrExit(aArgs[0].IsEmpty(), error = OT_ERROR_INVALID_ARGS); + OutputLine("%u", otNetDataGetLength(GetInstancePtr())); + +exit: + return error; +} + +template <> otError NetworkData::Process(Arg aArgs[]) +{ + otError error = OT_ERROR_NONE; + + /** + * @cli netdata maxlength + * @code + * netdata maxlength + * 40 + * Done + * @endcode + * @par api_copy + * #otNetDataGetMaxLength + */ + if (aArgs[0].IsEmpty()) + { + OutputLine("%u", otNetDataGetMaxLength(GetInstancePtr())); + } + /** + * @cli netdata maxlength reset + * @code + * netdata maxlength reset + * Done + * @endcode + * @par api_copy + * #otNetDataResetMaxLength + */ + else if (aArgs[0] == "reset") + { + otNetDataResetMaxLength(GetInstancePtr()); + } + else + { + error = OT_ERROR_INVALID_ARGS; + } + + return error; +} + #if OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE template <> otError NetworkData::Process(Arg aArgs[]) { @@ -669,6 +729,8 @@ otError NetworkData::Process(Arg aArgs[]) } static constexpr Command kCommands[] = { + CmdEntry("length"), + CmdEntry("maxlength"), #if OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE CmdEntry("publish"), #endif @@ -693,7 +755,8 @@ otError NetworkData::Process(Arg aArgs[]) * @cli netdata help * @code * netdata help - * help + * length + * maxlength * publish * register * show diff --git a/src/core/api/netdata_api.cpp b/src/core/api/netdata_api.cpp index 39259f6eb..9325ee255 100644 --- a/src/core/api/netdata_api.cpp +++ b/src/core/api/netdata_api.cpp @@ -49,6 +49,21 @@ otError otNetDataGet(otInstance *aInstance, bool aStable, uint8_t *aData, uint8_ aStable ? NetworkData::kStableSubset : NetworkData::kFullSet, aData, *aDataLength); } +uint8_t otNetDataGetLength(otInstance *aInstance) +{ + return AsCoreType(aInstance).Get().GetLength(); +} + +uint8_t otNetDataGetMaxLength(otInstance *aInstance) +{ + return AsCoreType(aInstance).Get().GetMaxLength(); +} + +void otNetDataResetMaxLength(otInstance *aInstance) +{ + AsCoreType(aInstance).Get().ResetMaxLength(); +} + otError otNetDataGetNextOnMeshPrefix(otInstance *aInstance, otNetworkDataIterator *aIterator, otBorderRouterConfig *aConfig) diff --git a/src/core/thread/network_data_leader.cpp b/src/core/thread/network_data_leader.cpp index 9eca3a2e7..95d20ba6b 100644 --- a/src/core/thread/network_data_leader.cpp +++ b/src/core/thread/network_data_leader.cpp @@ -60,7 +60,7 @@ void LeaderBase::Reset(void) mVersion = Random::NonCrypto::GetUint8(); mStableVersion = Random::NonCrypto::GetUint8(); SetLength(0); - Get().Signal(kEventThreadNetdataChanged); + SignalNetDataChanged(); } Error LeaderBase::GetServiceId(uint32_t aEnterpriseNumber, @@ -412,7 +412,7 @@ Error LeaderBase::SetNetworkData(uint8_t aVersion, DumpDebg("SetNetworkData", GetBytes(), GetLength()); - Get().Signal(kEventThreadNetdataChanged); + SignalNetDataChanged(); exit: return error; @@ -437,7 +437,7 @@ Error LeaderBase::SetCommissioningData(const uint8_t *aValue, uint8_t aValueLeng } mVersion++; - Get().Signal(kEventThreadNetdataChanged); + SignalNetDataChanged(); exit: return error; @@ -532,5 +532,11 @@ Error LeaderBase::SteeringDataCheckJoiner(const MeshCoP::JoinerDiscerner &aDisce return SteeringDataCheck(filterIndexes); } +void LeaderBase::SignalNetDataChanged(void) +{ + mMaxLength = Max(mMaxLength, GetLength()); + Get().Signal(kEventThreadNetdataChanged); +} + } // namespace NetworkData } // namespace ot diff --git a/src/core/thread/network_data_leader.hpp b/src/core/thread/network_data_leader.hpp index bbf7c3f90..92dae9382 100644 --- a/src/core/thread/network_data_leader.hpp +++ b/src/core/thread/network_data_leader.hpp @@ -74,6 +74,7 @@ public: */ explicit LeaderBase(Instance &aInstance) : MutableNetworkData(aInstance, mTlvBuffer, 0, sizeof(mTlvBuffer)) + , mMaxLength(0) { Reset(); } @@ -84,6 +85,23 @@ public: */ void Reset(void); + /** + * This method returns the maximum observed Network Data length since OT stack initialization or since the last + * call to `ResetMaxLength()`. + * + * @returns The maximum observed Network Data length (high water mark for Network Data length). + * + */ + uint8_t GetMaxLength(void) const { return mMaxLength; } + + /** + * This method resets the tracked maximum Network Data Length. + * + * @sa GetMaxLength + * + */ + void ResetMaxLength(void) { mMaxLength = GetLength(); } + /** * This method returns the Data Version value for a type (full set or stable subset). * @@ -280,6 +298,8 @@ public: Error GetPreferredNat64Prefix(ExternalRouteConfig &aConfig) const; protected: + void SignalNetDataChanged(void); + uint8_t mStableVersion; uint8_t mVersion; @@ -302,6 +322,7 @@ private: void GetContextForMeshLocalPrefix(Lowpan::Context &aContext) const; uint8_t mTlvBuffer[kMaxSize]; + uint8_t mMaxLength; }; /** diff --git a/src/core/thread/network_data_leader_ftd.cpp b/src/core/thread/network_data_leader_ftd.cpp index a33c8ba56..e85946a90 100644 --- a/src/core/thread/network_data_leader_ftd.cpp +++ b/src/core/thread/network_data_leader_ftd.cpp @@ -117,7 +117,7 @@ void Leader::IncrementVersions(bool aIncludeStable) } mVersion++; - Get().Signal(kEventThreadNetdataChanged); + SignalNetDataChanged(); } void Leader::RemoveBorderRouter(uint16_t aRloc16, MatchMode aMatchMode)