Skip to content

Commit

Permalink
[spinel] allow registering callback to handle compatability errors
Browse files Browse the repository at this point in the history
  • Loading branch information
gytxxsy committed Sep 24, 2024
1 parent d015004 commit 40e7b3e
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 8 deletions.
10 changes: 10 additions & 0 deletions src/lib/spinel/openthread-spinel-config.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,16 @@
#define OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE 0
#endif

/**
* @def OPENTHREAD_SPINEL_CONFIG_COMPATABILITY_ERROR_CALLBACK_ENABLE
*
* Enables compilation of compatability error callback code for Spinel
*
*/
#ifndef OPENTHREAD_SPINEL_CONFIG_COMPATABILITY_ERROR_CALLBACK_ENABLE
#define OPENTHREAD_SPINEL_CONFIG_COMPATABILITY_ERROR_CALLBACK_ENABLE 0
#endif

/**
* @def OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_HEADER
*
Expand Down
35 changes: 29 additions & 6 deletions src/lib/spinel/radio_spinel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ RadioSpinel::RadioSpinel(void)
#if OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE
, mVendorRestorePropertiesCallback(nullptr)
, mVendorRestorePropertiesContext(nullptr)
#endif
#if OPENTHREAD_SPINEL_CONFIG_COMPATABILITY_ERROR_CALLBACK_ENABLE
, mCompatabilityErrorCallback(nullptr)
, mCompatabilityErrorContext(nullptr)
#endif
, mTimeSyncEnabled(false)
, mTimeSyncOn(false)
Expand Down Expand Up @@ -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);
HandleCompatabilityError();
}

exit:
Expand All @@ -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);
HandleCompatabilityError();
}

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);
HandleCompatabilityError();
}

sSupportsLogStream = GetSpinelDriver().CoprocessorHasCap(SPINEL_CAP_OPENTHREAD_LOG_METADATA);
Expand Down Expand Up @@ -251,7 +255,7 @@ otError RadioSpinel::CheckRadioCapabilities(otRadioCaps aRequiredRadioCaps)
}
}

DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
HandleCompatabilityError();
}

exit:
Expand Down Expand Up @@ -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);
HandleCompatabilityError();
}
}

Expand All @@ -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);
HandleCompatabilityError();
}
}

Expand Down Expand Up @@ -2395,5 +2399,24 @@ otError RadioSpinel::SetChannelTargetPower(uint8_t aChannel, int16_t aTargetPowe
}
#endif // OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE

#if OPENTHREAD_SPINEL_CONFIG_COMPATABILITY_ERROR_CALLBACK_ENABLE
void RadioSpinel::SetCompatabilityErrorCallback(otRadioSpinelCompatabilityErrorCallback aCallback, void *aContext)
{
mCompatabilityErrorCallback = aCallback;
mCompatabilityErrorContext = aContext;
}
#endif // OPENTHREAD_SPINEL_CONFIG_COMPATABILITY_ERROR_CALLBACK_ENABLE

void RadioSpinel::HandleCompatabilityError(void)
{
#if OPENTHREAD_SPINEL_CONFIG_COMPATABILITY_ERROR_CALLBACK_ENABLE
if (mCompatabilityErrorCallback)
{
mCompatabilityErrorCallback(mCompatabilityErrorContext);
}
#endif // OPENTHREAD_SPINEL_CONFIG_COMPATABILITY_ERROR_CALLBACK_ENABLE
DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
}

} // namespace Spinel
} // namespace ot
37 changes: 35 additions & 2 deletions src/lib/spinel/radio_spinel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1090,8 +1090,10 @@ class RadioSpinel : private Logger
/**
* 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.
Expand All @@ -1100,12 +1102,36 @@ class RadioSpinel : private Logger
* 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_COMPATABILITY_ERROR_CALLBACK_ENABLE
/**
* A callback type for handling compatability error of radio spinel.
*
* @param[in] aContext A pointer to the user context.
*
*/
typedef void (*otRadioSpinelCompatabilityErrorCallback)(void *aContext);

/**
* Registers a callback to handle error of radio spinel.
*
* This function is used to register a callback to handle radio spinel compatability errors. When a radio spinel
* compatability 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 SetCompatabilityErrorCallback(otRadioSpinelCompatabilityErrorCallback aCallback, void *aContext);
#endif

/**
* Enables or disables the time synchronization between the host and RCP.
*
Expand Down Expand Up @@ -1244,6 +1270,8 @@ class RadioSpinel : private Logger
void PlatDiagOutput(const char *aFormat, ...);
#endif

void HandleCompatabilityError(void);

otInstance *mInstance;

RadioSpinelCallbacks mCallbacks; ///< Callbacks for notifications of higher layer.
Expand Down Expand Up @@ -1349,6 +1377,11 @@ class RadioSpinel : private Logger
void *mVendorRestorePropertiesContext;
#endif

#if OPENTHREAD_SPINEL_CONFIG_COMPATABILITY_ERROR_CALLBACK_ENABLE
otRadioSpinelCompatabilityErrorCallback mCompatabilityErrorCallback;
void *mCompatabilityErrorContext;
#endif

bool mTimeSyncEnabled : 1;
bool mTimeSyncOn : 1;

Expand Down

0 comments on commit 40e7b3e

Please sign in to comment.