diff --git a/components/openthread/src/esp_openthread.cpp b/components/openthread/src/esp_openthread.cpp index b667e9bcad..311617f6a0 100644 --- a/components/openthread/src/esp_openthread.cpp +++ b/components/openthread/src/esp_openthread.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -80,19 +80,20 @@ esp_err_t esp_openthread_init(const esp_openthread_platform_config_t *config) ESP_RETURN_ON_ERROR(esp_openthread_platform_init(config), OT_PLAT_LOG_TAG, "Failed to initialize OpenThread platform driver"); esp_openthread_lock_acquire(portMAX_DELAY); - ESP_RETURN_ON_FALSE(otInstanceInitSingle() != NULL, ESP_FAIL, OT_PLAT_LOG_TAG, - "Failed to initialize OpenThread instance"); + esp_err_t ret = ESP_OK; + ESP_GOTO_ON_FALSE(otInstanceInitSingle() != NULL, ESP_FAIL, exit, OT_PLAT_LOG_TAG, + "Failed to initialize OpenThread instance"); #if CONFIG_OPENTHREAD_DNS64_CLIENT - ESP_RETURN_ON_ERROR(esp_openthread_dns64_client_init(), OT_PLAT_LOG_TAG, - "Failed to initialize OpenThread dns64 client"); + ESP_GOTO_ON_ERROR(esp_openthread_dns64_client_init(), exit, OT_PLAT_LOG_TAG, + "Failed to initialize OpenThread dns64 client"); #endif #if !CONFIG_OPENTHREAD_RADIO - ESP_RETURN_ON_ERROR(esp_openthread_state_event_init(esp_openthread_get_instance()), OT_PLAT_LOG_TAG, - "Failed to initialize OpenThread state event"); + ESP_GOTO_ON_ERROR(esp_openthread_state_event_init(esp_openthread_get_instance()), exit, OT_PLAT_LOG_TAG, + "Failed to initialize OpenThread state event"); #endif +exit: esp_openthread_lock_release(); - - return ESP_OK; + return ret; } esp_err_t esp_openthread_auto_start(otOperationalDatasetTlvs *datasetTlvs) @@ -140,7 +141,7 @@ esp_err_t esp_openthread_auto_start(otOperationalDatasetTlvs *datasetTlvs) memcpy(dataset.mMeshLocalPrefix.m8, prefix.mPrefix.mFields.m8, sizeof(dataset.mMeshLocalPrefix.m8)); dataset.mComponents.mIsMeshLocalPrefixPresent = true; } else { - ESP_LOGE("Failed to parse mesh local prefix", CONFIG_OPENTHREAD_MESH_LOCAL_PREFIX); + ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to parse mesh local prefix: %s", CONFIG_OPENTHREAD_MESH_LOCAL_PREFIX); } // Network Key diff --git a/components/openthread/src/esp_openthread_cli.c b/components/openthread/src/esp_openthread_cli.c index 28125ba893..83bda1d2ca 100644 --- a/components/openthread/src/esp_openthread_cli.c +++ b/components/openthread/src/esp_openthread_cli.c @@ -64,8 +64,12 @@ static int cli_output_callback(void *context, const char *format, va_list args) { char prompt_check[3]; int ret = 0; + va_list args_copy; + + va_copy(args_copy, args); + vsnprintf(prompt_check, sizeof(prompt_check), format, args_copy); + va_end(args_copy); - vsnprintf(prompt_check, sizeof(prompt_check), format, args); if (!strncmp(prompt_check, "> ", sizeof(prompt_check)) && s_cli_task) { xTaskNotifyGive(s_cli_task); } else { @@ -93,7 +97,11 @@ esp_err_t esp_openthread_cli_input(const char *line) ESP_RETURN_ON_FALSE(line_copy != NULL, ESP_ERR_NO_MEM, OT_PLAT_LOG_TAG, "Failed to copy OpenThread CLI line input"); - return esp_openthread_task_queue_post(line_handle_task, line_copy); + esp_err_t ret = esp_openthread_task_queue_post(line_handle_task, line_copy); + if (ret != ESP_OK) { + free(line_copy); + } + return ret; } static int ot_cli_console_callback(int argc, char **argv) @@ -140,6 +148,11 @@ static void ot_cli_loop(void *context) console_config.hint_color = -1; ret = esp_console_init(&console_config); + if (ret != ESP_OK) { + ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to initialize console: %s", esp_err_to_name(ret)); + vTaskDelete(NULL); + return; + } linenoiseSetMultiLine(true); linenoiseHistorySetMaxLen(100); @@ -183,9 +196,8 @@ static void ot_cli_loop(void *context) } } -void esp_openthread_cli_create_task() +void esp_openthread_cli_create_task(void) { - xTaskCreate(ot_cli_loop, "ot_cli", 4096, xTaskGetCurrentTaskHandle(), 4, &s_cli_task); - - return; + BaseType_t ret = xTaskCreate(ot_cli_loop, "ot_cli", 4096, xTaskGetCurrentTaskHandle(), 4, &s_cli_task); + ESP_RETURN_ON_FALSE(ret == pdPASS, , OT_PLAT_LOG_TAG, "Failed to create OpenThread CLI task"); } diff --git a/components/openthread/src/esp_openthread_dns64.c b/components/openthread/src/esp_openthread_dns64.c index 442ec4308f..2659b1a451 100644 --- a/components/openthread/src/esp_openthread_dns64.c +++ b/components/openthread/src/esp_openthread_dns64.c @@ -107,6 +107,7 @@ static void dns_found_handler(const char *name, const ip_addr_t *ipaddr, void *c if (resolve_entry && resolve_entry->found) { if (!ipaddr) { resolve_entry->found(name, NULL, resolve_entry->callback_arg); + resolve_entry->is_using = false; } else if (lwip_strnicmp(name, resolve_entry->name, sizeof(resolve_entry->name)) == 0) { ip_addr_t ipaddr_copy = *ipaddr; ip6_addr_t nat64_prefix; @@ -117,8 +118,8 @@ static void dns_found_handler(const char *name, const ip_addr_t *ipaddr, void *c ipaddr_copy.u_addr.ip6.zone = IP6_NO_ZONE; } resolve_entry->found(name, &ipaddr_copy, resolve_entry->callback_arg); + resolve_entry->is_using = false; } - resolve_entry->is_using = false; } } diff --git a/components/openthread/src/esp_openthread_lock.c b/components/openthread/src/esp_openthread_lock.c index 7e35da6c21..322c00c1f7 100644 --- a/components/openthread/src/esp_openthread_lock.c +++ b/components/openthread/src/esp_openthread_lock.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,9 +20,14 @@ bool esp_openthread_lock_acquire(TickType_t block_ticks) { ESP_RETURN_ON_FALSE(s_openthread_mutex && s_openthread_task_mutex, false, OT_PLAT_LOG_TAG, "Failed to acquire the lock because the mutex is not ready"); - BaseType_t ret = xSemaphoreTakeRecursive(s_openthread_mutex, block_ticks) && - xSemaphoreTakeRecursive(s_openthread_task_mutex, block_ticks); - return (ret == pdTRUE); + if (xSemaphoreTakeRecursive(s_openthread_mutex, block_ticks) != pdTRUE) { + return false; + } + if (xSemaphoreTakeRecursive(s_openthread_task_mutex, block_ticks) != pdTRUE) { + xSemaphoreGiveRecursive(s_openthread_mutex); + return false; + } + return true; } void esp_openthread_lock_release(void) @@ -61,6 +66,7 @@ esp_err_t esp_openthread_lock_init(void) s_openthread_mutex = xSemaphoreCreateRecursiveMutex(); s_openthread_task_mutex = xSemaphoreCreateRecursiveMutex(); if (s_openthread_mutex == NULL || s_openthread_task_mutex == NULL) { + esp_openthread_lock_deinit(); return ESP_ERR_NO_MEM; } return ESP_OK; diff --git a/components/openthread/src/esp_openthread_netif_glue.c b/components/openthread/src/esp_openthread_netif_glue.c index c49a260407..35dd8db149 100644 --- a/components/openthread/src/esp_openthread_netif_glue.c +++ b/components/openthread/src/esp_openthread_netif_glue.c @@ -243,10 +243,8 @@ void esp_openthread_register_meshcop_e_handler(esp_event_handler_t handler, bool { if (for_publish) { meshcop_e_publish_handler = handler; - } else if (!for_publish) { - meshcop_e_remove_handler = handler; } else { - ESP_ERROR_CHECK(ESP_FAIL); + meshcop_e_remove_handler = handler; } } @@ -345,6 +343,8 @@ void *esp_openthread_netif_glue_init(const esp_openthread_platform_config_t *con s_openthread_netif_glue.event_fd = eventfd(0, 0); if (s_openthread_netif_glue.event_fd < 0) { ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to create event fd for Thread netif"); + vQueueDelete(s_packet_queue); + s_packet_queue = NULL; ExitNow(error = ESP_FAIL); } s_openthread_netif_glue.base.post_attach = openthread_netif_post_attach; diff --git a/components/openthread/src/esp_openthread_task_queue.c b/components/openthread/src/esp_openthread_task_queue.c index 9d9bf87e6f..d656b77dde 100644 --- a/components/openthread/src/esp_openthread_task_queue.c +++ b/components/openthread/src/esp_openthread_task_queue.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -34,8 +34,12 @@ esp_err_t esp_openthread_task_queue_init(const esp_openthread_platform_config_t ESP_RETURN_ON_FALSE(s_task_queue_event_fd >= 0, ESP_FAIL, OT_PLAT_LOG_TAG, "Failed to create OpenThread task queue event fd"); s_task_queue = xQueueCreate(config->port_config.task_queue_size, sizeof(task_storage_t)); - ESP_RETURN_ON_FALSE(s_task_queue != NULL, ESP_ERR_NO_MEM, OT_PLAT_LOG_TAG, - "Failed to create OpenThread task queue"); + if (s_task_queue == NULL) { + close(s_task_queue_event_fd); + s_task_queue_event_fd = -1; + ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to create OpenThread task queue"); + return ESP_ERR_NO_MEM; + } return esp_openthread_platform_workflow_register(&esp_openthread_task_queue_update, &esp_openthread_task_queue_process, task_queue_workflow); } diff --git a/components/openthread/src/port/esp_openthread_messagepool.c b/components/openthread/src/port/esp_openthread_messagepool.c index 7996af3340..3704603349 100644 --- a/components/openthread/src/port/esp_openthread_messagepool.c +++ b/components/openthread/src/port/esp_openthread_messagepool.c @@ -18,11 +18,14 @@ #define OT_MSGPOOL_NUM_BUFFERS_NO_PSRAM 65 static int s_buffer_pool_head = -1; +static uint16_t s_buffer_pool_size = 0; static otMessageBuffer **s_buffer_pool_pointer = NULL; static otMessageBuffer *s_buffer_pool = NULL; void otPlatMessagePoolInit(otInstance *aInstance, uint16_t aMinNumFreeBuffers, size_t aBufferSize) { + assert(aBufferSize % sizeof(otMessageBuffer) == 0); + uint16_t num_buffers = aMinNumFreeBuffers; if (!esp_psram_is_initialized() && num_buffers > OT_MSGPOOL_NUM_BUFFERS_NO_PSRAM) { @@ -41,6 +44,7 @@ void otPlatMessagePoolInit(otInstance *aInstance, uint16_t aMinNumFreeBuffers, s s_buffer_pool_pointer[i] = buffer_pool + i * aBufferSize / sizeof(otMessageBuffer); } s_buffer_pool_head = num_buffers - 1; + s_buffer_pool_size = num_buffers; s_buffer_pool = buffer_pool; ESP_LOGI(OT_PLAT_LOG_TAG, "Create message buffer pool successfully, size %d", num_buffers * aBufferSize); } @@ -57,6 +61,7 @@ otMessageBuffer *otPlatMessagePoolNew(otInstance *aInstance) void otPlatMessagePoolFree(otInstance *aInstance, otMessageBuffer *aBuffer) { + assert(s_buffer_pool_head + 1 < s_buffer_pool_size); s_buffer_pool_head++; s_buffer_pool_pointer[s_buffer_pool_head] = aBuffer; } @@ -77,4 +82,5 @@ void otPlatMessagePoolDeinit(otInstance *aInstance) s_buffer_pool = NULL; } s_buffer_pool_head = -1; + s_buffer_pool_size = 0; } diff --git a/components/openthread/src/port/esp_openthread_radio.c b/components/openthread/src/port/esp_openthread_radio.c index c4e4cf654c..326175ec6d 100644 --- a/components/openthread/src/port/esp_openthread_radio.c +++ b/components/openthread/src/port/esp_openthread_radio.c @@ -81,7 +81,7 @@ static uint32_t s_csl_sample_time; #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 static uint32_t s_mac_frame_counter; static uint8_t s_key_id; -static struct otMacKeyMaterial s_pervious_key; +static struct otMacKeyMaterial s_previous_key; static struct otMacKeyMaterial s_current_key; static struct otMacKeyMaterial s_next_key; #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE @@ -101,7 +101,7 @@ static void ot_set_security_key_from_key_material(struct otMacKeyMaterial a_key_ /* Key bytes are pre-exported in task context (otPlatRadioSetMacKey). * Identify which cached buffer to use by comparing the key reference. * Jira TZ-2472 */ - if (a_key_material.mKeyMaterial.mKeyRef == s_pervious_key.mKeyMaterial.mKeyRef) { + if (a_key_material.mKeyMaterial.mKeyRef == s_previous_key.mKeyMaterial.mKeyRef) { memcpy(s_security_key, s_pervious_key_bytes, 16); } else if (a_key_material.mKeyMaterial.mKeyRef == s_next_key.mKeyMaterial.mKeyRef) { memcpy(s_security_key, s_next_key_bytes, 16); @@ -165,7 +165,7 @@ esp_err_t esp_openthread_radio_init(const esp_openthread_platform_config_t *conf void esp_openthread_radio_deinit(void) { - if (s_radio_event_fd > 0) { + if (s_radio_event_fd != -1) { close(s_radio_event_fd); s_radio_event_fd = -1; } @@ -521,7 +521,7 @@ void otPlatRadioSetMacKey(otInstance *aInstance, uint8_t aKeyIdMode, uint8_t aKe assert(aPrevKey != NULL && aCurrKey != NULL && aNextKey != NULL); s_key_id = aKeyId; - s_pervious_key = *aPrevKey; + s_previous_key = *aPrevKey; s_current_key = *aCurrKey; s_next_key = *aNextKey; #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE @@ -656,7 +656,7 @@ static esp_err_t IRAM_ATTR enh_ack_set_security_addr_and_key(otRadioFrame *ack_f if (key_id == s_key_id) { key = &s_current_key; } else if (key_id == s_key_id - 1) { - key = &s_pervious_key; + key = &s_previous_key; } else if (key_id == s_key_id + 1) { key = &s_next_key; } else { @@ -729,6 +729,7 @@ void IRAM_ATTR esp_ieee802154_receive_done(uint8_t *data, esp_ieee802154_frame_i if (atomic_load(&s_recv_queue.used) == CONFIG_IEEE802154_RX_BUFFER_SIZE) { ESP_EARLY_LOGE(OT_PLAT_LOG_TAG, "radio receive buffer full!"); + esp_ieee802154_receive_handle_done(data); return; } diff --git a/components/openthread/src/port/esp_openthread_radio_spinel.cpp b/components/openthread/src/port/esp_openthread_radio_spinel.cpp index b7892da9af..f9695b2387 100644 --- a/components/openthread/src/port/esp_openthread_radio_spinel.cpp +++ b/components/openthread/src/port/esp_openthread_radio_spinel.cpp @@ -414,7 +414,11 @@ otError otPlatDiagProcess(otInstance *aInstance, uint8_t aArgsLength, char *aArg char *end = cmd + sizeof(cmd); for (int index = 0; index < aArgsLength; index++) { - cur += snprintf(cur, static_cast(end - cur), "%s ", aArgs[index]); + if (end > cur + strlen(aArgs[index])) { + cur += snprintf(cur, static_cast(end - cur), "%s ", aArgs[index]); + } else { + return OT_ERROR_INVALID_ARGS; + } } return s_radio.PlatDiagProcess(cmd); diff --git a/components/openthread/src/port/esp_openthread_settings.c b/components/openthread/src/port/esp_openthread_settings.c index e2cc930d26..c9f62f25ae 100644 --- a/components/openthread/src/port/esp_openthread_settings.c +++ b/components/openthread/src/port/esp_openthread_settings.c @@ -223,4 +223,5 @@ otError otPlatSettingsDelete(otInstance *aInstance, uint16_t aKey, int aIndex) void otPlatSettingsWipe(otInstance *aInstance) { nvs_erase_all(s_ot_nvs_handle); + nvs_commit(s_ot_nvs_handle); } diff --git a/components/openthread/src/port/esp_openthread_sleep.c b/components/openthread/src/port/esp_openthread_sleep.c index 8ca7504a6f..8570ed5aa6 100644 --- a/components/openthread/src/port/esp_openthread_sleep.c +++ b/components/openthread/src/port/esp_openthread_sleep.c @@ -36,6 +36,7 @@ esp_err_t esp_openthread_sleep_init(void) void esp_openthread_sleep_process(void) { + assert(s_pm_lock != NULL); if (s_ot_sleep == false && esp_ieee802154_get_state() == ESP_IEEE802154_RADIO_SLEEP) { esp_pm_lock_release(s_pm_lock); s_ot_sleep = true; diff --git a/components/openthread/src/port/esp_openthread_spi_slave.c b/components/openthread/src/port/esp_openthread_spi_slave.c index 754300e5c9..1a47a00451 100644 --- a/components/openthread/src/port/esp_openthread_spi_slave.c +++ b/components/openthread/src/port/esp_openthread_spi_slave.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -67,21 +67,22 @@ static void IRAM_ATTR handle_spi_transaction_done(spi_slave_transaction_t *trans trans->rx_buffer, pending_transaction->input_buf_len, trans->trans_len)) { esp_openthread_task_queue_post(s_process_callback, s_context); } - trans = NULL; } esp_err_t esp_openthread_host_rcp_spi_init(const esp_openthread_platform_config_t *config) { + esp_err_t ret = ESP_OK; + s_spi_config = heap_caps_malloc(sizeof(esp_openthread_spi_slave_config_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - ESP_RETURN_ON_FALSE(s_spi_config != NULL, ESP_ERR_NO_MEM, OT_PLAT_LOG_TAG, - "failed to allocate memory for SPI transaction on internal heap"); + ESP_GOTO_ON_FALSE(s_spi_config != NULL, ESP_ERR_NO_MEM, err, OT_PLAT_LOG_TAG, + "failed to allocate memory for SPI transaction on internal heap"); memcpy(s_spi_config, &(config->host_config.spi_slave_config), sizeof(esp_openthread_spi_slave_config_t)); gpio_config_t io_conf = { .intr_type = GPIO_INTR_DISABLE, .mode = GPIO_MODE_OUTPUT, - .pin_bit_mask = (1 << s_spi_config->intr_pin), + .pin_bit_mask = (1ULL << s_spi_config->intr_pin), }; - ESP_RETURN_ON_ERROR(gpio_config(&io_conf), OT_PLAT_LOG_TAG, "fail to configure SPI gpio"); + ESP_GOTO_ON_ERROR(gpio_config(&io_conf), err, OT_PLAT_LOG_TAG, "fail to configure SPI gpio"); gpio_set_pull_mode(s_spi_config->bus_config.mosi_io_num, GPIO_PULLUP_ONLY); gpio_set_pull_mode(s_spi_config->bus_config.sclk_io_num, GPIO_PULLUP_ONLY); @@ -90,11 +91,9 @@ esp_err_t esp_openthread_host_rcp_spi_init(const esp_openthread_platform_config_ s_spi_transaction = heap_caps_malloc(sizeof(spi_slave_transaction_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); s_pending_transaction = heap_caps_malloc(sizeof(pending_transaction_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); if (s_spi_transaction == NULL || s_pending_transaction == NULL) { - heap_caps_free(s_spi_config); - heap_caps_free(s_spi_transaction); - heap_caps_free(s_pending_transaction); ESP_LOGE(OT_PLAT_LOG_TAG, "failed to allocate memory for SPI transaction on internal heap"); - return ESP_ERR_NO_MEM; + ret = ESP_ERR_NO_MEM; + goto err; } s_spi_transaction->user = (void *)s_pending_transaction; @@ -102,11 +101,20 @@ esp_err_t esp_openthread_host_rcp_spi_init(const esp_openthread_platform_config_ /* Initialize SPI slave interface */ s_spi_config->slave_config.post_setup_cb = handle_spi_setup_done; s_spi_config->slave_config.post_trans_cb = handle_spi_transaction_done; - ESP_RETURN_ON_ERROR(spi_slave_initialize(s_spi_config->host_device, &s_spi_config->bus_config, - &s_spi_config->slave_config, SPI_DMA_CH_AUTO), - OT_PLAT_LOG_TAG, "fail to initialize SPI slave"); + ESP_GOTO_ON_ERROR(spi_slave_initialize(s_spi_config->host_device, &s_spi_config->bus_config, + &s_spi_config->slave_config, SPI_DMA_CH_AUTO), + err, OT_PLAT_LOG_TAG, "fail to initialize SPI slave"); return ESP_OK; + +err: + heap_caps_free(s_spi_config); + s_spi_config = NULL; + heap_caps_free(s_spi_transaction); + s_spi_transaction = NULL; + heap_caps_free(s_pending_transaction); + s_pending_transaction = NULL; + return ret; } void esp_openthread_spi_slave_deinit(void) diff --git a/components/openthread/src/port/esp_openthread_trel.c b/components/openthread/src/port/esp_openthread_trel.c index 8eca69ce4e..9b50504385 100644 --- a/components/openthread/src/port/esp_openthread_trel.c +++ b/components/openthread/src/port/esp_openthread_trel.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -191,6 +191,8 @@ esp_err_t esp_openthread_trel_process(otInstance *aInstance, const esp_openthrea } if (should_handle) { otPlatTrelHandleReceived(aInstance, data_buf, length, source_addr); + s_trel_counters.mRxPackets++; + s_trel_counters.mRxBytes += length; } pbuf_free(recv_buf); free(data_buf_to_free); @@ -255,7 +257,13 @@ void otPlatTrelSend(otInstance *aInstance, esp_openthread_task_switching_lock_release(); 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"); + if (err == ESP_OK) { + s_trel_counters.mTxPackets++; + s_trel_counters.mTxBytes += aUdpPayloadLen; + } else { + s_trel_counters.mTxFailure++; + ESP_LOGW(OT_PLAT_LOG_TAG, "Failed to send TREL message"); + } } void otPlatTrelNotifyPeerSocketAddressDifference(otInstance *aInstance, @@ -284,8 +292,10 @@ void otPlatTrelRegisterService(otInstance *aInstance, uint16_t aPort, const uint s_is_service_registered = true; uint16_t index = 0; while (index < aTxtLength) { - const uint8_t *item_header = aTxtData + index + 1; uint8_t item_len = aTxtData[index]; + ESP_GOTO_ON_FALSE(index + 1 + item_len <= aTxtLength, ESP_FAIL, exit, OT_PLAT_LOG_TAG, + "Malformed _trel._udp TXT record: item exceeds data length"); + const uint8_t *item_header = aTxtData + index + 1; char key[UINT8_MAX + 1]; for (uint16_t i = 0; i < item_len; i++) { @@ -348,6 +358,7 @@ void otPlatTrelDisable(otInstance *aInstance) free_all_buffer(); close(s_trel_event_fd); s_trel_event_fd = -1; + s_trel_netif = NULL; } const otPlatTrelCounters *otPlatTrelGetCounters(otInstance *aInstance) diff --git a/components/openthread/src/port/esp_openthread_uart.c b/components/openthread/src/port/esp_openthread_uart.c index 1e19af66e5..685e2ee558 100644 --- a/components/openthread/src/port/esp_openthread_uart.c +++ b/components/openthread/src/port/esp_openthread_uart.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -30,7 +30,8 @@ #endif static int s_uart_port; -static int s_uart_fd; +static int s_uart_fd = -1; +static bool s_uart_driver_installed = false; static uint8_t s_uart_buffer[ESP_OPENTHREAD_UART_BUFFER_SIZE]; static const char *uart_workflow = "uart"; @@ -89,6 +90,7 @@ esp_err_t esp_openthread_uart_init_port(const esp_openthread_uart_config_t *conf OT_PLAT_LOG_TAG, "uart_set_pin failed"); ESP_RETURN_ON_ERROR(uart_driver_install(config->port, ESP_OPENTHREAD_UART_BUFFER_SIZE, 0, 0, NULL, 0), OT_PLAT_LOG_TAG, "uart_driver_install failed"); + s_uart_driver_installed = true; uart_vfs_dev_use_driver(config->port); return ESP_OK; } @@ -173,7 +175,10 @@ void esp_openthread_uart_deinit() close(s_uart_fd); s_uart_fd = -1; } - uart_driver_delete(s_uart_port); + if (s_uart_driver_installed) { + uart_driver_delete(s_uart_port); + s_uart_driver_installed = false; + } esp_openthread_platform_workflow_unregister(uart_workflow); } diff --git a/components/openthread/src/port/esp_openthread_udp.c b/components/openthread/src/port/esp_openthread_udp.c index 614bac12b2..b298ce3121 100644 --- a/components/openthread/src/port/esp_openthread_udp.c +++ b/components/openthread/src/port/esp_openthread_udp.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -135,8 +135,12 @@ static void udp_recv_task(void *ctx) ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to copy OpenThread message when receiving OpenThread plat UDP")); task->socket->mHandler(task->socket->mContext, message, &message_info); otMessageFree(message); + message = NULL; exit: + if (message != NULL) { + otMessageFree(message); + } free(task); if (data_buf_to_free) { free(data_buf_to_free); @@ -156,6 +160,8 @@ static void handle_udp_recv(void *ctx, struct udp_pcb *pcb, struct pbuf *p, cons if (task == NULL) { ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to allocate recv task when receiving OpenThread plat UDP"); + pbuf_free(p); + return; } task->socket = (otUdpSocket *)ctx; task->recv_buf = p;