mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-03 03:31:41 +03:00
Merge branch 'backport/openthread_154_related_feature_v52' into 'release/v5.2'
Backport some openthread and IEEE802154 related feature(Backport v5.2) See merge request espressif/esp-idf!34273
This commit is contained in:
@@ -469,11 +469,10 @@ static IRAM_ATTR void isr_handle_ack_rx_done(void)
|
||||
NEEDS_NEXT_OPT(true);
|
||||
}
|
||||
|
||||
static IRAM_ATTR void isr_handle_rx_phase_rx_abort(void)
|
||||
static IRAM_ATTR void isr_handle_rx_phase_rx_abort(ieee802154_ll_rx_abort_reason_t rx_abort_reason)
|
||||
{
|
||||
event_end_process();
|
||||
uint32_t rx_status = ieee802154_ll_get_rx_status();
|
||||
ieee802154_ll_rx_abort_reason_t rx_abort_reason = ieee802154_ll_get_rx_abort_reason();
|
||||
switch (rx_abort_reason) {
|
||||
case IEEE802154_RX_ABORT_BY_RX_STOP:
|
||||
case IEEE802154_RX_ABORT_BY_TX_ACK_STOP:
|
||||
@@ -508,13 +507,12 @@ static IRAM_ATTR void isr_handle_rx_phase_rx_abort(void)
|
||||
NEEDS_NEXT_OPT(true);
|
||||
}
|
||||
|
||||
static IRAM_ATTR void isr_handle_tx_ack_phase_rx_abort(void)
|
||||
static IRAM_ATTR void isr_handle_tx_ack_phase_rx_abort(ieee802154_ll_rx_abort_reason_t rx_abort_reason)
|
||||
{
|
||||
event_end_process();
|
||||
#if CONFIG_IEEE802154_TEST
|
||||
uint32_t rx_status = ieee802154_ll_get_rx_status();
|
||||
#endif
|
||||
ieee802154_ll_rx_abort_reason_t rx_abort_reason = ieee802154_ll_get_rx_abort_reason();
|
||||
switch (rx_abort_reason) {
|
||||
case IEEE802154_RX_ABORT_BY_RX_STOP:
|
||||
case IEEE802154_RX_ABORT_BY_TX_ACK_STOP:
|
||||
@@ -553,10 +551,9 @@ static IRAM_ATTR void isr_handle_tx_ack_phase_rx_abort(void)
|
||||
NEEDS_NEXT_OPT(true);
|
||||
}
|
||||
|
||||
static IRAM_ATTR void isr_handle_tx_abort(void)
|
||||
static IRAM_ATTR void isr_handle_tx_abort(ieee802154_ll_tx_abort_reason_t tx_abort_reason)
|
||||
{
|
||||
event_end_process();
|
||||
ieee802154_ll_tx_abort_reason_t tx_abort_reason = ieee802154_ll_get_tx_abort_reason();
|
||||
switch (tx_abort_reason) {
|
||||
case IEEE802154_TX_ABORT_BY_RX_ACK_STOP:
|
||||
case IEEE802154_TX_ABORT_BY_TX_STOP:
|
||||
@@ -636,6 +633,8 @@ static void ieee802154_isr(void *arg)
|
||||
{
|
||||
ieee802154_enter_critical();
|
||||
ieee802154_ll_events events = ieee802154_ll_get_events();
|
||||
ieee802154_ll_rx_abort_reason_t rx_abort_reason = ieee802154_ll_get_rx_abort_reason();
|
||||
ieee802154_ll_tx_abort_reason_t tx_abort_reason = ieee802154_ll_get_tx_abort_reason();
|
||||
|
||||
IEEE802154_PROBE(events);
|
||||
|
||||
@@ -643,7 +642,7 @@ static void ieee802154_isr(void *arg)
|
||||
|
||||
if (events & IEEE802154_EVENT_RX_ABORT) {
|
||||
// First phase rx abort process, will clear RX_ABORT event in second.
|
||||
isr_handle_rx_phase_rx_abort();
|
||||
isr_handle_rx_phase_rx_abort(rx_abort_reason);
|
||||
}
|
||||
|
||||
if (events & IEEE802154_EVENT_RX_SFD_DONE) {
|
||||
@@ -701,12 +700,12 @@ static void ieee802154_isr(void *arg)
|
||||
|
||||
if (events & IEEE802154_EVENT_RX_ABORT) {
|
||||
// Second phase rx abort process, clears RX_ABORT event.
|
||||
isr_handle_tx_ack_phase_rx_abort();
|
||||
isr_handle_tx_ack_phase_rx_abort(rx_abort_reason);
|
||||
events &= (uint16_t)(~IEEE802154_EVENT_RX_ABORT);
|
||||
}
|
||||
|
||||
if (events & IEEE802154_EVENT_TX_ABORT) {
|
||||
isr_handle_tx_abort();
|
||||
isr_handle_tx_abort(tx_abort_reason);
|
||||
|
||||
events &= (uint16_t)(~IEEE802154_EVENT_TX_ABORT);
|
||||
}
|
||||
@@ -773,7 +772,7 @@ esp_err_t ieee802154_mac_init(void)
|
||||
ieee802154_ll_enable_rx_abort_events(BIT(IEEE802154_RX_ABORT_BY_TX_ACK_TIMEOUT - 1) | BIT(IEEE802154_RX_ABORT_BY_TX_ACK_COEX_BREAK - 1));
|
||||
|
||||
ieee802154_ll_set_ed_sample_mode(IEEE802154_ED_SAMPLE_AVG);
|
||||
#if !CONFIG_IEEE802154_TEST && CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE
|
||||
#if !CONFIG_IEEE802154_TEST && (CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE)
|
||||
esp_coex_ieee802154_ack_pti_set(IEEE802154_MIDDLE);
|
||||
IEEE802154_SET_TXRX_PTI(IEEE802154_SCENE_IDLE);
|
||||
#else
|
||||
|
||||
@@ -309,7 +309,7 @@ uint8_t IEEE802154_INLINE ieee802154_frame_get_version(const uint8_t *frame)
|
||||
|
||||
bool IEEE802154_INLINE ieee802154_frame_is_ack_required(const uint8_t *frame)
|
||||
{
|
||||
return frame[IEEE802154_FRAME_AR_OFFSET] & IEEE802154_FRAME_AR_BIT;
|
||||
return (is_suported_frame_type(ieee802154_frame_get_type(frame))) && (frame[IEEE802154_FRAME_AR_OFFSET] & IEEE802154_FRAME_AR_BIT);
|
||||
}
|
||||
|
||||
uint8_t ieee802154_frame_get_dst_addr(const uint8_t *frame, uint8_t *addr)
|
||||
|
||||
@@ -21,7 +21,7 @@ uint8_t ieee802154_channel_to_freq(uint8_t channel)
|
||||
return (channel - 11) * 5 + 3;
|
||||
}
|
||||
|
||||
#if !CONFIG_IEEE802154_TEST && CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE
|
||||
#if !CONFIG_IEEE802154_TEST && (CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE)
|
||||
void ieee802154_set_txrx_pti(ieee802154_txrx_scene_t txrx_scene)
|
||||
{
|
||||
|
||||
|
||||
@@ -265,7 +265,7 @@ typedef enum {
|
||||
IEEE802154_SCENE_RX_AT, /*!< IEEE802154 radio coexistence scene RX AT */
|
||||
} ieee802154_txrx_scene_t;
|
||||
|
||||
#if !CONFIG_IEEE802154_TEST && CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE
|
||||
#if !CONFIG_IEEE802154_TEST && (CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE)
|
||||
|
||||
/**
|
||||
* @brief Set the IEEE802154 radio coexistence scene during transmitting or receiving.
|
||||
|
||||
@@ -15,7 +15,6 @@ if(CONFIG_OPENTHREAD_ENABLED)
|
||||
|
||||
set(private_include_dirs
|
||||
"openthread/examples/platforms"
|
||||
"openthread/include/openthread"
|
||||
"openthread/src"
|
||||
"openthread/src/core"
|
||||
"openthread/src/lib"
|
||||
@@ -140,6 +139,19 @@ if(CONFIG_OPENTHREAD_ENABLED)
|
||||
list(APPEND exclude_srcs
|
||||
"src/port/esp_openthread_radio.c"
|
||||
"src/port/esp_openthread_sleep.c")
|
||||
elseif(CONFIG_OPENTHREAD_RADIO_154_NONE)
|
||||
list(APPEND exclude_srcs
|
||||
"src/port/esp_openthread_radio_spinel.cpp"
|
||||
"src/port/esp_spi_spinel_interface.cpp"
|
||||
"src/port/esp_uart_spinel_interface.cpp"
|
||||
"src/port/esp_openthread_radio.c"
|
||||
"src/port/esp_openthread_sleep.c"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT CONFIG_OPENTHREAD_RADIO_TREL)
|
||||
list(APPEND exclude_srcs
|
||||
"src/port/esp_openthread_trel.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_OPENTHREAD_BORDER_ROUTER)
|
||||
@@ -156,6 +168,13 @@ if(CONFIG_OPENTHREAD_ENABLED)
|
||||
if(CONFIG_OPENTHREAD_NCP_VENDOR_HOOK)
|
||||
list(APPEND src_dirs
|
||||
"src/ncp")
|
||||
if(CONFIG_OPENTHREAD_RCP_UART)
|
||||
list(APPEND exclude_srcs
|
||||
"src/ncp/esp_openthread_ncp_spi.cpp")
|
||||
elseif(CONFIG_OPENTHREAD_RCP_SPI)
|
||||
list(APPEND exclude_srcs
|
||||
"src/ncp/esp_openthread_ncp_hdlc.cpp")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT CONFIG_OPENTHREAD_DNS64_CLIENT)
|
||||
@@ -252,6 +271,10 @@ idf_component_register(SRC_DIRS "${src_dirs}"
|
||||
PRIV_REQUIRES console esp_event esp_partition esp_timer
|
||||
ieee802154 mbedtls nvs_flash)
|
||||
|
||||
if(CONFIG_OPENTHREAD_RADIO_TREL)
|
||||
idf_component_optional_requires(PRIVATE espressif__mdns)
|
||||
endif()
|
||||
|
||||
if(CONFIG_OPENTHREAD_ENABLED OR CONFIG_OPENTHREAD_SPINEL_ONLY)
|
||||
if(CONFIG_OPENTHREAD_RADIO)
|
||||
set(CONFIG_FILE_TYPE "radio")
|
||||
|
||||
@@ -101,7 +101,7 @@ menu "OpenThread"
|
||||
default 5 if OPENTHREAD_LOG_LEVEL_DEBG
|
||||
|
||||
choice OPENTHREAD_RADIO_TYPE
|
||||
prompt "Config the Thread radio type"
|
||||
prompt "Config the Thread radio type with 15.4 link"
|
||||
depends on OPENTHREAD_ENABLED
|
||||
default OPENTHREAD_RADIO_NATIVE if SOC_IEEE802154_SUPPORTED
|
||||
default OPENTHREAD_RADIO_SPINEL_UART
|
||||
@@ -124,8 +124,26 @@ menu "OpenThread"
|
||||
help
|
||||
Select this to connect to a Radio Co-Processor via SPI.
|
||||
|
||||
config OPENTHREAD_RADIO_154_NONE
|
||||
bool "Disable the Thread radio based on 15.4 link"
|
||||
help
|
||||
Select this to disable the Thread radio based on 15.4 link.
|
||||
endchoice
|
||||
|
||||
config OPENTHREAD_RADIO_TREL
|
||||
bool "Enable Thread Radio Encapsulation Link (TREL)"
|
||||
depends on EXAMPLE_CONNECT_WIFI || EXAMPLE_CONNECT_ETHERNET
|
||||
default n
|
||||
help
|
||||
Select this option to enable Thread Radio Encapsulation Link.
|
||||
|
||||
config OPENTHREAD_TREL_PORT
|
||||
int "The port of openthread trel service"
|
||||
depends on OPENTHREAD_RADIO_TREL
|
||||
default 12390
|
||||
help
|
||||
Configure the port number of TREL service.
|
||||
|
||||
choice OPENTHREAD_DEVICE_TYPE
|
||||
prompt "Config the Thread device type"
|
||||
depends on OPENTHREAD_ENABLED
|
||||
|
||||
@@ -117,6 +117,7 @@ typedef enum {
|
||||
RADIO_MODE_NATIVE = 0x0, /*!< Use the native 15.4 radio */
|
||||
RADIO_MODE_UART_RCP, /*!< UART connection to a 15.4 capable radio co-processor (RCP) */
|
||||
RADIO_MODE_SPI_RCP, /*!< SPI connection to a 15.4 capable radio co-processor (RCP) */
|
||||
RADIO_MODE_TREL, /*!< Use the Thread Radio Encapsulation Link (TREL) */
|
||||
RADIO_MODE_MAX, /*!< Using for parameter check */
|
||||
} esp_openthread_radio_mode_t;
|
||||
|
||||
|
||||
@@ -203,16 +203,6 @@
|
||||
#define OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
|
||||
*
|
||||
* Set to 1 to enable support for Thread Radio Encapsulation Link (TREL).
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
|
||||
#define OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
*
|
||||
@@ -225,6 +215,28 @@
|
||||
|
||||
#endif // CONFIG_OPENTHREAD_BORDER_ROUTER
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
|
||||
*
|
||||
* Set to 1 to enable support for Thread Radio Encapsulation Link (TREL).
|
||||
*
|
||||
*/
|
||||
#if CONFIG_OPENTHREAD_RADIO_TREL
|
||||
#define OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 1
|
||||
#endif // CONFIG_OPENTHREAD_RADIO_TREL
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
|
||||
*
|
||||
* Set to 1 to enable support for IEEE802.15.4 radio link.
|
||||
*
|
||||
*/
|
||||
#if !CONFIG_OPENTHREAD_RADIO_154_NONE
|
||||
#define OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE 1
|
||||
#else
|
||||
#define OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE 0
|
||||
#endif
|
||||
|
||||
#if !CONFIG_OPENTHREAD_RADIO_NATIVE
|
||||
/**
|
||||
* @def OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT
|
||||
|
||||
@@ -94,14 +94,18 @@ static esp_err_t esp_openthread_host_interface_init(const esp_openthread_platfor
|
||||
{
|
||||
esp_openthread_host_connection_mode_t host_mode = get_host_connection_mode();
|
||||
switch (host_mode) {
|
||||
#if CONFIG_OPENTHREAD_RCP_SPI
|
||||
case HOST_CONNECTION_MODE_RCP_SPI:
|
||||
ESP_RETURN_ON_ERROR(esp_openthread_host_rcp_spi_init(config), OT_PLAT_LOG_TAG,
|
||||
"esp_openthread_host_rcp_spi_init failed");
|
||||
break;
|
||||
#endif
|
||||
#if CONFIG_OPENTHREAD_RCP_UART
|
||||
case HOST_CONNECTION_MODE_RCP_UART:
|
||||
ESP_RETURN_ON_ERROR(esp_openthread_host_rcp_uart_init(config), OT_PLAT_LOG_TAG,
|
||||
"esp_openthread_host_rcp_uart_init failed");
|
||||
break;
|
||||
#endif
|
||||
#if CONFIG_OPENTHREAD_CONSOLE_TYPE_UART
|
||||
case HOST_CONNECTION_MODE_CLI_UART:
|
||||
ESP_RETURN_ON_ERROR(esp_openthread_host_cli_uart_init(config), OT_PLAT_LOG_TAG,
|
||||
|
||||
@@ -4,12 +4,11 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_ieee802154.h"
|
||||
#include "esp_openthread_ncp.h"
|
||||
#include "ncp_base.hpp"
|
||||
|
||||
#if OPENTHREAD_ENABLE_NCP_VENDOR_HOOK
|
||||
|
||||
#if CONFIG_OPENTHREAD_RCP_UART
|
||||
#include "utils/uart.h"
|
||||
#endif
|
||||
@@ -107,5 +106,3 @@ otError NcpBase::VendorSetPropertyHandler(spinel_prop_key_t aPropKey)
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
|
||||
#endif // #if OPENTHREAD_ENABLE_NCP_VENDOR_HOOK
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -7,8 +7,6 @@
|
||||
#include "common/new.hpp"
|
||||
#include "ncp_hdlc.hpp"
|
||||
|
||||
#if OPENTHREAD_ENABLE_NCP_VENDOR_HOOK
|
||||
|
||||
namespace ot {
|
||||
namespace Ncp {
|
||||
|
||||
@@ -29,5 +27,3 @@ extern "C" void otNcpHdlcInit(otInstance *aInstance, otNcpHdlcSendCallback aSend
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
|
||||
#endif // #if OPENTHREAD_ENABLE_NCP_VENDOR_HOOK
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "common/new.hpp"
|
||||
#include "ncp_spi.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Ncp {
|
||||
|
||||
static OT_DEFINE_ALIGNED_VAR(sNcpRaw, sizeof(NcpSpi), uint64_t);
|
||||
|
||||
extern "C" void otNcpSpiInit(otInstance *aInstance)
|
||||
{
|
||||
NcpSpi *ncpSpi = nullptr;
|
||||
Instance *instance = static_cast<Instance *>(aInstance);
|
||||
|
||||
ncpSpi = new (&sNcpRaw) NcpSpi(instance);
|
||||
|
||||
if (ncpSpi == nullptr || ncpSpi != NcpBase::GetNcpInstance())
|
||||
{
|
||||
OT_ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <stdatomic.h>
|
||||
#include "esp_openthread_radio.h"
|
||||
|
||||
#include "error.h"
|
||||
#include "esp_err.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_check.h"
|
||||
@@ -25,6 +24,7 @@
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
#include "openthread/error.h"
|
||||
#include "openthread/link.h"
|
||||
#include "openthread/platform/diag.h"
|
||||
#include "openthread/platform/radio.h"
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "esp_openthread_radio.h"
|
||||
|
||||
#include "link_raw.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <string.h>
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/spi_slave.h"
|
||||
#include "esp_private/cache_utils.h"
|
||||
#include "esp_private/spi_slave_internal.h"
|
||||
#include "ncp/ncp_config.h"
|
||||
#include "openthread/error.h"
|
||||
|
||||
@@ -0,0 +1,352 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_netif_types.h"
|
||||
#include "lwip/ip6_addr.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "common/code_utils.hpp"
|
||||
#include "openthread/error.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_netif.h"
|
||||
#include "mdns.h"
|
||||
#include "esp_netif_ip_addr.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_radio.h"
|
||||
#include "esp_openthread_task_queue.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/tcpip.h"
|
||||
#include "lwip/udp.h"
|
||||
#include "openthread/trel.h"
|
||||
#include "openthread/platform/diag.h"
|
||||
|
||||
static esp_netif_t *s_trel_netif = NULL;
|
||||
static otPlatTrelCounters s_trel_counters;
|
||||
|
||||
#define TREL_MDNS_TYPE "_trel"
|
||||
#define TREL_MDNS_PROTO "_udp"
|
||||
|
||||
typedef struct {
|
||||
uint16_t port;
|
||||
struct udp_pcb *trel_pcb;
|
||||
} ot_trel_t;
|
||||
|
||||
typedef struct {
|
||||
struct pbuf *p;
|
||||
} ot_trel_recv_task_t;
|
||||
|
||||
typedef struct {
|
||||
struct udp_pcb *pcb;
|
||||
const uint8_t *payload;
|
||||
uint16_t length;
|
||||
ip_addr_t peer_addr;
|
||||
uint16_t peer_port;
|
||||
} ot_trel_send_task_t;
|
||||
|
||||
static ot_trel_t s_ot_trel = {CONFIG_OPENTHREAD_TREL_PORT, NULL};
|
||||
static bool s_is_service_registered = false;
|
||||
|
||||
static void trel_browse_notifier(mdns_result_t *result)
|
||||
{
|
||||
while (result) {
|
||||
if (result->addr && result->addr->addr.type == IPADDR_TYPE_V6) {
|
||||
otPlatTrelPeerInfo info;
|
||||
uint8_t trel_txt[1024] = {0};
|
||||
uint16_t trel_txt_len = 0;
|
||||
size_t index = 0;
|
||||
while (index < result->txt_count) {
|
||||
trel_txt[trel_txt_len++] = strlen(result->txt[index].key) + result->txt_value_len[index] + 1;
|
||||
memcpy((trel_txt + trel_txt_len), (void *)result->txt[index].key, strlen(result->txt[index].key));
|
||||
trel_txt_len += (strlen(result->txt[index].key));
|
||||
trel_txt[trel_txt_len++] = '=';
|
||||
memcpy((trel_txt + trel_txt_len), (void *)result->txt[index].value, result->txt_value_len[index]);
|
||||
trel_txt_len += result->txt_value_len[index];
|
||||
index++;
|
||||
}
|
||||
if (!s_trel_netif) {
|
||||
s_trel_netif = result->esp_netif;
|
||||
}
|
||||
info.mTxtData = trel_txt;
|
||||
info.mTxtLength = trel_txt_len;
|
||||
info.mSockAddr.mPort = result->port;
|
||||
memcpy(info.mSockAddr.mAddress.mFields.m32, result->addr->addr.u_addr.ip6.addr, OT_IP6_ADDRESS_SIZE);
|
||||
info.mRemoved = (result->ttl == 0);
|
||||
ESP_LOGI(OT_PLAT_LOG_TAG, "%s TREL peer: address: %s, port:%d", info.mRemoved ? "Remove" : "Found", ip6addr_ntoa(((ip6_addr_t*)(&result->addr->addr.u_addr.ip6))), info.mSockAddr.mPort);
|
||||
esp_openthread_task_switching_lock_acquire(portMAX_DELAY);
|
||||
otPlatTrelHandleDiscoveredPeerInfo(esp_openthread_get_instance(), &info);
|
||||
esp_openthread_task_switching_lock_release();
|
||||
}
|
||||
result = result->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void trel_recv_task(void *ctx)
|
||||
{
|
||||
struct pbuf *recv_buf = (struct pbuf *)ctx;
|
||||
uint8_t *data_buf = (uint8_t *)recv_buf->payload;
|
||||
uint8_t *data_buf_to_free = NULL;
|
||||
uint16_t length = recv_buf->len;
|
||||
|
||||
if (recv_buf->next != NULL) {
|
||||
data_buf = (uint8_t *)malloc(recv_buf->tot_len);
|
||||
if (data_buf != NULL) {
|
||||
length = recv_buf->tot_len;
|
||||
data_buf_to_free = data_buf;
|
||||
pbuf_copy_partial(recv_buf, data_buf, recv_buf->tot_len, 0);
|
||||
} else {
|
||||
ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to allocate data buf when receiving Thread TREL message");
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
otPlatTrelHandleReceived(esp_openthread_get_instance(), data_buf, length);
|
||||
|
||||
exit:
|
||||
if (data_buf_to_free) {
|
||||
free(data_buf_to_free);
|
||||
}
|
||||
pbuf_free(recv_buf);
|
||||
}
|
||||
|
||||
static void handle_trel_udp_recv(void *ctx, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, uint16_t port)
|
||||
{
|
||||
ESP_LOGD(OT_PLAT_LOG_TAG, "Receive from %s:%d", ip6addr_ntoa(&(addr->u_addr.ip6)), port);
|
||||
if (esp_openthread_task_queue_post(trel_recv_task, p) != ESP_OK) {
|
||||
ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to receive OpenThread TREL message");
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t ot_new_trel(void *ctx)
|
||||
{
|
||||
ot_trel_t *task = (ot_trel_t *)ctx;
|
||||
|
||||
task->trel_pcb = udp_new();
|
||||
ESP_RETURN_ON_FALSE(task->trel_pcb != NULL, ESP_ERR_NO_MEM, OT_PLAT_LOG_TAG, "Failed to create a new UDP pcb");
|
||||
udp_bind(task->trel_pcb, IP6_ADDR_ANY, task->port);
|
||||
udp_recv(task->trel_pcb, handle_trel_udp_recv, NULL);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void otPlatTrelEnable(otInstance *aInstance, uint16_t *aUdpPort)
|
||||
{
|
||||
*aUdpPort = s_ot_trel.port;
|
||||
esp_openthread_task_switching_lock_release();
|
||||
esp_err_t err = esp_netif_tcpip_exec(ot_new_trel, &s_ot_trel);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(OT_PLAT_LOG_TAG, "Fail to create trel udp");
|
||||
}
|
||||
mdns_browse_new(TREL_MDNS_TYPE, TREL_MDNS_PROTO, trel_browse_notifier);
|
||||
esp_openthread_task_switching_lock_acquire(portMAX_DELAY);
|
||||
}
|
||||
|
||||
static void trel_send_task(void *ctx)
|
||||
{
|
||||
err_t err = ERR_OK;
|
||||
struct pbuf *send_buf = NULL;
|
||||
ot_trel_send_task_t *task = (ot_trel_send_task_t *)ctx;
|
||||
|
||||
task->pcb = s_ot_trel.trel_pcb;
|
||||
task->pcb->ttl = UDP_TTL;
|
||||
task->pcb->netif_idx = esp_netif_get_netif_impl_index(s_trel_netif);
|
||||
task->peer_addr.u_addr.ip6.zone = 0;
|
||||
task->peer_addr.type = IPADDR_TYPE_V6;
|
||||
task->pcb->flags = (task->pcb->flags & (~UDP_FLAGS_MULTICAST_LOOP));
|
||||
task->pcb->local_port = s_ot_trel.port;
|
||||
send_buf = pbuf_alloc(PBUF_TRANSPORT, task->length, PBUF_RAM);
|
||||
if (send_buf == NULL) {
|
||||
ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to allocate data buf when sending Thread TREL message");
|
||||
ExitNow();
|
||||
}
|
||||
memcpy(send_buf->payload, task->payload, task->length);
|
||||
err = udp_sendto_if(task->pcb, send_buf, &task->peer_addr, task->peer_port, netif_get_by_index(task->pcb->netif_idx));
|
||||
if(err != ERR_OK) {
|
||||
ESP_LOGE(OT_PLAT_LOG_TAG, "Fail to send trel msg to %s:%d %d (%d)", ip6addr_ntoa(&(task->peer_addr.u_addr.ip6)), task->peer_port, task->pcb->netif_idx, err);
|
||||
}
|
||||
exit:
|
||||
pbuf_free(send_buf);
|
||||
free(task);
|
||||
}
|
||||
|
||||
void otPlatTrelSend(otInstance *aInstance,
|
||||
const uint8_t *aUdpPayload,
|
||||
uint16_t aUdpPayloadLen,
|
||||
const otSockAddr *aDestSockAddr)
|
||||
{
|
||||
if (!s_trel_netif) {
|
||||
ESP_LOGE(OT_PLAT_LOG_TAG, "None Thread TREL interface");
|
||||
return;
|
||||
}
|
||||
ot_trel_send_task_t *task = (ot_trel_send_task_t *)malloc(sizeof(ot_trel_send_task_t));
|
||||
if (task == NULL) {
|
||||
ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to allocate buf for Thread TREL");
|
||||
return;
|
||||
}
|
||||
memcpy(task->peer_addr.u_addr.ip6.addr, aDestSockAddr->mAddress.mFields.m32, OT_IP6_ADDRESS_SIZE);
|
||||
task->peer_port = aDestSockAddr->mPort;
|
||||
ESP_LOGD(OT_PLAT_LOG_TAG, "send trel msg to %s:%d", ip6addr_ntoa(&(task->peer_addr.u_addr.ip6)), task->peer_port);
|
||||
task->payload = aUdpPayload;
|
||||
task->length = aUdpPayloadLen;
|
||||
esp_openthread_task_switching_lock_release();
|
||||
tcpip_callback(trel_send_task, task);
|
||||
esp_openthread_task_switching_lock_acquire(portMAX_DELAY);
|
||||
}
|
||||
|
||||
void otPlatTrelRegisterService(otInstance *aInstance, uint16_t aPort, const uint8_t *aTxtData, uint8_t aTxtLength)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
esp_openthread_task_switching_lock_release();
|
||||
if (s_is_service_registered) {
|
||||
mdns_service_remove(TREL_MDNS_TYPE, TREL_MDNS_PROTO);
|
||||
}
|
||||
mdns_service_add(NULL, TREL_MDNS_TYPE, TREL_MDNS_PROTO, aPort, NULL, 0);
|
||||
s_is_service_registered = true;
|
||||
uint16_t index = 0;
|
||||
while (index < aTxtLength) {
|
||||
const uint8_t *item_header = aTxtData + index + 1;
|
||||
uint8_t item_len = aTxtData[index];
|
||||
|
||||
char key[UINT8_MAX + 1];
|
||||
for (uint16_t i = 0; i < item_len; i++) {
|
||||
if (item_header[i] == '=') {
|
||||
ESP_GOTO_ON_FALSE(i != 0, ESP_FAIL, exit, OT_PLAT_LOG_TAG, "Wrong format of _trel._udp txt key");
|
||||
key[i] = '\0';
|
||||
uint16_t value_len = item_len - i - 1;
|
||||
ESP_GOTO_ON_FALSE(value_len != 0, ESP_FAIL, exit, OT_PLAT_LOG_TAG, "Wrong format of _trel._udp txt value");
|
||||
mdns_service_txt_item_set_with_explicit_value_len(TREL_MDNS_TYPE, TREL_MDNS_PROTO, key, (const char *)item_header + i + 1, value_len);
|
||||
break;
|
||||
}
|
||||
key[i] = item_header[i];
|
||||
}
|
||||
index += item_len + 1;
|
||||
}
|
||||
exit:
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(OT_PLAT_LOG_TAG, "Registered TREL service with some errors");
|
||||
}
|
||||
esp_openthread_task_switching_lock_acquire(portMAX_DELAY);
|
||||
}
|
||||
|
||||
void otPlatTrelResetCounters(otInstance *aInstance)
|
||||
{
|
||||
memset(&s_trel_counters, 0, sizeof(otPlatTrelCounters));
|
||||
}
|
||||
|
||||
static void trel_disable_task(void *ctx)
|
||||
{
|
||||
struct udp_pcb *pcb = (struct udp_pcb *)ctx;
|
||||
udp_remove(pcb);
|
||||
}
|
||||
|
||||
void otPlatTrelDisable(otInstance *aInstance)
|
||||
{
|
||||
esp_openthread_task_switching_lock_release();
|
||||
if (s_ot_trel.trel_pcb) {
|
||||
tcpip_callback(trel_disable_task, s_ot_trel.trel_pcb);
|
||||
}
|
||||
mdns_service_remove(TREL_MDNS_TYPE, TREL_MDNS_PROTO);
|
||||
s_is_service_registered = false;
|
||||
mdns_browse_delete(TREL_MDNS_TYPE, TREL_MDNS_PROTO);
|
||||
esp_openthread_task_switching_lock_acquire(portMAX_DELAY);
|
||||
s_ot_trel.trel_pcb = NULL;
|
||||
}
|
||||
|
||||
const otPlatTrelCounters *otPlatTrelGetCounters(otInstance *aInstance)
|
||||
{
|
||||
return &s_trel_counters;
|
||||
}
|
||||
|
||||
// TODO: TZ-1169
|
||||
OT_TOOL_WEAK otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower)
|
||||
{
|
||||
ESP_LOGD(OT_PLAT_LOG_TAG, "Running in TREL mode and not support `otPlatRadioSetTransmitPower`");
|
||||
return OT_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
|
||||
{
|
||||
ESP_LOGD(OT_PLAT_LOG_TAG, "Running in TREL mode and not support `otPlatRadioGetTransmitPower`");
|
||||
return OT_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK bool otPlatRadioGetPromiscuous(otInstance *aInstance)
|
||||
{
|
||||
ESP_LOGD(OT_PLAT_LOG_TAG, "Running in TREL mode and not support `otPlatRadioGetPromiscuous`");
|
||||
return false;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aThreshold)
|
||||
{
|
||||
ESP_LOGD(OT_PLAT_LOG_TAG, "Running in TREL mode and not support `otPlatRadioSetCcaEnergyDetectThreshold`");
|
||||
return OT_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatRadioGetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t *aThreshold)
|
||||
{
|
||||
ESP_LOGD(OT_PLAT_LOG_TAG, "Running in TREL mode and not support `otPlatRadioGetCcaEnergyDetectThreshold`");
|
||||
return OT_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
|
||||
{
|
||||
ESP_LOGD(OT_PLAT_LOG_TAG, "Running in TREL mode and not support `otPlatRadioGetIeeeEui64`");
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
|
||||
{
|
||||
ESP_LOGD(OT_PLAT_LOG_TAG, "Running in TREL mode and not support `otPlatRadioGetTransmitBuffer`");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if CONFIG_OPENTHREAD_DIAG
|
||||
|
||||
OT_TOOL_WEAK void otPlatDiagSetOutputCallback(otInstance *aInstance, otPlatDiagOutputCallback aCallback, void *aContext)
|
||||
{
|
||||
ESP_LOGD(OT_PLAT_LOG_TAG, "Running in TREL mode and not support `otPlatDiagSetOutputCallback`");
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK void otPlatDiagModeSet(bool mode)
|
||||
{
|
||||
ESP_LOGD(OT_PLAT_LOG_TAG, "Running in TREL mode and not support `otPlatDiagModeSet`");
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK bool otPlatDiagModeGet(void)
|
||||
{
|
||||
ESP_LOGD(OT_PLAT_LOG_TAG, "Running in TREL mode and not support `otPlatDiagModeGet`");
|
||||
return false;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK void otPlatDiagTxPowerSet(int8_t tx_power)
|
||||
{
|
||||
ESP_LOGD(OT_PLAT_LOG_TAG, "Running in TREL mode and not support `otPlatDiagTxPowerSet`");
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK void otPlatDiagChannelSet(uint8_t channel)
|
||||
{
|
||||
ESP_LOGD(OT_PLAT_LOG_TAG, "Running in TREL mode and not support `otPlatDiagChannelSet`");
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK void otPlatDiagAlarmCallback(otInstance *aInstance)
|
||||
{
|
||||
ESP_LOGD(OT_PLAT_LOG_TAG, "Running in TREL mode and not support `otPlatDiagAlarmCallback`");
|
||||
}
|
||||
|
||||
#endif // CONFIG_OPENTHREAD_DIAG
|
||||
|
||||
OT_TOOL_WEAK esp_err_t esp_openthread_radio_init(const esp_openthread_platform_config_t *config)
|
||||
{
|
||||
ESP_LOGI(OT_PLAT_LOG_TAG, "Running in TREL mode");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK void esp_openthread_radio_deinit(void)
|
||||
{
|
||||
ESP_LOGI(OT_PLAT_LOG_TAG, "Running in TREL mode");
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include "esp_spi_spinel_interface.hpp"
|
||||
|
||||
#include "error.h"
|
||||
#include "openthread/error.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_openthread_common_macro.h"
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
Reference in New Issue
Block a user