mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 17:19:09 -04:00
Merge branch 'feat/add_callback_for_esp_ot_radio_spinel_init_v5.4' into 'release/v5.4'
feat(openthread): add an API to set rcp version string (v5.4) See merge request espressif/esp-idf!36746
This commit is contained in:
commit
5fa3e381c9
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -9,6 +9,7 @@
|
||||
#include "esp_netif.h"
|
||||
#include "esp_netif_types.h"
|
||||
#include "esp_openthread.h"
|
||||
#include "esp_openthread_spinel.h"
|
||||
#include "openthread/instance.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -60,42 +61,6 @@ esp_err_t esp_openthread_border_router_deinit(void);
|
||||
*/
|
||||
esp_netif_t *esp_openthread_get_backbone_netif(void);
|
||||
|
||||
/**
|
||||
* @brief Registers the callback for RCP failure.
|
||||
*
|
||||
*/
|
||||
void esp_openthread_register_rcp_failure_handler(esp_openthread_rcp_failure_handler handler);
|
||||
|
||||
/**
|
||||
* @brief Registers the callback for spinel compatibility error.
|
||||
*
|
||||
* @note This function must be called before esp_openthread_init.
|
||||
*
|
||||
* @param[in] callback The callback.
|
||||
*
|
||||
*/
|
||||
void esp_openthread_set_compatibility_error_callback(esp_openthread_compatibility_error_callback callback);
|
||||
|
||||
/**
|
||||
* @brief Deinitializes the connection to RCP.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_STATE if fail to deinitialize RCP
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_openthread_rcp_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Initializes the connection to RCP.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL if fail to initialize RCP
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_openthread_rcp_init(void);
|
||||
|
||||
/**
|
||||
* @brief Sets the meshcop(e) instance name.
|
||||
*
|
||||
|
71
components/openthread/include/esp_openthread_spinel.h
Normal file
71
components/openthread/include/esp_openthread_spinel.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_openthread_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Registers the callback for RCP failure.
|
||||
*
|
||||
*/
|
||||
void esp_openthread_register_rcp_failure_handler(esp_openthread_rcp_failure_handler handler);
|
||||
|
||||
/**
|
||||
* @brief Registers the callback for spinel compatibility error.
|
||||
*
|
||||
* @note This function should be called before esp_openthread_init.
|
||||
*
|
||||
* @param[in] callback The callback.
|
||||
*
|
||||
*/
|
||||
void esp_openthread_set_compatibility_error_callback(esp_openthread_compatibility_error_callback callback);
|
||||
|
||||
/**
|
||||
* @brief Deinitializes the connection to RCP.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_STATE if fail to deinitialize RCP
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_openthread_rcp_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Initializes the connection to RCP.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL if fail to initialize RCP
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_openthread_rcp_init(void);
|
||||
|
||||
/**
|
||||
* @brief Set the RCP version string.
|
||||
*
|
||||
* @note This function should be called before esp_openthread_init. When the RCP version string is not an empty string,
|
||||
* compatibility checks will be performed during the initialization of the ESP OpenThread radio spinel.
|
||||
* The `esp_openthread_compatibility_error_callback` will be triggered if the desired RCP version does not match
|
||||
* the actual version running on the RCP. If needed, a NULL parameter can be passed to clear the version string.
|
||||
*
|
||||
* @param[in] version_str The pointer to RCP version string.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL if fail to set RCP version string
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_openthread_rcp_version_set(const char *version_str);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -198,8 +198,16 @@ typedef struct {
|
||||
esp_openthread_port_config_t port_config; /*!< The port configuration */
|
||||
} esp_openthread_platform_config_t;
|
||||
|
||||
/**
|
||||
* @brief The OpenThread rcp failure handler
|
||||
*
|
||||
*/
|
||||
typedef void (*esp_openthread_rcp_failure_handler)(void);
|
||||
|
||||
/**
|
||||
* @brief The OpenThread compatibility error callback
|
||||
*
|
||||
*/
|
||||
typedef void (*esp_openthread_compatibility_error_callback)(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -494,16 +494,6 @@
|
||||
#define OPENTHREAD_POSIX_CONFIG_RCP_TIME_SYNC_INTERVAL (60 * 1000 * 1000)
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXTERNAL_COEX_ENABLE
|
||||
/**
|
||||
* @def OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE
|
||||
*
|
||||
* Enables compilation of vendor specific code for Spinel
|
||||
*/
|
||||
#ifndef OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE
|
||||
#define OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE 1
|
||||
#endif
|
||||
#endif
|
||||
#endif // CONFIG_OPENTHREAD_RADIO_SPINEL_UART || CONFIG_OPENTHREAD_RADIO_SPINEL_SPI
|
||||
|
||||
#if CONFIG_OPENTHREAD_LINK_METRICS
|
||||
|
@ -25,6 +25,9 @@
|
||||
#include "openthread/platform/time.h"
|
||||
#include "platform/exit_code.h"
|
||||
#include "spinel_driver.hpp"
|
||||
#include <cstring>
|
||||
|
||||
#define OT_SPINEL_RCP_VERSION_MAX_SIZE 100
|
||||
|
||||
using ot::Spinel::RadioSpinel;
|
||||
using esp::openthread::SpinelInterfaceAdapter;
|
||||
@ -56,34 +59,7 @@ static const esp_openthread_radio_config_t *s_esp_openthread_radio_config = NULL
|
||||
|
||||
static esp_openthread_compatibility_error_callback s_compatibility_error_callback = NULL;
|
||||
|
||||
#if CONFIG_EXTERNAL_COEX_ENABLE
|
||||
|
||||
#define SPINEL_PROP_VENDOR_ESP_COEX_EVENT (SPINEL_PROP_VENDOR_ESP__BEGIN + 3)
|
||||
|
||||
static esp_ieee802154_coex_config_t s_coex_config = {
|
||||
.idle = IEEE802154_IDLE,
|
||||
.txrx = IEEE802154_LOW,
|
||||
.txrx_at = IEEE802154_MIDDLE,
|
||||
};
|
||||
|
||||
static void esp_openthread_restore_coex_config(void *context)
|
||||
{
|
||||
esp_openthread_set_coex_config(s_coex_config);
|
||||
}
|
||||
|
||||
static esp_err_t esp_openthread_radio_spinel_coex_config_init(void)
|
||||
{
|
||||
s_radio.SetVendorRestorePropertiesCallback(esp_openthread_restore_coex_config, esp_openthread_get_instance());
|
||||
esp_ieee802154_coex_config_t coex_config;
|
||||
uint16_t coex_config_len = 0;
|
||||
ESP_RETURN_ON_ERROR(s_radio.Get(SPINEL_PROP_VENDOR_ESP_COEX_EVENT, SPINEL_DATATYPE_DATA_WLEN_S, &coex_config, &coex_config_len),
|
||||
OT_PLAT_LOG_TAG, "Fail to get coex config");
|
||||
ESP_RETURN_ON_FALSE(coex_config_len == sizeof(esp_ieee802154_coex_config_t), ESP_FAIL, OT_PLAT_LOG_TAG,
|
||||
"Fail to get coex config");
|
||||
s_coex_config = coex_config;
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
static char s_internal_rcp_version[OT_SPINEL_RCP_VERSION_MAX_SIZE] = {'\0'};
|
||||
|
||||
static void esp_openthread_radio_config_set(const esp_openthread_radio_config_t *config)
|
||||
{
|
||||
@ -136,11 +112,18 @@ esp_err_t esp_openthread_radio_init(const esp_openthread_platform_config_t *conf
|
||||
"Spinel interface init failed");
|
||||
#endif
|
||||
s_spinel_driver.Init(s_spinel_interface.GetSpinelInterface(), true, iidList, ot::Spinel::kSpinelHeaderMaxNumIid);
|
||||
if (strlen(s_internal_rcp_version) > 0) {
|
||||
const char *running_rcp_version = s_spinel_driver.GetVersion();
|
||||
if (strcmp(s_internal_rcp_version, running_rcp_version) != 0) {
|
||||
if (s_compatibility_error_callback) {
|
||||
s_compatibility_error_callback();
|
||||
} else {
|
||||
ESP_LOGW(OT_PLAT_LOG_TAG, "The running rcp does not match the provided rcp");
|
||||
}
|
||||
}
|
||||
}
|
||||
s_radio.SetCompatibilityErrorCallback(ot_spinel_compatibility_error_callback, esp_openthread_get_instance());
|
||||
s_radio.Init(/*skip_rcp_compatibility_check=*/false, /*reset_radio=*/true, &s_spinel_driver, s_radio_caps, /*RCP_time_sync=*/true);
|
||||
#if CONFIG_EXTERNAL_COEX_ENABLE
|
||||
ESP_RETURN_ON_ERROR(esp_openthread_radio_spinel_coex_config_init(), OT_PLAT_LOG_TAG, "Coex config init failed");
|
||||
#endif
|
||||
#if CONFIG_OPENTHREAD_RADIO_SPINEL_SPI // CONFIG_OPENTHREAD_RADIO_SPINEL_SPI
|
||||
ESP_RETURN_ON_ERROR(s_spinel_interface.GetSpinelInterface().AfterRadioInit(), OT_PLAT_LOG_TAG, "Spinel interface init failed");
|
||||
#endif
|
||||
@ -185,12 +168,24 @@ esp_err_t esp_openthread_rcp_init(void)
|
||||
radiospinel_workflow);
|
||||
}
|
||||
|
||||
esp_err_t esp_openthread_rcp_version_set(const char *version_str)
|
||||
{
|
||||
if (version_str == NULL) {
|
||||
memset(s_internal_rcp_version, 0, OT_SPINEL_RCP_VERSION_MAX_SIZE);
|
||||
return ESP_OK;
|
||||
}
|
||||
ESP_RETURN_ON_FALSE(strlen(version_str) > 0 && strlen(version_str) < OT_SPINEL_RCP_VERSION_MAX_SIZE, ESP_FAIL, OT_PLAT_LOG_TAG, "Invalid rcp version");
|
||||
strcpy(s_internal_rcp_version, version_str);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void esp_openthread_radio_deinit(void)
|
||||
{
|
||||
s_radio.Deinit();
|
||||
s_spinel_driver.Deinit();
|
||||
s_spinel_interface.GetSpinelInterface().Disable();
|
||||
esp_openthread_platform_workflow_unregister(radiospinel_workflow);
|
||||
s_compatibility_error_callback = NULL;
|
||||
}
|
||||
|
||||
esp_err_t esp_openthread_radio_process(otInstance *instance, const esp_openthread_mainloop_context_t *mainloop)
|
||||
@ -502,37 +497,16 @@ uint16_t otPlatTimeGetXtalAccuracy(void)
|
||||
return CONFIG_OPENTHREAD_XTAL_ACCURACY;
|
||||
}
|
||||
|
||||
#if CONFIG_EXTERNAL_COEX_ENABLE
|
||||
void esp_openthread_set_coex_config(esp_ieee802154_coex_config_t config)
|
||||
uint32_t otPlatRadioGetPreferredChannelMask(otInstance *aInstance)
|
||||
{
|
||||
otError err = s_radio.Set(SPINEL_PROP_VENDOR_ESP_COEX_EVENT, SPINEL_DATATYPE_DATA_WLEN_S, &s_coex_config, sizeof(esp_ieee802154_coex_config_t));
|
||||
ESP_RETURN_ON_FALSE(err == OT_ERROR_NONE, , OT_PLAT_LOG_TAG, "Fail to set coex config");
|
||||
s_coex_config = config;
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
// Refer to `GetRadioChannelMask(bool aPreferred)`: TRUE to get preferred channel mask
|
||||
return s_radio.GetRadioChannelMask(true);
|
||||
}
|
||||
|
||||
esp_ieee802154_coex_config_t esp_openthread_get_coex_config(void)
|
||||
uint32_t otPlatRadioGetSupportedChannelMask(otInstance *aInstance)
|
||||
{
|
||||
return s_coex_config;
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
// Refer to `GetRadioChannelMask(bool aPreferred)`: FALSE to get supported channel mask
|
||||
return s_radio.GetRadioChannelMask(false);
|
||||
}
|
||||
|
||||
namespace ot {
|
||||
namespace Spinel {
|
||||
|
||||
otError RadioSpinel::VendorHandleValueIs(spinel_prop_key_t aPropKey)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
switch (aPropKey)
|
||||
{
|
||||
default:
|
||||
ESP_LOGW(OT_PLAT_LOG_TAG, "Not Implemented!");
|
||||
error = OT_ERROR_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
} // namespace Spinel
|
||||
} // namespace ot
|
||||
|
||||
#endif
|
||||
|
@ -63,7 +63,7 @@ static void handle_ot_netdata_change(void)
|
||||
|
||||
static void handle_ot_role_change(otInstance* instance)
|
||||
{
|
||||
#if ((CONFIG_ESP_COEX_SW_COEXIST_ENABLE && OPENTHREAD_RADIO_NATIVE) || CONFIG_EXTERNAL_COEX_ENABLE)
|
||||
#if ((CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE) && OPENTHREAD_RADIO_NATIVE)
|
||||
otLinkModeConfig linkmode = otThreadGetLinkMode(instance);
|
||||
esp_ieee802154_coex_config_t config = esp_openthread_get_coex_config();
|
||||
config.txrx = (linkmode.mRxOnWhenIdle) ? IEEE802154_LOW : IEEE802154_MIDDLE;
|
||||
|
Loading…
x
Reference in New Issue
Block a user