From 1178983eb32d3825115b37e721bebb2600a1ccb2 Mon Sep 17 00:00:00 2001 From: CHEN Dejin <45139296+DejinChen@users.noreply.github.com> Date: Wed, 1 Nov 2023 22:22:15 +0800 Subject: [PATCH] ESP32: Add otcli command in matter console (#29004) * ESP32: Add otcli command in matter console * add function cli_transmit_task_post * use char ptr in xQueueSend * add constant for otcli transmit task --- examples/lighting-app/esp32/main/main.cpp | 4 + .../openthread_cli_register.cpp | 68 ++++++++++++++++ .../shell_extension/openthread_cli_register.h | 24 ++++++ src/platform/ESP32/BUILD.gn | 2 +- ...hreadLauncher.c => OpenthreadLauncher.cpp} | 81 +++++++++++++++++++ src/platform/ESP32/OpenthreadLauncher.h | 11 +-- 6 files changed, 181 insertions(+), 9 deletions(-) create mode 100644 examples/platform/esp32/shell_extension/openthread_cli_register.cpp create mode 100644 examples/platform/esp32/shell_extension/openthread_cli_register.h rename src/platform/ESP32/{OpenthreadLauncher.c => OpenthreadLauncher.cpp} (56%) diff --git a/examples/lighting-app/esp32/main/main.cpp b/examples/lighting-app/esp32/main/main.cpp index 280131263efa96..790bd9b7867dff 100644 --- a/examples/lighting-app/esp32/main/main.cpp +++ b/examples/lighting-app/esp32/main/main.cpp @@ -32,6 +32,7 @@ #include "freertos/task.h" #include "nvs_flash.h" #include "shell_extension/launch.h" +#include "shell_extension/openthread_cli_register.h" #include #include #include @@ -156,6 +157,9 @@ extern "C" void app_main() ESP_LOGI(TAG, "=================================================="); #if CONFIG_ENABLE_CHIP_SHELL +#if CONFIG_OPENTHREAD_CLI + chip::RegisterOpenThreadCliCommands(); +#endif chip::LaunchShell(); #endif #if CHIP_DEVICE_CONFIG_ENABLE_WIFI diff --git a/examples/platform/esp32/shell_extension/openthread_cli_register.cpp b/examples/platform/esp32/shell_extension/openthread_cli_register.cpp new file mode 100644 index 00000000000000..bc8ccae7e2af00 --- /dev/null +++ b/examples/platform/esp32/shell_extension/openthread_cli_register.cpp @@ -0,0 +1,68 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * 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 "sdkconfig.h" +#if CONFIG_OPENTHREAD_CLI +#include "esp_check.h" +#include "esp_err.h" +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "openthread_cli_register.h" +#include "platform/ESP32/OpenthreadLauncher.h" +#include +#include + +#define CLI_INPUT_BUFF_LENGTH 256u +namespace chip { + +static CHIP_ERROR OtcliHandler(int argc, char * argv[]) +{ + /* the beginning of command "matter otcli" has already been removed */ + std::unique_ptr cli_str(new char[CLI_INPUT_BUFF_LENGTH]); + memset(cli_str.get(), 0, CLI_INPUT_BUFF_LENGTH); + uint8_t len = 0; + for (size_t i = 0; i < (size_t) argc; ++i) + { + len = len + strlen(argv[i]) + 1; + if (len > CLI_INPUT_BUFF_LENGTH - 1) + { + return CHIP_ERROR_INTERNAL; + } + strcat(cli_str.get(), argv[i]); + strcat(cli_str.get(), " "); + } + + if (cli_transmit_task_post(std::move(cli_str)) != CHIP_NO_ERROR) + { + return CHIP_ERROR_INTERNAL; + } + return CHIP_NO_ERROR; +} + +void RegisterOpenThreadCliCommands() +{ + static const chip::Shell::shell_command_t cmds[] = { + { + .cmd_func = OtcliHandler, + .cmd_name = "otcli", + .cmd_help = "OpenThread cli commands", + }, + }; + int cmds_num = sizeof(cmds) / sizeof(chip::Shell::shell_command_t); + chip::Shell::Engine::Root().RegisterCommands(cmds, cmds_num); +} +} // namespace chip +#endif // CONFIG_OPENTHREAD_CLI diff --git a/examples/platform/esp32/shell_extension/openthread_cli_register.h b/examples/platform/esp32/shell_extension/openthread_cli_register.h new file mode 100644 index 00000000000000..4811146415c593 --- /dev/null +++ b/examples/platform/esp32/shell_extension/openthread_cli_register.h @@ -0,0 +1,24 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * 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 + +namespace chip { + +void RegisterOpenThreadCliCommands(); + +} // namespace chip diff --git a/src/platform/ESP32/BUILD.gn b/src/platform/ESP32/BUILD.gn index 0a9c9b7dbaef20..c5b59add8e9e34 100644 --- a/src/platform/ESP32/BUILD.gn +++ b/src/platform/ESP32/BUILD.gn @@ -154,7 +154,7 @@ static_library("ESP32") { "../OpenThread/GenericNetworkCommissioningThreadDriver.cpp", "../OpenThread/GenericNetworkCommissioningThreadDriver.h", "../OpenThread/OpenThreadUtils.cpp", - "OpenthreadLauncher.c", + "OpenthreadLauncher.cpp", "OpenthreadLauncher.h", "ThreadStackManagerImpl.cpp", "ThreadStackManagerImpl.h", diff --git a/src/platform/ESP32/OpenthreadLauncher.c b/src/platform/ESP32/OpenthreadLauncher.cpp similarity index 56% rename from src/platform/ESP32/OpenthreadLauncher.c rename to src/platform/ESP32/OpenthreadLauncher.cpp index 4eaa674e4d8c48..8c76c1db809082 100644 --- a/src/platform/ESP32/OpenthreadLauncher.c +++ b/src/platform/ESP32/OpenthreadLauncher.cpp @@ -20,18 +20,95 @@ #include "esp_netif.h" #include "esp_netif_types.h" #include "esp_openthread.h" +#include "esp_openthread_cli.h" #include "esp_openthread_lock.h" #include "esp_openthread_netif_glue.h" #include "esp_openthread_types.h" #include "esp_vfs_eventfd.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "openthread/cli.h" #include "openthread/instance.h" #include "openthread/logging.h" #include "openthread/tasklet.h" +#include +#include static esp_netif_t * openthread_netif = NULL; static esp_openthread_platform_config_t * s_platform_config = NULL; +static TaskHandle_t cli_transmit_task = NULL; +static QueueHandle_t cli_transmit_task_queue = NULL; +static constexpr uint16_t OTCLI_TRANSMIT_TASK_STACK_SIZE = 1024; +static constexpr UBaseType_t OTCLI_TRANSMIT_TASK_PRIORITY = 5; + +CHIP_ERROR cli_transmit_task_post(std::unique_ptr && cli_str) +{ + char * cmd = cli_str.get(); + if (!cli_transmit_task_queue || xQueueSend(cli_transmit_task_queue, &cmd, portMAX_DELAY) != pdTRUE) + { + return CHIP_ERROR_INTERNAL; + } + cli_str.release(); + return CHIP_NO_ERROR; +} + +static int cli_output_callback(void * context, const char * format, va_list args) +{ + int ret = 0; + char prompt_check[3]; + vsnprintf(prompt_check, sizeof(prompt_check), format, args); + if (!strncmp(prompt_check, "> ", sizeof(prompt_check)) && cli_transmit_task) + { + xTaskNotifyGive(cli_transmit_task); + } + else + { + ret = vprintf(format, args); + } + return ret; +} + +static void esp_openthread_matter_cli_init(void) +{ + otCliInit(esp_openthread_get_instance(), cli_output_callback, NULL); +} + +static void cli_transmit_worker(void * context) +{ + cli_transmit_task_queue = xQueueCreate(8, sizeof(char *)); + if (!cli_transmit_task_queue) + { + vTaskDelete(NULL); + return; + } + + while (true) + { + char * cmd = NULL; + if (xQueueReceive(cli_transmit_task_queue, &cmd, portMAX_DELAY) == pdTRUE) + { + if (cmd) + { + std::unique_ptr cmd_ptr(cmd); + esp_openthread_cli_input(cmd_ptr.get()); + } + else + { + continue; + } + xTaskNotifyWait(0, 0, NULL, portMAX_DELAY); + } + } + vQueueDelete(cli_transmit_task_queue); + vTaskDelete(NULL); +} + +static esp_err_t cli_command_transmit_task(void) +{ + xTaskCreate(cli_transmit_worker, "otcli_trans", OTCLI_TRANSMIT_TASK_STACK_SIZE, xTaskGetCurrentTaskHandle(), + OTCLI_TRANSMIT_TASK_PRIORITY, &cli_transmit_task); + return ESP_OK; +} static esp_netif_t * init_openthread_netif(const esp_openthread_platform_config_t * config) { @@ -84,6 +161,10 @@ esp_err_t openthread_init_stack(void) assert(s_platform_config); // Initialize the OpenThread stack ESP_ERROR_CHECK(esp_openthread_init(s_platform_config)); +#if CONFIG_OPENTHREAD_CLI + esp_openthread_matter_cli_init(); + cli_command_transmit_task(); +#endif // Initialize the esp_netif bindings openthread_netif = init_openthread_netif(s_platform_config); free(s_platform_config); diff --git a/src/platform/ESP32/OpenthreadLauncher.h b/src/platform/ESP32/OpenthreadLauncher.h index a7f4ef02747eb2..0a10b486d74afc 100644 --- a/src/platform/ESP32/OpenthreadLauncher.h +++ b/src/platform/ESP32/OpenthreadLauncher.h @@ -19,15 +19,10 @@ #include #include - -#ifdef __cplusplus -extern "C" { -#endif +#include +#include esp_err_t set_openthread_platform_config(esp_openthread_platform_config_t * config); esp_err_t openthread_init_stack(void); esp_err_t openthread_launch_task(void); - -#ifdef __cplusplus -} -#endif +CHIP_ERROR cli_transmit_task_post(std::unique_ptr && cli_str);