From b6c5152231721375b6665c10f898de9e56d26442 Mon Sep 17 00:00:00 2001 From: Xu Si Yu Date: Thu, 27 Feb 2025 16:53:56 +0800 Subject: [PATCH 1/4] feat(openthread): add a function to ensure monotonically increasing frame counter --- components/openthread/src/port/esp_openthread_radio.c | 9 +++++++++ .../openthread/src/port/esp_openthread_radio_spinel.cpp | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/components/openthread/src/port/esp_openthread_radio.c b/components/openthread/src/port/esp_openthread_radio.c index 7caf21fc3a..5fa6205213 100644 --- a/components/openthread/src/port/esp_openthread_radio.c +++ b/components/openthread/src/port/esp_openthread_radio.c @@ -528,6 +528,15 @@ void otPlatRadioSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCoun s_mac_frame_counter = aMacFrameCounter; } + +void otPlatRadioSetMacFrameCounterIfLarger(otInstance *aInstance, uint32_t aMacFrameCounter) +{ + OT_UNUSED_VARIABLE(aInstance); + + if (aMacFrameCounter > s_mac_frame_counter) { + s_mac_frame_counter = aMacFrameCounter; + } +} #endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 uint64_t otPlatRadioGetNow(otInstance *aInstance) diff --git a/components/openthread/src/port/esp_openthread_radio_spinel.cpp b/components/openthread/src/port/esp_openthread_radio_spinel.cpp index 615728807f..17fa36bbe6 100644 --- a/components/openthread/src/port/esp_openthread_radio_spinel.cpp +++ b/components/openthread/src/port/esp_openthread_radio_spinel.cpp @@ -380,6 +380,11 @@ void otPlatRadioSetMacKey(otInstance *aInstance, uint8_t aKeyIdMode, uint8_t aKe } void otPlatRadioSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCounter) +{ + SuccessOrDie(s_radio.SetMacFrameCounter(aMacFrameCounter, false)); +} + +void otPlatRadioSetMacFrameCounterIfLarger(otInstance *aInstance, uint32_t aMacFrameCounter) { SuccessOrDie(s_radio.SetMacFrameCounter(aMacFrameCounter, true)); } From 6aa0f96ae83e05865d5e35ca408a26236741654b Mon Sep 17 00:00:00 2001 From: Xu Si Yu Date: Wed, 16 Apr 2025 16:27:29 +0800 Subject: [PATCH 2/4] fix(openthread): use esp_netif_tcpip_exec when sending a trel message --- .../openthread/src/port/esp_openthread_trel.c | 90 ++++++++----------- 1 file changed, 35 insertions(+), 55 deletions(-) diff --git a/components/openthread/src/port/esp_openthread_trel.c b/components/openthread/src/port/esp_openthread_trel.c index 91603b4bd0..3c56e7a1c1 100644 --- a/components/openthread/src/port/esp_openthread_trel.c +++ b/components/openthread/src/port/esp_openthread_trel.c @@ -91,6 +91,8 @@ static void trel_browse_notifier(mdns_result_t *result) static void trel_recv_task(void *ctx) { + esp_err_t ret = ESP_OK; + OT_UNUSED_VARIABLE(ret); ot_trel_recv_task_t *task_ctx = (ot_trel_recv_task_t *)ctx; struct pbuf *recv_buf = task_ctx->p; uint8_t *data_buf = (uint8_t *)recv_buf->payload; @@ -99,58 +101,47 @@ static void trel_recv_task(void *ctx) if (recv_buf->next != NULL) { data_buf = (uint8_t *)malloc(recv_buf->tot_len); - if (data_buf != NULL) { - length = recv_buf->tot_len; - data_buf_to_free = data_buf; - pbuf_copy_partial(recv_buf, data_buf, recv_buf->tot_len, 0); - } else { - ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to allocate data buf when receiving Thread TREL message"); - ExitNow(); - } + ESP_GOTO_ON_FALSE(data_buf, ESP_ERR_NO_MEM, exit, OT_PLAT_LOG_TAG, "Failed to allocate data buf when receiving Thread TREL message"); + length = recv_buf->tot_len; + data_buf_to_free = data_buf; + pbuf_copy_partial(recv_buf, data_buf, recv_buf->tot_len, 0); } otPlatTrelHandleReceived(esp_openthread_get_instance(), data_buf, length, task_ctx->source_addr); exit: - if (data_buf_to_free) { - free(data_buf_to_free); - } - pbuf_free(recv_buf); - if(task_ctx) { - free(task_ctx->source_addr); + if (recv_buf) { + pbuf_free(recv_buf); } + free(data_buf_to_free); + free(task_ctx->source_addr); free(task_ctx); } +// TZ-1704 static void handle_trel_udp_recv(void *ctx, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, uint16_t port) { + esp_err_t ret = ESP_OK; ESP_LOGD(OT_PLAT_LOG_TAG, "Receive from %s:%d", ip6addr_ntoa(&(addr->u_addr.ip6)), port); ot_trel_recv_task_t *task_ctx = (ot_trel_recv_task_t *)malloc(sizeof(ot_trel_recv_task_t)); - if (task_ctx == NULL) { - ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to allocate buf for Thread TREL"); - ExitNow(); - } + ESP_GOTO_ON_FALSE(task_ctx, ESP_ERR_NO_MEM, exit, OT_PLAT_LOG_TAG, "Failed to allocate buf for Thread TREL"); task_ctx->p = p; task_ctx->source_addr = (otSockAddr *)malloc(sizeof(otSockAddr)); - if (task_ctx->source_addr == NULL) { - ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to allocate buf for Thread TREL"); - ExitNow(); - } + ESP_GOTO_ON_FALSE(task_ctx->source_addr, ESP_ERR_NO_MEM, exit, OT_PLAT_LOG_TAG, "Failed to allocate buf for Thread TREL"); memset(task_ctx->source_addr, 0, sizeof(otSockAddr)); task_ctx->source_addr->mPort = port; memcpy(&task_ctx->source_addr->mAddress.mFields.m32, addr->u_addr.ip6.addr, sizeof(addr->u_addr.ip6.addr)); - if (esp_openthread_task_queue_post(trel_recv_task, task_ctx) != ESP_OK) { - ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to receive OpenThread TREL message"); - ExitNow(); - } - return; + ESP_GOTO_ON_ERROR(esp_openthread_task_queue_post(trel_recv_task, task_ctx), exit, OT_PLAT_LOG_TAG, "Failed to receive OpenThread TREL message"); + exit: - if(task_ctx) { + if (ret != ESP_OK) { free(task_ctx->source_addr); + free(task_ctx); + if (p) { + pbuf_free(p); + } } - free(task_ctx); - pbuf_free(p); } static esp_err_t ot_new_trel(void *ctx) @@ -176,7 +167,7 @@ void otPlatTrelEnable(otInstance *aInstance, uint16_t *aUdpPort) esp_openthread_task_switching_lock_acquire(portMAX_DELAY); } -static void trel_send_task(void *ctx) +static esp_err_t trel_send_task(void *ctx) { err_t err = ERR_OK; struct pbuf *send_buf = NULL; @@ -190,18 +181,12 @@ static void trel_send_task(void *ctx) task->pcb->flags = (task->pcb->flags & (~UDP_FLAGS_MULTICAST_LOOP)); task->pcb->local_port = s_ot_trel.port; send_buf = pbuf_alloc(PBUF_TRANSPORT, task->length, PBUF_RAM); - if (send_buf == NULL) { - ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to allocate data buf when sending Thread TREL message"); - ExitNow(); - } + ESP_RETURN_ON_FALSE(send_buf, ESP_ERR_NO_MEM, OT_PLAT_LOG_TAG, "Failed to allocate data buf when sending Thread TREL message"); memcpy(send_buf->payload, task->payload, task->length); err = udp_sendto_if(task->pcb, send_buf, &task->peer_addr, task->peer_port, netif_get_by_index(task->pcb->netif_idx)); - if(err != ERR_OK) { - ESP_LOGE(OT_PLAT_LOG_TAG, "Fail to send trel msg to %s:%d %d (%d)", ip6addr_ntoa(&(task->peer_addr.u_addr.ip6)), task->peer_port, task->pcb->netif_idx, err); - } -exit: pbuf_free(send_buf); - free(task); + ESP_RETURN_ON_FALSE(err == ERR_OK, ESP_FAIL, OT_PLAT_LOG_TAG, "Fail to send trel msg to %s:%d %d (%d)", ip6addr_ntoa(&(task->peer_addr.u_addr.ip6)), task->peer_port, task->pcb->netif_idx, err); + return ESP_OK; } void otPlatTrelSend(otInstance *aInstance, @@ -209,23 +194,18 @@ void otPlatTrelSend(otInstance *aInstance, uint16_t aUdpPayloadLen, const otSockAddr *aDestSockAddr) { - if (!s_trel_netif) { - ESP_LOGE(OT_PLAT_LOG_TAG, "None Thread TREL interface"); - return; - } - ot_trel_send_task_t *task = (ot_trel_send_task_t *)malloc(sizeof(ot_trel_send_task_t)); - if (task == NULL) { - ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to allocate buf for Thread TREL"); - return; - } - memcpy(task->peer_addr.u_addr.ip6.addr, aDestSockAddr->mAddress.mFields.m32, OT_IP6_ADDRESS_SIZE); - task->peer_port = aDestSockAddr->mPort; - ESP_LOGD(OT_PLAT_LOG_TAG, "send trel msg to %s:%d", ip6addr_ntoa(&(task->peer_addr.u_addr.ip6)), task->peer_port); - task->payload = aUdpPayload; - task->length = aUdpPayloadLen; + esp_err_t err = ESP_OK; + ot_trel_send_task_t task; + + ESP_RETURN_ON_FALSE(s_trel_netif, , OT_PLAT_LOG_TAG, "None Thread TREL interface"); + memcpy(task.peer_addr.u_addr.ip6.addr, aDestSockAddr->mAddress.mFields.m32, OT_IP6_ADDRESS_SIZE); + task.peer_port = aDestSockAddr->mPort; + task.payload = aUdpPayload; + task.length = aUdpPayloadLen; esp_openthread_task_switching_lock_release(); - tcpip_callback(trel_send_task, task); + err = esp_netif_tcpip_exec(trel_send_task, &task); esp_openthread_task_switching_lock_acquire(portMAX_DELAY); + ESP_RETURN_ON_FALSE(err == ESP_OK, , OT_PLAT_LOG_TAG, "Failed to send TREL message"); } void otPlatTrelNotifyPeerSocketAddressDifference(otInstance *aInstance, From 105fe8d804a43f794e626a6f1b8a3ab3ef5d2e73 Mon Sep 17 00:00:00 2001 From: Xu Si Yu Date: Thu, 24 Apr 2025 12:12:22 +0800 Subject: [PATCH 3/4] feat(openthread): dns server of border router bind unspecified netif --- .../private_include/openthread-core-esp32x-ftd-config.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/components/openthread/private_include/openthread-core-esp32x-ftd-config.h b/components/openthread/private_include/openthread-core-esp32x-ftd-config.h index 1eec63bc70..942ceeb6bf 100644 --- a/components/openthread/private_include/openthread-core-esp32x-ftd-config.h +++ b/components/openthread/private_include/openthread-core-esp32x-ftd-config.h @@ -440,6 +440,15 @@ #define OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE 1 #endif +/** + * @def OPENTHREAD_CONFIG_DNSSD_SERVER_BIND_UNSPECIFIED_NETIF + * + * Define to 1 to bind DNS-SD server to unspecified interface, 0 to bind to Thread interface. + */ +#ifndef OPENTHREAD_CONFIG_DNSSD_SERVER_BIND_UNSPECIFIED_NETIF +#define OPENTHREAD_CONFIG_DNSSD_SERVER_BIND_UNSPECIFIED_NETIF 1 +#endif + /** * @def OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE * From 300a5ed9f4efee8508af0c3b65d296468592be6f Mon Sep 17 00:00:00 2001 From: Xu Si Yu Date: Fri, 18 Apr 2025 16:51:49 +0800 Subject: [PATCH 4/4] feat(openthread): add a callback to handle rcp reset failure --- .../include/esp_openthread_spinel.h | 10 ++++++++ .../openthread/include/esp_openthread_types.h | 6 +++++ .../openthread/include/esp_radio_spinel.h | 13 +++++++++- .../openthread-core-esp32x-ftd-config.h | 9 +++++++ .../openthread-core-esp32x-spinel-config.h | 9 +++++++ .../src/port/esp_openthread_radio_spinel.cpp | 25 ++++++++++++------- .../src/spinel/esp_radio_spinel.cpp | 25 +++++++++++++------ 7 files changed, 80 insertions(+), 17 deletions(-) diff --git a/components/openthread/include/esp_openthread_spinel.h b/components/openthread/include/esp_openthread_spinel.h index 70c74413e2..2900095420 100644 --- a/components/openthread/include/esp_openthread_spinel.h +++ b/components/openthread/include/esp_openthread_spinel.h @@ -29,6 +29,16 @@ void esp_openthread_register_rcp_failure_handler(esp_openthread_rcp_failure_hand */ void esp_openthread_set_compatibility_error_callback(esp_openthread_compatibility_error_callback callback); +/** + * @brief Registers the callback for co-processor reset failure. + * + * @note This function should be called before esp_openthread_init. + * + * @param[in] callback The callback. + * + */ +void esp_openthread_set_coprocessor_reset_failure_callback(esp_openthread_coprocessor_reset_failure_callback callback); + /** * @brief Deinitializes the connection to RCP. * diff --git a/components/openthread/include/esp_openthread_types.h b/components/openthread/include/esp_openthread_types.h index df552ed142..364d596100 100644 --- a/components/openthread/include/esp_openthread_types.h +++ b/components/openthread/include/esp_openthread_types.h @@ -210,6 +210,12 @@ typedef void (*esp_openthread_rcp_failure_handler)(void); */ typedef void (*esp_openthread_compatibility_error_callback)(void); +/** + * @brief The OpenThread co-processor reset failure callback + * + */ +typedef void (*esp_openthread_coprocessor_reset_failure_callback)(void); + #ifdef __cplusplus } #endif diff --git a/components/openthread/include/esp_radio_spinel.h b/components/openthread/include/esp_radio_spinel.h index 710d61d646..3f21e9e198 100644 --- a/components/openthread/include/esp_radio_spinel.h +++ b/components/openthread/include/esp_radio_spinel.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -47,6 +47,7 @@ typedef void (*esp_radio_spinel_rcp_failure_handler)(void); typedef esp_err_t (*esp_radio_spinel_uart_init_handler)(const esp_radio_spinel_uart_config_t *uart_config_t, int *uart_fd); /* The handler for UART initialization.*/ typedef esp_err_t (*esp_radio_spinel_uart_deinit_handler)(const esp_radio_spinel_uart_config_t *uart_config_t, int *uart_fd); /* The handler for UART deinitialization.*/ typedef void (*esp_radio_spinel_compatibility_error_callback)(void); +typedef void (*esp_radio_spinel_coprocessor_reset_failure_callback)(void); typedef struct { @@ -402,6 +403,16 @@ esp_err_t esp_radio_spinel_rcp_version_get(char *running_rcp_version, esp_radio_ */ void esp_radio_spinel_set_compatibility_error_callback(esp_radio_spinel_compatibility_error_callback callback); +/** + * @brief Registers the callback for co-processor reset failure. + * + * @note This function should be called before esp_radio_spinel_init. + * + * @param[in] callback The callback. + * + */ +void esp_radio_spinel_set_coprocessor_reset_failure_callback(esp_radio_spinel_coprocessor_reset_failure_callback callback); + #ifdef __cplusplus } #endif diff --git a/components/openthread/private_include/openthread-core-esp32x-ftd-config.h b/components/openthread/private_include/openthread-core-esp32x-ftd-config.h index 942ceeb6bf..59d3780fa9 100644 --- a/components/openthread/private_include/openthread-core-esp32x-ftd-config.h +++ b/components/openthread/private_include/openthread-core-esp32x-ftd-config.h @@ -513,6 +513,15 @@ #define OPENTHREAD_POSIX_CONFIG_RCP_TIME_SYNC_INTERVAL (60 * 1000 * 1000) #endif +/** + * @def OPENTHREAD_SPINEL_CONFIG_COPROCESSOR_RESET_FAILURE_CALLBACK_ENABLE + * + * Enables co-processor reset failure callback in Spinel driver + */ +#ifndef OPENTHREAD_SPINEL_CONFIG_COPROCESSOR_RESET_FAILURE_CALLBACK_ENABLE +#define OPENTHREAD_SPINEL_CONFIG_COPROCESSOR_RESET_FAILURE_CALLBACK_ENABLE 1 +#endif + #endif // CONFIG_OPENTHREAD_RADIO_SPINEL_UART || CONFIG_OPENTHREAD_RADIO_SPINEL_SPI #if CONFIG_OPENTHREAD_LINK_METRICS diff --git a/components/openthread/private_include/openthread-core-esp32x-spinel-config.h b/components/openthread/private_include/openthread-core-esp32x-spinel-config.h index 350a21c6dc..7c3853ecb5 100644 --- a/components/openthread/private_include/openthread-core-esp32x-spinel-config.h +++ b/components/openthread/private_include/openthread-core-esp32x-spinel-config.h @@ -67,3 +67,12 @@ #ifndef OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE #define OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE 1 #endif + +/** + * @def OPENTHREAD_SPINEL_CONFIG_COPROCESSOR_RESET_FAILURE_CALLBACK_ENABLE + * + * Enables co-processor reset failure callback in Spinel driver + */ +#ifndef OPENTHREAD_SPINEL_CONFIG_COPROCESSOR_RESET_FAILURE_CALLBACK_ENABLE +#define OPENTHREAD_SPINEL_CONFIG_COPROCESSOR_RESET_FAILURE_CALLBACK_ENABLE 1 +#endif diff --git a/components/openthread/src/port/esp_openthread_radio_spinel.cpp b/components/openthread/src/port/esp_openthread_radio_spinel.cpp index 17fa36bbe6..2a2995483e 100644 --- a/components/openthread/src/port/esp_openthread_radio_spinel.cpp +++ b/components/openthread/src/port/esp_openthread_radio_spinel.cpp @@ -54,11 +54,9 @@ static otRadioCaps s_radio_caps = (OT_RADIO_CAPS_ENERGY_SCAN | OT_RADIO_CAPS_SLEEP_TO_TX); static const char *radiospinel_workflow = "radio_spinel"; - static const esp_openthread_radio_config_t *s_esp_openthread_radio_config = NULL; - static esp_openthread_compatibility_error_callback s_compatibility_error_callback = NULL; - +static esp_openthread_coprocessor_reset_failure_callback s_coprocessor_reset_failure_callback = NULL; static char s_internal_rcp_version[OT_SPINEL_RCP_VERSION_MAX_SIZE] = {'\0'}; static void esp_openthread_radio_config_set(const esp_openthread_radio_config_t *config) @@ -74,12 +72,15 @@ static const esp_openthread_radio_config_t *esp_openthread_radio_config_get(void static void ot_spinel_compatibility_error_callback(void *context) { OT_UNUSED_VARIABLE(context); - if (s_compatibility_error_callback) { - s_compatibility_error_callback(); - } else { - ESP_LOGE(OT_PLAT_LOG_TAG, "None callback to handle compatibility error of openthread spinel"); - assert(false); - } + assert(s_compatibility_error_callback); + s_compatibility_error_callback(); +} + +static void ot_spinel_coprocessor_reset_failure_callback(void *context) +{ + OT_UNUSED_VARIABLE(context); + assert(s_coprocessor_reset_failure_callback); + s_coprocessor_reset_failure_callback(); } void esp_openthread_set_compatibility_error_callback(esp_openthread_compatibility_error_callback callback) @@ -87,6 +88,11 @@ void esp_openthread_set_compatibility_error_callback(esp_openthread_compatibilit s_compatibility_error_callback = callback; } +void esp_openthread_set_coprocessor_reset_failure_callback(esp_openthread_coprocessor_reset_failure_callback callback) +{ + s_coprocessor_reset_failure_callback = callback; +} + esp_err_t esp_openthread_radio_init(const esp_openthread_platform_config_t *config) { spinel_iid_t iidList[ot::Spinel::kSpinelHeaderMaxNumIid]; @@ -112,6 +118,7 @@ esp_err_t esp_openthread_radio_init(const esp_openthread_platform_config_t *conf ESP_RETURN_ON_ERROR(s_spinel_interface.GetSpinelInterface().Enable(config->radio_config.radio_spi_config), OT_PLAT_LOG_TAG, "Spinel interface init failed"); #endif + s_spinel_driver.SetCoprocessorResetFailureCallback(ot_spinel_coprocessor_reset_failure_callback, esp_openthread_get_instance()); s_spinel_driver.Init(s_spinel_interface.GetSpinelInterface(), true, iidList, ot::Spinel::kSpinelHeaderMaxNumIid); if (strlen(s_internal_rcp_version) > 0) { const char *running_rcp_version = s_spinel_driver.GetVersion(); diff --git a/components/openthread/src/spinel/esp_radio_spinel.cpp b/components/openthread/src/spinel/esp_radio_spinel.cpp index aba599e355..bef9cbe011 100644 --- a/components/openthread/src/spinel/esp_radio_spinel.cpp +++ b/components/openthread/src/spinel/esp_radio_spinel.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -42,6 +42,7 @@ static otRadioCaps s_radio_caps = (OT_RADIO_CAPS_ENERGY_SCAN | OT_RADIO_CAPS_SLEEP_TO_TX); static esp_radio_spinel_compatibility_error_callback s_radio_spinel_compatibility_error_callback = NULL; +static esp_radio_spinel_coprocessor_reset_failure_callback s_radio_spinel_coprocessor_reset_failure_callback = NULL; static esp_radio_spinel_idx_t get_index_from_instance(otInstance *instance) { @@ -74,12 +75,15 @@ static void esp_radio_spinel_restore_vendor_properities(void *context) static void radio_spinel_compatibility_error_callback(void *context) { OT_UNUSED_VARIABLE(context); - if (s_radio_spinel_compatibility_error_callback) { - s_radio_spinel_compatibility_error_callback(); - } else { - ESP_LOGE(ESP_SPINEL_LOG_TAG, "None callback to handle compatibility error of openthread spinel"); - assert(false); - } + assert(s_radio_spinel_compatibility_error_callback); + s_radio_spinel_compatibility_error_callback(); +} + +static void radio_spinel_coprocessor_reset_failure_callback(void *context) +{ + OT_UNUSED_VARIABLE(context); + assert(s_radio_spinel_coprocessor_reset_failure_callback); + s_radio_spinel_coprocessor_reset_failure_callback(); } void esp_radio_spinel_set_compatibility_error_callback(esp_radio_spinel_compatibility_error_callback callback) @@ -87,6 +91,11 @@ void esp_radio_spinel_set_compatibility_error_callback(esp_radio_spinel_compatib s_radio_spinel_compatibility_error_callback = callback; } +void esp_radio_spinel_set_coprocessor_reset_failure_callback(esp_radio_spinel_coprocessor_reset_failure_callback callback) +{ + s_radio_spinel_coprocessor_reset_failure_callback = callback; +} + void ReceiveDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError) { esp_radio_spinel_idx_t idx = get_index_from_instance(aInstance); @@ -232,6 +241,7 @@ void esp_radio_spinel_set_callbacks(const esp_radio_spinel_callbacks_t aCallback { s_esp_radio_spinel_callbacks[idx] = aCallbacks; RadioSpinelCallbacks Callbacks; + memset(&Callbacks, 0, sizeof(Callbacks)); Callbacks.mReceiveDone = ReceiveDone; Callbacks.mTransmitDone = TransmitDone; Callbacks.mEnergyScanDone = EnergyScanDone; @@ -266,6 +276,7 @@ void esp_radio_spinel_init(esp_radio_spinel_idx_t idx) // Multipan is not currently supported iidList[0] = 0; + s_spinel_driver[idx].SetCoprocessorResetFailureCallback(radio_spinel_coprocessor_reset_failure_callback, instance); s_spinel_driver[idx].Init(s_spinel_interface[idx].GetSpinelInterface(), true, iidList, ot::Spinel::kSpinelHeaderMaxNumIid); s_radio[idx].SetCompatibilityErrorCallback(radio_spinel_compatibility_error_callback, instance); s_radio[idx].Init(/*skip_rcp_compatibility_check=*/false, /*reset_radio=*/true, &s_spinel_driver[idx], s_radio_caps, false);