mirror of
https://github.com/espressif/openthread.git
synced 2026-07-30 23:57:47 +00:00
[spinel] allow registering callback to handle compatibility errors (#10724)
When the RCP capabilities check fails, a mechanism should be provided to notify the user of the error instead of causing the program to crash. For example, the hardware reboot function provided in the Spinel driver interface could be invoked. The specific hardware reboot implementation is left to the user, such as performing an RCP update.
This commit is contained in:
@@ -136,6 +136,15 @@
|
||||
#define OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE
|
||||
*
|
||||
* Enables compatibility error callback in Spinel
|
||||
*/
|
||||
#ifndef OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE
|
||||
#define OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_HEADER
|
||||
*
|
||||
|
||||
@@ -111,6 +111,10 @@ RadioSpinel::RadioSpinel(void)
|
||||
#if OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE
|
||||
, mVendorRestorePropertiesCallback(nullptr)
|
||||
, mVendorRestorePropertiesContext(nullptr)
|
||||
#endif
|
||||
#if OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE
|
||||
, mCompatibilityErrorCallback(nullptr)
|
||||
, mCompatibilityErrorContext(nullptr)
|
||||
#endif
|
||||
, mTimeSyncEnabled(false)
|
||||
, mTimeSyncOn(false)
|
||||
@@ -198,7 +202,7 @@ otError RadioSpinel::CheckSpinelVersion(void)
|
||||
{
|
||||
LogCrit("Spinel version mismatch - Posix:%d.%d, RCP:%d.%d", SPINEL_PROTOCOL_VERSION_THREAD_MAJOR,
|
||||
SPINEL_PROTOCOL_VERSION_THREAD_MINOR, versionMajor, versionMinor);
|
||||
DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
|
||||
HandleCompatibilityError();
|
||||
}
|
||||
|
||||
exit:
|
||||
@@ -210,13 +214,13 @@ void RadioSpinel::InitializeCaps(bool &aSupportsRcpApiVersion, bool &aSupportsRc
|
||||
if (!GetSpinelDriver().CoprocessorHasCap(SPINEL_CAP_CONFIG_RADIO))
|
||||
{
|
||||
LogCrit("The co-processor isn't a RCP!");
|
||||
DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
|
||||
HandleCompatibilityError();
|
||||
}
|
||||
|
||||
if (!GetSpinelDriver().CoprocessorHasCap(SPINEL_CAP_MAC_RAW))
|
||||
{
|
||||
LogCrit("RCP capability list does not include support for radio/raw mode");
|
||||
DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
|
||||
HandleCompatibilityError();
|
||||
}
|
||||
|
||||
sSupportsLogStream = GetSpinelDriver().CoprocessorHasCap(SPINEL_CAP_OPENTHREAD_LOG_METADATA);
|
||||
@@ -251,7 +255,7 @@ otError RadioSpinel::CheckRadioCapabilities(otRadioCaps aRequiredRadioCaps)
|
||||
}
|
||||
}
|
||||
|
||||
DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
|
||||
HandleCompatibilityError();
|
||||
}
|
||||
|
||||
exit:
|
||||
@@ -279,7 +283,7 @@ otError RadioSpinel::CheckRcpApiVersion(bool aSupportsRcpApiVersion, bool aSuppo
|
||||
LogCrit("RCP and host are using incompatible API versions");
|
||||
LogCrit("RCP API Version %u is older than min required by host %u", rcpApiVersion,
|
||||
SPINEL_MIN_HOST_SUPPORTED_RCP_API_VERSION);
|
||||
DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
|
||||
HandleCompatibilityError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,7 +303,7 @@ otError RadioSpinel::CheckRcpApiVersion(bool aSupportsRcpApiVersion, bool aSuppo
|
||||
LogCrit("RCP and host are using incompatible API versions");
|
||||
LogCrit("RCP requires min host API version %u but host is older and at version %u", minHostRcpApiVersion,
|
||||
SPINEL_RCP_API_VERSION);
|
||||
DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
|
||||
HandleCompatibilityError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2399,5 +2403,24 @@ exit:
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE
|
||||
|
||||
#if OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE
|
||||
void RadioSpinel::SetCompatibilityErrorCallback(otRadioSpinelCompatibilityErrorCallback aCallback, void *aContext)
|
||||
{
|
||||
mCompatibilityErrorCallback = aCallback;
|
||||
mCompatibilityErrorContext = aContext;
|
||||
}
|
||||
#endif
|
||||
|
||||
void RadioSpinel::HandleCompatibilityError(void)
|
||||
{
|
||||
#if OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE
|
||||
if (mCompatibilityErrorCallback)
|
||||
{
|
||||
mCompatibilityErrorCallback(mCompatibilityErrorContext);
|
||||
}
|
||||
#endif
|
||||
DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
|
||||
}
|
||||
|
||||
} // namespace Spinel
|
||||
} // namespace ot
|
||||
|
||||
@@ -1006,8 +1006,10 @@ public:
|
||||
|
||||
/**
|
||||
* A callback type for restoring vendor properties.
|
||||
*
|
||||
* @param[in] aContext A pointer to the user context.
|
||||
*/
|
||||
typedef void (*otRadioSpinelVendorRestorePropertiesCallback)(void *context);
|
||||
typedef void (*otRadioSpinelVendorRestorePropertiesCallback)(void *aContext);
|
||||
|
||||
/**
|
||||
* Registers a callback to restore vendor properties.
|
||||
@@ -1016,11 +1018,32 @@ public:
|
||||
* properties occurs (such as an unexpected RCP reset), the user can restore the vendor properties via the callback.
|
||||
*
|
||||
* @param[in] aCallback The callback.
|
||||
* @param[in] aContext The context.
|
||||
* @param[in] aContext A pointer to the user context.
|
||||
*/
|
||||
void SetVendorRestorePropertiesCallback(otRadioSpinelVendorRestorePropertiesCallback aCallback, void *aContext);
|
||||
#endif // OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE
|
||||
|
||||
#if OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE
|
||||
/**
|
||||
* A callback type for handling compatibility error of radio spinel.
|
||||
*
|
||||
* @param[in] aContext A pointer to the user context.
|
||||
*/
|
||||
typedef void (*otRadioSpinelCompatibilityErrorCallback)(void *aContext);
|
||||
|
||||
/**
|
||||
* Registers a callback to handle error of radio spinel.
|
||||
*
|
||||
* This function is used to register a callback to handle radio spinel compatibility errors. When a radio spinel
|
||||
* compatibility error occurs that cannot be resolved by a restart (e.g., RCP version mismatch), the user can
|
||||
* handle the error through the callback(such as OTA) instead of letting the program crash directly.
|
||||
*
|
||||
* @param[in] aCallback The callback.
|
||||
* @param[in] aContext A pointer to the user context.
|
||||
*/
|
||||
void SetCompatibilityErrorCallback(otRadioSpinelCompatibilityErrorCallback aCallback, void *aContext);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Enables or disables the time synchronization between the host and RCP.
|
||||
*
|
||||
@@ -1155,6 +1178,8 @@ private:
|
||||
void PlatDiagOutput(const char *aFormat, ...);
|
||||
#endif
|
||||
|
||||
void HandleCompatibilityError(void);
|
||||
|
||||
otInstance *mInstance;
|
||||
|
||||
RadioSpinelCallbacks mCallbacks; ///< Callbacks for notifications of higher layer.
|
||||
@@ -1262,6 +1287,11 @@ private:
|
||||
void *mVendorRestorePropertiesContext;
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE
|
||||
otRadioSpinelCompatibilityErrorCallback mCompatibilityErrorCallback;
|
||||
void *mCompatibilityErrorContext;
|
||||
#endif
|
||||
|
||||
bool mTimeSyncEnabled : 1;
|
||||
bool mTimeSyncOn : 1;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user