From 268cce160a5e29fd792ef6810ec4a95993ca97a9 Mon Sep 17 00:00:00 2001 From: Piotr Koziar <44554861+piotrkoziar@users.noreply.github.com> Date: Tue, 9 Mar 2021 20:08:08 +0100 Subject: [PATCH] [spinel] add support for Backbone Router service (#6232) This commit adds spinel properties for Backbone Router: - SPINEL_PROP_THREAD_BACKBONE_ROUTER_PRIMARY - SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_STATE - SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_CONFIG - SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_REGISTER - SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_REGISTRATION_JITTER Property numbers have been adjusted to match the ones from #6228 and #6231. --- src/lib/spinel/spinel.c | 6 ++ src/lib/spinel/spinel.h | 85 +++++++++++++++++++++++--- src/ncp/ncp_base.cpp | 4 ++ src/ncp/ncp_base_dispatcher.cpp | 16 +++++ src/ncp/ncp_base_ftd.cpp | 102 ++++++++++++++++++++++++++++++++ src/ncp/ncp_base_mtd.cpp | 21 +++++++ 6 files changed, 225 insertions(+), 9 deletions(-) diff --git a/src/lib/spinel/spinel.c b/src/lib/spinel/spinel.c index 04dc471f5..b2af6fd04 100644 --- a/src/lib/spinel/spinel.c +++ b/src/lib/spinel/spinel.c @@ -1350,6 +1350,11 @@ const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key) SPINEL_PROP_CSTR(THREAD_CSL_TIMEOUT), SPINEL_PROP_CSTR(THREAD_CSL_CHANNEL), SPINEL_PROP_CSTR(THREAD_DOMAIN_NAME), + SPINEL_PROP_CSTR(THREAD_BACKBONE_ROUTER_PRIMARY), + SPINEL_PROP_CSTR(THREAD_BACKBONE_ROUTER_LOCAL_STATE), + SPINEL_PROP_CSTR(THREAD_BACKBONE_ROUTER_LOCAL_CONFIG), + SPINEL_PROP_CSTR(THREAD_BACKBONE_ROUTER_LOCAL_REGISTER), + SPINEL_PROP_CSTR(THREAD_BACKBONE_ROUTER_LOCAL_REGISTRATION_JITTER), SPINEL_PROP_CSTR(MESHCOP_JOINER_STATE), SPINEL_PROP_CSTR(MESHCOP_JOINER_COMMISSIONING), SPINEL_PROP_CSTR(IPV6_LL_ADDR), @@ -1615,6 +1620,7 @@ const char *spinel_capability_to_cstr(spinel_capability_t capability) SPINEL_CAP_CSTR(THREAD_BORDER_ROUTER), SPINEL_CAP_CSTR(THREAD_SERVICE), SPINEL_CAP_CSTR(THREAD_CSL_RECEIVER), + SPINEL_CAP_CSTR(THREAD_BACKBONE_ROUTER), SPINEL_CAP_CSTR(NEST_LEGACY_INTERFACE), SPINEL_CAP_CSTR(NEST_LEGACY_NET_WAKE), SPINEL_CAP_CSTR(NEST_TRANSMIT_HOOK), diff --git a/src/lib/spinel/spinel.h b/src/lib/spinel/spinel.h index 1c070314c..92e379a7a 100644 --- a/src/lib/spinel/spinel.h +++ b/src/lib/spinel/spinel.h @@ -724,6 +724,15 @@ enum SPINEL_RADIO_LINK_TREL_UDP6 = 1, }; +// Backbone Router states used for: +// @ref SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_STATE +enum +{ + SPINEL_THREAD_BACKBONE_ROUTER_STATE_DISABLED = 0, + SPINEL_THREAD_BACKBONE_ROUTER_STATE_SECONDARY = 1, + SPINEL_THREAD_BACKBONE_ROUTER_STATE_PRIMARY = 2, +}; + typedef enum { SPINEL_SRP_CLIENT_ITEM_STATE_TO_ADD = 0, // Item to be added/registered. @@ -1190,15 +1199,16 @@ enum SPINEL_CAP_DUA = (SPINEL_CAP_OPENTHREAD__BEGIN + 15), SPINEL_CAP_OPENTHREAD__END = 640, - SPINEL_CAP_THREAD__BEGIN = 1024, - SPINEL_CAP_THREAD_COMMISSIONER = (SPINEL_CAP_THREAD__BEGIN + 0), - SPINEL_CAP_THREAD_TMF_PROXY = (SPINEL_CAP_THREAD__BEGIN + 1), - SPINEL_CAP_THREAD_UDP_FORWARD = (SPINEL_CAP_THREAD__BEGIN + 2), - SPINEL_CAP_THREAD_JOINER = (SPINEL_CAP_THREAD__BEGIN + 3), - SPINEL_CAP_THREAD_BORDER_ROUTER = (SPINEL_CAP_THREAD__BEGIN + 4), - SPINEL_CAP_THREAD_SERVICE = (SPINEL_CAP_THREAD__BEGIN + 5), - SPINEL_CAP_THREAD_CSL_RECEIVER = (SPINEL_CAP_THREAD__BEGIN + 6), - SPINEL_CAP_THREAD__END = 1152, + SPINEL_CAP_THREAD__BEGIN = 1024, + SPINEL_CAP_THREAD_COMMISSIONER = (SPINEL_CAP_THREAD__BEGIN + 0), + SPINEL_CAP_THREAD_TMF_PROXY = (SPINEL_CAP_THREAD__BEGIN + 1), + SPINEL_CAP_THREAD_UDP_FORWARD = (SPINEL_CAP_THREAD__BEGIN + 2), + SPINEL_CAP_THREAD_JOINER = (SPINEL_CAP_THREAD__BEGIN + 3), + SPINEL_CAP_THREAD_BORDER_ROUTER = (SPINEL_CAP_THREAD__BEGIN + 4), + SPINEL_CAP_THREAD_SERVICE = (SPINEL_CAP_THREAD__BEGIN + 5), + SPINEL_CAP_THREAD_CSL_RECEIVER = (SPINEL_CAP_THREAD__BEGIN + 6), + SPINEL_CAP_THREAD_BACKBONE_ROUTER = (SPINEL_CAP_THREAD__BEGIN + 8), + SPINEL_CAP_THREAD__END = 1152, SPINEL_CAP_NEST__BEGIN = 15296, SPINEL_CAP_NEST_LEGACY_INTERFACE = (SPINEL_CAP_NEST__BEGIN + 0), @@ -2960,6 +2970,63 @@ enum */ SPINEL_PROP_THREAD_DUA_ID = SPINEL_PROP_THREAD_EXT__BEGIN + 54, + /// Thread 1.2 Primary Backbone Router information in the Thread Network. + /** Format: `SSLC` - Read-Only + * + * Required capability: `SPINEL_CAP_NET_THREAD_1_2` + * + * `S`: Server. + * `S`: Reregistration Delay (in seconds). + * `L`: Multicast Listener Registration Timeout (in seconds). + * `C`: Sequence Number. + * + */ + SPINEL_PROP_THREAD_BACKBONE_ROUTER_PRIMARY = SPINEL_PROP_THREAD_EXT__BEGIN + 55, + + /// Thread 1.2 Backbone Router local state. + /** Format: `C` - Read-Write + * + * Required capability: `SPINEL_CAP_THREAD_BACKBONE_ROUTER` + * + * The valid values are specified by SPINEL_THREAD_BACKBONE_ROUTER_STATE_ enumeration. + * Backbone functionality will be disabled if SPINEL_THREAD_BACKBONE_ROUTER_STATE_DISABLED + * is writted to this property, enabled otherwise. + * + */ + SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_STATE = SPINEL_PROP_THREAD_EXT__BEGIN + 56, + + /// Local Thread 1.2 Backbone Router configuration. + /** Format: SLC - Read-Write + * + * Required capability: `SPINEL_CAP_THREAD_BACKBONE_ROUTER` + * + * `S`: Reregistration Delay (in seconds). + * `L`: Multicast Listener Registration Timeout (in seconds). + * `C`: Sequence Number. + * + */ + SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_CONFIG = SPINEL_PROP_THREAD_EXT__BEGIN + 57, + + /// Register local Thread 1.2 Backbone Router configuration. + /** Format: Empty (Write only). + * + * Required capability: `SPINEL_CAP_THREAD_BACKBONE_ROUTER` + * + * Writing to this property (with any value) will register local Backbone Router configuration. + * + */ + SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_REGISTER = SPINEL_PROP_THREAD_EXT__BEGIN + 58, + + /// Thread 1.2 Backbone Router registration jitter. + /** Format: `C` - Read-Write + * + * Required capability: `SPINEL_CAP_THREAD_BACKBONE_ROUTER` + * + * `C`: Backbone Router registration jitter. + * + */ + SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_REGISTRATION_JITTER = SPINEL_PROP_THREAD_EXT__BEGIN + 59, + SPINEL_PROP_THREAD_EXT__END = 0x1600, SPINEL_PROP_IPV6__BEGIN = 0x60, diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index 78632e738..46f355fcc 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -1935,6 +1935,10 @@ template <> otError NcpBase::HandlePropertyGet(void) SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_DUA)); #endif +#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE + SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_THREAD_BACKBONE_ROUTER)); +#endif + #endif // OPENTHREAD_MTD || OPENTHREAD_FTD exit: diff --git a/src/ncp/ncp_base_dispatcher.cpp b/src/ncp/ncp_base_dispatcher.cpp index f79bf6dc3..98b7e0efc 100644 --- a/src/ncp/ncp_base_dispatcher.cpp +++ b/src/ncp/ncp_base_dispatcher.cpp @@ -313,6 +313,16 @@ NcpBase::PropertyHandler NcpBase::FindGetPropertyHandler(spinel_prop_key_t aKey) #if OPENTHREAD_CONFIG_DUA_ENABLE OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_DUA_ID), #endif +#endif // OPENTHREAD_FTD +#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) + OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_BACKBONE_ROUTER_PRIMARY), +#endif +#if OPENTHREAD_FTD +#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE + OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_STATE), + OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_CONFIG), + OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_REGISTRATION_JITTER), +#endif #if OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MANAGER_NEW_CHANNEL), OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MANAGER_DELAY), @@ -547,6 +557,12 @@ NcpBase::PropertyHandler NcpBase::FindSetPropertyHandler(spinel_prop_key_t aKey) #if OPENTHREAD_CONFIG_DUA_ENABLE OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_DUA_ID), #endif +#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE + OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_STATE), + OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_CONFIG), + OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_REGISTER), + OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_REGISTRATION_JITTER), +#endif #if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_ANNOUNCE_BEGIN), OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_ENERGY_SCAN), diff --git a/src/ncp/ncp_base_ftd.cpp b/src/ncp/ncp_base_ftd.cpp index d576978f0..a62ae8b28 100644 --- a/src/ncp/ncp_base_ftd.cpp +++ b/src/ncp/ncp_base_ftd.cpp @@ -33,6 +33,9 @@ #include "ncp_base.hpp" #include +#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE +#include +#endif #if OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE #include #endif @@ -398,6 +401,105 @@ exit: } #endif // OPENTHREAD_CONFIG_DUA_ENABLE +#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE +template <> otError NcpBase::HandlePropertyGet(void) +{ + uint8_t state = SPINEL_THREAD_BACKBONE_ROUTER_STATE_DISABLED; + + switch (otBackboneRouterGetState(mInstance)) + { + case OT_BACKBONE_ROUTER_STATE_DISABLED: + state = SPINEL_THREAD_BACKBONE_ROUTER_STATE_DISABLED; + break; + + case OT_BACKBONE_ROUTER_STATE_SECONDARY: + state = SPINEL_THREAD_BACKBONE_ROUTER_STATE_SECONDARY; + break; + + case OT_BACKBONE_ROUTER_STATE_PRIMARY: + state = SPINEL_THREAD_BACKBONE_ROUTER_STATE_PRIMARY; + break; + } + + return mEncoder.WriteUint8(state); +} + +template <> otError NcpBase::HandlePropertySet(void) +{ + uint8_t state; + otError error = OT_ERROR_NONE; + + SuccessOrExit(error = mDecoder.ReadUint8(state)); + + if (state) + { + otBackboneRouterSetEnabled(mInstance, true); + } + else + { + otBackboneRouterSetEnabled(mInstance, false); + } + +exit: + return error; +} + +template <> otError NcpBase::HandlePropertyGet(void) +{ + otError error = OT_ERROR_NONE; + otBackboneRouterConfig bbrConfig; + + otBackboneRouterGetConfig(mInstance, &bbrConfig); + + SuccessOrExit(error = mEncoder.WriteUint16(bbrConfig.mReregistrationDelay)); + SuccessOrExit(error = mEncoder.WriteUint32(bbrConfig.mMlrTimeout)); + SuccessOrExit(error = mEncoder.WriteUint8(bbrConfig.mSequenceNumber)); + +exit: + return error; +} + +template <> otError NcpBase::HandlePropertySet(void) +{ + otError error = OT_ERROR_NONE; + otBackboneRouterConfig bbrConfig; + + SuccessOrExit(error = mDecoder.ReadUint16(bbrConfig.mReregistrationDelay)); + SuccessOrExit(error = mDecoder.ReadUint32(bbrConfig.mMlrTimeout)); + SuccessOrExit(error = mDecoder.ReadUint8(bbrConfig.mSequenceNumber)); + + SuccessOrExit(error = otBackboneRouterSetConfig(mInstance, &bbrConfig)); + +exit: + return error; +} + +template <> otError NcpBase::HandlePropertySet(void) +{ + return otBackboneRouterRegister(mInstance); +} + +template <> otError NcpBase::HandlePropertyGet(void) +{ + uint8_t jitter = otBackboneRouterGetRegistrationJitter(mInstance); + + return mEncoder.WriteUint8(jitter); +} + +template <> otError NcpBase::HandlePropertySet(void) +{ + otError error = OT_ERROR_NONE; + uint8_t jitter; + + SuccessOrExit(error = mDecoder.ReadUint8(jitter)); + + otBackboneRouterSetRegistrationJitter(mInstance, jitter); + +exit: + return error; +} +#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE + template <> otError NcpBase::HandlePropertyGet(void) { return mEncoder.WriteData(otThreadGetPskc(mInstance)->m8, sizeof(spinel_net_pskc_t)); diff --git a/src/ncp/ncp_base_mtd.cpp b/src/ncp/ncp_base_mtd.cpp index 3a4f1755c..eda5b10a7 100644 --- a/src/ncp/ncp_base_mtd.cpp +++ b/src/ncp/ncp_base_mtd.cpp @@ -60,6 +60,9 @@ #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE #include #endif +#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) +#include "openthread/backbone_router.h" +#endif #include "common/code_utils.hpp" #include "common/debug.hpp" @@ -259,6 +262,24 @@ template <> otError NcpBase::HandlePropertyGet(v } #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE +#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) +template <> otError NcpBase::HandlePropertyGet(void) +{ + otError error = OT_ERROR_NONE; + otBackboneRouterConfig bbrConfig; + + SuccessOrExit(error = otBackboneRouterGetPrimary(mInstance, &bbrConfig)); + + SuccessOrExit(error = mEncoder.WriteUint16(bbrConfig.mServer16)); + SuccessOrExit(error = mEncoder.WriteUint16(bbrConfig.mReregistrationDelay)); + SuccessOrExit(error = mEncoder.WriteUint32(bbrConfig.mMlrTimeout)); + SuccessOrExit(error = mEncoder.WriteUint8(bbrConfig.mSequenceNumber)); + +exit: + return error; +} +#endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 + template <> otError NcpBase::HandlePropertyGet(void) { return mEncoder.WriteUint32(otLinkGetPollPeriod(mInstance));