|
25 | 25 | #include "openthread/platform/time.h" |
26 | 26 | #include "platform/exit_code.h" |
27 | 27 | #include "spinel_driver.hpp" |
| 28 | +#include <cstring> |
| 29 | + |
| 30 | +#define OT_SPINEL_RCP_VERSION_MAX_SIZE 100 |
28 | 31 |
|
29 | 32 | using ot::Spinel::RadioSpinel; |
30 | 33 | using esp::openthread::SpinelInterfaceAdapter; |
@@ -56,34 +59,7 @@ static const esp_openthread_radio_config_t *s_esp_openthread_radio_config = NULL |
56 | 59 |
|
57 | 60 | static esp_openthread_compatibility_error_callback s_compatibility_error_callback = NULL; |
58 | 61 |
|
59 | | -#if CONFIG_EXTERNAL_COEX_ENABLE |
60 | | - |
61 | | -#define SPINEL_PROP_VENDOR_ESP_COEX_EVENT (SPINEL_PROP_VENDOR_ESP__BEGIN + 3) |
62 | | - |
63 | | -static esp_ieee802154_coex_config_t s_coex_config = { |
64 | | - .idle = IEEE802154_IDLE, |
65 | | - .txrx = IEEE802154_LOW, |
66 | | - .txrx_at = IEEE802154_MIDDLE, |
67 | | -}; |
68 | | - |
69 | | -static void esp_openthread_restore_coex_config(void *context) |
70 | | -{ |
71 | | - esp_openthread_set_coex_config(s_coex_config); |
72 | | -} |
73 | | - |
74 | | -static esp_err_t esp_openthread_radio_spinel_coex_config_init(void) |
75 | | -{ |
76 | | - s_radio.SetVendorRestorePropertiesCallback(esp_openthread_restore_coex_config, esp_openthread_get_instance()); |
77 | | - esp_ieee802154_coex_config_t coex_config; |
78 | | - uint16_t coex_config_len = 0; |
79 | | - ESP_RETURN_ON_ERROR(s_radio.Get(SPINEL_PROP_VENDOR_ESP_COEX_EVENT, SPINEL_DATATYPE_DATA_WLEN_S, &coex_config, &coex_config_len), |
80 | | - OT_PLAT_LOG_TAG, "Fail to get coex config"); |
81 | | - ESP_RETURN_ON_FALSE(coex_config_len == sizeof(esp_ieee802154_coex_config_t), ESP_FAIL, OT_PLAT_LOG_TAG, |
82 | | - "Fail to get coex config"); |
83 | | - s_coex_config = coex_config; |
84 | | - return ESP_OK; |
85 | | -} |
86 | | -#endif |
| 62 | +static char s_internal_rcp_version[OT_SPINEL_RCP_VERSION_MAX_SIZE] = {'\0'}; |
87 | 63 |
|
88 | 64 | static void esp_openthread_radio_config_set(const esp_openthread_radio_config_t *config) |
89 | 65 | { |
@@ -136,11 +112,18 @@ esp_err_t esp_openthread_radio_init(const esp_openthread_platform_config_t *conf |
136 | 112 | "Spinel interface init failed"); |
137 | 113 | #endif |
138 | 114 | s_spinel_driver.Init(s_spinel_interface.GetSpinelInterface(), true, iidList, ot::Spinel::kSpinelHeaderMaxNumIid); |
| 115 | + if (strlen(s_internal_rcp_version) > 0) { |
| 116 | + const char *running_rcp_version = s_spinel_driver.GetVersion(); |
| 117 | + if (strcmp(s_internal_rcp_version, running_rcp_version) != 0) { |
| 118 | + if (s_compatibility_error_callback) { |
| 119 | + s_compatibility_error_callback(); |
| 120 | + } else { |
| 121 | + ESP_LOGW(OT_PLAT_LOG_TAG, "The running rcp does not match the provided rcp"); |
| 122 | + } |
| 123 | + } |
| 124 | + } |
139 | 125 | s_radio.SetCompatibilityErrorCallback(ot_spinel_compatibility_error_callback, esp_openthread_get_instance()); |
140 | 126 | s_radio.Init(/*skip_rcp_compatibility_check=*/false, /*reset_radio=*/true, &s_spinel_driver, s_radio_caps, /*RCP_time_sync=*/true); |
141 | | -#if CONFIG_EXTERNAL_COEX_ENABLE |
142 | | - ESP_RETURN_ON_ERROR(esp_openthread_radio_spinel_coex_config_init(), OT_PLAT_LOG_TAG, "Coex config init failed"); |
143 | | -#endif |
144 | 127 | #if CONFIG_OPENTHREAD_RADIO_SPINEL_SPI // CONFIG_OPENTHREAD_RADIO_SPINEL_SPI |
145 | 128 | ESP_RETURN_ON_ERROR(s_spinel_interface.GetSpinelInterface().AfterRadioInit(), OT_PLAT_LOG_TAG, "Spinel interface init failed"); |
146 | 129 | #endif |
@@ -185,12 +168,24 @@ esp_err_t esp_openthread_rcp_init(void) |
185 | 168 | radiospinel_workflow); |
186 | 169 | } |
187 | 170 |
|
| 171 | +esp_err_t esp_openthread_rcp_version_set(const char *version_str) |
| 172 | +{ |
| 173 | + if (version_str == NULL) { |
| 174 | + memset(s_internal_rcp_version, 0, OT_SPINEL_RCP_VERSION_MAX_SIZE); |
| 175 | + return ESP_OK; |
| 176 | + } |
| 177 | + ESP_RETURN_ON_FALSE(strlen(version_str) > 0 && strlen(version_str) < OT_SPINEL_RCP_VERSION_MAX_SIZE, ESP_FAIL, OT_PLAT_LOG_TAG, "Invalid rcp version"); |
| 178 | + strcpy(s_internal_rcp_version, version_str); |
| 179 | + return ESP_OK; |
| 180 | +} |
| 181 | + |
188 | 182 | void esp_openthread_radio_deinit(void) |
189 | 183 | { |
190 | 184 | s_radio.Deinit(); |
191 | 185 | s_spinel_driver.Deinit(); |
192 | 186 | s_spinel_interface.GetSpinelInterface().Disable(); |
193 | 187 | esp_openthread_platform_workflow_unregister(radiospinel_workflow); |
| 188 | + s_compatibility_error_callback = NULL; |
194 | 189 | } |
195 | 190 |
|
196 | 191 | esp_err_t esp_openthread_radio_process(otInstance *instance, const esp_openthread_mainloop_context_t *mainloop) |
@@ -515,39 +510,3 @@ uint32_t otPlatRadioGetSupportedChannelMask(otInstance *aInstance) |
515 | 510 | // Refer to `GetRadioChannelMask(bool aPreferred)`: FALSE to get supported channel mask |
516 | 511 | return s_radio.GetRadioChannelMask(false); |
517 | 512 | } |
518 | | - |
519 | | -#if CONFIG_EXTERNAL_COEX_ENABLE |
520 | | - |
521 | | -void esp_openthread_set_coex_config(esp_ieee802154_coex_config_t config) |
522 | | -{ |
523 | | - otError err = s_radio.Set(SPINEL_PROP_VENDOR_ESP_COEX_EVENT, SPINEL_DATATYPE_DATA_WLEN_S, &s_coex_config, sizeof(esp_ieee802154_coex_config_t)); |
524 | | - ESP_RETURN_ON_FALSE(err == OT_ERROR_NONE, , OT_PLAT_LOG_TAG, "Fail to set coex config"); |
525 | | - s_coex_config = config; |
526 | | -} |
527 | | - |
528 | | -esp_ieee802154_coex_config_t esp_openthread_get_coex_config(void) |
529 | | -{ |
530 | | - return s_coex_config; |
531 | | -} |
532 | | - |
533 | | -namespace ot { |
534 | | -namespace Spinel { |
535 | | - |
536 | | -otError RadioSpinel::VendorHandleValueIs(spinel_prop_key_t aPropKey) |
537 | | -{ |
538 | | - otError error = OT_ERROR_NONE; |
539 | | - |
540 | | - switch (aPropKey) |
541 | | - { |
542 | | - default: |
543 | | - ESP_LOGW(OT_PLAT_LOG_TAG, "Not Implemented!"); |
544 | | - error = OT_ERROR_NOT_FOUND; |
545 | | - break; |
546 | | - } |
547 | | - return error; |
548 | | -} |
549 | | - |
550 | | -} // namespace Spinel |
551 | | -} // namespace ot |
552 | | - |
553 | | -#endif |
0 commit comments