Skip to content

Commit 58e2098

Browse files
committed
[spinel] allow registering callback to handle compatibility errors
1 parent 287dbfa commit 58e2098

File tree

3 files changed

+70
-8
lines changed

3 files changed

+70
-8
lines changed

src/lib/spinel/openthread-spinel-config.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,15 @@
136136
#define OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE 0
137137
#endif
138138

139+
/**
140+
* @def OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE
141+
*
142+
* Enables compatibility error callback in Spinel
143+
*/
144+
#ifndef OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE
145+
#define OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE 0
146+
#endif
147+
139148
/**
140149
* @def OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_HEADER
141150
*

src/lib/spinel/radio_spinel.cpp

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ RadioSpinel::RadioSpinel(void)
111111
#if OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE
112112
, mVendorRestorePropertiesCallback(nullptr)
113113
, mVendorRestorePropertiesContext(nullptr)
114+
#endif
115+
#if OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE
116+
, mCompatibilityErrorCallback(nullptr)
117+
, mCompatibilityErrorContext(nullptr)
114118
#endif
115119
, mTimeSyncEnabled(false)
116120
, mTimeSyncOn(false)
@@ -198,7 +202,7 @@ otError RadioSpinel::CheckSpinelVersion(void)
198202
{
199203
LogCrit("Spinel version mismatch - Posix:%d.%d, RCP:%d.%d", SPINEL_PROTOCOL_VERSION_THREAD_MAJOR,
200204
SPINEL_PROTOCOL_VERSION_THREAD_MINOR, versionMajor, versionMinor);
201-
DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
205+
HandleCompatibilityError();
202206
}
203207

204208
exit:
@@ -210,13 +214,13 @@ void RadioSpinel::InitializeCaps(bool &aSupportsRcpApiVersion, bool &aSupportsRc
210214
if (!GetSpinelDriver().CoprocessorHasCap(SPINEL_CAP_CONFIG_RADIO))
211215
{
212216
LogCrit("The co-processor isn't a RCP!");
213-
DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
217+
HandleCompatibilityError();
214218
}
215219

216220
if (!GetSpinelDriver().CoprocessorHasCap(SPINEL_CAP_MAC_RAW))
217221
{
218222
LogCrit("RCP capability list does not include support for radio/raw mode");
219-
DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
223+
HandleCompatibilityError();
220224
}
221225

222226
sSupportsLogStream = GetSpinelDriver().CoprocessorHasCap(SPINEL_CAP_OPENTHREAD_LOG_METADATA);
@@ -251,7 +255,7 @@ otError RadioSpinel::CheckRadioCapabilities(otRadioCaps aRequiredRadioCaps)
251255
}
252256
}
253257

254-
DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
258+
HandleCompatibilityError();
255259
}
256260

257261
exit:
@@ -279,7 +283,7 @@ otError RadioSpinel::CheckRcpApiVersion(bool aSupportsRcpApiVersion, bool aSuppo
279283
LogCrit("RCP and host are using incompatible API versions");
280284
LogCrit("RCP API Version %u is older than min required by host %u", rcpApiVersion,
281285
SPINEL_MIN_HOST_SUPPORTED_RCP_API_VERSION);
282-
DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
286+
HandleCompatibilityError();
283287
}
284288
}
285289

@@ -299,7 +303,7 @@ otError RadioSpinel::CheckRcpApiVersion(bool aSupportsRcpApiVersion, bool aSuppo
299303
LogCrit("RCP and host are using incompatible API versions");
300304
LogCrit("RCP requires min host API version %u but host is older and at version %u", minHostRcpApiVersion,
301305
SPINEL_RCP_API_VERSION);
302-
DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
306+
HandleCompatibilityError();
303307
}
304308
}
305309

@@ -2395,5 +2399,24 @@ otError RadioSpinel::SetChannelTargetPower(uint8_t aChannel, int16_t aTargetPowe
23952399
}
23962400
#endif // OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE
23972401

2402+
#if OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE
2403+
void RadioSpinel::SetCompatibilityErrorCallback(otRadioSpinelCompatibilityErrorCallback aCallback, void *aContext)
2404+
{
2405+
mCompatibilityErrorCallback = aCallback;
2406+
mCompatibilityErrorContext = aContext;
2407+
}
2408+
#endif
2409+
2410+
void RadioSpinel::HandleCompatibilityError(void)
2411+
{
2412+
#if OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE
2413+
if (mCompatibilityErrorCallback)
2414+
{
2415+
mCompatibilityErrorCallback(mCompatibilityErrorContext);
2416+
}
2417+
#endif
2418+
DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
2419+
}
2420+
23982421
} // namespace Spinel
23992422
} // namespace ot

src/lib/spinel/radio_spinel.hpp

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,8 +1006,10 @@ class RadioSpinel : private Logger
10061006

10071007
/**
10081008
* A callback type for restoring vendor properties.
1009+
*
1010+
* @param[in] aContext A pointer to the user context.
10091011
*/
1010-
typedef void (*otRadioSpinelVendorRestorePropertiesCallback)(void *context);
1012+
typedef void (*otRadioSpinelVendorRestorePropertiesCallback)(void *aContext);
10111013

10121014
/**
10131015
* Registers a callback to restore vendor properties.
@@ -1016,11 +1018,32 @@ class RadioSpinel : private Logger
10161018
* properties occurs (such as an unexpected RCP reset), the user can restore the vendor properties via the callback.
10171019
*
10181020
* @param[in] aCallback The callback.
1019-
* @param[in] aContext The context.
1021+
* @param[in] aContext A pointer to the user context.
10201022
*/
10211023
void SetVendorRestorePropertiesCallback(otRadioSpinelVendorRestorePropertiesCallback aCallback, void *aContext);
10221024
#endif // OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE
10231025

1026+
#if OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE
1027+
/**
1028+
* A callback type for handling compatibility error of radio spinel.
1029+
*
1030+
* @param[in] aContext A pointer to the user context.
1031+
*/
1032+
typedef void (*otRadioSpinelCompatibilityErrorCallback)(void *aContext);
1033+
1034+
/**
1035+
* Registers a callback to handle error of radio spinel.
1036+
*
1037+
* This function is used to register a callback to handle radio spinel compatibility errors. When a radio spinel
1038+
* compatibility error occurs that cannot be resolved by a restart (e.g., RCP version mismatch), the user can
1039+
* handle the error through the callback(such as OTA) instead of letting the program crash directly.
1040+
*
1041+
* @param[in] aCallback The callback.
1042+
* @param[in] aContext A pointer to the user context.
1043+
*/
1044+
void SetCompatibilityErrorCallback(otRadioSpinelCompatibilityErrorCallback aCallback, void *aContext);
1045+
#endif
1046+
10241047
/**
10251048
* Enables or disables the time synchronization between the host and RCP.
10261049
*
@@ -1155,6 +1178,8 @@ class RadioSpinel : private Logger
11551178
void PlatDiagOutput(const char *aFormat, ...);
11561179
#endif
11571180

1181+
void HandleCompatibilityError(void);
1182+
11581183
otInstance *mInstance;
11591184

11601185
RadioSpinelCallbacks mCallbacks; ///< Callbacks for notifications of higher layer.
@@ -1262,6 +1287,11 @@ class RadioSpinel : private Logger
12621287
void *mVendorRestorePropertiesContext;
12631288
#endif
12641289

1290+
#if OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE
1291+
otRadioSpinelCompatibilityErrorCallback mCompatibilityErrorCallback;
1292+
void *mCompatibilityErrorContext;
1293+
#endif
1294+
12651295
bool mTimeSyncEnabled : 1;
12661296
bool mTimeSyncOn : 1;
12671297

0 commit comments

Comments
 (0)