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)