feat(openthread): add openthread start stop APIs

This commit is contained in:
Xu Si Yu
2025-10-16 18:40:33 +08:00
parent 7863b3c419
commit 2d7ef9efeb
5 changed files with 155 additions and 3 deletions
@@ -4,12 +4,17 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#include "esp_openthread.h"
#include "esp_check.h"
#include "esp_heap_caps.h"
#include "esp_openthread_border_router.h"
#include "esp_openthread_common_macro.h"
#include "esp_openthread_cli.h"
#include "esp_openthread_dns64.h"
#include "esp_openthread_lock.h"
#include "esp_openthread_ncp.h"
#include "esp_openthread_netif_glue.h"
#include "esp_openthread_platform.h"
#include "esp_openthread_sleep.h"
#include "esp_openthread_state.h"
@@ -18,15 +23,19 @@
#include "freertos/FreeRTOS.h"
#include "lwip/dns.h"
#include "openthread/instance.h"
#include "openthread/logging.h"
#include "openthread/netdata.h"
#include "openthread/tasklet.h"
#include "openthread/thread.h"
#include <cstddef>
#if CONFIG_OPENTHREAD_FTD
#include "openthread/dataset_ftd.h"
#endif
static bool s_ot_mainloop_running = false;
static SemaphoreHandle_t s_ot_syn_semaphore = NULL;
static TaskHandle_t s_ot_task_handle = NULL;
static int hex_digit_to_int(char hex)
{
@@ -223,3 +232,81 @@ esp_err_t esp_openthread_deinit(void)
otInstanceFinalize(esp_openthread_get_instance());
return esp_openthread_platform_deinit();
}
static void ot_task_worker(void *aContext)
{
esp_openthread_platform_config_t* config = (esp_openthread_platform_config_t *)aContext;
// Initialize the OpenThread stack
ESP_ERROR_CHECK(esp_openthread_init(config));
#if CONFIG_OPENTHREAD_FTD || CONFIG_OPENTHREAD_MTD
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_OPENTHREAD();
esp_netif_t *openthread_netif = esp_netif_new(&cfg);
assert(openthread_netif != NULL);
ESP_ERROR_CHECK(esp_netif_attach(openthread_netif, esp_openthread_netif_glue_init(config)));
#endif
#if CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC
// The OpenThread log level directly matches ESP log level
(void)otLoggingSetLevel(CONFIG_LOG_DEFAULT_LEVEL);
#endif // CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC
#if CONFIG_OPENTHREAD_CLI
esp_openthread_cli_init();
esp_openthread_cli_console_command_register();
#endif // CONFIG_OPENTHREAD_CLI
xSemaphoreGive(s_ot_syn_semaphore);
#if CONFIG_OPENTHREAD_RADIO
otAppNcpInit(esp_openthread_get_instance());
#endif
// Run the main loop
esp_openthread_launch_mainloop();
#if CONFIG_OPENTHREAD_RADIO
ESP_LOGE(OT_PLAT_LOG_TAG, "RCP deinitialization is not supported for now");
assert(false);
#endif
#if CONFIG_OPENTHREAD_CLI
esp_openthread_cli_console_command_unregister();
#endif // CONFIG_OPENTHREAD_CLI
#if CONFIG_OPENTHREAD_FTD || CONFIG_OPENTHREAD_MTD
// Clean up
esp_openthread_netif_glue_deinit();
esp_netif_destroy(openthread_netif);
#endif
ESP_ERROR_CHECK(esp_openthread_deinit());
xSemaphoreGive(s_ot_syn_semaphore);
vTaskDelay(portMAX_DELAY);
}
esp_err_t esp_openthread_start(esp_openthread_platform_config_t *config)
{
ESP_RETURN_ON_FALSE(s_ot_syn_semaphore == NULL, ESP_ERR_INVALID_STATE, OT_PLAT_LOG_TAG, "OpenThread has been initialized");
s_ot_syn_semaphore = xSemaphoreCreateBinary();
ESP_RETURN_ON_FALSE(s_ot_syn_semaphore != NULL, ESP_ERR_INVALID_STATE, OT_PLAT_LOG_TAG, "Failed to create s_ot_syn_semaphore");
assert(xTaskCreate(ot_task_worker, CONFIG_OPENTHREAD_TASK_NAME, CONFIG_OPENTHREAD_TASK_SIZE, config, CONFIG_OPENTHREAD_TASK_PRIORITY, &s_ot_task_handle) == pdPASS);
xSemaphoreTake(s_ot_syn_semaphore, portMAX_DELAY);
return ESP_OK;
}
esp_err_t esp_openthread_stop(void)
{
ESP_RETURN_ON_FALSE(s_ot_syn_semaphore != NULL, ESP_ERR_INVALID_STATE, OT_PLAT_LOG_TAG, "OpenThread is not initialized");
esp_openthread_lock_acquire(portMAX_DELAY);
otInstance *instance = esp_openthread_get_instance();
bool is_thread_not_active = (otThreadGetDeviceRole(instance) == OT_DEVICE_ROLE_DISABLED && otIp6IsEnabled(instance) == false);
esp_openthread_lock_release();
ESP_RETURN_ON_FALSE(is_thread_not_active, ESP_ERR_INVALID_STATE, OT_PLAT_LOG_TAG, "Thread interface is still active");
esp_openthread_mainloop_exit();
xSemaphoreTake(s_ot_syn_semaphore, portMAX_DELAY);
vTaskDelete(s_ot_task_handle);
vSemaphoreDelete(s_ot_syn_semaphore);
s_ot_task_handle = NULL;
s_ot_syn_semaphore = NULL;
return ESP_OK;
}