From 2cc6d6c11f2543145fcabdb5cce774043a8876b6 Mon Sep 17 00:00:00 2001 From: Li Cao Date: Sat, 1 Mar 2025 05:53:22 +0800 Subject: [PATCH] [ncp] add spinel properties for border agent (#11271) This commit adds spinel properties for border agent MeshCoP service to work under NCP. * `SPINEL_PROP_BORDER_AGENT_MESHCOP_SERIVCE_STATE`: this simply conveys the MeshCoP service state, including `IsActive`, udp port and the encoded Txt values. * `SPINEL_PROP_BORDER_AGENT_MESHCOP_SERIVCE_STATE_SUBSCRIPTION`: this notifies the NCP side to register the state change callback. Because we hope that the host side can have initial values. But if we register the state change callback in NCP's initialization, the callback will be invoked at a very early stage and send the values while the host isn't ready to receive the MeshCoP service values. So this property enables the host to decide when to receive the initial values. --- src/lib/spinel/spinel.c | 1 + src/lib/spinel/spinel.h | 14 +++++++++++++ src/ncp/changed_props_set.cpp | 3 +++ src/ncp/ncp_base.cpp | 4 ++++ src/ncp/ncp_base.hpp | 6 ++++++ src/ncp/ncp_base_dispatcher.cpp | 3 +++ src/ncp/ncp_base_ftd.cpp | 35 ++++++++++++++++++++++++++++++++- 7 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/lib/spinel/spinel.c b/src/lib/spinel/spinel.c index 8c32b4a26..35988d4b1 100644 --- a/src/lib/spinel/spinel.c +++ b/src/lib/spinel/spinel.c @@ -1418,6 +1418,7 @@ const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key) {SPINEL_PROP_DNSSD_HOST, "DNSSD_HOST"}, {SPINEL_PROP_DNSSD_SERVICE, "DNSSD_SERVICE"}, {SPINEL_PROP_DNSSD_KEY_RECORD, "DNSSD_KEY_RECORD"}, + {SPINEL_PROP_BORDER_AGENT_MESHCOP_SERVICE_STATE, "BORDER_AGENT_MESHCOP_SERVICE_STATE"}, {SPINEL_PROP_PARENT_RESPONSE_INFO, "PARENT_RESPONSE_INFO"}, {SPINEL_PROP_SLAAC_ENABLED, "SLAAC_ENABLED"}, {SPINEL_PROP_SUPPORTED_RADIO_LINKS, "SUPPORTED_RADIO_LINKS"}, diff --git a/src/lib/spinel/spinel.h b/src/lib/spinel/spinel.h index 3c2476397..667437bd8 100644 --- a/src/lib/spinel/spinel.h +++ b/src/lib/spinel/spinel.h @@ -4884,6 +4884,20 @@ enum SPINEL_PROP_DNSSD__END = 0x950, + SPINEL_PROP_BORDER_AGENT__BEGIN = 0x950, + + /// Border Agent MeshCoP service state. + /** + * Format: `bSD`: Get and Unsolicited notifications. + * + * `b`: Whether the border agent is running or not. + * `S`: The UDP port that is being used by the border agent. If the state is 'Stopped', the port MUST be 0. + * `D`: The encoded MeshCoP service TXT data (from Thread side). + */ + SPINEL_PROP_BORDER_AGENT_MESHCOP_SERVICE_STATE = SPINEL_PROP_BORDER_AGENT__BEGIN + 1, + + SPINEL_PROP_BORDER_AGENT__END = 0x970, + SPINEL_PROP_NEST__BEGIN = 0x3BC0, SPINEL_PROP_NEST_STREAM_MFG = SPINEL_PROP_NEST__BEGIN + 0, diff --git a/src/ncp/changed_props_set.cpp b/src/ncp/changed_props_set.cpp index a1afabc1e..6706c8362 100644 --- a/src/ncp/changed_props_set.cpp +++ b/src/ncp/changed_props_set.cpp @@ -93,6 +93,9 @@ const ChangedPropsSet::Entry ChangedPropsSet::mSupportedProps[] = { #endif {SPINEL_PROP_PARENT_RESPONSE_INFO, SPINEL_STATUS_OK, true}, {SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET_TLVS, SPINEL_STATUS_OK, false}, +#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE + {SPINEL_PROP_BORDER_AGENT_MESHCOP_SERVICE_STATE, SPINEL_STATUS_OK, false} +#endif }; uint8_t ChangedPropsSet::GetNumEntries(void) const diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index b8646c019..e16b1db4c 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -367,6 +368,9 @@ NcpBase::NcpBase(Instance *aInstance) #if OPENTHREAD_CONFIG_MLE_PARENT_RESPONSE_CALLBACK_API_ENABLE otThreadRegisterParentResponseCallback(mInstance, &NcpBase::HandleParentResponseInfo, static_cast(this)); #endif +#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE + otBorderAgentSetMeshCoPServiceChangedCallback(mInstance, HandleBorderAgentMeshCoPServiceChanged, this); +#endif #endif // OPENTHREAD_FTD #if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE otSrpClientSetCallback(mInstance, HandleSrpClientCallback, this); diff --git a/src/ncp/ncp_base.hpp b/src/ncp/ncp_base.hpp index d27908bf9..2e9ec3e89 100644 --- a/src/ncp/ncp_base.hpp +++ b/src/ncp/ncp_base.hpp @@ -457,6 +457,12 @@ protected: static void HandleParentResponseInfo(otThreadParentResponseInfo *aInfo, void *aContext); void HandleParentResponseInfo(const otThreadParentResponseInfo &aInfo); #endif + +#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE + static void HandleBorderAgentMeshCoPServiceChanged(void *aContext); + void HandleBorderAgentMeshCoPServiceChanged(void); +#endif + #endif static void HandleDatagramFromStack(otMessage *aMessage, void *aContext); diff --git a/src/ncp/ncp_base_dispatcher.cpp b/src/ncp/ncp_base_dispatcher.cpp index ae6530596..2e72d04b8 100644 --- a/src/ncp/ncp_base_dispatcher.cpp +++ b/src/ncp/ncp_base_dispatcher.cpp @@ -227,6 +227,9 @@ NcpBase::PropertyHandler NcpBase::FindGetPropertyHandler(spinel_prop_key_t aKey) #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SRP_SERVER_AUTO_ENABLE_MODE), #endif +#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE + OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_BORDER_AGENT_MESHCOP_SERVICE_STATE), +#endif #endif OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_UNSOL_UPDATE_FILTER), OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_UNSOL_UPDATE_LIST), diff --git a/src/ncp/ncp_base_ftd.cpp b/src/ncp/ncp_base_ftd.cpp index cd1957ccb..f3435989e 100644 --- a/src/ncp/ncp_base_ftd.cpp +++ b/src/ncp/ncp_base_ftd.cpp @@ -117,7 +117,7 @@ void NcpBase::HandleParentResponseInfo(const otThreadParentResponseInfo &aInfo) exit: return; } -#endif +#endif // OPENTHREAD_CONFIG_MLE_PARENT_RESPONSE_CALLBACK_API_ENABLE void NcpBase::HandleNeighborTableChanged(otNeighborTableEvent aEvent, const otNeighborTableEntryInfo *aEntry) { @@ -190,6 +190,21 @@ exit: } } +#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE + +void NcpBase::HandleBorderAgentMeshCoPServiceChanged(void *aContext) +{ + static_cast(aContext)->HandleBorderAgentMeshCoPServiceChanged(); +} + +void NcpBase::HandleBorderAgentMeshCoPServiceChanged(void) +{ + mChangedPropsSet.AddProperty(SPINEL_PROP_BORDER_AGENT_MESHCOP_SERVICE_STATE); + mUpdateChangedPropsTask.Post(); +} + +#endif // OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE + // ---------------------------------------------------------------------------- // MARK: Individual Property Handlers // ---------------------------------------------------------------------------- @@ -1633,6 +1648,24 @@ exit: #endif // OPENTHREAD_CONFIG_NCP_DNSSD_ENABLE && OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE +#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE + +template <> otError NcpBase::HandlePropertyGet(void) +{ + otError error = OT_ERROR_NONE; + otBorderAgentMeshCoPServiceTxtData txtData; + + SuccessOrExit(error = otBorderAgentGetMeshCoPServiceTxtData(mInstance, &txtData)); + SuccessOrExit(error = mEncoder.WriteBool(otBorderAgentIsActive(mInstance))); + SuccessOrExit(error = mEncoder.WriteUint16(otBorderAgentGetUdpPort(mInstance))); + SuccessOrExit(error = mEncoder.WriteData(txtData.mData, txtData.mLength)); + +exit: + return error; +} + +#endif // OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE + } // namespace Ncp } // namespace ot