mirror of
https://github.com/espressif/openthread.git
synced 2026-07-30 23:57:47 +00:00
[border-agent] move TXT data management to TxtData class (#12120)
Moves the management of MeshCoP service TXT data from the `BorderAgent::Manager` class into the `TxtData` class. This change improves separation of concerns by isolating all TXT data-related logic, including vendor TXT data, change callbacks, and notifier event handling, within the `TxtData` class. The `BorderAgent::Manager` is simplified and its responsibilities are more focused. A new public method, `Refresh()`, is introduced on `TxtData` to provide a clear API for other modules to signal that the MeshCoP service TXT data needs to be re-evaluated and updated.
This commit is contained in:
@@ -67,7 +67,7 @@ otError otBorderAgentSetMeshCoPServiceBaseName(otInstance *aInstance, const char
|
||||
|
||||
void otBorderAgentSetVendorTxtData(otInstance *aInstance, const uint8_t *aVendorData, uint16_t aVendorDataLength)
|
||||
{
|
||||
AsCoreType(aInstance).Get<MeshCoP::BorderAgent::Manager>().SetVendorTxtData(aVendorData, aVendorDataLength);
|
||||
AsCoreType(aInstance).Get<MeshCoP::BorderAgent::TxtData>().SetVendorData(aVendorData, aVendorDataLength);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -106,7 +106,7 @@ void otBorderAgentSetMeshCoPServiceChangedCallback(otInstance
|
||||
otBorderAgentMeshCoPServiceChangedCallback aCallback,
|
||||
void *aContext)
|
||||
{
|
||||
AsCoreType(aInstance).Get<MeshCoP::BorderAgent::Manager>().SetServiceChangedCallback(aCallback, aContext);
|
||||
AsCoreType(aInstance).Get<MeshCoP::BorderAgent::TxtData>().SetChangedCallback(aCallback, aContext);
|
||||
}
|
||||
|
||||
otError otBorderAgentGetMeshCoPServiceTxtData(otInstance *aInstance, otBorderAgentMeshCoPServiceTxtData *aTxtData)
|
||||
|
||||
@@ -827,7 +827,7 @@ void RoutingManager::OmrPrefixManager::SetFavoredPrefix(const OmrPrefix &aOmrPre
|
||||
if (oldFavoredPrefix != mFavoredPrefix)
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
|
||||
Get<MeshCoP::BorderAgent::Manager>().HandleFavoredOmrPrefixChanged();
|
||||
Get<MeshCoP::BorderAgent::TxtData>().Refresh();
|
||||
#endif
|
||||
LogInfo("Favored OMR prefix: %s -> %s", FavoredToString(oldFavoredPrefix).AsCString(),
|
||||
FavoredToString(mFavoredPrefix).AsCString());
|
||||
|
||||
@@ -132,6 +132,7 @@ void Notifier::EmitEvents(void)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
|
||||
Get<MeshCoP::BorderAgent::Manager>().HandleNotifierEvents(events);
|
||||
Get<MeshCoP::BorderAgent::TxtData>().HandleNotifierEvents(events);
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_MLR_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE)
|
||||
Get<MlrManager>().HandleNotifierEvents(events);
|
||||
|
||||
@@ -172,8 +172,8 @@ Instance::Instance(void)
|
||||
, mNetworkDiagnosticClient(*this)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
|
||||
, mBorderAgentManager(*this)
|
||||
, mBorderAgentTxtData(*this)
|
||||
, mBorderAgentManager(*this)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE && OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
, mBorderAgentEphemeralKeyManager(*this)
|
||||
|
||||
@@ -592,8 +592,8 @@ private:
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
|
||||
MeshCoP::BorderAgent::Manager mBorderAgentManager;
|
||||
MeshCoP::BorderAgent::TxtData mBorderAgentTxtData;
|
||||
MeshCoP::BorderAgent::Manager mBorderAgentManager;
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE && OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
|
||||
@@ -60,13 +60,11 @@ Manager::Manager(Instance &aInstance)
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
|
||||
, mIdInitialized(false)
|
||||
#endif
|
||||
, mServiceTask(aInstance)
|
||||
{
|
||||
ClearAllBytes(mCounters);
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_ENABLE
|
||||
ClearAllBytes(mServiceName);
|
||||
PostServiceTask();
|
||||
|
||||
static_assert(sizeof(kDefaultBaseServiceName) - 1 <= kBaseServiceNameMaxLen,
|
||||
"OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_BASE_NAME is too long");
|
||||
@@ -105,7 +103,8 @@ void Manager::SetId(const Id &aId)
|
||||
Get<Settings>().Save<Settings::BorderAgentId>(aId);
|
||||
mId = aId;
|
||||
mIdInitialized = true;
|
||||
PostServiceTask();
|
||||
|
||||
Get<TxtData>().Refresh();
|
||||
|
||||
exit:
|
||||
return;
|
||||
@@ -117,6 +116,9 @@ void Manager::SetEnabled(bool aEnabled)
|
||||
VerifyOrExit(mEnabled != aEnabled);
|
||||
mEnabled = aEnabled;
|
||||
LogInfo("%sabling Border Agent", mEnabled ? "En" : "Dis");
|
||||
|
||||
Get<TxtData>().Refresh();
|
||||
|
||||
UpdateState();
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_ENABLE
|
||||
@@ -160,10 +162,10 @@ void Manager::Start(void)
|
||||
pskc.Clear();
|
||||
|
||||
mIsRunning = true;
|
||||
PostServiceTask();
|
||||
|
||||
LogInfo("Border Agent start listening on port %u", GetUdpPort());
|
||||
|
||||
Get<TxtData>().Refresh();
|
||||
|
||||
exit:
|
||||
if (!mIsRunning)
|
||||
{
|
||||
@@ -179,23 +181,17 @@ void Manager::Stop(void)
|
||||
|
||||
mDtlsTransport.Close();
|
||||
mIsRunning = false;
|
||||
PostServiceTask();
|
||||
|
||||
LogInfo("Border Agent stopped");
|
||||
|
||||
Get<TxtData>().Refresh();
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t Manager::GetUdpPort(void) const { return mDtlsTransport.GetUdpPort(); }
|
||||
|
||||
void Manager::SetServiceChangedCallback(ServiceChangedCallback aCallback, void *aContext)
|
||||
{
|
||||
mServiceChangedCallback.Set(aCallback, aContext);
|
||||
|
||||
PostServiceTask();
|
||||
}
|
||||
|
||||
void Manager::HandleNotifierEvents(Events aEvents)
|
||||
{
|
||||
if (aEvents.Contains(kEventThreadRoleChanged))
|
||||
@@ -205,12 +201,6 @@ void Manager::HandleNotifierEvents(Events aEvents)
|
||||
|
||||
VerifyOrExit(mEnabled);
|
||||
|
||||
if (aEvents.ContainsAny(kEventThreadRoleChanged | kEventThreadExtPanIdChanged | kEventThreadNetworkNameChanged |
|
||||
kEventThreadBackboneRouterStateChanged | kEventActiveDatasetChanged))
|
||||
{
|
||||
PostServiceTask();
|
||||
}
|
||||
|
||||
if (aEvents.ContainsAny(kEventPskcChanged))
|
||||
{
|
||||
Pskc pskc;
|
||||
@@ -358,33 +348,6 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Manager::PostServiceTask(void)
|
||||
{
|
||||
VerifyOrExit(mEnabled);
|
||||
|
||||
#if !OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_ENABLE
|
||||
VerifyOrExit(mServiceChangedCallback.IsSet());
|
||||
#endif
|
||||
|
||||
mServiceTask.Post();
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Manager::HandleServiceTask(void)
|
||||
{
|
||||
VerifyOrExit(mEnabled);
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_ENABLE
|
||||
RegisterService();
|
||||
#endif
|
||||
mServiceChangedCallback.InvokeIfSet();
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_ENABLE
|
||||
|
||||
Error Manager::SetServiceBaseName(const char *aBaseName)
|
||||
@@ -407,17 +370,6 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void Manager::SetVendorTxtData(const uint8_t *aVendorData, uint16_t aVendorDataLength)
|
||||
{
|
||||
VerifyOrExit(!mVendorTxtData.Matches(aVendorData, aVendorDataLength));
|
||||
|
||||
SuccessOrAssert(mVendorTxtData.SetFrom(aVendorData, aVendorDataLength));
|
||||
PostServiceTask();
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
const char *Manager::GetServiceName(void)
|
||||
{
|
||||
if (IsServiceNameEmpty())
|
||||
@@ -438,6 +390,7 @@ void Manager::ConstrcutServiceName(const char *aBaseName, Dns::Name::LabelBuffer
|
||||
void Manager::RegisterService(void)
|
||||
{
|
||||
Dnssd::Service service;
|
||||
uint16_t vendorDataLength;
|
||||
uint8_t *txtDataBuffer;
|
||||
uint16_t txtDataBufferSize;
|
||||
uint16_t txtDataLength;
|
||||
@@ -450,16 +403,17 @@ void Manager::RegisterService(void)
|
||||
// TXT data. The vendor TXT Data is appended at the
|
||||
// end.
|
||||
|
||||
txtDataBufferSize = kTxtDataMaxSize + mVendorTxtData.GetLength();
|
||||
vendorDataLength = Get<TxtData>().GetVendorData().GetLength();
|
||||
txtDataBufferSize = kTxtDataMaxSize + vendorDataLength;
|
||||
txtDataBuffer = reinterpret_cast<uint8_t *>(Heap::CAlloc(txtDataBufferSize, sizeof(uint8_t)));
|
||||
OT_ASSERT(txtDataBuffer != nullptr);
|
||||
|
||||
SuccessOrAssert(Get<TxtData>().Prepare(txtDataBuffer, txtDataBufferSize, txtDataLength));
|
||||
|
||||
if (mVendorTxtData.GetLength() != 0)
|
||||
if (vendorDataLength != 0)
|
||||
{
|
||||
mVendorTxtData.CopyBytesTo(txtDataBuffer + txtDataLength);
|
||||
txtDataLength += mVendorTxtData.GetLength();
|
||||
Get<TxtData>().GetVendorData().CopyBytesTo(txtDataBuffer + txtDataLength);
|
||||
txtDataLength += vendorDataLength;
|
||||
}
|
||||
|
||||
service.Clear();
|
||||
@@ -553,16 +507,16 @@ void EphemeralKeyManager::SetEnabled(bool aEnabled)
|
||||
{
|
||||
VerifyOrExit(mState == kStateDisabled);
|
||||
SetState(kStateStopped);
|
||||
Get<Manager>().PostServiceTask();
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrExit(mState != kStateDisabled);
|
||||
Stop();
|
||||
SetState(kStateDisabled);
|
||||
Get<Manager>().PostServiceTask();
|
||||
}
|
||||
|
||||
Get<TxtData>().Refresh();
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -45,13 +45,13 @@
|
||||
#include "common/appender.hpp"
|
||||
#include "common/as_core_type.hpp"
|
||||
#include "common/heap_allocatable.hpp"
|
||||
#include "common/heap_data.hpp"
|
||||
#include "common/linked_list.hpp"
|
||||
#include "common/locator.hpp"
|
||||
#include "common/non_copyable.hpp"
|
||||
#include "common/notifier.hpp"
|
||||
#include "common/owned_ptr.hpp"
|
||||
#include "common/tasklet.hpp"
|
||||
#include "meshcop/border_agent_txt_data.hpp"
|
||||
#include "meshcop/dataset.hpp"
|
||||
#include "meshcop/secure_transport.hpp"
|
||||
#include "net/dns_types.hpp"
|
||||
@@ -102,9 +102,6 @@ struct Id : public otBorderAgentId, public Clearable<Id>, public Equatable<Id>
|
||||
|
||||
class Manager : public InstanceLocator, private NonCopyable
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
friend class ot::BorderRouter::RoutingManager;
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_ENABLE
|
||||
friend ot::Dnssd;
|
||||
#endif
|
||||
@@ -113,13 +110,13 @@ class Manager : public InstanceLocator, private NonCopyable
|
||||
#endif
|
||||
friend class ot::Notifier;
|
||||
friend class Tmf::Agent;
|
||||
friend class TxtData;
|
||||
|
||||
class CoapDtlsSession;
|
||||
|
||||
public:
|
||||
typedef otBorderAgentCounters Counters; ///< Border Agent Counters.
|
||||
typedef otBorderAgentSessionInfo SessionInfo; ///< A session info.
|
||||
typedef otBorderAgentMeshCoPServiceChangedCallback ServiceChangedCallback; ///< Service changed callback.
|
||||
typedef otBorderAgentCounters Counters; ///< Border Agent Counters.
|
||||
typedef otBorderAgentSessionInfo SessionInfo; ///< A session info.
|
||||
|
||||
/**
|
||||
* Represents an iterator for secure sessions.
|
||||
@@ -223,21 +220,6 @@ public:
|
||||
*/
|
||||
uint16_t GetUdpPort(void) const;
|
||||
|
||||
/**
|
||||
* Sets the callback function used by the Border Agent to notify any changes on the MeshCoP service TXT values.
|
||||
*
|
||||
* The callback is invoked when the state of MeshCoP service TXT values changes. For example, it is
|
||||
* invoked when the network name or the extended PAN ID changes and pass the updated encoded TXT data to the
|
||||
* application layer.
|
||||
*
|
||||
* This callback is invoked once right after this API is called to provide initial states of the MeshCoP
|
||||
* service to the application.
|
||||
*
|
||||
* @param[in] aCallback The callback to invoke when there are any changes of the MeshCoP service.
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
*/
|
||||
void SetServiceChangedCallback(ServiceChangedCallback aCallback, void *aContext);
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_ENABLE
|
||||
/**
|
||||
* Sets the base name to construct the service instance name used when advertising the mDNS `_meshcop._udp` service
|
||||
@@ -249,27 +231,6 @@ public:
|
||||
* @retval kErrorInvalidArgs The name is too long or invalid.
|
||||
*/
|
||||
Error SetServiceBaseName(const char *aBaseName);
|
||||
|
||||
/**
|
||||
* Sets the vendor extra TXT data to be included when the Border Agent advertises the mDNS `_meshcop._udp` service.
|
||||
*
|
||||
* The provided @p aVendorData bytes are appended as they appear in the buffer to the end of the TXT data generated
|
||||
* by the Border Agent itself, and are then included in the advertised mDNS `_meshcop._udp` service.
|
||||
*
|
||||
* This method itself does not perform any validation of the format of the provided @p aVendorData. Therefore, the
|
||||
* caller MUST ensure it is formatted properly. Per the Thread specification, vendor-specific Key-Value TXT data
|
||||
* pairs use TXT keys starting with 'v'. For example, `vn` for vendor name.
|
||||
*
|
||||
* The `BorderAgent` will create and retain its own copy of the bytes in @p aVendorData. So, the buffer passed to
|
||||
* this method does not need to persist beyond the scope of the call.
|
||||
*
|
||||
* The vendor TXT data can be set at any time while the Border Agent is in any state. If there is a change from the
|
||||
* previously set value, it will trigger an update of the registered mDNS service to advertise the new TXT data.
|
||||
*
|
||||
* @param[in] aVendorData A pointer to the buffer containing the vendor TXT data.
|
||||
* @param[in] aVendorDataLength The length of @p aVendorData in bytes.
|
||||
*/
|
||||
void SetVendorTxtData(const uint8_t *aVendorData, uint16_t aVendorDataLength);
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -359,6 +320,8 @@ private:
|
||||
void UpdateState(void);
|
||||
void Start(void);
|
||||
void Stop(void);
|
||||
|
||||
// Callback from Notifier
|
||||
void HandleNotifierEvents(Events aEvents);
|
||||
|
||||
template <Uri kUri> void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
@@ -373,24 +336,20 @@ private:
|
||||
void HandleSessionDisconnected(CoapDtlsSession &aSession, CoapDtlsSession::ConnectEvent aEvent);
|
||||
void HandleCommissionerPetitionAccepted(CoapDtlsSession &aSession);
|
||||
|
||||
void PostServiceTask(void);
|
||||
void HandleServiceTask(void);
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
// Callback from `RoutingManager`
|
||||
void HandleFavoredOmrPrefixChanged(void) { PostServiceTask(); }
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_ENABLE
|
||||
// Callback from `BorderAgent::TxtData`.
|
||||
void HandleServiceTxtDataChanged(void) { RegisterService(); }
|
||||
|
||||
// Callback from `Dnssd`
|
||||
void HandleDnssdPlatformStateChange(void) { RegisterService(); }
|
||||
|
||||
const char *GetServiceName(void);
|
||||
bool IsServiceNameEmpty(void) const { return mServiceName[0] == kNullChar; }
|
||||
void ConstrcutServiceName(const char *aBaseName, Dns::Name::LabelBuffer &aNameBuffer);
|
||||
void RegisterService(void);
|
||||
void UnregisterService(void);
|
||||
void HandleDnssdPlatformStateChange(void) { PostServiceTask(); }
|
||||
#endif
|
||||
|
||||
using ServiceTask = TaskletIn<Manager, &Manager::HandleServiceTask>;
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_ENABLE
|
||||
static const char kServiceType[];
|
||||
static const char kDefaultBaseServiceName[];
|
||||
@@ -403,11 +362,8 @@ private:
|
||||
Id mId;
|
||||
bool mIdInitialized;
|
||||
#endif
|
||||
Callback<ServiceChangedCallback> mServiceChangedCallback;
|
||||
ServiceTask mServiceTask;
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_ENABLE
|
||||
Dns::Name::LabelBuffer mServiceName;
|
||||
Heap::Data mVendorTxtData;
|
||||
#endif
|
||||
Counters mCounters;
|
||||
};
|
||||
|
||||
@@ -64,6 +64,9 @@ const char TxtData::Key::kModelName[] = "mn";
|
||||
|
||||
TxtData::TxtData(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
|
||||
, mChangedTask(aInstance)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
@@ -160,6 +163,50 @@ Error TxtData::Prepare(ServiceTxtData &aTxtData)
|
||||
return Prepare(aTxtData.mData, sizeof(aTxtData.mData), aTxtData.mLength);
|
||||
}
|
||||
|
||||
void TxtData::SetChangedCallback(ChangedCallback aCallback, void *aContext)
|
||||
{
|
||||
mChangedCallback.Set(aCallback, aContext);
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void TxtData::HandleNotifierEvents(Events aEvents)
|
||||
{
|
||||
if (aEvents.ContainsAny(kEventThreadRoleChanged | kEventThreadExtPanIdChanged | kEventThreadNetworkNameChanged |
|
||||
kEventThreadBackboneRouterStateChanged | kEventActiveDatasetChanged))
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void TxtData::HandleChangedTask(void)
|
||||
{
|
||||
VerifyOrExit(Get<Manager>().IsEnabled());
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_ENABLE
|
||||
Get<Manager>().HandleServiceTxtDataChanged();
|
||||
#endif
|
||||
|
||||
mChangedCallback.InvokeIfSet();
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_ENABLE
|
||||
|
||||
void TxtData::SetVendorData(const uint8_t *aVendorData, uint16_t aVendorDataLength)
|
||||
{
|
||||
VerifyOrExit(!mVendorData.Matches(aVendorData, aVendorDataLength));
|
||||
|
||||
SuccessOrAssert(mVendorData.SetFrom(aVendorData, aVendorDataLength));
|
||||
Refresh();
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
uint32_t TxtData::StateBitmap::Determine(Instance &aInstance)
|
||||
{
|
||||
uint32_t bitmap = 0;
|
||||
@@ -206,6 +253,8 @@ uint32_t TxtData::StateBitmap::Determine(Instance &aInstance)
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE
|
||||
|
||||
Error TxtData::Info::ParseFrom(const uint8_t *aTxtData, uint16_t aTxtDataLength)
|
||||
|
||||
@@ -40,10 +40,14 @@
|
||||
#include <openthread/border_agent_txt_data.h>
|
||||
|
||||
#include "common/as_core_type.hpp"
|
||||
#include "common/callback.hpp"
|
||||
#include "common/clearable.hpp"
|
||||
#include "common/encoding.hpp"
|
||||
#include "common/error.hpp"
|
||||
#include "common/heap_data.hpp"
|
||||
#include "common/locator.hpp"
|
||||
#include "common/notifier.hpp"
|
||||
#include "common/tasklet.hpp"
|
||||
#include "common/type_traits.hpp"
|
||||
#include "net/dns_types.hpp"
|
||||
#include "net/ip6_address.hpp"
|
||||
@@ -56,6 +60,8 @@ namespace BorderAgent {
|
||||
|
||||
class TxtData : public InstanceLocator
|
||||
{
|
||||
friend class ot::Notifier;
|
||||
|
||||
public:
|
||||
typedef otBorderAgentConnMode ConnMode; ///< Connection Mode in a Border Agent State Bitmap.
|
||||
typedef otBorderAgentThreadIfState IfState; ///< Thread Interface State in a Border Agent State Bitmap.
|
||||
@@ -147,7 +153,8 @@ public:
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
|
||||
|
||||
typedef otBorderAgentMeshCoPServiceTxtData ServiceTxtData; ///< Service TXT Data.
|
||||
typedef otBorderAgentMeshCoPServiceTxtData ServiceTxtData; ///< Service TXT Data.
|
||||
typedef otBorderAgentMeshCoPServiceChangedCallback ChangedCallback; ///< Service TXT Data changed callback.
|
||||
|
||||
/**
|
||||
* Prepares the MeshCoP service TXT data.
|
||||
@@ -171,6 +178,60 @@ public:
|
||||
*/
|
||||
Error Prepare(ServiceTxtData &aTxtData);
|
||||
|
||||
/**
|
||||
* Sets the callback function used to notify any changes on the MeshCoP service TXT Data.
|
||||
*
|
||||
* The callback is invoked when the state of MeshCoP service TXT values changes. For example, it is
|
||||
* invoked when the network name or the extended PAN ID changes.
|
||||
*
|
||||
* This callback is invoked once right after this API is called to provide initial states of the MeshCoP
|
||||
* service to the application.
|
||||
*
|
||||
* @param[in] aCallback The callback to invoke when there are any changes of the MeshCoP service.
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
*/
|
||||
void SetChangedCallback(ChangedCallback aCallback, void *aContext);
|
||||
|
||||
/**
|
||||
* Requests a refresh of the MeshCoP service TXT data.
|
||||
*
|
||||
* This method is used to notify the `TxtData` module that a network parameter impacting one of the MeshCoP service
|
||||
* TXT data entries has changed. For example, `RoutingManager` uses this method when the favored OMR prefix is
|
||||
* changed.
|
||||
*/
|
||||
void Refresh(void) { mChangedTask.Post(); }
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_ENABLE
|
||||
/**
|
||||
* Returns the vendor TXT data.
|
||||
*
|
||||
* @returns The vendor TXT data.
|
||||
*/
|
||||
const Heap::Data &GetVendorData(void) const { return mVendorData; }
|
||||
|
||||
/**
|
||||
* Sets the vendor extra TXT data to be included when the Border Agent advertises the mDNS `_meshcop._udp` service.
|
||||
*
|
||||
* The provided @p aVendorData bytes are appended as they appear in the buffer to the end of the TXT data generated
|
||||
* by the Border Agent itself, and are then included in the advertised mDNS `_meshcop._udp` service.
|
||||
*
|
||||
* This method itself does not perform any validation of the format of the provided @p aVendorData. Therefore, the
|
||||
* caller MUST ensure it is formatted properly. Per the Thread specification, vendor-specific Key-Value TXT data
|
||||
* pairs use TXT keys starting with 'v'. For example, `vn` for vendor name.
|
||||
*
|
||||
* The `BorderAgent` will create and retain its own copy of the bytes in @p aVendorData. So, the buffer passed to
|
||||
* this method does not need to persist beyond the scope of the call.
|
||||
*
|
||||
* The vendor TXT data can be set at any time while the Border Agent is in any state. If there is a change from the
|
||||
* previously set value, it will trigger an update of the registered mDNS service to advertise the new TXT data.
|
||||
*
|
||||
* @param[in] aVendorData A pointer to the buffer containing the vendor TXT data.
|
||||
* @param[in] aVendorDataLength The length of @p aVendorData in bytes.
|
||||
*/
|
||||
void SetVendorData(const uint8_t *aVendorData, uint16_t aVendorDataLength);
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_ENABLE
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
|
||||
|
||||
private:
|
||||
@@ -243,6 +304,21 @@ private:
|
||||
static uint32_t Determine(Instance &aInstance);
|
||||
#endif
|
||||
};
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
|
||||
// Callback from Notifier
|
||||
void HandleNotifierEvents(Events aEvents);
|
||||
|
||||
void HandleChangedTask(void);
|
||||
|
||||
using ChangedTask = TaskletIn<TxtData, &TxtData::HandleChangedTask>;
|
||||
|
||||
Callback<ChangedCallback> mChangedCallback;
|
||||
ChangedTask mChangedTask;
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_ENABLE
|
||||
Heap::Data mVendorData;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE || OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE
|
||||
|
||||
@@ -1403,7 +1403,7 @@ void TestBorderAgentTxtDataCallback(void)
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Set MeshCoP service change callback. Will get initial values.
|
||||
Log("Set MeshCoP service change callback and check initial values");
|
||||
node0.Get<Manager>().SetServiceChangedCallback(HandleServiceChanged, &callbackInvoked);
|
||||
node0.Get<BaTxtData>().SetChangedCallback(HandleServiceChanged, &callbackInvoked);
|
||||
nexus.AdvanceTime(1);
|
||||
|
||||
// Check the initial TXT entries
|
||||
@@ -1904,7 +1904,7 @@ void TestBorderAgentServiceRegistration(void)
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Log("Set vendor TXT data and validate that it is included in the registered mDNS service");
|
||||
|
||||
node0.Get<Manager>().SetVendorTxtData(kVendorTxtData, sizeof(kVendorTxtData));
|
||||
node0.Get<BaTxtData>().SetVendorData(kVendorTxtData, sizeof(kVendorTxtData));
|
||||
nexus.AdvanceTime(5 * Time::kOneSecondInMsec);
|
||||
|
||||
iterator = node0.Get<Dns::Multicast::Core>().AllocateIterator();
|
||||
@@ -1942,7 +1942,7 @@ void TestBorderAgentServiceRegistration(void)
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Log("Clear vendor TXT data and validate that the registered mDNS service is updated accordingly");
|
||||
|
||||
node0.Get<Manager>().SetVendorTxtData(nullptr, 0);
|
||||
node0.Get<BaTxtData>().SetVendorData(nullptr, 0);
|
||||
nexus.AdvanceTime(5 * Time::kOneSecondInMsec);
|
||||
|
||||
iterator = node0.Get<Dns::Multicast::Core>().AllocateIterator();
|
||||
|
||||
@@ -106,14 +106,19 @@ void TestTasklet(void)
|
||||
sInstance = static_cast<Instance *>(testInitInstance());
|
||||
VerifyOrQuit(sInstance != nullptr);
|
||||
|
||||
sInstance->Get<Tasklet::Scheduler>().ProcessQueuedTasklets();
|
||||
|
||||
{
|
||||
Tasklet::Scheduler &scheduler = sInstance->Get<Tasklet::Scheduler>();
|
||||
Tasklet task1(*sInstance, HandleTask1);
|
||||
Tasklet task2(*sInstance, HandleTask2);
|
||||
Tasklet task3(*sInstance, HandleTask3);
|
||||
|
||||
Log("Process all initially posted tasks after `Instance` initialization");
|
||||
|
||||
while (scheduler.AreTaskletsPending())
|
||||
{
|
||||
scheduler.ProcessQueuedTasklets();
|
||||
}
|
||||
|
||||
VerifyOrQuit(!task1.IsPosted());
|
||||
VerifyOrQuit(!task2.IsPosted());
|
||||
VerifyOrQuit(!task3.IsPosted());
|
||||
|
||||
Reference in New Issue
Block a user