mirror of
https://github.com/espressif/openthread.git
synced 2026-08-12 13:47:47 +00:00
[radio-spinel] check RCP API Version to be in the supported range (#5863)
This commit adds a new method `CheckRcpApiVersion()` which is used during `Init()` to get the API version from RCP and verify that it is within supported range.
This commit is contained in:
committed by
Jonathan Hui
parent
5111bbee65
commit
0ca10a6538
@@ -650,13 +650,16 @@ public:
|
||||
otError SetMacFrameCounter(uint32_t aMacFrameCounter);
|
||||
|
||||
/**
|
||||
* This method checks whether the spinel interface is radio-only
|
||||
* This method checks whether the spinel interface is radio-only.
|
||||
*
|
||||
* @param[out] aSupportsRcpApiVersion A reference to a boolean variable to update whether the list of spinel
|
||||
* capabilities include `SPINEL_CAP_RCP_API_VERSION`.
|
||||
*
|
||||
* @retval TRUE The radio chip is in radio-only mode.
|
||||
* @retval FALSE Otherwise.
|
||||
*
|
||||
*/
|
||||
bool IsRcp(void);
|
||||
bool IsRcp(bool &aSupportsRcpApiVersion);
|
||||
|
||||
/**
|
||||
* This method checks whether there is pending frame in the buffer.
|
||||
@@ -726,6 +729,7 @@ private:
|
||||
|
||||
otError CheckSpinelVersion(void);
|
||||
otError CheckRadioCapabilities(void);
|
||||
otError CheckRcpApiVersion(bool aSupportsRcpApiVersion);
|
||||
|
||||
/**
|
||||
* This method triggers a state transfer of the state machine.
|
||||
|
||||
@@ -222,6 +222,7 @@ template <typename InterfaceType, typename ProcessContextType>
|
||||
void RadioSpinel<InterfaceType, ProcessContextType>::Init(bool aResetRadio, bool aRestoreDatasetFromNcp)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
bool supportsRcpApiVersion;
|
||||
|
||||
#if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0
|
||||
mResetRadioOnStartup = aResetRadio;
|
||||
@@ -239,7 +240,7 @@ void RadioSpinel<InterfaceType, ProcessContextType>::Init(bool aResetRadio, bool
|
||||
SuccessOrExit(error = Get(SPINEL_PROP_NCP_VERSION, SPINEL_DATATYPE_UTF8_S, mVersion, sizeof(mVersion)));
|
||||
SuccessOrExit(error = Get(SPINEL_PROP_HWADDR, SPINEL_DATATYPE_EUI64_S, mIeeeEui64.m8));
|
||||
|
||||
if (!IsRcp())
|
||||
if (!IsRcp(supportsRcpApiVersion))
|
||||
{
|
||||
uint8_t exitCode = OT_EXIT_RADIO_SPINEL_INCOMPATIBLE;
|
||||
|
||||
@@ -251,6 +252,7 @@ void RadioSpinel<InterfaceType, ProcessContextType>::Init(bool aResetRadio, bool
|
||||
DieNow(exitCode);
|
||||
}
|
||||
|
||||
SuccessOrDie(CheckRcpApiVersion(supportsRcpApiVersion));
|
||||
SuccessOrDie(CheckRadioCapabilities());
|
||||
|
||||
mRxRadioFrame.mPsdu = mRxPsdu;
|
||||
@@ -285,7 +287,7 @@ exit:
|
||||
}
|
||||
|
||||
template <typename InterfaceType, typename ProcessContextType>
|
||||
bool RadioSpinel<InterfaceType, ProcessContextType>::IsRcp(void)
|
||||
bool RadioSpinel<InterfaceType, ProcessContextType>::IsRcp(bool &aSupportsRcpApiVersion)
|
||||
{
|
||||
uint8_t capsBuffer[kCapsBufferSize];
|
||||
const uint8_t *capsData = capsBuffer;
|
||||
@@ -293,6 +295,8 @@ bool RadioSpinel<InterfaceType, ProcessContextType>::IsRcp(void)
|
||||
bool supportsRawRadio = false;
|
||||
bool isRcp = false;
|
||||
|
||||
aSupportsRcpApiVersion = false;
|
||||
|
||||
SuccessOrDie(Get(SPINEL_PROP_CAPS, SPINEL_DATATYPE_DATA_S, capsBuffer, &capsLength));
|
||||
|
||||
while (capsLength > 0)
|
||||
@@ -318,6 +322,11 @@ bool RadioSpinel<InterfaceType, ProcessContextType>::IsRcp(void)
|
||||
mSupportsLogStream = true;
|
||||
}
|
||||
|
||||
if (capability == SPINEL_CAP_RCP_API_VERSION)
|
||||
{
|
||||
aSupportsRcpApiVersion = true;
|
||||
}
|
||||
|
||||
capsData += unpacked;
|
||||
capsLength -= static_cast<spinel_size_t>(unpacked);
|
||||
}
|
||||
@@ -364,6 +373,36 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <typename InterfaceType, typename ProcessContextType>
|
||||
otError RadioSpinel<InterfaceType, ProcessContextType>::CheckRcpApiVersion(bool aSupportsRcpApiVersion)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
unsigned int rcpApiVersion = 1;
|
||||
|
||||
// Use RCP API Version value 1, when the RCP capability
|
||||
// list does not contain `SPINEL_CAP_RCP_API_VERSION`.
|
||||
|
||||
if (aSupportsRcpApiVersion)
|
||||
{
|
||||
SuccessOrExit(error = Get(SPINEL_PROP_RCP_API_VERSION, SPINEL_DATATYPE_UINT_PACKED_S, &rcpApiVersion));
|
||||
}
|
||||
|
||||
otLogNotePlat("RCP API Version: %u", rcpApiVersion);
|
||||
|
||||
static_assert(SPINEL_MIN_HOST_SUPPORTED_RCP_API_VERSION <= SPINEL_RCP_API_VERSION,
|
||||
"MIN_HOST_SUPPORTED_RCP_API_VERSION must be smaller than or equal to RCP_API_VERSION");
|
||||
|
||||
if ((rcpApiVersion < SPINEL_MIN_HOST_SUPPORTED_RCP_API_VERSION) || (rcpApiVersion > SPINEL_RCP_API_VERSION))
|
||||
{
|
||||
otLogCritPlat("RCP API Version %u is not in the supported range [%u-%u]", rcpApiVersion,
|
||||
SPINEL_MIN_HOST_SUPPORTED_RCP_API_VERSION, SPINEL_RCP_API_VERSION);
|
||||
DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <typename InterfaceType, typename ProcessContextType>
|
||||
otError RadioSpinel<InterfaceType, ProcessContextType>::RestoreDatasetFromNcp(void)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user