From f41b43dc431f39a38c40e92cb6a6d31389cdedfe Mon Sep 17 00:00:00 2001 From: Xu Si Yu Date: Tue, 29 Oct 2024 11:56:16 +0800 Subject: [PATCH] feat(openthread): update openthread submodule and border router lib --- .../include/esp_openthread_border_router.h | 10 +++++ .../openthread/include/esp_openthread_types.h | 2 + .../openthread/include/esp_radio_spinel.h | 11 ++++++ .../include/esp_radio_spinel_platform.h | 28 ++++++++++++++ components/openthread/lib | 2 +- components/openthread/openthread | 2 +- .../openthread-core-esp32x-ftd-config.h | 10 +++++ .../openthread-core-esp32x-spinel-config.h | 21 +++++++++- components/openthread/sbom_openthread.yml | 2 +- .../src/esp_openthread_netif_glue.c | 15 ++++++++ .../src/port/esp_openthread_radio_spinel.cpp | 27 +++++++++++-- .../src/spinel/esp_radio_spinel.cpp | 38 ++++++++++++++++++- examples/openthread/ot_ci_function.py | 3 +- 13 files changed, 159 insertions(+), 12 deletions(-) create mode 100644 components/openthread/include/esp_radio_spinel_platform.h diff --git a/components/openthread/include/esp_openthread_border_router.h b/components/openthread/include/esp_openthread_border_router.h index de4b8ee604..8960fc861d 100644 --- a/components/openthread/include/esp_openthread_border_router.h +++ b/components/openthread/include/esp_openthread_border_router.h @@ -66,6 +66,16 @@ esp_netif_t *esp_openthread_get_backbone_netif(void); */ void esp_openthread_register_rcp_failure_handler(esp_openthread_rcp_failure_handler handler); +/** + * @brief Registers the callback for spinel compatibility error. + * + * @note This function must be called before esp_openthread_init. + * + * @param[in] callback The callback. + * + */ +void esp_openthread_set_compatibility_error_callback(esp_openthread_compatibility_error_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 debc464066..ce1d258a3d 100644 --- a/components/openthread/include/esp_openthread_types.h +++ b/components/openthread/include/esp_openthread_types.h @@ -200,6 +200,8 @@ typedef struct { typedef void (*esp_openthread_rcp_failure_handler)(void); +typedef void (*esp_openthread_compatibility_error_callback)(void); + #ifdef __cplusplus } #endif diff --git a/components/openthread/include/esp_radio_spinel.h b/components/openthread/include/esp_radio_spinel.h index 24c5f1a629..710d61d646 100644 --- a/components/openthread/include/esp_radio_spinel.h +++ b/components/openthread/include/esp_radio_spinel.h @@ -46,6 +46,7 @@ typedef struct { typedef void (*esp_radio_spinel_rcp_failure_handler)(void); /* The handler for rcp failure.*/ 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 struct { @@ -391,6 +392,16 @@ esp_err_t esp_radio_spinel_rcp_deinit(esp_radio_spinel_idx_t idx); */ esp_err_t esp_radio_spinel_rcp_version_get(char *running_rcp_version, esp_radio_spinel_idx_t idx); +/** + * @brief Registers the callback for spinel compatibility error. + * + * @note This function must be called before esp_radio_spinel_init. + * + * @param[in] callback The callback. + * + */ +void esp_radio_spinel_set_compatibility_error_callback(esp_radio_spinel_compatibility_error_callback callback); + #ifdef __cplusplus } #endif diff --git a/components/openthread/include/esp_radio_spinel_platform.h b/components/openthread/include/esp_radio_spinel_platform.h new file mode 100644 index 0000000000..d6ce871716 --- /dev/null +++ b/components/openthread/include/esp_radio_spinel_platform.h @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Get frame counter. + * + * @param[in] idx The index of 802.15.4 related protocol stack. + * + * @return + * - The frame counter + * + */ +uint32_t esp_radio_spinel_extern_get_frame_counter(esp_radio_spinel_idx_t idx); + +#ifdef __cplusplus +} +#endif diff --git a/components/openthread/lib b/components/openthread/lib index 56af58057c..55f18e4cc6 160000 --- a/components/openthread/lib +++ b/components/openthread/lib @@ -1 +1 @@ -Subproject commit 56af58057c259405aa90c478e294f6216cc2f6db +Subproject commit 55f18e4cc6a249974247fd408aad79b1049d4b31 diff --git a/components/openthread/openthread b/components/openthread/openthread index f32c18bc08..005c5cefc2 160000 --- a/components/openthread/openthread +++ b/components/openthread/openthread @@ -1 +1 @@ -Subproject commit f32c18bc0840f400182456e58ae3900fc2fb4af7 +Subproject commit 005c5cefc22aaf0396e4327ee7f2e0ad32a7733b 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 ec94801505..42ea9d9546 100644 --- a/components/openthread/private_include/openthread-core-esp32x-ftd-config.h +++ b/components/openthread/private_include/openthread-core-esp32x-ftd-config.h @@ -261,6 +261,16 @@ #define OPENTHREAD_POSIX_CONFIG_RCP_TIME_SYNC_INTERVAL (60 * 1000 * 1000) #endif +/** + * @def OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE + * + * Enables compatibility error callback in Spinel + */ +#ifndef OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE +#define OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE 1 +#endif + + #endif /** 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 3c9def7840..0b257baeba 100644 --- a/components/openthread/private_include/openthread-core-esp32x-spinel-config.h +++ b/components/openthread/private_include/openthread-core-esp32x-spinel-config.h @@ -41,7 +41,6 @@ * */ #ifndef OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT -// TZ-567: Set OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT to 3 after adding rcp failure notification mechanism #define OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT 3 #endif @@ -77,3 +76,23 @@ #ifndef OPENTHREAD_CONFIG_MAC_MAX_CSMA_BACKOFFS_DIRECT #define OPENTHREAD_CONFIG_MAC_MAX_CSMA_BACKOFFS_DIRECT CONFIG_OPENTHREAD_MAC_MAX_CSMA_BACKOFFS_DIRECT #endif + + +/** + * @def OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE + * + * Enables compatibility error callback in Spinel + */ +#ifndef OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE +#define OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE 1 +#endif + +/** + * @def OPENTHREAD_SPINEL_CONFIG_MAX_SRC_MATCH_ENTRIES + * + * Defines size of the local source match table used by RadioSpinel + * when OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT is used. + */ +#ifndef OPENTHREAD_SPINEL_CONFIG_MAX_SRC_MATCH_ENTRIES +#define OPENTHREAD_SPINEL_CONFIG_MAX_SRC_MATCH_ENTRIES 12 +#endif diff --git a/components/openthread/sbom_openthread.yml b/components/openthread/sbom_openthread.yml index 7738bbe0a2..b227b42db8 100644 --- a/components/openthread/sbom_openthread.yml +++ b/components/openthread/sbom_openthread.yml @@ -5,4 +5,4 @@ supplier: 'Organization: Espressif Systems (Shanghai) CO LTD' originator: 'Organization: Google LLC' description: OpenThread released by Google is an open-source implementation of the Thread networking url: https://github.com/espressif/openthread -hash: f32c18bc0840f400182456e58ae3900fc2fb4af7 +hash: 005c5cefc22aaf0396e4327ee7f2e0ad32a7733b diff --git a/components/openthread/src/esp_openthread_netif_glue.c b/components/openthread/src/esp_openthread_netif_glue.c index e718469868..dd623aa5f7 100644 --- a/components/openthread/src/esp_openthread_netif_glue.c +++ b/components/openthread/src/esp_openthread_netif_glue.c @@ -16,6 +16,7 @@ #include "esp_log.h" #include "esp_netif.h" #include "esp_openthread.h" +#include "esp_openthread_border_router.h" #include "esp_openthread_common_macro.h" #include "esp_openthread_lock.h" #include "esp_openthread_netif_glue_priv.h" @@ -33,6 +34,7 @@ #include "openthread/ip6.h" #include "openthread/link.h" #include "openthread/message.h" +#include "openthread/platform/infra_if.h" #include "openthread/thread.h" typedef struct { @@ -381,3 +383,16 @@ esp_netif_t *esp_openthread_get_netif(void) { return s_openthread_netif; } + +otError otPlatGetInfraIfLinkLayerAddress(otInstance *aInstance, uint32_t aIfIndex, otPlatInfraIfLinkLayerAddress *aInfraIfLinkLayerAddress) +{ + esp_netif_t *backbone_netif = esp_openthread_get_backbone_netif(); + if (esp_netif_get_netif_impl_index(backbone_netif) != aIfIndex) { + ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to get LL address, error: Invalid If index"); + return OT_ERROR_FAILED; + } else { + esp_netif_get_mac(backbone_netif, aInfraIfLinkLayerAddress->mAddress); + aInfraIfLinkLayerAddress->mLength = 6; + return OT_ERROR_NONE; + } +} diff --git a/components/openthread/src/port/esp_openthread_radio_spinel.cpp b/components/openthread/src/port/esp_openthread_radio_spinel.cpp index b851c5608b..67cb2bb66a 100644 --- a/components/openthread/src/port/esp_openthread_radio_spinel.cpp +++ b/components/openthread/src/port/esp_openthread_radio_spinel.cpp @@ -54,6 +54,8 @@ 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 void esp_openthread_radio_config_set(const esp_openthread_radio_config_t *config) { s_esp_openthread_radio_config = config; @@ -64,6 +66,22 @@ static const esp_openthread_radio_config_t *esp_openthread_radio_config_get(void return s_esp_openthread_radio_config; } +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); + } +} + +void esp_openthread_set_compatibility_error_callback(esp_openthread_compatibility_error_callback callback) +{ + s_compatibility_error_callback = callback; +} + esp_err_t esp_openthread_radio_init(const esp_openthread_platform_config_t *config) { spinel_iid_t iidList[ot::Spinel::kSpinelHeaderMaxNumIid]; @@ -89,7 +107,8 @@ esp_err_t esp_openthread_radio_init(const esp_openthread_platform_config_t *conf "Spinel interface init failed"); #endif s_spinel_driver.Init(s_spinel_interface.GetSpinelInterface(), true, iidList, ot::Spinel::kSpinelHeaderMaxNumIid); - s_radio.Init(/*skip_rcp_compatibility_check=*/false, /*reset_radio=*/true, &s_spinel_driver, s_radio_caps); + s_radio.SetCompatibilityErrorCallback(ot_spinel_compatibility_error_callback, esp_openthread_get_instance()); + s_radio.Init(/*skip_rcp_compatibility_check=*/false, /*reset_radio=*/true, &s_spinel_driver, s_radio_caps, /*RCP_time_sync=*/true); #if CONFIG_OPENTHREAD_RADIO_SPINEL_SPI // CONFIG_OPENTHREAD_RADIO_SPINEL_SPI ESP_RETURN_ON_ERROR(s_spinel_interface.GetSpinelInterface().AfterRadioInit(), OT_PLAT_LOG_TAG, "Spinel interface init failed"); #endif @@ -336,15 +355,15 @@ void otPlatRadioSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCoun } #if CONFIG_OPENTHREAD_DIAG -otError otPlatDiagProcess(otInstance *instance, int argc, char *argv[], char *output, size_t output_max_len) +otError otPlatDiagProcess(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[]) { // deliver the platform specific diags commands to radio only ncp. char cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE] = {'\0'}; char *cur = cmd; char *end = cmd + sizeof(cmd); - for (int index = 0; index < argc; index++) { - cur += snprintf(cur, static_cast(end - cur), "%s ", argv[index]); + for (int index = 0; index < aArgsLength; index++) { + cur += snprintf(cur, static_cast(end - cur), "%s ", aArgs[index]); } return s_radio.PlatDiagProcess(cmd); diff --git a/components/openthread/src/spinel/esp_radio_spinel.cpp b/components/openthread/src/spinel/esp_radio_spinel.cpp index fbf794046d..79ae1efbe7 100644 --- a/components/openthread/src/spinel/esp_radio_spinel.cpp +++ b/components/openthread/src/spinel/esp_radio_spinel.cpp @@ -10,9 +10,11 @@ #include "platform/exit_code.h" #include "radio_spinel.hpp" #include "esp_radio_spinel.h" +#include "esp_radio_spinel_platform.h" #include "esp_radio_spinel_adapter.hpp" #include "esp_radio_spinel_uart_interface.hpp" #include "spinel_driver.hpp" +#include "openthread/link.h" #define SPINEL_VENDOR_PROPERTY_BIT_PENDINGMODE BIT(0) #define SPINEL_VENDOR_PROPERTY_BIT_COORDINATOR BIT(1) @@ -39,6 +41,8 @@ static otRadioCaps s_radio_caps = (OT_RADIO_CAPS_ENERGY_SCAN | OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_SLEEP_TO_TX); +static esp_radio_spinel_compatibility_error_callback s_radio_spinel_compatibility_error_callback = NULL; + static esp_radio_spinel_idx_t get_index_from_instance(otInstance *instance) { // TZ-563: Implement the function to get the esp radio spinel idx from otInstance for multipan rcp @@ -67,6 +71,22 @@ 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); + } +} + +void esp_openthread_set_compatibility_error_callback(esp_radio_spinel_compatibility_error_callback callback) +{ + s_radio_spinel_compatibility_error_callback = callback; +} + void ReceiveDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError) { esp_radio_spinel_idx_t idx = get_index_from_instance(aInstance); @@ -242,12 +262,13 @@ esp_err_t esp_radio_spinel_uart_interface_enable(const esp_radio_spinel_uart_con void esp_radio_spinel_init(esp_radio_spinel_idx_t idx) { spinel_iid_t iidList[ot::Spinel::kSpinelHeaderMaxNumIid]; + otInstance *instance = get_instance_from_index(idx); // Multipan is not currently supported iidList[0] = 0; s_spinel_driver[idx].Init(s_spinel_interface[idx].GetSpinelInterface(), true, iidList, ot::Spinel::kSpinelHeaderMaxNumIid); - s_radio[idx].Init(/*skip_rcp_compatibility_check=*/false, /*reset_radio=*/true, &s_spinel_driver[idx], s_radio_caps); - otInstance *instance = get_instance_from_index(idx); + 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); s_radio[idx].SetVendorRestorePropertiesCallback(esp_radio_spinel_restore_vendor_properities, instance); } @@ -405,6 +426,19 @@ esp_err_t esp_radio_spinel_set_rcp_ready(esp_radio_spinel_idx_t idx) return ESP_OK; } +// TZ-1261 +uint32_t otLinkGetFrameCounter(otInstance *aInstance) +{ + esp_radio_spinel_idx_t idx = get_index_from_instance(aInstance); + return esp_radio_spinel_extern_get_frame_counter(idx); +} + +__attribute__((weak)) uint32_t esp_radio_spinel_extern_get_frame_counter(esp_radio_spinel_idx_t idx) +{ + ESP_LOGW(ESP_SPINEL_LOG_TAG, "None function to get frame counter"); + return 0; +} + namespace ot { namespace Spinel { diff --git a/examples/openthread/ot_ci_function.py b/examples/openthread/ot_ci_function.py index 3561f4ad1d..4793b7cb7d 100644 --- a/examples/openthread/ot_ci_function.py +++ b/examples/openthread/ot_ci_function.py @@ -2,7 +2,6 @@ # SPDX-License-Identifier: Unlicense OR CC0-1.0 # !/usr/bin/env python3 # this file defines some functions for testing cli and br under pytest framework - import re import socket import struct @@ -145,7 +144,7 @@ def changeDeviceRole(dut:IdfDut, role:str) -> None: def getDataset(dut:IdfDut) -> str: clean_buffer(dut) execute_command(dut, 'dataset active -x') - dut_data = dut.expect(r'\n(\w{212})\r', timeout=5)[1].decode() + dut_data = dut.expect(r'\n(\w+)\r', timeout=5)[1].decode() return str(dut_data)