diff --git a/src/lib/spinel/spinel.c b/src/lib/spinel/spinel.c index 3c180d38f..f314f8142 100644 --- a/src/lib/spinel/spinel.c +++ b/src/lib/spinel/spinel.c @@ -2003,6 +2003,10 @@ const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key) ret = "SERVER_LEADER_SERVICES"; break; + case SPINEL_PROP_RCP_API_VERSION: + ret = "RCP_API_VERSION"; + break; + case SPINEL_PROP_UART_BITRATE: ret = "UART_BITRATE"; break; @@ -2615,6 +2619,10 @@ const char *spinel_capability_to_cstr(spinel_capability_t capability) ret = "NET_THREAD_1_1"; break; + case SPINEL_CAP_RCP_API_VERSION: + ret = "RCP_API_VERSION"; + break; + case SPINEL_CAP_MAC_ALLOWLIST: ret = "MAC_ALLOWLIST"; break; diff --git a/src/lib/spinel/spinel.h b/src/lib/spinel/spinel.h index fd0722e55..e98f78f26 100644 --- a/src/lib/spinel/spinel.h +++ b/src/lib/spinel/spinel.h @@ -292,7 +292,10 @@ * * --------------------------------------------------------------------------- * - * Spinel definition guideline: + * Spinel definition compatibility guideline: + * + * The compatibility policy for NCP versus RCP and host side are handled + * differently in spinel. * * New NCP firmware should work with an older host driver, i.e., NCP * implementation should remain backward compatible. @@ -305,6 +308,24 @@ * optional (i.e., a driver not aware of and therefore not using the * new fields should continue to function as before). * + * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * + * For RCP and host, the "RCP API Version" numbers are used to check the + * compatibility between host implementation and RCP firmware. Generally, + * a newer host side implementation would work with a range of previous + * or older RCP firmware versions. + * + * - SPINEL_RCP_API_VERSION specifies the current spinel RCP API version. + * This number MUST be incremented anytime there is a change in any of RCP + * specific spinel definitions. + * + * - SPINEL_MIN_HOST_SUPPORTED_RCP_API_VERSION specifies the minimum spinel + * RCP API Version which is supported by the host-side implementation. + * + * - On start, host implementation queries the RCP API version and accepts + * any version number from SPINEL_MIN_HOST_SUPPORTED_RCP_API_VERSION up to + * and including SPINEL_RCP_API_VERSION. + * * --------------------------------------------------------------------------- */ @@ -345,6 +366,31 @@ #define SPINEL_PROTOCOL_VERSION_THREAD_MAJOR 4 #define SPINEL_PROTOCOL_VERSION_THREAD_MINOR 3 +/** + * @def SPINEL_RCP_API_VERSION + * + * The RCP API version number. + * + * This number MUST increase by one each time any of the spinel definitions used by RCP change (independent of whether + * the change is backward-compatible or not). + * + * Please see section "Spinel definition compatibility guideline" for more details. + * + */ +#define SPINEL_RCP_API_VERSION 1 + +/** + * @def SPINEL_MIN_HOST_SUPPORTED_RCP_API_VERSION + * + * The minimum RCP API version supported by the host implementation. + * + * This number MUST increase when there is a non-compatible RCP spinel related change on host implementation. + * + * Please see section "Spinel definition compatibility guideline" for more details. + * + */ +#define SPINEL_MIN_HOST_SUPPORTED_RCP_API_VERSION 1 + /** * @def SPINEL_FRAME_MAX_SIZE * @@ -1079,6 +1125,10 @@ enum SPINEL_CAP_NET_THREAD_1_1 = (SPINEL_CAP_NET__BEGIN + 1), SPINEL_CAP_NET__END = 64, + SPINEL_CAP_RCP__BEGIN = 64, + SPINEL_CAP_RCP_API_VERSION = (SPINEL_CAP_RCP__BEGIN + 0), + SPINEL_CAP_RCP__END = 80, + SPINEL_CAP_OPENTHREAD__BEGIN = 512, SPINEL_CAP_MAC_ALLOWLIST = (SPINEL_CAP_OPENTHREAD__BEGIN + 0), SPINEL_CAP_MAC_RAW = (SPINEL_CAP_OPENTHREAD__BEGIN + 1), @@ -1137,10 +1187,11 @@ typedef uint32_t spinel_capability_t; * MeshCop | 0x080 - 0x08F, 0x1800 - 0x18FF | Thread Mesh Commissioning * OpenThread | 0x1900 - 0x19FF | OpenThread specific * Server | 0x0A0 - 0x0AF | ALOC Service Server + * RCP | 0x0B0 - 0x0FF | RCP specific * Interface | 0x100 - 0x1FF | Interface (e.g., UART) * PIB | 0x400 - 0x4FF | 802.15.4 PIB * Counter | 0x500 - 0x7FF | Counters (MAC, IP, etc). - * RCP | 0x800 - 0x8FF | RCP specific property + * RCP | 0x800 - 0x8FF | RCP specific property (extended) * Nest | 0x3BC0 - 0x3BFF | Nest (legacy) * Vendor | 0x3C00 - 0x3FFF | Vendor specific * Debug | 0x4000 - 0x43FF | Debug related @@ -3585,6 +3636,22 @@ enum SPINEL_PROP_SERVER__END = 0xB0, + SPINEL_PROP_RCP__BEGIN = 0xB0, + + /// RCP API Version number + /** Format: `i` (read-only) + * + * Required capability: SPINEL_CAP_RADIO and SPINEL_CAP_RCP_API_VERSION. + * + * This property gives the RCP API Version number. + * + * Please see "Spinel definition compatibility guideline" section. + * + */ + SPINEL_PROP_RCP_API_VERSION = SPINEL_PROP_RCP__BEGIN + 0, + + SPINEL_PROP_RCP__END = 0xFF, + SPINEL_PROP_INTERFACE__BEGIN = 0x100, /// UART Bitrate @@ -3973,7 +4040,7 @@ enum SPINEL_PROP_CNTR__END = 0x800, - SPINEL_PROP_RCP__BEGIN = 0x800, + SPINEL_PROP_RCP_EXT__BEGIN = 0x800, /// MAC Key /** Format: `CCddd`. @@ -3987,7 +4054,7 @@ enum * The Spinel property is used to set/get MAC key materials to and from RCP. * */ - SPINEL_PROP_RCP_MAC_KEY = SPINEL_PROP_RCP__BEGIN + 0, + SPINEL_PROP_RCP_MAC_KEY = SPINEL_PROP_RCP_EXT__BEGIN + 0, /// MAC Frame Counter /** Format: `L`. @@ -3997,7 +4064,7 @@ enum * The Spinel property is used to set MAC frame counter to RCP. * */ - SPINEL_PROP_RCP_MAC_FRAME_COUNTER = SPINEL_PROP_RCP__BEGIN + 1, + SPINEL_PROP_RCP_MAC_FRAME_COUNTER = SPINEL_PROP_RCP_EXT__BEGIN + 1, /// Timestamps when Spinel frame is received and transmitted /** Format: `X`. @@ -4007,9 +4074,9 @@ enum * The Spinel property is used to get timestamp from RCP to calculate host and RCP timer difference. * */ - SPINEL_PROP_RCP_TIMESTAMP = SPINEL_PROP_RCP__BEGIN + 2, + SPINEL_PROP_RCP_TIMESTAMP = SPINEL_PROP_RCP_EXT__BEGIN + 2, - SPINEL_PROP_RCP__END = 0x900, + SPINEL_PROP_RCP_EXT__END = 0x900, SPINEL_PROP_NEST__BEGIN = 0x3BC0, diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index 682344dff..bdd7b8bc0 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -1796,6 +1796,10 @@ template <> otError NcpBase::HandlePropertyGet(void) SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_MAC_RAW)); #endif +#if OPENTHREAD_RADIO + SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_RCP_API_VERSION)); +#endif + #if OPENTHREAD_PLATFORM_POSIX SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_POSIX)); #endif diff --git a/src/ncp/ncp_base_dispatcher.cpp b/src/ncp/ncp_base_dispatcher.cpp index 8b3dbb859..2d13ea430 100644 --- a/src/ncp/ncp_base_dispatcher.cpp +++ b/src/ncp/ncp_base_dispatcher.cpp @@ -149,6 +149,11 @@ NcpBase::PropertyHandler NcpBase::FindGetPropertyHandler(spinel_prop_key_t aKey) OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SERVER_SERVICES), #endif OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SERVER_LEADER_SERVICES), +#endif // OPENTHREAD_MTD || OPENTHREAD_FTD +#if OPENTHREAD_RADIO + OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_RCP_API_VERSION), +#endif +#if OPENTHREAD_MTD || OPENTHREAD_FTD OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_TX_PKT_TOTAL), OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_TX_PKT_ACK_REQ), OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_TX_PKT_ACKED), diff --git a/src/ncp/ncp_base_radio.cpp b/src/ncp/ncp_base_radio.cpp index cac86387f..3be08286f 100644 --- a/src/ncp/ncp_base_radio.cpp +++ b/src/ncp/ncp_base_radio.cpp @@ -48,6 +48,13 @@ namespace ot { namespace Ncp { +#if OPENTHREAD_RADIO +template <> otError NcpBase::HandlePropertyGet(void) +{ + return mEncoder.WriteUintPacked(SPINEL_RCP_API_VERSION); +} +#endif + // ---------------------------------------------------------------------------- // MARK: Raw Link-Layer Datapath Glue // ----------------------------------------------------------------------------