From 560940af20557e363fd0f63170df50f4bcced5b2 Mon Sep 17 00:00:00 2001 From: Li Cao Date: Thu, 27 Feb 2025 11:37:47 +0800 Subject: [PATCH] [border agent] add OT API to get Border Agent MeshCoP Service TXT data (#11291) This commit adds a new OT API `otBorderAgentGetMeshCoPServiceTxtData` to get MeshCoP Service TXT data from OT core. The intention is to facilitate the NCP property update for MeshCoP Service TXT data. With the get API, NCP property update can use the `ChangedPropsSet` way which is more robust. --- include/openthread/border_agent.h | 26 +++++++++++++++++++++++--- include/openthread/instance.h | 2 +- src/core/api/border_agent_api.cpp | 5 +++++ src/core/meshcop/border_agent.cpp | 21 +++++++++------------ src/core/meshcop/border_agent.hpp | 26 +++++++++++++++++--------- tests/nexus/test_border_agent.cpp | 25 +++++++++---------------- 6 files changed, 64 insertions(+), 41 deletions(-) diff --git a/include/openthread/border_agent.h b/include/openthread/border_agent.h index c91292fb5..920b294dc 100644 --- a/include/openthread/border_agent.h +++ b/include/openthread/border_agent.h @@ -117,6 +117,17 @@ typedef struct otBorderAgentSessionIterator uint64_t mData; } otBorderAgentSessionIterator; +#define OT_BORDER_AGENT_MESHCOP_SERVICE_TXT_DATA_MAX_LENGTH 128 + +/** + * Represents the Border Agent MeshCoP Service TXT data. + */ +typedef struct otBorderAgentMeshCoPServiceTxtData +{ + uint8_t mData[OT_BORDER_AGENT_MESHCOP_SERVICE_TXT_DATA_MAX_LENGTH]; + uint16_t mLength; +} otBorderAgentMeshCoPServiceTxtData; + /** * Indicates whether or not the Border Agent service is active and running. * @@ -149,11 +160,9 @@ uint16_t otBorderAgentGetUdpPort(otInstance *aInstance); * In specific, the 'state' includes the MeshCoP TXT data originated from the Thread network and whether the * Border Agent is Active (which can be obtained by `otBorderAgentIsActive`). * - * @param[in] aTxtData A pointer to the encoded MeshCoP TXT data originated from the Thread network. - * @param[in] aLength The length of the encoded TXT data. * @param[in] aContext A pointer to application-specific context. */ -typedef void (*otBorderAgentMeshCoPServiceChangedCallback)(const uint8_t *aTxtData, uint16_t aLength, void *aContext); +typedef void (*otBorderAgentMeshCoPServiceChangedCallback)(void *aContext); /** * Sets the callback function used by the Border Agent to notify of any changes to the state of the MeshCoP service. @@ -172,6 +181,17 @@ void otBorderAgentSetMeshCoPServiceChangedCallback(otInstance otBorderAgentMeshCoPServiceChangedCallback aCallback, void *aContext); +/** + * Gets the MeshCoP service TXT data. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * @param[out] aTxtData A pointer to a MeshCoP Service TXT data struct to get the data. + * + * @retval OT_ERROR_NONE If successfully retrieved the Border Agent MeshCoP Service TXT data. + * @retval OT_ERROR_NO_BUFS If the buffer in @p aTxtData doesn't have enough size. + */ +otError otBorderAgentGetMeshCoPServiceTxtData(otInstance *aInstance, otBorderAgentMeshCoPServiceTxtData *aTxtData); + /** * Gets the randomly generated Border Agent ID. * diff --git a/include/openthread/instance.h b/include/openthread/instance.h index 7749aac7b..117a3e887 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -52,7 +52,7 @@ extern "C" { * * @note This number versions both OpenThread platform and user APIs. */ -#define OPENTHREAD_API_VERSION (478) +#define OPENTHREAD_API_VERSION (479) /** * @addtogroup api-instance diff --git a/src/core/api/border_agent_api.cpp b/src/core/api/border_agent_api.cpp index f19c0433c..4a83ed6d6 100644 --- a/src/core/api/border_agent_api.cpp +++ b/src/core/api/border_agent_api.cpp @@ -83,6 +83,11 @@ void otBorderAgentSetMeshCoPServiceChangedCallback(otInstance AsCoreType(aInstance).Get().SetMeshCoPServiceChangedCallback(aCallback, aContext); } +otError otBorderAgentGetMeshCoPServiceTxtData(otInstance *aInstance, otBorderAgentMeshCoPServiceTxtData *aTxtData) +{ + return AsCoreType(aInstance).Get().GetMeshCoPServiceTxtData(*aTxtData); +} + const otBorderAgentCounters *otBorderAgentGetCounters(otInstance *aInstance) { return &AsCoreType(aInstance).Get().GetCounters(); diff --git a/src/core/meshcop/border_agent.cpp b/src/core/meshcop/border_agent.cpp index b7f441b9f..152699836 100644 --- a/src/core/meshcop/border_agent.cpp +++ b/src/core/meshcop/border_agent.cpp @@ -151,6 +151,13 @@ void BorderAgent::SetMeshCoPServiceChangedCallback(MeshCoPServiceChangedCallback mNotifyMeshCoPServiceChangedTask.Post(); } +Error BorderAgent::GetMeshCoPServiceTxtData(MeshCoPServiceTxtData &aTxtData) const +{ + MeshCoPTxtEncoder meshCoPTxtEncoder(GetInstance(), aTxtData); + + return meshCoPTxtEncoder.EncodeTxtData(); +} + void BorderAgent::HandleNotifierEvents(Events aEvents) { if (aEvents.Contains(kEventThreadRoleChanged)) @@ -340,18 +347,7 @@ exit: FreeMessageOnError(message, error); } -void BorderAgent::NotifyMeshCoPServiceChanged(void) -{ - MeshCoPTxtEncoder meshCoPTxtEncoder(GetInstance()); - - VerifyOrExit(mMeshCoPServiceChangedCallback.IsSet()); - SuccessOrAssert(meshCoPTxtEncoder.EncodeTxtData()); - - mMeshCoPServiceChangedCallback.Invoke(meshCoPTxtEncoder.GetTxtData(), meshCoPTxtEncoder.GetTxtDataLen()); - -exit: - return; -} +void BorderAgent::NotifyMeshCoPServiceChanged(void) { mMeshCoPServiceChangedCallback.InvokeIfSet(); } void BorderAgent::PostNotifyMeshCoPServiceChangedTask(void) { @@ -415,6 +411,7 @@ Error BorderAgent::MeshCoPTxtEncoder::EncodeTxtData(void) #if OTBR_ENABLE_BORDER_ROUTING SuccessOrExit(error = AppendOmrTxtEntry()); #endif + mTxtData.mLength = mAppender.GetAppendedLength(); exit: return error; diff --git a/src/core/meshcop/border_agent.hpp b/src/core/meshcop/border_agent.hpp index 5c65bc40e..d289af216 100644 --- a/src/core/meshcop/border_agent.hpp +++ b/src/core/meshcop/border_agent.hpp @@ -184,6 +184,18 @@ public: */ void SetMeshCoPServiceChangedCallback(MeshCoPServiceChangedCallback aCallback, void *aContext); + typedef otBorderAgentMeshCoPServiceTxtData MeshCoPServiceTxtData; + + /** + * Gets the MeshCoP service TXT data. + * + * @param[out] aTxtData A reference to a MeshCoP Service TXT data struct to get the data. + * + * @retval kErrorNone If successfully retrieved the Border Agent MeshCoP Service TXT data. + * @retval kErrorNoBufs If the buffer in @p aTxtData doesn't have enough size. + */ + Error GetMeshCoPServiceTxtData(MeshCoPServiceTxtData &aTxtData) const; + #if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE /** * Manages the ephemeral key use by Border Agent. @@ -429,9 +441,10 @@ private: class MeshCoPTxtEncoder : public InstanceLocator { public: - explicit MeshCoPTxtEncoder(Instance &aInstance) + MeshCoPTxtEncoder(Instance &aInstance, MeshCoPServiceTxtData &aTxtData) : InstanceLocator(aInstance) - , mAppender(mTxtDataBuffer, sizeof(mTxtDataBuffer)) + , mTxtData(aTxtData) + , mAppender(mTxtData.mData, sizeof(mTxtData.mData)) { } @@ -503,10 +516,6 @@ private: Error EncodeTxtData(void); - uint8_t *GetTxtData(void) { return mTxtDataBuffer; } - - uint16_t GetTxtDataLen(void) { return mAppender.GetAppendedLength(); } - private: Error AppendTxtEntry(const char *aKey, const void *aValue, uint16_t aValueLength); @@ -527,9 +536,8 @@ private: StateBitmap GetStateBitmap(void); - static constexpr uint16_t kMaxTxtDataLen = 128; - uint8_t mTxtDataBuffer[kMaxTxtDataLen]; - Appender mAppender; + MeshCoPServiceTxtData &mTxtData; + Appender mAppender; }; void Start(void); diff --git a/tests/nexus/test_border_agent.cpp b/tests/nexus/test_border_agent.cpp index 6b24280ea..587395926 100644 --- a/tests/nexus/test_border_agent.cpp +++ b/tests/nexus/test_border_agent.cpp @@ -752,15 +752,11 @@ public: { } - void HandleMeshCoPServiceChanged(const uint8_t *aTxtData, uint16_t aLength) + void HandleMeshCoPServiceChanged(void) { mIsRunning = mBorderAgent.IsRunning(); mUdpPort = mBorderAgent.GetUdpPort(); - - assert(aLength <= kMaxTxtDataLen); - - memcpy(mTxtData, aTxtData, aLength); - mTxtDataLength = aLength; + SuccessOrQuit(mBorderAgent.GetMeshCoPServiceTxtData(mTxtData)); } bool FindTxtEntry(const char *aKey, TxtEntry &aTxtEntry) @@ -768,7 +764,7 @@ public: bool found = false; TxtEntry::Iterator iter; - iter.Init(mTxtData, mTxtDataLength); + iter.Init(mTxtData.mData, mTxtData.mLength); while (iter.GetNextEntry(aTxtEntry) == kErrorNone) { if (strcmp(aTxtEntry.mKey, aKey) == 0) @@ -781,18 +777,15 @@ public: return found; } - static constexpr uint16_t kMaxTxtDataLen = 128; - - BorderAgent &mBorderAgent; - uint8_t mTxtData[kMaxTxtDataLen]; - uint16_t mTxtDataLength; - bool mIsRunning; - uint16_t mUdpPort; + BorderAgent &mBorderAgent; + otBorderAgentMeshCoPServiceTxtData mTxtData; + bool mIsRunning; + uint16_t mUdpPort; }; -static void HandleMeshCoPServiceChanged(const uint8_t *aTxtData, uint16_t aLength, void *aContext) +static void HandleMeshCoPServiceChanged(void *aContext) { - static_cast(aContext)->HandleMeshCoPServiceChanged(aTxtData, aLength); + static_cast(aContext)->HandleMeshCoPServiceChanged(); } template bool CheckObjectSameAsTxtEntryData(const TxtEntry &aTxtEntry, const ObjectType &aObject)