From 0050248918bbef05a04a4aff517f4bfe8523da33 Mon Sep 17 00:00:00 2001 From: Jiacheng Guo Date: Mon, 28 Jun 2021 19:20:51 +0800 Subject: [PATCH] openthread: provide prebuilt libopenthread libraries --- .gitlab/ci/rules.yml | 1 + .gitmodules | 4 + components/openthread/CMakeLists.txt | 50 ++- components/openthread/Kconfig | 22 +- components/openthread/component.mk | 10 + .../include/esp_openthread_defaults.h | 7 + .../include/esp_openthread_netif_glue.h | 4 +- .../openthread/include/esp_openthread_types.h | 12 + .../include/openthread-core-esp32x-config.h | 40 +- components/openthread/lib | 1 + components/openthread/port/esp_openthread.cpp | 94 ----- .../openthread/port/esp_openthread_alarm.c | 143 ------- .../port/esp_openthread_border_router.c | 34 -- .../openthread/port/esp_openthread_flash.c | 70 ---- .../openthread/port/esp_openthread_lock.c | 52 --- .../openthread/port/esp_openthread_logging.c | 68 ---- .../openthread/port/esp_openthread_misc.c | 87 ----- .../port/esp_openthread_netif_glue.c | 353 ----------------- .../port/esp_openthread_platform.cpp | 108 ------ .../port/esp_openthread_radio_uart.cpp | 299 --------------- .../port/esp_openthread_task_queue.c | 102 ----- .../openthread/port/esp_openthread_uart.c | 129 ------- .../openthread/port/esp_openthread_udp.c | 360 ------------------ .../port/esp_uart_spinel_interface.cpp | 295 -------------- .../private_include/esp_openthread_alarm.h | 43 --- .../esp_openthread_common_macro.h | 31 -- .../esp_openthread_netif_glue_priv.h | 55 --- .../private_include/esp_openthread_platform.h | 87 ----- .../esp_openthread_radio_uart.h | 66 ---- .../esp_openthread_task_queue.h | 87 ----- .../private_include/esp_openthread_uart.h | 76 ---- .../esp_uart_spinel_interface.hpp | 157 -------- examples/openthread/ot_br/main/esp_ot_br.c | 3 +- examples/openthread/ot_cli/main/esp_ot_cli.c | 7 +- 34 files changed, 109 insertions(+), 2848 deletions(-) create mode 160000 components/openthread/lib delete mode 100644 components/openthread/port/esp_openthread.cpp delete mode 100644 components/openthread/port/esp_openthread_alarm.c delete mode 100644 components/openthread/port/esp_openthread_border_router.c delete mode 100644 components/openthread/port/esp_openthread_flash.c delete mode 100644 components/openthread/port/esp_openthread_lock.c delete mode 100644 components/openthread/port/esp_openthread_logging.c delete mode 100644 components/openthread/port/esp_openthread_misc.c delete mode 100644 components/openthread/port/esp_openthread_netif_glue.c delete mode 100644 components/openthread/port/esp_openthread_platform.cpp delete mode 100644 components/openthread/port/esp_openthread_radio_uart.cpp delete mode 100644 components/openthread/port/esp_openthread_task_queue.c delete mode 100644 components/openthread/port/esp_openthread_uart.c delete mode 100644 components/openthread/port/esp_openthread_udp.c delete mode 100644 components/openthread/port/esp_uart_spinel_interface.cpp delete mode 100644 components/openthread/private_include/esp_openthread_alarm.h delete mode 100644 components/openthread/private_include/esp_openthread_common_macro.h delete mode 100644 components/openthread/private_include/esp_openthread_netif_glue_priv.h delete mode 100644 components/openthread/private_include/esp_openthread_platform.h delete mode 100644 components/openthread/private_include/esp_openthread_radio_uart.h delete mode 100644 components/openthread/private_include/esp_openthread_task_queue.h delete mode 100644 components/openthread/private_include/esp_openthread_uart.h delete mode 100644 components/openthread/private_include/esp_uart_spinel_interface.hpp diff --git a/.gitlab/ci/rules.yml b/.gitlab/ci/rules.yml index ba46aca194..b78e9b650e 100644 --- a/.gitlab/ci/rules.yml +++ b/.gitlab/ci/rules.yml @@ -149,6 +149,7 @@ - "components/nghttp/nghttp2" - "components/nghttp/nghttp2/third-party/mruby" - "components/nghttp/nghttp2/third-party/neverbleed" + - "components/openthread/lib" - "components/protobuf-c/protobuf-c" - "components/spiffs/spiffs" - "components/tinyusb/tinyusb" diff --git a/.gitmodules b/.gitmodules index 09b86fe88e..e4b1fe8f1f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -102,3 +102,7 @@ [submodule "components/esp_phy/lib"] path = components/esp_phy/lib url = ../../espressif/esp-phy-lib.git + +[submodule "components/openthread/lib"] + path = components/openthread/lib + url = ../../espressif/esp-thread-lib.git diff --git a/components/openthread/CMakeLists.txt b/components/openthread/CMakeLists.txt index bc805b3d02..c521ae5327 100644 --- a/components/openthread/CMakeLists.txt +++ b/components/openthread/CMakeLists.txt @@ -10,8 +10,7 @@ if(CONFIG_OPENTHREAD_ENABLED) "openthread/src/lib/hdlc" "openthread/src/lib/spinel" "openthread/src/ncp" - "openthread/examples/platforms/" - "private_include") + "openthread/examples/platforms/") set(src_dirs "openthread/examples/apps/cli" @@ -31,12 +30,17 @@ if(CONFIG_OPENTHREAD_ENABLED) "openthread/src/core/utils" "openthread/src/lib/platform" "openthread/src/lib/hdlc" - "openthread/src/lib/spinel" - "port") + "openthread/src/lib/spinel") + + if(CONFIG_OPENTHREAD_BORDER_ROUTER) + list(APPEND src_dirs + "openthread/src/core/border_router") + endif() set(exclude_srcs "openthread/examples/apps/cli/main.cpp" "openthread/examples/platforms/utils/logging_rtt.c" + "openthread/examples/platforms/utils/soft_source_match_table.c" "openthread/src/core/common/extension_example.cpp") if(CONFIG_OPENTHREAD_FTD) @@ -46,6 +50,7 @@ if(CONFIG_OPENTHREAD_ENABLED) elseif(CONFIG_OPENTHREAD_RADIO) set(device_type "OPENTHREAD_RADIO=1") endif() + endif() execute_process( @@ -64,11 +69,38 @@ idf_component_register(SRC_DIRS "${src_dirs}" EXCLUDE_SRCS "${exclude_srcs}" INCLUDE_DIRS "${public_include_dirs}" PRIV_INCLUDE_DIRS "${private_include_dirs}" - REQUIRES mbedtls spi_flash) + REQUIRES mbedtls) if(CONFIG_OPENTHREAD_ENABLED) - target_compile_definitions(${COMPONENT_LIB} PRIVATE - "OPENTHREAD_CONFIG_FILE=\"openthread-core-esp32x-config.h\"" - "PACKAGE_VERSION=\"${IDF_VERSION_FOR_OPENTHREAD_PACKAGE}-${OPENTHREAD_VERSION}\"" - "${device_type}") + target_compile_definitions( + ${COMPONENT_LIB} + PUBLIC + "OPENTHREAD_CONFIG_FILE=\"openthread-core-esp32x-config.h\"" + "${device_type}" + PRIVATE + "PACKAGE_VERSION=\"${IDF_VERSION_FOR_OPENTHREAD_PACKAGE}-${OPENTHREAD_VERSION}\"") + + if(CONFIG_OPENTHREAD_ESP_LIB_FROM_INTERNAL_SRC) + idf_component_get_property(openthread_port_lib openthread_port COMPONENT_LIB) + target_link_libraries(${COMPONENT_LIB} PUBLIC $) + + if(CONFIG_OPENTHREAD_BORDER_ROUTER) + idf_component_get_property(openthread_br_lib openthread_br COMPONENT_LIB) + target_link_libraries(${COMPONENT_LIB} PUBLIC $) + endif() + + else() + add_prebuilt_library(openthread_port "${CMAKE_CURRENT_SOURCE_DIR}/lib/${idf_target}/libopenthread_port.a" + REQUIRES openthread) + add_prebuilt_library(openthread_br "${CMAKE_CURRENT_SOURCE_DIR}/lib/${idf_target}/libopenthread_br.a" + REQUIRES openthread) + + target_link_libraries(${COMPONENT_LIB} INTERFACE openthread_port) + + if(CONFIG_OPENTHREAD_BORDER_ROUTER) + target_link_libraries(${COMPONENT_LIB} INTERFACE openthread_br) + endif() + + endif() + endif() diff --git a/components/openthread/Kconfig b/components/openthread/Kconfig index da042ceac7..3318a0b0ee 100644 --- a/components/openthread/Kconfig +++ b/components/openthread/Kconfig @@ -65,25 +65,11 @@ menu "OpenThread" help Select this option to enable border router features in OpenThread. - config OPENTHREAD_PARTITION_NAME - string "The partition for OpenThread to store its network data" + config OPENTHREAD_ESP_LIB_FROM_INTERNAL_SRC + bool "Build esp_openthread libraries from source" depends on OPENTHREAD_ENABLED - default "ot_storage" + default n help - The storage size should be at least 8192 bytes. - - config OPENTHREAD_NETIF_QUEUE_SIZE - int "The size of the packet queue for OpenThread lwIP network interface" - depends on OPENTHREAD_ENABLED - default 10 - help - The size of the packet queue for OpenThread lwIP network interface. - - config OPENTHREAD_TASK_QUEUE_SIZE - int "The size of the OpenThread task queue" - depends on OPENTHREAD_ENABLED - default 10 - help - The size of the OpenThread task queue. + Override the shipped libopenthread_br.a and libopenthread_port.a, for internal builds. endmenu diff --git a/components/openthread/component.mk b/components/openthread/component.mk index 03be7277b2..6c872950c8 100644 --- a/components/openthread/component.mk +++ b/components/openthread/component.mk @@ -38,6 +38,16 @@ COMPONENT_OBJEXCLUDE := \ openthread/examples/apps/cli/main.o \ openthread/src/core/common/extension_example.o \ + +COMPONENT_SUBMODULES += lib + +ALL_LIB_FILES := $(COMPONENT_PATH)/lib/$(IDF_TARGET)/libopenthread_port.a + +ifdef CONFIG_OPENTHREAD_BORDER_ROUTER + ALL_LIB_FILES += $(COMPONENT_PATH)/lib/$(IDF_TARGET)/libopenthread_br.a +endif +COMPONENT_ADD_LDFLAGS += $(ALL_LIB_FILES) + IDF_VERSION_FOR_OPENTHREAD_PACKAGE := $(shell git -C $(COMPONENT_PATH) rev-parse --short HEAD) OPENTHREAD_VERSION := $(shell git -C $(COMPONENT_PATH)/openthread rev-parse --short HEAD) OPENTHREAD_PACKAGE_VERSION := $(IDF_VERSION_FOR_OPENTHREAD_PACKAGE)-$(OPENTHREAD_VERSION) diff --git a/components/openthread/include/esp_openthread_defaults.h b/components/openthread/include/esp_openthread_defaults.h index cbbfc15ac5..07ae0f67e5 100644 --- a/components/openthread/include/esp_openthread_defaults.h +++ b/components/openthread/include/esp_openthread_defaults.h @@ -55,3 +55,10 @@ .tx_pin = UART_PIN_NO_CHANGE, \ }, \ } + +#define ESP_OPENTHREAD_DEFAULT_PORT_CONFIG() \ + { \ + .storage_partition_name = "ot_storage", \ + .netif_queue_size = 10, \ + .task_queue_size = 10, \ + } diff --git a/components/openthread/include/esp_openthread_netif_glue.h b/components/openthread/include/esp_openthread_netif_glue.h index 61bd1ee1a7..1f94dcedd3 100644 --- a/components/openthread/include/esp_openthread_netif_glue.h +++ b/components/openthread/include/esp_openthread_netif_glue.h @@ -26,12 +26,14 @@ extern "C" { /** * @brief This function initializes the OpenThread network interface glue. * + * @param[in] config The platform configuration. + * * @return * - glue pointer on success * - NULL on failure * */ -void *esp_openthread_netif_glue_init(void); +void *esp_openthread_netif_glue_init(const esp_openthread_platform_config_t *config); /** * @brief This function deinitializes the OpenThread network interface glue. diff --git a/components/openthread/include/esp_openthread_types.h b/components/openthread/include/esp_openthread_types.h index dbe7c01797..eaa6528852 100644 --- a/components/openthread/include/esp_openthread_types.h +++ b/components/openthread/include/esp_openthread_types.h @@ -15,6 +15,7 @@ #pragma once #include "hal/uart_types.h" +#include "sys/_stdint.h" #include "sys/select.h" #include "esp_event_base.h" @@ -101,6 +102,16 @@ typedef struct { esp_openthread_uart_config_t host_uart_config; /*!< The uart configuration to host*/ } esp_openthread_host_connection_config_t; +/** + * @brief The OpenThread port specific configuration + * + */ +typedef struct { + const char *storage_partition_name; /*!< The partition for storing OpenThread dataset*/ + uint8_t netif_queue_size; /*!< The packet queue size for the network interface*/ + uint8_t task_queue_size; /*!< The task queue size*/ +} esp_openthread_port_config_t; + /** * @brief The OpenThread platform configuration * @@ -108,6 +119,7 @@ typedef struct { typedef struct { esp_openthread_radio_config_t radio_config; /*!< The radio configuration*/ esp_openthread_host_connection_config_t host_config; /*!< The host connection configuration*/ + esp_openthread_port_config_t port_config; /*!< The port configuration*/ } esp_openthread_platform_config_t; #ifdef __cplusplus diff --git a/components/openthread/include/openthread-core-esp32x-config.h b/components/openthread/include/openthread-core-esp32x-config.h index 8d00379d16..db046c73dc 100644 --- a/components/openthread/include/openthread-core-esp32x-config.h +++ b/components/openthread/include/openthread-core-esp32x-config.h @@ -105,26 +105,6 @@ */ #define OPENTHREAD_CONFIG_COAP_API_ENABLE 1 -/** - * @def OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE - * - * Define to 1 to enable Border Router support. - * - */ -#ifndef OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE -#define OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE 1 -#endif - -/** - * @def OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE - * - * Define to 1 to enable platform UDP support. - * - */ -#ifndef OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE -#define OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE 1 -#endif - /** * @def OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE * @@ -147,6 +127,26 @@ #define OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE 1 #endif +/** + * @def OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE + * + * Define to 1 to enable Border Router support. + * + */ +#ifndef OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE +#define OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE 1 +#endif + +/** + * @def OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE + * + * Define to 1 to enable platform UDP support. + * + */ +#ifndef OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE +#define OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE 1 +#endif + #endif // CONFIG_OPENTHREAD_BORDER_ROUTER /** diff --git a/components/openthread/lib b/components/openthread/lib new file mode 160000 index 0000000000..3a3009e7a1 --- /dev/null +++ b/components/openthread/lib @@ -0,0 +1 @@ +Subproject commit 3a3009e7a1d9a89f2a06453eb299d6c1a9ee7cad diff --git a/components/openthread/port/esp_openthread.cpp b/components/openthread/port/esp_openthread.cpp deleted file mode 100644 index f3b6d37acd..0000000000 --- a/components/openthread/port/esp_openthread.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License - -#include "esp_check.h" -#include "esp_openthread.h" -#include "esp_openthread_common_macro.h" -#include "esp_openthread_lock.h" -#include "esp_openthread_netif_glue_priv.h" -#include "esp_openthread_platform.h" -#include "esp_openthread_types.h" -#include "freertos/FreeRTOS.h" -#include "openthread/instance.h" -#include "openthread/tasklet.h" - -static void esp_openthread_state_callback(otChangedFlags changed_flags, void *ctx) -{ - esp_openthread_netif_glue_state_callback(changed_flags); -} - -static esp_err_t register_esp_openthread_state_callbacks(void) -{ - otInstance *instance = esp_openthread_get_instance(); - ESP_RETURN_ON_FALSE(otSetStateChangedCallback(instance, esp_openthread_state_callback, NULL) == OT_ERROR_NONE, - ESP_FAIL, OT_PLAT_LOG_TAG, "Failed to install OpenThread state callback"); - return ESP_OK; -} - -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_RETURN_ON_FALSE(otInstanceInitSingle() != NULL, ESP_FAIL, OT_PLAT_LOG_TAG, - "Failed to initialize OpenThread instance"); - - return register_esp_openthread_state_callbacks(); -} - -esp_err_t esp_openthread_launch_mainloop(void) -{ - esp_openthread_mainloop_context_t mainloop; - otInstance *instance = esp_openthread_get_instance(); - esp_err_t error = ESP_OK; - - while (true) { - FD_ZERO(&mainloop.read_fds); - FD_ZERO(&mainloop.write_fds); - FD_ZERO(&mainloop.error_fds); - - mainloop.max_fd = -1; - mainloop.timeout.tv_sec = 10; - mainloop.timeout.tv_usec = 0; - - esp_openthread_lock_acquire(portMAX_DELAY); - esp_openthread_platform_update(&mainloop); - if (otTaskletsArePending(instance)) { - mainloop.timeout.tv_sec = 0; - mainloop.timeout.tv_usec = 0; - } - esp_openthread_lock_release(); - - if (select(mainloop.max_fd + 1, &mainloop.read_fds, &mainloop.write_fds, &mainloop.error_fds, - &mainloop.timeout) >= 0) { - esp_openthread_lock_acquire(portMAX_DELAY); - otTaskletsProcess(instance); - error = esp_openthread_platform_process(instance, &mainloop); - esp_openthread_lock_release(); - if (error != ESP_OK) { - ESP_LOGE(OT_PLAT_LOG_TAG, "esp_openthread_platform_process failed"); - break; - } - } else { - error = ESP_FAIL; - ESP_LOGE(OT_PLAT_LOG_TAG, "OpenThread system polling failed"); - break; - } - } - return error; -} - -esp_err_t esp_openthread_deinit(void) -{ - otInstanceFinalize(esp_openthread_get_instance()); - return esp_openthread_platform_deinit(); -} diff --git a/components/openthread/port/esp_openthread_alarm.c b/components/openthread/port/esp_openthread_alarm.c deleted file mode 100644 index 132d89f166..0000000000 --- a/components/openthread/port/esp_openthread_alarm.c +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License - - -#include "esp_openthread_alarm.h" - -#include -#include -#include - -#include "esp_log.h" -#include "esp_openthread_common_macro.h" -#include "esp_timer.h" -#include "common/logging.hpp" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "openthread/platform/alarm-micro.h" -#include "openthread/platform/alarm-milli.h" -#include "openthread/platform/diag.h" -#include "openthread/platform/time.h" - -static uint64_t s_alarm_ms_t0 = 0; -static uint64_t s_alarm_ms_dt = 0; -static bool s_is_ms_running = false; -static uint64_t s_alarm_us_t0 = 0; -static uint64_t s_alarm_us_dt = 0; -static bool s_is_us_running = false; - -uint64_t otPlatTimeGet(void) -{ - struct timeval tv_now; - - int err = gettimeofday(&tv_now, NULL); - assert(err == 0); - - return (uint64_t)tv_now.tv_sec * US_PER_S + tv_now.tv_usec; -} - -void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt) -{ - OT_UNUSED_VARIABLE(aInstance); - - s_alarm_ms_t0 = aT0; - s_alarm_ms_dt = aDt; - s_is_ms_running = true; - - otLogDebgPlat("Millisecond timer alarm start running, t0=%llu, dt=%llu", s_alarm_ms_t0, s_alarm_ms_dt); -} - -void otPlatAlarmMilliStop(otInstance *aInstance) -{ - OT_UNUSED_VARIABLE(aInstance); - - s_is_ms_running = false; -} - -uint32_t otPlatAlarmMilliGetNow(void) -{ - return esp_timer_get_time() / US_PER_MS; -} - -void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt) -{ - OT_UNUSED_VARIABLE(aInstance); - - s_alarm_us_t0 = aT0; - s_alarm_us_dt = aDt; - s_is_us_running = true; - - otLogDebgPlat("Microsecond timer alarm start running, t0=%llu, dt=%llu", s_alarm_us_t0, s_alarm_us_dt); -} - -void otPlatAlarmMicroStop(otInstance *aInstance) -{ - OT_UNUSED_VARIABLE(aInstance); - s_is_us_running = false; -} - -uint32_t otPlatAlarmMicroGetNow(void) -{ - return esp_timer_get_time(); -} - -void esp_openthread_alarm_update(esp_openthread_mainloop_context_t *mainloop) -{ - struct timeval *timeout = &mainloop->timeout; - uint32_t now = otPlatAlarmMicroGetNow(); - int64_t remain_min_time_us = INT64_MAX; - int64_t remaining_us = 0; - if (s_is_ms_running) { - remaining_us = (s_alarm_ms_dt + s_alarm_ms_t0) * US_PER_MS - now; - if (remain_min_time_us > remaining_us) { - remain_min_time_us = remaining_us; - } - } - if (s_is_us_running) { - remaining_us = s_alarm_us_dt + s_alarm_us_t0 - now; - if (remain_min_time_us > remaining_us) { - remain_min_time_us = remaining_us; - } - } - if (remain_min_time_us > 0) { - timeout->tv_sec = remain_min_time_us / US_PER_S; - timeout->tv_usec = remain_min_time_us % US_PER_S; - } else { - timeout->tv_sec = 0; - timeout->tv_usec = 0; - } -} - -void esp_openthread_alarm_process(otInstance *aInstance) -{ - if (s_is_ms_running && s_alarm_ms_t0 + s_alarm_ms_dt <= otPlatAlarmMilliGetNow()) { - s_is_ms_running = false; - -#if OPENTHREAD_CONFIG_DIAG_ENABLE - if (otPlatDiagModeGet()) { - otPlatDiagAlarmFired(aInstance); - } else -#endif - { - otPlatAlarmMilliFired(aInstance); - } - - otLogDebgPlat("Millisecond timer alarm fired"); - } - if (s_is_us_running && s_alarm_us_t0 + s_alarm_us_dt <= otPlatAlarmMicroGetNow()) { - s_is_us_running = false; - otPlatAlarmMicroFired(aInstance); - otLogDebgPlat("Microsecond timer alarm fired"); - } -} diff --git a/components/openthread/port/esp_openthread_border_router.c b/components/openthread/port/esp_openthread_border_router.c deleted file mode 100644 index 4f219efae4..0000000000 --- a/components/openthread/port/esp_openthread_border_router.c +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License - -#include "esp_openthread_border_router.h" -#include "esp_err.h" - -static esp_netif_t *s_backbone_netif = NULL; - -esp_err_t esp_openthread_border_router_init(esp_netif_t *backbone_if) -{ -#if CONFIG_OPENTHREAD_BORDER_ROUTER - s_backbone_netif = backbone_if; - - return ESP_OK; -#else - return ESP_ERR_NOT_SUPPORTED; -#endif -} - -esp_netif_t *esp_openthread_get_backbone_netif(void) -{ - return s_backbone_netif; -} diff --git a/components/openthread/port/esp_openthread_flash.c b/components/openthread/port/esp_openthread_flash.c deleted file mode 100644 index ca57dcd07c..0000000000 --- a/components/openthread/port/esp_openthread_flash.c +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the Licens - -#include "esp_partition.h" -#include "esp_spi_flash.h" -#include "openthread/instance.h" -#include "openthread/platform/flash.h" -#include "openthread/platform/settings.h" - -#define ESP_OT_FLASH_PAGE_NUM 2 -#define ESP_OT_FLASH_PAGE_SIZE 4096 - -static const esp_partition_t *s_ot_partition = NULL; - -void otPlatFlashInit(otInstance *instance) -{ - s_ot_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, CONFIG_OPENTHREAD_PARTITION_NAME); - - assert(s_ot_partition != NULL); - assert(s_ot_partition->size >= otPlatFlashGetSwapSize(instance)); -} - -uint32_t otPlatFlashGetSwapSize(otInstance *instance) -{ - return ESP_OT_FLASH_PAGE_SIZE; -} - -void otPlatFlashErase(otInstance *instance, uint8_t index) -{ - uint32_t address = ESP_OT_FLASH_PAGE_SIZE * (index != 0); - uint32_t size = ESP_OT_FLASH_PAGE_SIZE; - esp_err_t err = ESP_OK; - - err = esp_partition_erase_range(s_ot_partition, address, size); - - assert(err == ESP_OK); -} - -void otPlatFlashRead(otInstance *instance, uint8_t index, uint32_t offset, void *data, uint32_t size) -{ - esp_err_t err = ESP_OK; - - offset += ESP_OT_FLASH_PAGE_SIZE * (index != 0); - - err = esp_partition_read(s_ot_partition, offset, data, size); - - assert(err == ESP_OK); -} - -void otPlatFlashWrite(otInstance *instance, uint8_t index, uint32_t offset, const void *data, uint32_t size) -{ - esp_err_t err = ESP_OK; - - offset += ESP_OT_FLASH_PAGE_SIZE * (index != 0); - - err = esp_partition_write(s_ot_partition, offset, data, size); - - assert(err == ESP_OK); -} diff --git a/components/openthread/port/esp_openthread_lock.c b/components/openthread/port/esp_openthread_lock.c deleted file mode 100644 index a3472d0b84..0000000000 --- a/components/openthread/port/esp_openthread_lock.c +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License - -#include "esp_openthread_lock.h" - -#include "esp_err.h" -#include "freertos/FreeRTOS.h" -#include "freertos/semphr.h" - -static SemaphoreHandle_t s_openthread_mutex = NULL; - -bool esp_openthread_lock_acquire(TickType_t block_ticks) -{ - BaseType_t ret = xSemaphoreTakeRecursive(s_openthread_mutex, block_ticks); - return (ret == pdTRUE); -} - -void esp_openthread_lock_release(void) -{ - xSemaphoreGiveRecursive(s_openthread_mutex); -} - -esp_err_t esp_openthread_lock_init(void) -{ - if (s_openthread_mutex != NULL) { - return ESP_ERR_INVALID_STATE; - } - s_openthread_mutex = xSemaphoreCreateRecursiveMutex(); - if (s_openthread_mutex == NULL) { - return ESP_ERR_NO_MEM; - } - return ESP_OK; -} - -void esp_openthread_lock_deinit(void) -{ - if (s_openthread_mutex) { - vSemaphoreDelete(s_openthread_mutex); - s_openthread_mutex = NULL; - } -} diff --git a/components/openthread/port/esp_openthread_logging.c b/components/openthread/port/esp_openthread_logging.c deleted file mode 100644 index 08011ce7b1..0000000000 --- a/components/openthread/port/esp_openthread_logging.c +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License - -#include "esp_openthread.h" - -#include - -#include "esp_log.h" -#include "esp_openthread_common_macro.h" -#include "openthread/platform/logging.h" - -/** - * The default platform logging tag. - * - */ -#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \ - (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL) -OT_TOOL_WEAK void otPlatLog(otLogLevel log_level, otLogRegion log_region, const char *format, ...) -{ - va_list args; - - va_start(args, format); - - switch (log_level) { - case OT_LOG_LEVEL_CRIT: - if (LOG_LOCAL_LEVEL >= ESP_LOG_ERROR) { - esp_log_write(ESP_LOG_ERROR, OT_PLAT_LOG_TAG, LOG_COLOR_E "E(%u) %s:", esp_log_timestamp(), OT_PLAT_LOG_TAG); - esp_log_writev(ESP_LOG_ERROR, OT_PLAT_LOG_TAG, format, args); - esp_log_write(ESP_LOG_ERROR, OT_PLAT_LOG_TAG, LOG_RESET_COLOR "\n"); - } - break; - case OT_LOG_LEVEL_WARN: - if (LOG_LOCAL_LEVEL >= ESP_LOG_WARN) { - esp_log_write(ESP_LOG_WARN, OT_PLAT_LOG_TAG, LOG_COLOR_W "W(%u) %s:", esp_log_timestamp(), OT_PLAT_LOG_TAG); - esp_log_writev(ESP_LOG_WARN, OT_PLAT_LOG_TAG, format, args); - esp_log_write(ESP_LOG_WARN, OT_PLAT_LOG_TAG, LOG_RESET_COLOR "\n"); - } - break; - case OT_LOG_LEVEL_NOTE: - case OT_LOG_LEVEL_INFO: - if (LOG_LOCAL_LEVEL >= ESP_LOG_INFO) { - esp_log_write(ESP_LOG_INFO, OT_PLAT_LOG_TAG, LOG_COLOR_I "I(%u) %s:", esp_log_timestamp(), OT_PLAT_LOG_TAG); - esp_log_writev(ESP_LOG_INFO, OT_PLAT_LOG_TAG, format, args); - esp_log_write(ESP_LOG_INFO, OT_PLAT_LOG_TAG, LOG_RESET_COLOR "\n"); - } - break; - default: - if (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) { - esp_log_write(ESP_LOG_DEBUG, OT_PLAT_LOG_TAG, LOG_COLOR_D "D(%u) %s:", esp_log_timestamp(), OT_PLAT_LOG_TAG); - esp_log_writev(ESP_LOG_DEBUG, OT_PLAT_LOG_TAG, format, args); - esp_log_write(ESP_LOG_DEBUG, OT_PLAT_LOG_TAG, LOG_RESET_COLOR "\n"); - } - break; - } - va_end(args); -} -#endif diff --git a/components/openthread/port/esp_openthread_misc.c b/components/openthread/port/esp_openthread_misc.c deleted file mode 100644 index 36785a1a2e..0000000000 --- a/components/openthread/port/esp_openthread_misc.c +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License - -#include "esp_log.h" -#include "esp_openthread.h" -#include "esp_system.h" -#include "common/logging.hpp" -#include "openthread/platform/misc.h" - -static otPlatMcuPowerState s_mcu_power_state = OT_PLAT_MCU_POWER_STATE_ON; - -void otPlatReset(otInstance *aInstance) -{ - esp_restart(); -} - -otPlatResetReason otPlatGetResetReason(otInstance *instance) -{ - switch (esp_reset_reason()) { - case ESP_RST_UNKNOWN: - return OT_PLAT_RESET_REASON_UNKNOWN; - case ESP_RST_POWERON: - return OT_PLAT_RESET_REASON_POWER_ON; - case ESP_RST_EXT: - return OT_PLAT_RESET_REASON_EXTERNAL; - case ESP_RST_SW: - return OT_PLAT_RESET_REASON_SOFTWARE; - case ESP_RST_PANIC: - return OT_PLAT_RESET_REASON_FAULT; - case ESP_RST_INT_WDT: - return OT_PLAT_RESET_REASON_WATCHDOG; - case ESP_RST_TASK_WDT: - return OT_PLAT_RESET_REASON_WATCHDOG; - case ESP_RST_WDT: - return OT_PLAT_RESET_REASON_WATCHDOG; - default: - return OT_PLAT_RESET_REASON_OTHER; - } -} - -void otPlatWakeHost(void) -{ - // Not Implemented. -} - -otError otPlatSetMcuPowerState(otInstance *instance, otPlatMcuPowerState state) -{ - otError error = OT_ERROR_NONE; - - OT_UNUSED_VARIABLE(instance); - - switch (state) { - case OT_PLAT_MCU_POWER_STATE_ON: - case OT_PLAT_MCU_POWER_STATE_LOW_POWER: - s_mcu_power_state = state; - break; - - default: - error = OT_ERROR_FAILED; - break; - } - - return error; -} - -otPlatMcuPowerState otPlatGetMcuPowerState(otInstance *instance) -{ - OT_UNUSED_VARIABLE(instance); - return s_mcu_power_state; -} - -void otPlatAssertFail(const char *filename, int line) -{ - otLogCritPlat("Assert failed at %s:%d", filename, line); - assert(false); -} diff --git a/components/openthread/port/esp_openthread_netif_glue.c b/components/openthread/port/esp_openthread_netif_glue.c deleted file mode 100644 index 1fe5bea4a3..0000000000 --- a/components/openthread/port/esp_openthread_netif_glue.c +++ /dev/null @@ -1,353 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License - -#include "esp_openthread_netif_glue.h" - -#include -#include - -#include "esp_check.h" -#include "esp_err.h" -#include "esp_event.h" -#include "esp_netif.h" -#include "esp_openthread.h" -#include "esp_openthread_common_macro.h" -#include "esp_openthread_lock.h" -#include "esp_openthread_netif_glue_priv.h" -#include "esp_vfs_eventfd.h" -#include "sdkconfig.h" -#include "common/code_utils.hpp" -#include "common/logging.hpp" -#include "config/link_quality.h" -#include "freertos/FreeRTOS.h" -#include "openthread/error.h" -#include "openthread/icmp6.h" -#include "openthread/instance.h" -#include "openthread/ip6.h" -#include "openthread/link.h" -#include "openthread/message.h" -#include "openthread/thread.h" - -typedef struct { - esp_netif_driver_base_t base; - int event_fd; -} esp_openthread_netif_glue_t; - -static esp_openthread_netif_glue_t s_openthread_netif_glue = { - .event_fd = -1, -}; - -ESP_EVENT_DEFINE_BASE(OPENTHREAD_EVENT); - -static QueueHandle_t s_packet_queue; -static esp_netif_t *s_openthread_netif; - -#define NETIF_OUTPUT_SIGNAL 1 - -static esp_err_t notify_packets_pending(void) -{ - uint64_t signal = NETIF_OUTPUT_SIGNAL; - ssize_t ret = write(s_openthread_netif_glue.event_fd, &signal, sizeof(signal)); - if (ret != sizeof(signal)) { - otLogWarnPlat("Thread netif failed to notify eventfd"); - return ESP_FAIL; - } - return ESP_OK; -} - -void process_thread_address(const otIp6AddressInfo *address_info, bool is_added, void *context) -{ - bool is_multicast = address_info->mAddress->mFields.m8[0] == 0xff; - esp_ip6_addr_t addr; - - memcpy(addr.addr, address_info->mAddress->mFields.m8, sizeof(addr.addr)); - if (is_added) { - if (is_multicast) { - if (esp_event_post(OPENTHREAD_EVENT, OPENTHREAD_EVENT_MULTICAST_GROUP_JOIN, &addr, sizeof(addr), 0) != - ESP_OK) { - otLogCritPlat("Failed to post OpenThread join multicast group event"); - } - } else { - ip_event_add_ip6_t add_addr; - add_addr.addr = addr; - add_addr.preferred = address_info->mPreferred; - if (esp_event_post(OPENTHREAD_EVENT, OPENTHREAD_EVENT_GOT_IP6, &add_addr, sizeof(add_addr), 0) != ESP_OK) { - otLogCritPlat("Failed to post OpenThread got ip6 address event"); - } - } - } else { - if (is_multicast) { - if (esp_event_post(OPENTHREAD_EVENT, OPENTHREAD_EVENT_MULTICAST_GROUP_LEAVE, &addr, sizeof(addr), 0) != - ESP_OK) { - otLogCritPlat("Failed to post OpenThread leave multicast group event"); - } - } else { - if (esp_event_post(OPENTHREAD_EVENT, OPENTHREAD_EVENT_LOST_IP6, &addr, sizeof(addr), 0) != ESP_OK) { - otLogCritPlat("Failed to post OpenThread lost ip6 address event"); - } - } - } -} - -static void process_thread_receive(otMessage *message, void *context) -{ - esp_err_t error; - uint16_t length = otMessageGetLength(message); - uint8_t *buffer = malloc(length); - - VerifyOrExit(buffer != NULL, error = OT_ERROR_NO_BUFS); - uint16_t read_length = otMessageRead(message, 0, buffer, length); - assert(read_length == length); - - error = esp_netif_receive(s_openthread_netif_glue.base.netif, buffer, length, NULL); - buffer = NULL; - -exit: - if (error != ESP_OK) { - otLogWarnPlat("process_thread_receive failed: %s", esp_err_to_name(error)); - } - - otMessageFree(message); -} - -static esp_err_t process_thread_transmit(otInstance *instance) -{ - otMessage *msg = NULL; - esp_err_t error = ESP_OK; - uint64_t event; - - int ret = read(s_openthread_netif_glue.event_fd, &event, sizeof(event)); - assert(ret == sizeof(event)); - while (xQueueReceive(s_packet_queue, &msg, 0) == pdTRUE) { - if (msg) { - otError ot_error = otIp6Send(esp_openthread_get_instance(), msg); - if (ot_error != OT_ERROR_NONE && ot_error != OT_ERROR_DROP) { - otLogWarnPlat("ThreadNetif Failed to send OpenThread IP6 message: %s", otThreadErrorToString(ot_error)); - } - if (ot_error == OT_ERROR_DROP) { - // OpenThread will intentionally drop some multicast and ICMPv6 packets - // which are not required for the Thread network. - otLogDebgPlat("OpenThread stack filtered netif packet"); - } - if (ot_error != OT_ERROR_NONE) { - break; - } - } - } - - if (uxQueueMessagesWaiting(s_packet_queue) > 0) { - error = notify_packets_pending(); - } - - return error; -} - -void esp_openthread_netif_glue_state_callback(otChangedFlags changed_flags) -{ - otInstance *instance = esp_openthread_get_instance(); - esp_err_t err = ESP_OK; - - if (s_packet_queue != NULL && (OT_CHANGED_THREAD_NETIF_STATE & changed_flags)) { - if (otLinkIsEnabled(instance)) { - otLogInfoPlat("netif up"); - if (esp_event_post(OPENTHREAD_EVENT, OPENTHREAD_EVENT_IF_UP, NULL, 0, 0) != ESP_OK) { - otLogCritPlat("Failed to post OpenThread if up event"); - } - } else { - otLogInfoPlat("netif down"); - if (esp_event_post(OPENTHREAD_EVENT, OPENTHREAD_EVENT_IF_DOWN, NULL, 0, 0) != ESP_OK) { - otLogCritPlat("Failed to post OpenThread if down event"); - } - } - } - - if (err != ESP_OK) { - otLogCritPlat("Failed to configure netif state"); - } -} - -static esp_err_t openthread_netif_transmit(void *handle, void *buffer, size_t len) -{ - esp_err_t error = ESP_OK; - otError ot_error = OT_ERROR_NONE; - - esp_openthread_lock_acquire(portMAX_DELAY); - otMessage *message = otIp6NewMessage(esp_openthread_get_instance(), NULL); - if (message == NULL) { - otLogCritPlat("Failed to allocate OpenThread message"); - ExitNow(error = ESP_ERR_NO_MEM); - } - - ot_error = otMessageAppend(message, buffer, len); - if (ot_error != OT_ERROR_NONE) { - otLogCritPlat("Failed to copy to OpenThread message: %s", otThreadErrorToString(ot_error)); - ExitNow(error = ESP_ERR_NO_MEM); - } - - if (xQueueSend(s_packet_queue, &message, 0) != pdTRUE) { - otLogCritPlat("Failed to send to Thread netif: packet queue full"); - ExitNow(error = ESP_ERR_NO_MEM); - } - VerifyOrExit(notify_packets_pending() == ESP_OK, error = ESP_FAIL); - -exit: - if (ot_error != OT_ERROR_NONE && message != NULL) { - otMessageFree(message); - } - esp_openthread_lock_release(); - return error; -} - -static esp_err_t register_openthread_event_handlers(esp_netif_t *esp_netif) -{ - ESP_RETURN_ON_ERROR( - esp_event_handler_register(OPENTHREAD_EVENT, OPENTHREAD_EVENT_START, esp_netif_action_start, esp_netif), - OT_PLAT_LOG_TAG, "OpenThread start event register failed"); - ESP_RETURN_ON_ERROR( - esp_event_handler_register(OPENTHREAD_EVENT, OPENTHREAD_EVENT_STOP, esp_netif_action_stop, esp_netif), - OT_PLAT_LOG_TAG, "OpenThread stop event register failed"); - ESP_RETURN_ON_ERROR( - esp_event_handler_register(OPENTHREAD_EVENT, OPENTHREAD_EVENT_IF_UP, esp_netif_action_connected, esp_netif), - OT_PLAT_LOG_TAG, "OpenThread interface up event register failed"); - ESP_RETURN_ON_ERROR(esp_event_handler_register(OPENTHREAD_EVENT, OPENTHREAD_EVENT_IF_DOWN, - esp_netif_action_disconnected, esp_netif), - OT_PLAT_LOG_TAG, "OpenThread interface down event register failed"); - ESP_RETURN_ON_ERROR(esp_event_handler_register(OPENTHREAD_EVENT, OPENTHREAD_EVENT_GOT_IP6, - esp_netif_action_add_ip6_address, esp_netif), - OT_PLAT_LOG_TAG, "OpenThread interface got ip6 event register failed"); - ESP_RETURN_ON_ERROR(esp_event_handler_register(OPENTHREAD_EVENT, OPENTHREAD_EVENT_LOST_IP6, - esp_netif_action_remove_ip6_address, esp_netif), - OT_PLAT_LOG_TAG, "OpenThread interface remove ip6 event register failed"); - ESP_RETURN_ON_ERROR(esp_event_handler_register(OPENTHREAD_EVENT, OPENTHREAD_EVENT_MULTICAST_GROUP_JOIN, - esp_netif_action_join_ip6_multicast_group, esp_netif), - OT_PLAT_LOG_TAG, "OpenThread interface join ip6 multicast group event register failed"); - ESP_RETURN_ON_ERROR(esp_event_handler_register(OPENTHREAD_EVENT, OPENTHREAD_EVENT_MULTICAST_GROUP_LEAVE, - esp_netif_action_leave_ip6_multicast_group, esp_netif), - OT_PLAT_LOG_TAG, "OpenThread interface leave ip6 multicast group event register failed"); - return ESP_OK; -} - -static void unregister_openthread_event_handlers(void) -{ - esp_event_handler_unregister(OPENTHREAD_EVENT, OPENTHREAD_EVENT_START, esp_netif_action_start); - esp_event_handler_unregister(OPENTHREAD_EVENT, OPENTHREAD_EVENT_STOP, esp_netif_action_stop); - esp_event_handler_unregister(OPENTHREAD_EVENT, OPENTHREAD_EVENT_IF_UP, esp_netif_action_connected); - esp_event_handler_unregister(OPENTHREAD_EVENT, OPENTHREAD_EVENT_IF_DOWN, esp_netif_action_disconnected); - esp_event_handler_unregister(OPENTHREAD_EVENT, OPENTHREAD_EVENT_GOT_IP6, esp_netif_action_add_ip6_address); - esp_event_handler_unregister(OPENTHREAD_EVENT, OPENTHREAD_EVENT_LOST_IP6, esp_netif_action_remove_ip6_address); - esp_event_handler_unregister(OPENTHREAD_EVENT, OPENTHREAD_EVENT_MULTICAST_GROUP_JOIN, - esp_netif_action_join_ip6_multicast_group); - esp_event_handler_unregister(OPENTHREAD_EVENT, OPENTHREAD_EVENT_MULTICAST_GROUP_LEAVE, - esp_netif_action_leave_ip6_multicast_group); -} - -static esp_err_t openthread_netif_post_attach(esp_netif_t *esp_netif, void *args) -{ - esp_netif_driver_base_t *base = (esp_netif_driver_base_t *)args; - base->netif = esp_netif; - - // set driver related config to esp-netif - esp_netif_driver_ifconfig_t driver_ifconfig = { - .handle = &s_openthread_netif_glue, .transmit = openthread_netif_transmit, .driver_free_rx_buffer = NULL - }; - - ESP_ERROR_CHECK(esp_netif_set_driver_config(esp_netif, &driver_ifconfig)); - - otLogInfoPlat("OpenThread attached to netif"); - esp_err_t error = register_openthread_event_handlers(esp_netif); - s_openthread_netif = esp_netif; - if (error == ESP_OK) { - error = esp_event_post(OPENTHREAD_EVENT, OPENTHREAD_EVENT_START, NULL, 0, 0); - } - - return error; -} - -void *esp_openthread_netif_glue_init(void) -{ - otInstance *instance = esp_openthread_get_instance(); - esp_err_t error = ESP_OK; - - if (instance == NULL || s_packet_queue || s_openthread_netif_glue.event_fd >= 0) { - return NULL; - } - - s_packet_queue = xQueueCreate(CONFIG_OPENTHREAD_NETIF_QUEUE_SIZE, sizeof(otMessage *)); - if (s_packet_queue == NULL) { - otLogCritPlat("Failed to allocate Thread netif packet queue"); - ExitNow(error = ESP_ERR_NO_MEM); - } - - otIp6SetAddressCallback(instance, process_thread_address, instance); - otIp6SetReceiveCallback(instance, process_thread_receive, instance); - otIp6SetReceiveFilterEnabled(instance, true); - otIcmp6SetEchoMode(instance, OT_ICMP6_ECHO_HANDLER_DISABLED); - - s_openthread_netif_glue.event_fd = eventfd(0, 0); - if (s_openthread_netif_glue.event_fd < 0) { - otLogCritPlat("Failed to create event fd for Thread netif"); - ExitNow(error = ESP_FAIL); - } - s_openthread_netif_glue.base.post_attach = openthread_netif_post_attach; - -exit: - if (error != ESP_OK) { - return NULL; - } - - return &s_openthread_netif_glue.base; -} - -void esp_openthread_netif_glue_deinit(void) -{ - otInstance *instance = esp_openthread_get_instance(); - otIp6SetAddressCallback(instance, NULL, NULL); - otIp6SetReceiveCallback(instance, NULL, NULL); - if (s_packet_queue) { - vQueueDelete(s_packet_queue); - s_packet_queue = NULL; - } - if (s_openthread_netif_glue.event_fd >= 0) { - close(s_openthread_netif_glue.event_fd); - s_openthread_netif_glue.event_fd = -1; - } - if (esp_event_post(OPENTHREAD_EVENT, OPENTHREAD_EVENT_STOP, NULL, 0, 0) != ESP_OK) { - otLogCritPlat("Failed to stop OpenThread netif"); - } - s_openthread_netif = NULL; - unregister_openthread_event_handlers(); -} - -void esp_openthread_netif_glue_update(esp_openthread_mainloop_context_t *mainloop) -{ - if (s_openthread_netif_glue.event_fd >= 0) { - FD_SET(s_openthread_netif_glue.event_fd, &mainloop->read_fds); - if (s_openthread_netif_glue.event_fd > mainloop->max_fd) { - mainloop->max_fd = s_openthread_netif_glue.event_fd; - } - } -} - -esp_err_t esp_openthread_netif_glue_process(otInstance *instance, const esp_openthread_mainloop_context_t *context) -{ - if (s_openthread_netif_glue.event_fd >= 0 && FD_ISSET(s_openthread_netif_glue.event_fd, &context->read_fds)) { - return process_thread_transmit(instance); - } - return ESP_OK; -} - -esp_netif_t *esp_openthread_get_netif(void) -{ - return s_openthread_netif; -} diff --git a/components/openthread/port/esp_openthread_platform.cpp b/components/openthread/port/esp_openthread_platform.cpp deleted file mode 100644 index 49838ed7d4..0000000000 --- a/components/openthread/port/esp_openthread_platform.cpp +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License - -#include "esp_openthread_platform.h" - -#include "esp_check.h" -#include "esp_err.h" -#include "esp_log.h" -#include "esp_openthread_alarm.h" -#include "esp_openthread_common_macro.h" -#include "esp_openthread_lock.h" -#include "esp_openthread_netif_glue.h" -#include "esp_openthread_netif_glue_priv.h" -#include "esp_openthread_radio_uart.h" -#include "esp_openthread_task_queue.h" -#include "esp_openthread_types.h" -#include "esp_openthread_uart.h" -#include "common/code_utils.hpp" -#include "common/logging.hpp" -#include "core/common/instance.hpp" -#include "freertos/FreeRTOS.h" -#include "freertos/queue.h" -#include "openthread/cli.h" -#include "openthread/instance.h" -#include "openthread/tasklet.h" - -static esp_openthread_platform_config_t s_platform_config; -static bool s_openthread_platform_initialized = false; - -esp_err_t esp_openthread_platform_init(const esp_openthread_platform_config_t *config) -{ - ESP_RETURN_ON_FALSE(config->radio_config.radio_mode == RADIO_MODE_UART_RCP, ESP_ERR_INVALID_ARG, OT_PLAT_LOG_TAG, - "Radio mode not supported"); - ESP_RETURN_ON_FALSE(config->host_config.host_connection_mode == HOST_CONNECTION_MODE_NONE || - config->host_config.host_connection_mode == HOST_CONNECTION_MODE_UART, - ESP_ERR_INVALID_ARG, OT_PLAT_LOG_TAG, "Host connection mode not supported"); - ESP_RETURN_ON_FALSE(!s_openthread_platform_initialized, ESP_ERR_INVALID_STATE, OT_PLAT_LOG_TAG, - "OpenThread platform already initialized"); - - esp_err_t ret = ESP_OK; - - s_platform_config = *config; - ESP_GOTO_ON_ERROR(esp_openthread_lock_init(), exit, OT_PLAT_LOG_TAG, "esp_openthread_lock_init failed"); - if (config->host_config.host_connection_mode == HOST_CONNECTION_MODE_UART) { - ESP_GOTO_ON_ERROR(esp_openthread_uart_init(config), exit, OT_PLAT_LOG_TAG, "esp_openthread_uart_init failed"); - } - ESP_GOTO_ON_ERROR(esp_openthread_task_queue_init(), exit, OT_PLAT_LOG_TAG, "esp_openthread_task_queue_init failed"); - ESP_GOTO_ON_ERROR(esp_openthread_radio_init(config), exit, OT_PLAT_LOG_TAG, "esp_openthread_radio_init failed"); - -exit: - if (ret != ESP_OK) { - esp_openthread_platform_deinit(); - } - - return ret; -} - -otInstance *esp_openthread_get_instance(void) -{ - return (otInstance *)&ot::Instance::Get(); -} - -esp_err_t esp_openthread_platform_deinit(void) -{ - ESP_RETURN_ON_FALSE(s_openthread_platform_initialized, ESP_ERR_INVALID_STATE, OT_PLAT_LOG_TAG, - "OpenThread platform not initialized"); - - esp_openthread_task_queue_deinit(); - esp_openthread_radio_deinit(); - if (s_platform_config.host_config.host_connection_mode == HOST_CONNECTION_MODE_UART) { - esp_openthread_uart_deinit(); - } - esp_openthread_lock_deinit(); - - return ESP_OK; -} - -void esp_openthread_platform_update(esp_openthread_mainloop_context_t *mainloop) -{ - esp_openthread_alarm_update(mainloop); - if (s_platform_config.host_config.host_connection_mode == HOST_CONNECTION_MODE_UART) { - esp_openthread_uart_update(mainloop); - } - esp_openthread_radio_update(mainloop); - esp_openthread_netif_glue_update(mainloop); - esp_openthread_task_queue_update(mainloop); -} - -esp_err_t esp_openthread_platform_process(otInstance *instance, const esp_openthread_mainloop_context_t *mainloop) -{ - if (s_platform_config.host_config.host_connection_mode == HOST_CONNECTION_MODE_UART) { - ESP_RETURN_ON_ERROR(esp_openthread_uart_process(), OT_PLAT_LOG_TAG, "esp_openthread_uart_process failed"); - } - esp_openthread_radio_process(instance, mainloop); - esp_openthread_alarm_process(instance); - esp_openthread_task_queue_process(instance, mainloop); - return esp_openthread_netif_glue_process(instance, mainloop); -} diff --git a/components/openthread/port/esp_openthread_radio_uart.cpp b/components/openthread/port/esp_openthread_radio_uart.cpp deleted file mode 100644 index d89e0d4ba3..0000000000 --- a/components/openthread/port/esp_openthread_radio_uart.cpp +++ /dev/null @@ -1,299 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License - -#include "esp_openthread_radio_uart.h" - -#include "esp_check.h" -#include "esp_err.h" -#include "esp_openthread_common_macro.h" -#include "esp_openthread_types.h" -#include "esp_uart_spinel_interface.hpp" -#include "lib/spinel/radio_spinel.hpp" -#include "openthread/platform/diag.h" -#include "openthread/platform/radio.h" - -using ot::Spinel::RadioSpinel; -using esp::openthread::UartSpinelInterface; - -static RadioSpinel s_radio; - -esp_err_t esp_openthread_radio_init(const esp_openthread_platform_config_t *config) -{ - ESP_RETURN_ON_ERROR(s_radio.GetSpinelInterface().Init(config->radio_config.radio_uart_config), OT_PLAT_LOG_TAG, - "Spinel interface init falied"); - s_radio.Init(/*reset_radio=*/true, /*restore_dataset_from_ncp=*/false, /*skip_rcp_compatibility_check=*/false); - return ESP_OK; -} - -void esp_openthread_radio_deinit(void) -{ - s_radio.Deinit(); -} - -esp_err_t esp_openthread_radio_process(otInstance *instance, const esp_openthread_mainloop_context_t *mainloop) -{ - s_radio.Process(*mainloop); - - return ESP_OK; -} - -void esp_openthread_radio_update(esp_openthread_mainloop_context_t *mainloop) -{ - s_radio.GetSpinelInterface().Update(*mainloop); -} - -void otPlatRadioGetIeeeEui64(otInstance *instance, uint8_t *ieee_eui64) -{ - SuccessOrDie(s_radio.GetIeeeEui64(ieee_eui64)); -} - -void otPlatRadioSetPanId(otInstance *instance, uint16_t pan_id) -{ - SuccessOrDie(s_radio.SetPanId(pan_id)); -} - -void otPlatRadioSetExtendedAddress(otInstance *instance, const otExtAddress *address) -{ - otExtAddress addr; - - for (size_t i = 0; i < sizeof(addr); i++) { - addr.m8[i] = address->m8[sizeof(addr) - 1 - i]; - } - - SuccessOrDie(s_radio.SetExtendedAddress(addr)); -} - -void otPlatRadioSetShortAddress(otInstance *instance, uint16_t address) -{ - SuccessOrDie(s_radio.SetShortAddress(address)); -} - -void otPlatRadioSetPromiscuous(otInstance *instance, bool enable) -{ - SuccessOrDie(s_radio.SetPromiscuous(enable)); -} - -bool otPlatRadioIsEnabled(otInstance *instance) -{ - return s_radio.IsEnabled(); -} - -otError otPlatRadioEnable(otInstance *instance) -{ - return s_radio.Enable(instance); -} - -otError otPlatRadioDisable(otInstance *instance) -{ - return s_radio.Disable(); -} - -otError otPlatRadioSleep(otInstance *instance) -{ - return s_radio.Sleep(); -} - -otError otPlatRadioReceive(otInstance *instance, uint8_t channel) -{ - return s_radio.Receive(channel); -} - -otError otPlatRadioTransmit(otInstance *instance, otRadioFrame *frame) -{ - return s_radio.Transmit(*frame); -} - -otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *instance) -{ - return &s_radio.GetTransmitFrame(); -} - -int8_t otPlatRadioGetRssi(otInstance *instance) -{ - return s_radio.GetRssi(); -} - -otRadioCaps otPlatRadioGetCaps(otInstance *instance) -{ - return s_radio.GetRadioCaps(); -} - -bool otPlatRadioGetPromiscuous(otInstance *instance) -{ - return s_radio.IsPromiscuous(); -} - -void otPlatRadioEnableSrcMatch(otInstance *instance, bool enable) -{ - SuccessOrDie(s_radio.EnableSrcMatch(enable)); -} - -otError otPlatRadioAddSrcMatchShortEntry(otInstance *instance, uint16_t short_address) -{ - return s_radio.AddSrcMatchShortEntry(short_address); -} - -otError otPlatRadioAddSrcMatchExtEntry(otInstance *instance, const otExtAddress *ext_address) -{ - otExtAddress addr; - - for (size_t i = 0; i < sizeof(addr); i++) { - addr.m8[i] = ext_address->m8[sizeof(addr) - 1 - i]; - } - - return s_radio.AddSrcMatchExtEntry(addr); -} - -otError otPlatRadioClearSrcMatchShortEntry(otInstance *instance, uint16_t short_address) -{ - return s_radio.ClearSrcMatchShortEntry(short_address); -} - -otError otPlatRadioClearSrcMatchExtEntry(otInstance *instance, const otExtAddress *ext_address) -{ - otExtAddress addr; - - for (size_t i = 0; i < sizeof(addr); i++) { - addr.m8[i] = ext_address->m8[sizeof(addr) - 1 - i]; - } - - return s_radio.ClearSrcMatchExtEntry(addr); -} - -void otPlatRadioClearSrcMatchShortEntries(otInstance *instance) -{ - SuccessOrDie(s_radio.ClearSrcMatchShortEntries()); -} - -void otPlatRadioClearSrcMatchExtEntries(otInstance *instance) -{ - SuccessOrDie(s_radio.ClearSrcMatchExtEntries()); -} - -otError otPlatRadioEnergyScan(otInstance *instance, uint8_t channel, uint16_t duration) -{ - return s_radio.EnergyScan(channel, duration); -} - -otError otPlatRadioGetTransmitPower(otInstance *instance, int8_t *power) -{ - otError error; - - VerifyOrExit(power != NULL, error = OT_ERROR_INVALID_ARGS); - error = s_radio.GetTransmitPower(*power); - -exit: - return error; -} - -otError otPlatRadioSetTransmitPower(otInstance *instance, int8_t power) -{ - return s_radio.SetTransmitPower(power); -} - -otError otPlatRadioGetCcaEnergyDetectThreshold(otInstance *instance, int8_t *threshold) -{ - otError error; - - VerifyOrExit(threshold != NULL, error = OT_ERROR_INVALID_ARGS); - error = s_radio.GetCcaEnergyDetectThreshold(*threshold); - -exit: - return error; -} - -otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *instance, int8_t threshold) -{ - return s_radio.SetCcaEnergyDetectThreshold(threshold); -} - -int8_t otPlatRadioGetReceiveSensitivity(otInstance *instance) -{ - return s_radio.GetReceiveSensitivity(); -} - -void otPlatRadioSetMacKey(otInstance *aInstance, - uint8_t aKeyIdMode, - uint8_t aKeyId, - const otMacKey *aPrevKey, - const otMacKey *aCurrKey, - const otMacKey *aNextKey) -{ - SuccessOrDie(s_radio.SetMacKey(aKeyIdMode, aKeyId, *aPrevKey, *aCurrKey, *aNextKey)); -} - -void otPlatRadioSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCounter) -{ - SuccessOrDie(s_radio.SetMacFrameCounter(aMacFrameCounter)); -} - -#if OPENTHREAD_CONFIG_DIAG_ENABLE -otError otPlatDiagProcess(otInstance *instance, int argc, char *argv[], char *output, size_t output_max_len) -{ - // 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]); - } - - return s_radio.PlatDiagProcess(cmd, output, output_max_len); -} - -void otPlatDiagModeSet(bool aMode) -{ - SuccessOrExit(s_radio.PlatDiagProcess(aMode ? "start" : "stop", NULL, 0)); - s_radio.SetDiagEnabled(aMode); - -exit: - return; -} - -bool otPlatDiagModeGet(void) -{ - return s_radio.IsDiagEnabled(); -} - -void otPlatDiagTxPowerSet(int8_t tx_power) -{ - char cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE]; - - snprintf(cmd, sizeof(cmd), "power %d", tx_power); - SuccessOrExit(s_radio.PlatDiagProcess(cmd, NULL, 0)); - -exit: - return; -} - -void otPlatDiagChannelSet(uint8_t channel) -{ - char cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE]; - - snprintf(cmd, sizeof(cmd), "channel %d", channel); - SuccessOrExit(s_radio.PlatDiagProcess(cmd, NULL, 0)); - -exit: - return; -} - -void otPlatDiagRadioReceived(otInstance *instance, otRadioFrame *frame, otError error) -{ -} - -void otPlatDiagAlarmCallback(otInstance *instance) -{ -} -#endif // OPENTHREAD_CONFIG_DIAG_ENABLE diff --git a/components/openthread/port/esp_openthread_task_queue.c b/components/openthread/port/esp_openthread_task_queue.c deleted file mode 100644 index 344ce1ab7c..0000000000 --- a/components/openthread/port/esp_openthread_task_queue.c +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License - -#include "esp_check.h" -#include "esp_err.h" -#include "esp_openthread_common_macro.h" -#include "esp_openthread_task_queue.h" -#include "esp_vfs.h" -#include "esp_vfs_eventfd.h" -#include "common/logging.hpp" -#include "freertos/FreeRTOS.h" -#include "freertos/queue.h" - -static QueueHandle_t s_task_queue = NULL; -static int s_task_queue_event_fd = -1; - -typedef struct { - esp_openthread_task_t task; - void *arg; -} task_storage_t; - -esp_err_t esp_openthread_task_queue_init(void) -{ - s_task_queue_event_fd = eventfd(0, EFD_SUPPORT_ISR); - 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_OPENTHREAD_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"); - return ESP_OK; -} - -esp_err_t esp_openthread_task_queue_post(esp_openthread_task_t task, void *arg) -{ - task_storage_t task_storage = { - .task = task, - .arg = arg, - }; - uint64_t val = 1; - ssize_t ret; - - ESP_RETURN_ON_FALSE(xQueueSend(s_task_queue, &task_storage, portMAX_DELAY), ESP_FAIL, OT_PLAT_LOG_TAG, - "Failed to post task to OpenThread task queue"); - ret = write(s_task_queue_event_fd, &val, sizeof(val)); - assert(ret == sizeof(val)); - - return ESP_OK; -} - -void esp_openthread_task_queue_update(esp_openthread_mainloop_context_t *mainloop) -{ - if (s_task_queue_event_fd >= 0) { - FD_SET(s_task_queue_event_fd, &mainloop->read_fds); - if (s_task_queue_event_fd > mainloop->max_fd) { - mainloop->max_fd = s_task_queue_event_fd; - } - } -} - -esp_err_t esp_openthread_task_queue_process(otInstance *instance, const esp_openthread_mainloop_context_t *mainloop) -{ - task_storage_t task_storage; - - if (FD_ISSET(s_task_queue_event_fd, &mainloop->read_fds)) { - uint64_t val; - ssize_t ret = read(s_task_queue_event_fd, &val, sizeof(val)); - assert(ret == sizeof(val)); - } - - ESP_RETURN_ON_FALSE(s_task_queue != NULL, ESP_ERR_INVALID_STATE, OT_PLAT_LOG_TAG, - "OpenThread task queue not initialized"); - while (xQueueReceive(s_task_queue, &task_storage, 0) == pdTRUE) { - task_storage.task(task_storage.arg); - } - - return ESP_OK; -} - -esp_err_t esp_openthread_task_queue_deinit(void) -{ - if (s_task_queue) { - vQueueDelete(s_task_queue); - s_task_queue = NULL; - } - if (s_task_queue_event_fd >= 0) { - close(s_task_queue_event_fd); - s_task_queue_event_fd = -1; - } - - return ESP_OK; -} diff --git a/components/openthread/port/esp_openthread_uart.c b/components/openthread/port/esp_openthread_uart.c deleted file mode 100644 index 5f5668b9c6..0000000000 --- a/components/openthread/port/esp_openthread_uart.c +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License - -#include "esp_openthread_uart.h" - -#include -#include -#include - -#include "esp_check.h" -#include "esp_err.h" -#include "esp_log.h" -#include "esp_openthread.h" -#include "esp_openthread_common_macro.h" -#include "esp_openthread_types.h" -#include "esp_vfs_dev.h" -#include "common/logging.hpp" -#include "driver/uart.h" -#include "utils/uart.h" - -static int s_uart_port; -static int s_uart_fd; -static uint8_t s_uart_buffer[ESP_OPENTHREAD_UART_BUFFER_SIZE]; - -otError otPlatUartEnable(void) -{ - return OT_ERROR_NONE; -} - -otError otPlatUartDisable(void) -{ - return OT_ERROR_NONE; -} - -otError otPlatUartFlush(void) -{ - return OT_ERROR_NONE; -} - -otError otPlatUartSend(const uint8_t *buf, uint16_t buf_length) -{ - int rval = write(s_uart_fd, buf, buf_length); - - if (rval != (int)buf_length) { - return OT_ERROR_FAILED; - } - - otPlatUartSendDone(); - - return OT_ERROR_NONE; -} - -esp_err_t esp_openthread_uart_init_port(const esp_openthread_uart_config_t *config) -{ - ESP_RETURN_ON_ERROR(uart_param_config(config->port, &config->uart_config), OT_PLAT_LOG_TAG, - "uart_param_config failed"); - ESP_RETURN_ON_ERROR( - uart_set_pin(config->port, config->tx_pin, config->rx_pin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE), - 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"); - esp_vfs_dev_uart_use_driver(config->port); - return ESP_OK; -} - -esp_err_t esp_openthread_uart_init(const esp_openthread_platform_config_t *config) -{ - char uart_path[16]; - - // Disable IO buffer. - setvbuf(stdin, NULL, _IONBF, 0); - setvbuf(stdout, NULL, _IONBF, 0); - - // Install UART driver for interrupt-driven reads and writes. - s_uart_port = config->host_config.host_uart_config.port; - ESP_RETURN_ON_ERROR(esp_openthread_uart_init_port(&config->host_config.host_uart_config), OT_PLAT_LOG_TAG, - "esp_openthread_uart_init_port failed"); - - esp_vfs_dev_uart_port_set_rx_line_endings(s_uart_port, ESP_LINE_ENDINGS_LF); - esp_vfs_dev_uart_port_set_tx_line_endings(s_uart_port, ESP_LINE_ENDINGS_CRLF); - - snprintf(uart_path, sizeof(uart_path), "/dev/uart/%d", s_uart_port); - s_uart_fd = open(uart_path, O_RDWR | O_NONBLOCK); - - return s_uart_fd >= 0 ? ESP_OK : ESP_FAIL; -} - -void esp_openthread_uart_deinit() -{ - if (s_uart_fd != -1) { - close(s_uart_fd); - s_uart_fd = -1; - } - uart_driver_delete(s_uart_port); -} - -void esp_openthread_uart_update(esp_openthread_mainloop_context_t *mainloop) -{ - FD_SET(s_uart_fd, &mainloop->read_fds); - if (s_uart_fd > mainloop->max_fd) { - mainloop->max_fd = s_uart_fd; - } -} - -esp_err_t esp_openthread_uart_process() -{ - int rval = read(s_uart_fd, s_uart_buffer, sizeof(s_uart_buffer)); - - if (rval > 0) { - otPlatUartReceived(s_uart_buffer, (uint16_t)rval); - } else if (rval < 0) { - if (errno != EAGAIN) { - otLogWarnPlat("read uart failed: %d", errno); - return ESP_FAIL; - } - } - return ESP_OK; -} diff --git a/components/openthread/port/esp_openthread_udp.c b/components/openthread/port/esp_openthread_udp.c deleted file mode 100644 index 55f347ecbd..0000000000 --- a/components/openthread/port/esp_openthread_udp.c +++ /dev/null @@ -1,360 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License - -#include - -#include "esp_check.h" -#include "esp_err.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.h" -#include "esp_openthread_task_queue.h" -#include "common/code_utils.hpp" -#include "common/logging.hpp" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/ip_addr.h" -#include "lwip/pbuf.h" -#include "lwip/prot/ip4.h" -#include "lwip/tcpip.h" -#include "lwip/udp.h" -#include "openthread/error.h" -#include "openthread/platform/udp.h" - -typedef struct { - otUdpSocket *socket; - struct pbuf *recv_buf; - ip_addr_t addr; - uint16_t port; - uint8_t hop_limit; - bool is_host_interface; -} udp_recv_task_t; - -typedef struct { - TaskHandle_t source_task; - otUdpSocket *socket; - struct udp_pcb *pcb_ret; -} udp_new_task_t; - -typedef struct { - TaskHandle_t source_task; - struct udp_pcb *pcb; - ip_addr_t addr; - uint16_t port; - err_t ret; -} udp_bind_connect_task_t; - -typedef struct { - TaskHandle_t source_task; - struct udp_pcb *pcb; - uint8_t netif_index; -} udp_bind_netif_task_t; - -typedef struct { - struct udp_pcb *pcb; - otMessage *message; - ip_addr_t addr; - uint16_t port; - bool multicast_loop; - uint8_t hop_limit; - uint8_t netif_index; -} udp_send_task_t; - -static void wait_for_task_notification(void) -{ - esp_openthread_lock_release(); - ulTaskNotifyTake(pdTRUE, portMAX_DELAY); - esp_openthread_lock_acquire(portMAX_DELAY); -} - -static ip_addr_t map_openthread_addr_to_lwip_addr(const otIp6Address *address) -{ - ip_addr_t addr; - - memcpy(ip_2_ip6(&addr)->addr, address->mFields.m8, sizeof(ip_2_ip6(&addr)->addr)); - if (ip6_addr_isipv4mappedipv6(ip_2_ip6(&addr))) { - unmap_ipv4_mapped_ipv6(ip_2_ip4(&addr), ip_2_ip6(&addr)); - addr.type = IPADDR_TYPE_V4; - } else { - addr.type = IPADDR_TYPE_V6; -#if LWIP_IPV6_SCOPES - addr.u_addr.ip6.zone = IP6_NO_ZONE; -#endif - } - return addr; -} - -static void udp_recv_task(void *ctx) -{ - udp_recv_task_t *task = (udp_recv_task_t *)ctx; - - otMessageInfo message_info; - otMessage *message = NULL; - otMessageSettings msg_settings = {.mLinkSecurityEnabled = false, .mPriority = OT_MESSAGE_PRIORITY_NORMAL}; - struct pbuf *recv_buf = task->recv_buf; - uint8_t *data_buf = (uint8_t *)recv_buf->payload; - uint8_t *data_buf_to_free = NULL; - - message_info.mSockPort = 0; - memset(&message_info.mSockAddr, 0, sizeof(message_info.mSockAddr)); - message_info.mHopLimit = task->hop_limit; - message_info.mPeerPort = task->port; - if (task->addr.type == IPADDR_TYPE_V4) { - ip4_2_ipv4_mapped_ipv6(ip_2_ip6(&task->addr), ip_2_ip4(&task->addr)); - } - memcpy(&message_info.mPeerAddr, ip_2_ip6(&task->addr)->addr, sizeof(message_info.mPeerAddr)); - - if (recv_buf->next != NULL) { - data_buf = (uint8_t *)malloc(recv_buf->tot_len); - if (data_buf != NULL) { - data_buf_to_free = data_buf; - pbuf_copy_partial(recv_buf, data_buf, recv_buf->tot_len, 0); - } - } - VerifyOrExit(data_buf != NULL, - ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to allocate data buf when receiving OpenThread plat UDP")); - message = otUdpNewMessage(esp_openthread_get_instance(), &msg_settings); - VerifyOrExit(message != NULL, - ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to allocate OpenThread message when receiving OpenThread plat UDP")); - VerifyOrExit(otMessageAppend(message, data_buf, recv_buf->tot_len) == OT_ERROR_NONE, - 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); - -exit: - free(task); - if (data_buf_to_free) { - free(data_buf_to_free); - } - pbuf_free(recv_buf); - return; -} - -static void handle_udp_recv(void *ctx, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, uint16_t port) -{ - udp_recv_task_t *task = (udp_recv_task_t *)malloc(sizeof(udp_recv_task_t)); - const struct ip6_hdr *ip6_hdr = ip6_current_header(); - const struct ip_hdr *ip4_hdr = ip4_current_header(); - struct netif *source_netif = ip_current_netif(); - - if (task == NULL) { - otLogCritPlat("Failed to allocate recv task when receiving OpenThread plat UDP"); - } - task->socket = (otUdpSocket *)ctx; - task->recv_buf = p; - task->addr = *addr; - task->port = port; - task->hop_limit = (addr->type == IPADDR_TYPE_V6) ? IP6H_HOPLIM(ip6_hdr) : IPH_TTL(ip4_hdr); - task->is_host_interface = - (netif_get_index(source_netif) == esp_netif_get_netif_impl_index(esp_openthread_get_backbone_netif())); - - if (esp_openthread_task_queue_post(udp_recv_task, task) != ESP_OK) { - free(task); - } -} - -static void udp_new_task(void *ctx) -{ - udp_new_task_t *task = (udp_new_task_t *)ctx; - - task->pcb_ret = udp_new(); - udp_recv(task->pcb_ret, handle_udp_recv, task->socket); - xTaskNotifyGive(task->source_task); -} - -otError otPlatUdpSocket(otUdpSocket *udp_socket) -{ - otError error = OT_ERROR_NONE; - - udp_new_task_t task = {.source_task = xTaskGetCurrentTaskHandle(), .socket = udp_socket}; - tcpip_callback(udp_new_task, &task); - wait_for_task_notification(); - VerifyOrExit(task.pcb_ret != NULL, error = OT_ERROR_FAILED); - udp_socket->mHandle = task.pcb_ret; - -exit: - return error; -} - -static void udp_close_task(void *ctx) -{ - struct udp_pcb *pcb = (struct udp_pcb *)ctx; - - udp_remove(pcb); -} - -otError otPlatUdpClose(otUdpSocket *udp_socket) -{ - struct udp_pcb *pcb = (struct udp_pcb *)udp_socket->mHandle; - - if (pcb) { - tcpip_callback(udp_close_task, pcb); - } - - return OT_ERROR_NONE; -} - -static void udp_bind_task(void *ctx) -{ - udp_bind_connect_task_t *task = (udp_bind_connect_task_t *)ctx; - - task->ret = udp_bind(task->pcb, &task->addr, task->port); - xTaskNotifyGive(task->source_task); -} - -otError otPlatUdpBind(otUdpSocket *udp_socket) -{ - udp_bind_connect_task_t task = { - .source_task = xTaskGetCurrentTaskHandle(), - .pcb = (struct udp_pcb *)udp_socket->mHandle, - .port = udp_socket->mSockName.mPort, - }; - ESP_LOGI(OT_PLAT_LOG_TAG, "Platform UDP bound to port %d", udp_socket->mSockName.mPort); - - task.addr.type = IPADDR_TYPE_ANY; - memcpy(ip_2_ip6(&task.addr)->addr, udp_socket->mSockName.mAddress.mFields.m8, sizeof(ip_2_ip6(&task.addr)->addr)); - tcpip_callback(udp_bind_task, &task); - wait_for_task_notification(); - - return task.ret == ERR_OK ? OT_ERROR_NONE : OT_ERROR_FAILED; -} - -static void udp_bind_netif_task(void *ctx) -{ - udp_bind_netif_task_t *task = (udp_bind_netif_task_t *)ctx; - - task->netif_index = task->netif_index; - xTaskNotifyGive(task->source_task); -} - -static uint8_t get_netif_index(otNetifIdentifier netif_identifier) -{ - switch (netif_identifier) { - case OT_NETIF_UNSPECIFIED: - return NETIF_NO_INDEX; - case OT_NETIF_THREAD: - return esp_netif_get_netif_impl_index(esp_openthread_get_netif()); - case OT_NETIF_BACKBONE: - return esp_netif_get_netif_impl_index(esp_openthread_get_backbone_netif()); - default: - return NETIF_NO_INDEX; - } -} - -otError otPlatUdpBindToNetif(otUdpSocket *udp_socket, otNetifIdentifier netif_identifier) -{ - udp_bind_netif_task_t task = { - .source_task = xTaskGetCurrentTaskHandle(), - .pcb = (struct udp_pcb *)udp_socket->mHandle, - .netif_index = get_netif_index(netif_identifier), - }; - - tcpip_callback(udp_bind_netif_task, &task); - wait_for_task_notification(); - - return OT_ERROR_NONE; -} - -static void udp_connect_task(void *ctx) -{ - udp_bind_connect_task_t *task = (udp_bind_connect_task_t *)ctx; - - task->ret = udp_connect(task->pcb, &task->addr, task->port); - xTaskNotifyGive(task->source_task); -} - -otError otPlatUdpConnect(otUdpSocket *udp_socket) -{ - udp_bind_connect_task_t task = { - .source_task = xTaskGetCurrentTaskHandle(), - .pcb = (struct udp_pcb *)udp_socket->mHandle, - .port = udp_socket->mPeerName.mPort, - }; - - task.addr = map_openthread_addr_to_lwip_addr(&udp_socket->mPeerName.mAddress); - tcpip_callback(udp_connect_task, &task); - wait_for_task_notification(); - - return task.ret == ERR_OK ? OT_ERROR_NONE : OT_ERROR_FAILED; -} - -static bool is_link_local(const otIp6Address *address) -{ - return address->mFields.m8[0] == 0xfe && address->mFields.m8[1] == 0x80; -} - -static bool is_multicast(const otIp6Address *address) -{ - return address->mFields.m8[0] == 0xff; -} - -static void udp_send_task(void *ctx) -{ - udp_send_task_t *task = (udp_send_task_t *)ctx; - struct pbuf *send_buf = NULL; - uint16_t len = otMessageGetLength(task->message); - - task->pcb->ttl = task->hop_limit; - task->pcb->netif_idx = task->netif_index; -#if LWIP_IPV6_SCOPES - if (task->addr.type == IPADDR_TYPE_V6) { - ip_2_ip6(&task->addr)->zone = task->netif_index; - } -#endif - task->pcb->flags = (task->pcb->flags & (~UDP_FLAGS_MULTICAST_LOOP)); - if (task->multicast_loop) { - task->pcb->flags |= UDP_FLAGS_MULTICAST_LOOP; - } - send_buf = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); - otMessageRead(task->message, 0, send_buf->payload, len); - VerifyOrExit(send_buf != NULL); - udp_sendto(task->pcb, send_buf, &task->addr, task->port); - -exit: - if (send_buf) { - pbuf_free(send_buf); - } - esp_openthread_lock_acquire(portMAX_DELAY); - otMessageFree(task->message); - esp_openthread_lock_release(); - free(task); -} - -otError otPlatUdpSend(otUdpSocket *udp_socket, otMessage *message, const otMessageInfo *message_info) -{ - udp_send_task_t *task = (udp_send_task_t *)malloc(sizeof(udp_send_task_t)); - otError error = OT_ERROR_NONE; - - VerifyOrExit(task != NULL, error = OT_ERROR_NO_BUFS); - task->pcb = (struct udp_pcb *)udp_socket->mHandle; - task->message = message; - task->port = message_info->mPeerPort; - task->multicast_loop = message_info->mMulticastLoop; - task->hop_limit = message_info->mHopLimit; - task->netif_index = NETIF_NO_INDEX; - task->addr = map_openthread_addr_to_lwip_addr(&message_info->mPeerAddr); - - if (is_link_local(&message_info->mPeerAddr) || is_multicast(&message_info->mPeerAddr)) { - task->netif_index = get_netif_index(message_info->mIsHostInterface ? OT_NETIF_BACKBONE : OT_NETIF_THREAD); - } - tcpip_callback(udp_send_task, task); - -exit: - return error; -} diff --git a/components/openthread/port/esp_uart_spinel_interface.cpp b/components/openthread/port/esp_uart_spinel_interface.cpp deleted file mode 100644 index 83296cbce2..0000000000 --- a/components/openthread/port/esp_uart_spinel_interface.cpp +++ /dev/null @@ -1,295 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License - - -#include "esp_uart_spinel_interface.hpp" - -#include -#include -#include -#include - -#include "esp_check.h" -#include "esp_err.h" -#include "esp_log.h" -#include "esp_openthread_common_macro.h" -#include "esp_openthread_types.h" -#include "esp_openthread_uart.h" -#include "esp_vfs_dev.h" -#include "core/common/code_utils.hpp" -#include "core/common/logging.hpp" -#include "driver/uart.h" -#include "lib/platform/exit_code.h" -#include "openthread/platform/time.h" - -namespace esp { -namespace openthread { - -UartSpinelInterface::UartSpinelInterface( - ot::Spinel::SpinelInterface::ReceiveFrameCallback callback, - void *callback_context, - ot::Spinel::SpinelInterface::RxFrameBuffer &frame_buffer) - : m_receiver_frame_callback(callback) - , m_receiver_frame_context(callback_context) - , m_receive_frame_buffer(frame_buffer) - , m_hdlc_decoder(frame_buffer, HandleHdlcFrame, this) - , m_uart_fd(-1) -{ -} - -UartSpinelInterface::~UartSpinelInterface(void) -{ -} - -esp_err_t UartSpinelInterface::Init(const esp_openthread_uart_config_t &radio_uart_config) -{ - m_uart_rx_buffer = static_cast(heap_caps_malloc(kMaxFrameSize, MALLOC_CAP_8BIT)); - if (m_uart_rx_buffer == NULL) { - return ESP_ERR_NO_MEM; - } - - return InitUart(radio_uart_config); -} - -esp_err_t UartSpinelInterface::Deinit(void) -{ - if (m_uart_rx_buffer) { - heap_caps_free(m_uart_rx_buffer); - } - m_uart_rx_buffer = NULL; - - return DeinitUart(); -} - -otError UartSpinelInterface::SendFrame(const uint8_t *frame, uint16_t length) -{ - otError error = OT_ERROR_NONE; - ot::Hdlc::FrameBuffer encoder_buffer; - ot::Hdlc::Encoder hdlc_encoder(encoder_buffer); - - SuccessOrExit(error = hdlc_encoder.BeginFrame()); - SuccessOrExit(error = hdlc_encoder.Encode(frame, length)); - SuccessOrExit(error = hdlc_encoder.EndFrame()); - - SuccessOrExit(error = Write(encoder_buffer.GetFrame(), encoder_buffer.GetLength())); - -exit: - if (error != OT_ERROR_NONE) { - otLogCritPlat("send radio frame failed"); - } else { - otLogDebgPlat("sent radio frame"); - } - - return error; -} - -void UartSpinelInterface::Process(const esp_openthread_mainloop_context_t &mainloop) -{ - if (FD_ISSET(m_uart_fd, &mainloop.read_fds)) { - otLogDebgPlat("radio uart read event"); - TryReadAndDecode(); - } -} - -void UartSpinelInterface::Update(esp_openthread_mainloop_context_t &mainloop) -{ - // Register only READ events for radio UART and always wait - // for a radio WRITE to complete. - FD_SET(m_uart_fd, &mainloop.read_fds); - if (m_uart_fd > mainloop.max_fd) { - mainloop.max_fd = m_uart_fd; - } -} - -int UartSpinelInterface::TryReadAndDecode(void) -{ - uint8_t buffer[UART_FIFO_LEN]; - ssize_t rval; - - do { - rval = read(m_uart_fd, buffer, sizeof(buffer)); - if (rval > 0) { - m_hdlc_decoder.Decode(buffer, static_cast(rval)); - } - } while (rval > 0); - - if ((rval < 0) && (errno != EAGAIN) && (errno != EWOULDBLOCK)) { - ESP_ERROR_CHECK(TryRecoverUart()); - } - - return rval; -} - -otError UartSpinelInterface::WaitForWritable(void) -{ - otError error = OT_ERROR_NONE; - struct timeval timeout = {kMaxWaitTime / MS_PER_S, (kMaxWaitTime % MS_PER_S) *US_PER_MS}; - uint64_t now = otPlatTimeGet(); - uint64_t end = now + kMaxWaitTime * US_PER_MS; - fd_set write_fds; - fd_set error_fds; - int rval; - - while (true) { - FD_ZERO(&write_fds); - FD_ZERO(&error_fds); - FD_SET(m_uart_fd, &write_fds); - FD_SET(m_uart_fd, &error_fds); - - rval = select(m_uart_fd + 1, NULL, &write_fds, &error_fds, &timeout); - - if (rval > 0) { - if (FD_ISSET(m_uart_fd, &write_fds)) { - ExitNow(); - } else if (FD_ISSET(m_uart_fd, &error_fds)) { - ExitNow(error = OT_ERROR_FAILED); - } - } else if ((rval < 0) && (errno != EINTR)) { - ESP_ERROR_CHECK(TryRecoverUart()); - ExitNow(error = OT_ERROR_FAILED); - } - - now = otPlatTimeGet(); - - if (end > now) { - uint64_t remain = end - now; - - timeout.tv_sec = static_cast(remain / 1000000); - timeout.tv_usec = static_cast(remain % 1000000); - } else { - break; - } - } - - error = OT_ERROR_FAILED; - -exit: - return error; -} - -otError UartSpinelInterface::Write(const uint8_t *aFrame, uint16_t length) -{ - otError error = OT_ERROR_NONE; - - while (length) { - ssize_t rval; - - rval = write(m_uart_fd, aFrame, length); - - if (rval > 0) { - assert(rval <= length); - length -= static_cast(rval); - aFrame += static_cast(rval); - continue; - } else if (rval < 0) { - ESP_ERROR_CHECK(TryRecoverUart()); - ExitNow(error = OT_ERROR_FAILED); - } - - SuccessOrExit(error = WaitForWritable()); - } - -exit: - return error; -} - -otError UartSpinelInterface::WaitForFrame(uint64_t timeout_us) -{ - otError error = OT_ERROR_NONE; - struct timeval timeout; - fd_set read_fds; - fd_set error_fds; - int rval; - - FD_ZERO(&read_fds); - FD_ZERO(&error_fds); - FD_SET(m_uart_fd, &read_fds); - FD_SET(m_uart_fd, &error_fds); - - timeout.tv_sec = static_cast(timeout_us / US_PER_S); - timeout.tv_usec = static_cast(timeout_us % US_PER_S); - - rval = select(m_uart_fd + 1, &read_fds, NULL, &error_fds, &timeout); - - if (rval > 0) { - if (FD_ISSET(m_uart_fd, &read_fds)) { - TryReadAndDecode(); - } else if (FD_ISSET(m_uart_fd, &error_fds)) { - ESP_ERROR_CHECK(TryRecoverUart()); - ExitNow(error = OT_ERROR_FAILED); - } - } else if (rval == 0) { - ExitNow(error = OT_ERROR_RESPONSE_TIMEOUT); - } else { - ESP_ERROR_CHECK(TryRecoverUart()); - ExitNow(error = OT_ERROR_FAILED); - } - -exit: - return error; -} - -void UartSpinelInterface::HandleHdlcFrame(void *context, otError error) -{ - static_cast(context)->HandleHdlcFrame(error); -} - -void UartSpinelInterface::HandleHdlcFrame(otError error) -{ - if (error == OT_ERROR_NONE) { - otLogDebgPlat("received hdlc radio frame"); - m_receiver_frame_callback(m_receiver_frame_context); - } else { - otLogCritPlat("dropping radio frame: %s", otThreadErrorToString(error)); - m_receive_frame_buffer.DiscardFrame(); - } -} - -esp_err_t UartSpinelInterface::InitUart(const esp_openthread_uart_config_t &radio_uart_config) -{ - char uart_path[16]; - - m_uart_config = radio_uart_config; - ESP_RETURN_ON_ERROR(esp_openthread_uart_init_port(&radio_uart_config), OT_PLAT_LOG_TAG, - "esp_openthread_uart_init_port failed"); - // We have a driver now installed so set up the read/write functions to use driver also. - esp_vfs_dev_uart_port_set_tx_line_endings(m_uart_config.port, ESP_LINE_ENDINGS_LF); - esp_vfs_dev_uart_port_set_rx_line_endings(m_uart_config.port, ESP_LINE_ENDINGS_LF); - - snprintf(uart_path, sizeof(uart_path), "/dev/uart/%d", radio_uart_config.port); - m_uart_fd = open(uart_path, O_RDWR | O_NONBLOCK); - - return m_uart_fd >= 0 ? ESP_OK : ESP_FAIL; -} - -esp_err_t UartSpinelInterface::DeinitUart(void) -{ - if (m_uart_fd != -1) { - close(m_uart_fd); - m_uart_fd = -1; - return uart_driver_delete(m_uart_config.port); - } else { - return ESP_ERR_INVALID_STATE; - } -} - -esp_err_t UartSpinelInterface::TryRecoverUart(void) -{ - ESP_RETURN_ON_ERROR(DeinitUart(), OT_PLAT_LOG_TAG, "DeInitUart failed"); - ESP_RETURN_ON_ERROR(InitUart(m_uart_config), OT_PLAT_LOG_TAG, "InitUart failed"); - return ESP_OK; -} - -} // namespace openthread -} // namespace esp diff --git a/components/openthread/private_include/esp_openthread_alarm.h b/components/openthread/private_include/esp_openthread_alarm.h deleted file mode 100644 index 0992bf77dc..0000000000 --- a/components/openthread/private_include/esp_openthread_alarm.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License - -#pragma once - -#include "esp_openthread_types.h" -#include "openthread/instance.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Updates the file descriptor with the OpenThread alarm timeout. - * - * @param[inout] mainloop The main loop context. - * - */ -void esp_openthread_alarm_update(esp_openthread_mainloop_context_t *mainloop); - -/** - * @brief Performs the alarm process and triggers the fired timers for OpenThread. - * - * @param[in] instance The OpenThread instance. - * - */ -void esp_openthread_alarm_process(otInstance *instance); - - -#ifdef __cplusplus -} -#endif diff --git a/components/openthread/private_include/esp_openthread_common_macro.h b/components/openthread/private_include/esp_openthread_common_macro.h deleted file mode 100644 index f134bbd87d..0000000000 --- a/components/openthread/private_include/esp_openthread_common_macro.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License - -#pragma once - -#define OT_PLAT_LOG_TAG "OPENTHREAD" - -#ifndef MS_PER_S -#define MS_PER_S 1000 -#endif - -#ifndef US_PER_MS -#define US_PER_MS 1000 -#endif - -#ifndef US_PER_S -#define US_PER_S (MS_PER_S * US_PER_MS) -#endif - -#define ESP_OPENTHREAD_UART_BUFFER_SIZE (UART_FIFO_LEN * 2) diff --git a/components/openthread/private_include/esp_openthread_netif_glue_priv.h b/components/openthread/private_include/esp_openthread_netif_glue_priv.h deleted file mode 100644 index b9c06f5e45..0000000000 --- a/components/openthread/private_include/esp_openthread_netif_glue_priv.h +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License - -#pragma once - -#include "esp_openthread.h" -#include "openthread/instance.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief The state handler to be called when OpenThread state changes - * - * @param[in] changed_flags The changed Openthread states - * - */ -void esp_openthread_netif_glue_state_callback(otChangedFlags changed_flags); - -/** - * @brief This function updates the netif fds and timeouts to the main loop. - * - * @param[inout] mainloop The main loop context. - * - */ -void esp_openthread_netif_glue_update(esp_openthread_mainloop_context_t *mainloop); - -/** - * @brief This function performs the netif process. - * - * @param[in] instance The OpenThread instance. - * - * @return - * - ESP_OK on success - * - ESP_FAIL on OpenThread failure - * - ESP_ERR_NO_MEM on memory allocation failure - * - */ -esp_err_t esp_openthread_netif_glue_process(otInstance *instance, const esp_openthread_mainloop_context_t *mainloop); - -#ifdef __cplusplus -} -#endif diff --git a/components/openthread/private_include/esp_openthread_platform.h b/components/openthread/private_include/esp_openthread_platform.h deleted file mode 100644 index 05bcabb813..0000000000 --- a/components/openthread/private_include/esp_openthread_platform.h +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License - -#pragma once - -#include "esp_err.h" -#include "esp_openthread_types.h" -#include "openthread/error.h" -#include "openthread/instance.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Initializes the platform-specific support for the OpenThread stack. - * - * @note This function is not called by and will not call the OpenThread library. - * The user needs to call otInstanceInitSingle to intialize the OpenThread - * stack after calling this function. - * - * @param[in] init_config The initialization configuration. - * - * @return - * - ESP_OK on success - * - ESP_ERR_NO_MEM if allocation has failed - * - ESP_ERR_INVALID_ARG if radio or host connection mode not supported - * - ESP_ERR_INVALID_STATE if already initialized - * - */ -esp_err_t esp_openthread_platform_init(const esp_openthread_platform_config_t *init_config); - -/** - * This function performs all platform-specific deinitialization for OpenThread's drivers. - * - * @note This function is not called by the OpenThread library. Instead, the user should - * call this function when deinitialization of OpenThread's drivers is most appropriate. - * - * @return - * - ESP_OK on success - * - ESP_ERR_INVALID_STATE if not initialized - * - */ -esp_err_t esp_openthread_platform_deinit(void); - -/** - * @brief This function updates the platform fds and timeouts - * - * @note This function will not update the OpenThread core stack pending events. - * The users need to call `otTaskletsArePending` to check whether there being - * pending OpenThread tasks. - * - * @param[inout] mainloop The main loop context. - * - */ -void esp_openthread_platform_update(esp_openthread_mainloop_context_t *mainloop); - -/** - * @brief This function performs the OpenThread related platform process (radio, uart, alarm etc.) - * - * @note This function will call the OpenThread core stack process functions. - * The users need to call `otTaskletsProcess` by self. - * - * @param[in] instance The OpenThread instance. - * @param[in] mainloop The main loop context. - * - * @return - * - ESP_OK on success - * - ESP_FAIL on failure - * - */ -esp_err_t esp_openthread_platform_process(otInstance *instance, const esp_openthread_mainloop_context_t *mainloop); - -#ifdef __cplusplus -} // end of extern "C" -#endif diff --git a/components/openthread/private_include/esp_openthread_radio_uart.h b/components/openthread/private_include/esp_openthread_radio_uart.h deleted file mode 100644 index 8041b1ccaf..0000000000 --- a/components/openthread/private_include/esp_openthread_radio_uart.h +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License - -#pragma once - -#include - -#include "esp_err.h" -#include "esp_openthread_types.h" -#include "openthread/instance.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief This function initializes the OpenThread radio. - * - * @return - * - ESP_OK on success - * - ESP_ERR_NO_MEM if allocation has failed - * - */ -esp_err_t esp_openthread_radio_init(const esp_openthread_platform_config_t *config); - -/** - * @brief This function deinitializes the OpenThread radio. - * - */ -void esp_openthread_radio_deinit(void); - -/** - * @brief This function updates the radio fds and timeouts to the main loop. - * - * @param[inout] mainloop The main loop context. - * - */ -void esp_openthread_radio_update(esp_openthread_mainloop_context_t *mainloop); - -/** - * @brief This function performs the OpenThread radio process. - * - * @param[in] instance The OpenThread instance. - * @param[in] mainloop The main loop context. - * - * @return - * - ESP_OK on success - * - ESP_FAIL on failure - * - */ -esp_err_t esp_openthread_radio_process(otInstance *instance, const esp_openthread_mainloop_context_t *mainloop); - -#ifdef __cplusplus -} -#endif diff --git a/components/openthread/private_include/esp_openthread_task_queue.h b/components/openthread/private_include/esp_openthread_task_queue.h deleted file mode 100644 index 662a42710d..0000000000 --- a/components/openthread/private_include/esp_openthread_task_queue.h +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License - -#pragma once - -#include "esp_err.h" -#include "esp_openthread.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** -* @brief OpenThread task declaration -* -*/ -typedef void (*esp_openthread_task_t)(void *); - -/** -* @brief This function allocs and initializes the OpenThread task queue. -* -* @return -* - ESP_OK on success -* - ESP_ERR_NO_MEM on queue allocation failure -* - ESP_FAIL on other failures -* -*/ -esp_err_t esp_openthread_task_queue_init(void); - -/** -* @brief This function posts a task to the OpenThread task queue. -* -* @param[in] task The task to execute. -* @param[in] arg The context argument to be passed to the task. -* -* @return -* - ESP_OK -* - ESP_FAIL -* -*/ -esp_err_t esp_openthread_task_queue_post(esp_openthread_task_t task, void *arg); - -/** -* @brief This function updates the task queue inner fd to the main loop. -* -* @param[inout] mainloop The main loop context. -* -*/ -void esp_openthread_task_queue_update(esp_openthread_mainloop_context_t *mainloop); - -/** - * @brief This function drives the execution of the task queue. - * - * @param[in] instance The OpenThread instance. - * @param[in] mainloop The main loop context. - * - * @return - * - ESP_OK - * - ESP_FAIL - * - */ -esp_err_t esp_openthread_task_queue_process(otInstance *instance, const esp_openthread_mainloop_context_t *mainloop); - -/** - * @brief This function deinitializes the task queue. - * - * @return - * - ESP_OK - * - ESP_FAIL - * - */ -esp_err_t esp_openthread_task_queue_deinit(void); - -#ifdef __cplusplus -} -#endif diff --git a/components/openthread/private_include/esp_openthread_uart.h b/components/openthread/private_include/esp_openthread_uart.h deleted file mode 100644 index b4903b17b6..0000000000 --- a/components/openthread/private_include/esp_openthread_uart.h +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License - -#pragma once - -#include "esp_err.h" -#include "esp_openthread_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Initializes an uart port with the given config. - * - * @note The user still needs to open the file descriptor by self. - * - * @param[in] config The uart configuration. - * - * @return - * - ESP_OK on success - * - ESP_ERROR on failure - * - */ -esp_err_t esp_openthread_uart_init_port(const esp_openthread_uart_config_t *config); - -/** - * @brief Initializes the uart for OpenThread host connection. - * - * @param[in] config The uart configuration. - * - * @return - * - ESP_OK on success - * - ESP_ERROR on failure - * - */ -esp_err_t esp_openthread_uart_init(const esp_openthread_platform_config_t *config); - -/** - * @brief Deintializes the uart for OpenThread host connection. - * - */ -void esp_openthread_uart_deinit(void); - -/** - * @brief Deintializes the uart for OpenThread host connection. - * - * @param[inout] mainloop The main loop context. - * - */ -void esp_openthread_uart_update(esp_openthread_mainloop_context_t *context); - -/** - * @brief Performs the uart I/O for OpenThread. - * - * @return - * - ESP_OK on success - * - ESP_ERROR on failure - * - */ -esp_err_t esp_openthread_uart_process(void); - -#ifdef __cplusplus -} -#endif diff --git a/components/openthread/private_include/esp_uart_spinel_interface.hpp b/components/openthread/private_include/esp_uart_spinel_interface.hpp deleted file mode 100644 index 3703d81d8e..0000000000 --- a/components/openthread/private_include/esp_uart_spinel_interface.hpp +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License - -#pragma once - -#include "esp_err.h" -#include "esp_openthread.h" -#include "esp_openthread_types.h" -#include "hal/uart_types.h" -#include "lib/spinel/spinel_interface.hpp" - -namespace esp { -namespace openthread { - -/** - * This class defines an UART interface to the Radio Co-processor (RCP). - * - */ -class UartSpinelInterface { -public: - /** - * @brief This constructor of object. - * - * @param[in] callback Callback on frame received - * @param[in] callback_context Callback context - * @param[in] frame_buffer A reference to a `RxFrameBuffer` object. - * - */ - UartSpinelInterface(ot::Spinel::SpinelInterface::ReceiveFrameCallback callback, - void *callback_context, - ot::Spinel::SpinelInterface::RxFrameBuffer &frame_buffer); - - /** - * @brief This destructor of the object. - * - */ - ~UartSpinelInterface(void); - - /** - * @brief This method initializes the HDLC interface. - * - * @return - * - ESP_OK on success - * - ESP_ERR_NO_MEM if allocation has failed - * - ESP_ERROR on failure - */ - esp_err_t Init(const esp_openthread_uart_config_t &radio_uart_config); - - /** - * @brief This method deinitializes the HDLC interface. - * - */ - esp_err_t Deinit(void); - - /** - * @brief This method encodes and sends a spinel frame to Radio Co-processor (RCP) over the socket. - * - * @note This is blocking call, i.e., if the socket is not writable, this method waits for it to become writable for - * up to `kMaxWaitTime` interval. - * - * @param[in] frame A pointer to buffer containing the spinel frame to send. - * @param[in] length The length (number of bytes) in the frame. - * - * @return - * -OT_ERROR_NONE Successfully encoded and sent the spinel frame. - * -OT_ERROR_NO_BUFS Insufficient buffer space available to encode the frame. - * -OT_ERROR_FAILED Failed to send due to socket not becoming writable within `kMaxWaitTime`. - * - */ - otError SendFrame(const uint8_t *frame, uint16_t length); - - /** - * This method waits for receiving part or all of spinel frame within specified timeout. - * - * @param[in] timeout_us The timeout value in microseconds. - * - * @return - * -OT_ERROR_NONE Part or all of spinel frame is received. - * -OT_ERROR_RESPONSE_TIMEOUT No spinel frame is received within @p timeout_us. - * - */ - otError WaitForFrame(uint64_t timeout_us); - - /** - * This method performs uart processing to the RCP. - * - * @param[in] mainloop The mainloop context - * - */ - void Process(const esp_openthread_mainloop_context_t &mainloop); - - /** - * This methods updates the mainloop context. - * - * @param[inout] mainloop The mainloop context. - * - */ - void Update(esp_openthread_mainloop_context_t &mainloop); - -private: - enum { - /** - * Maximum spinel frame size. - * - */ - kMaxFrameSize = ot::Spinel::SpinelInterface::kMaxFrameSize, - - /** - * Maximum wait time in Milliseconds for socket to become writable (see `SendFrame`). - * - */ - kMaxWaitTime = 2000, - }; - - esp_err_t InitUart(const esp_openthread_uart_config_t &radio_uart_config); - - esp_err_t DeinitUart(void); - - int TryReadAndDecode(void); - - otError WaitForWritable(void); - - otError Write(const uint8_t *frame, uint16_t length); - - esp_err_t TryRecoverUart(void); - - static void HandleHdlcFrame(void *context, otError error); - void HandleHdlcFrame(otError error); - - ot::Spinel::SpinelInterface::ReceiveFrameCallback m_receiver_frame_callback; - void *m_receiver_frame_context; - ot::Spinel::SpinelInterface::RxFrameBuffer &m_receive_frame_buffer; - - ot::Hdlc::Decoder m_hdlc_decoder; - uint8_t *m_uart_rx_buffer; - - esp_openthread_uart_config_t m_uart_config; - int m_uart_fd; - - // Non-copyable, intentionally not implemented. - UartSpinelInterface(const UartSpinelInterface &); - UartSpinelInterface &operator=(const UartSpinelInterface &); -}; - -} // namespace openthread -} // namespace esp diff --git a/examples/openthread/ot_br/main/esp_ot_br.c b/examples/openthread/ot_br/main/esp_ot_br.c index 7627869c88..4cceb4a1b8 100644 --- a/examples/openthread/ot_br/main/esp_ot_br.c +++ b/examples/openthread/ot_br/main/esp_ot_br.c @@ -145,6 +145,7 @@ static void ot_task_worker(void *aContext) esp_openthread_platform_config_t config = { .radio_config = ESP_OPENTHREAD_DEFAULT_RADIO_UART_RCP_CONFIG(4, 5), .host_config = ESP_OPENTHREAD_DEFAULT_UART_HOST_CONFIG(), + .port_config = ESP_OPENTHREAD_DEFAULT_PORT_CONFIG(), }; esp_netif_config_t cfg = ESP_NETIF_DEFAULT_OPENTHREAD(); @@ -155,7 +156,7 @@ static void ot_task_worker(void *aContext) ESP_ERROR_CHECK(esp_openthread_init(&config)); // Initialize border routing features - ESP_ERROR_CHECK(esp_netif_attach(openthread_netif, esp_openthread_netif_glue_init())); + ESP_ERROR_CHECK(esp_netif_attach(openthread_netif, esp_openthread_netif_glue_init(&config))); ESP_ERROR_CHECK(esp_openthread_border_router_init(get_example_netif())); esp_openthread_lock_acquire(portMAX_DELAY); diff --git a/examples/openthread/ot_cli/main/esp_ot_cli.c b/examples/openthread/ot_cli/main/esp_ot_cli.c index c1adb45e5d..3fe51b4317 100644 --- a/examples/openthread/ot_cli/main/esp_ot_cli.c +++ b/examples/openthread/ot_cli/main/esp_ot_cli.c @@ -43,12 +43,12 @@ extern void otAppCliInit(otInstance *instance); -static esp_netif_t *init_openthread_netif(void) +static esp_netif_t *init_openthread_netif(const esp_openthread_platform_config_t *config) { esp_netif_config_t cfg = ESP_NETIF_DEFAULT_OPENTHREAD(); esp_netif_t *netif = esp_netif_new(&cfg); assert(netif != NULL); - ESP_ERROR_CHECK(esp_netif_attach(netif, esp_openthread_netif_glue_init())); + ESP_ERROR_CHECK(esp_netif_attach(netif, esp_openthread_netif_glue_init(config))); return netif; } @@ -58,6 +58,7 @@ static void ot_task_worker(void *aContext) esp_openthread_platform_config_t config = { .radio_config = ESP_OPENTHREAD_DEFAULT_RADIO_UART_RCP_CONFIG(4, 5), .host_config = ESP_OPENTHREAD_DEFAULT_UART_HOST_CONFIG(), + .port_config = ESP_OPENTHREAD_DEFAULT_PORT_CONFIG(), }; esp_netif_t *openthread_netif; @@ -68,7 +69,7 @@ static void ot_task_worker(void *aContext) otAppCliInit(esp_openthread_get_instance()); // Initialize the esp_netif bindings - openthread_netif = init_openthread_netif(); + openthread_netif = init_openthread_netif(&config); #if CONFIG_OPENTHREAD_CUSTOM_COMMAND esp_cli_custom_command_init();