[border-agent] add API to enable/disable Border Agent service (#11458)

This commit adds a new API to allow the Border Agent service to be
enabled or disabled. By default, the Border Agent service is enabled
when the `OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE` feature is used.
This new API allows the user to explicitly control its state. This
can be useful in scenarios such as:
- The user code wishes to delay the start of the Border Agent service
  (and its mDNS advertisement of the `_meshcop._udp` service on the
  infrastructure link). This allows time to prepare or determine
  vendor-specific TXT data entries for inclusion.
- Unit tests or test scripts might disable the Border Agent service to
  prevent it from interfering with specific test steps. For example,
  tests validating mDNS or DNS-SD functionality may disable the
  Border Agent to prevent its registration of the MeshCoP service.

This commit also adds a corresponding CLI command for the new API and
updates `test_border_agent` to validate this functionality.
This commit is contained in:
Abtin Keshavarzian
2025-04-30 07:38:07 -07:00
committed by GitHub
parent 9e9522aaac
commit d56222a8db
8 changed files with 187 additions and 31 deletions

View File

@ -151,7 +151,35 @@ typedef struct otBorderAgentMeshCoPServiceTxtData
} otBorderAgentMeshCoPServiceTxtData;
/**
* Indicates whether or not the Border Agent service is active and running.
* Enables or disables the Border Agent service on the device.
*
* By default, the Border Agent service is enabled when the `OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE` feature is used.
* This function allows higher-layer code to explicitly control its state. This can be useful in scenarios such as:
*
* - The higher-layer code wishes to delay the start of the Border Agent service (and its mDNS advertisement of the
* `_meshcop._udp` service on the infrastructure link). This allows time to prepare or determine vendor-specific TXT
* data entries for inclusion.
* - Unit tests or test scripts might disable the Border Agent service to prevent it from interfering with specific
* test steps. For example, tests validating mDNS or DNS-SD functionality may disable the Border Agent to prevent its
* registration of the MeshCoP service.
*
* @param[in] aInstance The OpenThread instance.
* @param[in] aEnabled A boolean to indicate whether to to enable (TRUE), or disable (FALSE).
*/
void otBorderAgentSetEnabled(otInstance *aInstance, bool aEnabled);
/**
* Indicates whether or not the Border Agent service is enabled.
*
* @param[in] aInstance The OpenThread instance.
*
* @retval TRUE The Border Agent service is enabled.
* @retval FALSE The Border Agent service is disabled.
*/
bool otBorderAgentIsEnabled(otInstance *aInstance);
/**
* Indicates whether or not the Border Agent service is enabled and also active.
*
* While the Border Agent is active, external commissioner candidates can try to connect to and establish secure DTLS
* sessions with the Border Agent using PSKc. A connected commissioner can then petition to become a full commissioner.

View File

@ -52,7 +52,7 @@ extern "C" {
*
* @note This number versions both OpenThread platform and user APIs.
*/
#define OPENTHREAD_API_VERSION (503)
#define OPENTHREAD_API_VERSION (504)
/**
* @addtogroup api-instance

View File

@ -361,6 +361,29 @@ Done
Show current Border Agent information.
### ba enable
Enables Border Agent service.
By default, the Border Agent service is enabled. The `ba enable` and `ba disable` allow user to explicitly control its state. This can be useful in scenarios such as:
- The user wishes to delay the start of the Border Agent service (and its mDNS advertisement of the `_meshcop._udp` service on the infrastructure link). This allows time to prepare or determine vendor-specific TXT data entries for inclusion.
- Unit tests or test scripts might disable the Border Agent service to prevent it from interfering with specific test steps. For example, tests validating mDNS or DNS-SD functionality may disable the Border Agent to prevent its registration of the MeshCoP service.
```
> ba enable
Done
```
### ba disable
Disables Border Agent service.
```
> ba disable
Done
```
### ba port
Print Border Agent's service port.
@ -377,8 +400,9 @@ Print Border Agent's state.
Possible states are
- `Active`: Border Agent is active.
- `Inactive`: Border Agent is not active.
- `Disabled`: Border Agent service is disabled.
- `Inactive`: Border Agent service is enabled but not yet active.
- `Active`: Border Agent service is enabled and active. External commissioner can connect and establish secure DTLS sessions with the Border Agent using PSKc
```bash
> ba state

View File

@ -445,6 +445,23 @@ template <> otError Interpreter::Process<Cmd("ba")>(Arg aArgs[])
{
otError error = OT_ERROR_NONE;
/**
* @cli ba (enable, disable)
* @code
* ba enable
* Done
* @endcode
* @code
* ba disable
* Done
* @endcode
* @cparam ba @ca{enable|disable}
* @par api_copy
* #otBorderAgentSetEnabled
*/
if (ProcessEnableDisable(aArgs, otBorderAgentSetEnabled) == OT_ERROR_NONE)
{
}
/**
* @cli ba port
* @code
@ -455,7 +472,7 @@ template <> otError Interpreter::Process<Cmd("ba")>(Arg aArgs[])
* @par api_copy
* #otBorderAgentGetUdpPort
*/
if (aArgs[0] == "port")
else if (aArgs[0] == "port")
{
OutputLine("%u", otBorderAgentGetUdpPort(GetInstancePtr()));
}
@ -466,12 +483,24 @@ template <> otError Interpreter::Process<Cmd("ba")>(Arg aArgs[])
* Active
* Done
* @endcode
* @par api_copy
* #otBorderAgentIsActive
* @par
* Prints the current state of the Border Agent service. Possible states are:
* - `Disabled`: Border Agent service is disabled.
* - `Inactive`: Border Agent service is enabled but not yet active.
* - `Active`: Border Agent service is enabled and active. External commissioner can connect and establish secure
* DTLS sessions with the Border Agent using PSKc
* @sa #otBorderAgentIsActive
*/
else if (aArgs[0] == "state")
{
OutputLine("%s", otBorderAgentIsActive(GetInstancePtr()) ? "Active" : "Inactive");
if (!otBorderAgentIsEnabled(GetInstancePtr()))
{
OutputLine("Disabled");
}
else
{
OutputLine("%s", otBorderAgentIsActive(GetInstancePtr()) ? "Active" : "Inactive");
}
}
/**
* @cli ba sessions

View File

@ -42,6 +42,21 @@
using namespace ot;
void otBorderAgentSetEnabled(otInstance *aInstance, bool aEnabled)
{
AsCoreType(aInstance).Get<MeshCoP::BorderAgent>().SetEnabled(aEnabled);
}
bool otBorderAgentIsEnabled(otInstance *aInstance)
{
return AsCoreType(aInstance).Get<MeshCoP::BorderAgent>().IsEnabled();
}
bool otBorderAgentIsActive(otInstance *aInstance)
{
return AsCoreType(aInstance).Get<MeshCoP::BorderAgent>().IsRunning();
}
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
otError otBorderAgentGetId(otInstance *aInstance, otBorderAgentId *aId)
{
@ -54,11 +69,6 @@ otError otBorderAgentSetId(otInstance *aInstance, const otBorderAgentId *aId)
}
#endif
bool otBorderAgentIsActive(otInstance *aInstance)
{
return AsCoreType(aInstance).Get<MeshCoP::BorderAgent>().IsRunning();
}
uint16_t otBorderAgentGetUdpPort(otInstance *aInstance)
{
return AsCoreType(aInstance).Get<MeshCoP::BorderAgent>().GetUdpPort();

View File

@ -47,6 +47,7 @@ RegisterLogModule("BorderAgent");
BorderAgent::BorderAgent(Instance &aInstance)
: InstanceLocator(aInstance)
, mEnabled(true)
, mIsRunning(false)
, mDtlsTransport(aInstance, kNoLinkSecurity)
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
@ -103,6 +104,29 @@ exit:
}
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
void BorderAgent::SetEnabled(bool aEnabled)
{
VerifyOrExit(mEnabled != aEnabled);
mEnabled = aEnabled;
LogInfo("%sabling Border Agent", mEnabled ? "En" : "Dis");
UpdateState();
exit:
return;
}
void BorderAgent::UpdateState(void)
{
if (mEnabled && Get<Mle::Mle>().IsAttached())
{
Start();
}
else
{
Stop();
}
}
void BorderAgent::Start(void)
{
Error error = kErrorNone;
@ -168,16 +192,11 @@ void BorderAgent::HandleNotifierEvents(Events aEvents)
{
if (aEvents.Contains(kEventThreadRoleChanged))
{
if (Get<Mle::Mle>().IsAttached())
{
Start();
}
else
{
Stop();
}
UpdateState();
}
VerifyOrExit(mEnabled);
if (aEvents.ContainsAny(kEventThreadRoleChanged | kEventThreadExtPanIdChanged | kEventThreadNetworkNameChanged |
kEventThreadBackboneRouterStateChanged | kEventActiveDatasetChanged))
{
@ -353,11 +372,19 @@ exit:
FreeMessageOnError(message, error);
}
void BorderAgent::HandleServiceTask(void) { mServiceChangedCallback.InvokeIfSet(); }
void BorderAgent::HandleServiceTask(void)
{
VerifyOrExit(mEnabled);
mServiceChangedCallback.InvokeIfSet();
exit:
return;
}
void BorderAgent::PostServiceTask(void)
{
if (mServiceChangedCallback.IsSet())
if (mEnabled && mServiceChangedCallback.IsSet())
{
mServiceTask.Post();
}

View File

@ -120,6 +120,38 @@ public:
*/
explicit BorderAgent(Instance &aInstance);
/**
* Enables or disables the Border Agent service.
*
* By default, the Border Agent service is enabled. This method allows us to explicitly control its state. This can
* be useful in scenarios such as:
* - The code wishes to delay the start of the Border Agent service (and its mDNS advertisement of the
* `_meshcop._udp` service on the infrastructure link). This allows time to prepare or determine vendor-specific
* TXT data entries for inclusion.
* - Unit tests or test scripts might disable the Border Agent service to prevent it from interfering with specific
* test steps. For example, tests validating mDNS or DNS-SD functionality may disable the Border Agent to prevent
* its registration of the MeshCoP service.
*
* @param[in] aEnabled Whether to enable or disable.
*/
void SetEnabled(bool aEnabled);
/**
* Indicated whether or not the Border Agent is enabled.
*
* @retval TRUE The Border Agent is enabled.
* @retval FALSE The Border Agent is disabled.
*/
bool IsEnabled(void) const { return mEnabled; }
/**
* Indicates whether the Border Agent service is enabled and running.
*
* @retval TRUE Border Agent service is running.
* @retval FALSE Border Agent service is not running.
*/
bool IsRunning(void) const { return mIsRunning; }
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
/**
* Represents a Border Agent Identifier.
@ -172,14 +204,6 @@ public:
*/
uint16_t GetUdpPort(void) const;
/**
* Indicates whether the Border Agent service is running.
*
* @retval TRUE Border Agent service is running.
* @retval FALSE Border Agent service is not running.
*/
bool IsRunning(void) const { return mIsRunning; }
/**
* Sets the callback function used by the Border Agent to notify any changes on the MeshCoP service TXT values.
*
@ -549,6 +573,7 @@ private:
Appender mAppender;
};
void UpdateState(void);
void Start(void);
void Stop(void);
void HandleNotifierEvents(Events aEvents);
@ -576,6 +601,7 @@ private:
using ServiceTask = TaskletIn<BorderAgent, &BorderAgent::HandleServiceTask>;
bool mEnabled;
bool mIsRunning;
Dtls::Transport mDtlsTransport;
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE

View File

@ -85,6 +85,18 @@ void TestBorderAgent(void)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Log("Check Border Agent initial state");
VerifyOrQuit(node0.Get<BorderAgent>().IsEnabled());
VerifyOrQuit(node0.Get<BorderAgent>().IsRunning());
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Log("Check disabling and re-enabling of Border Agent");
node0.Get<BorderAgent>().SetEnabled(false);
VerifyOrQuit(!node0.Get<BorderAgent>().IsEnabled());
VerifyOrQuit(!node0.Get<BorderAgent>().IsRunning());
node0.Get<BorderAgent>().SetEnabled(true);
VerifyOrQuit(node0.Get<BorderAgent>().IsEnabled());
VerifyOrQuit(node0.Get<BorderAgent>().IsRunning());
SuccessOrQuit(node0.Get<Ip6::Filter>().AddUnsecurePort(node0.Get<BorderAgent>().GetUdpPort()));