mirror of
https://github.com/espressif/esp-idf
synced 2025-03-10 09:39:10 -04:00
Merge branch 'backport5.2/openthread_backport' into 'release/v5.2'
some openthread changes backport to release/v5.2 See merge request espressif/esp-idf!28637
This commit is contained in:
commit
dbbe2cf173
@ -182,7 +182,6 @@
|
||||
- "components/esp_phy/lib"
|
||||
- "components/esp_wifi/lib"
|
||||
- "components/esp_coex/lib"
|
||||
- "components/ieee802154/lib"
|
||||
- "components/json/cJSON"
|
||||
- "components/lwip/lwip"
|
||||
- "components/mbedtls/mbedtls"
|
||||
|
4
.gitmodules
vendored
4
.gitmodules
vendored
@ -120,10 +120,6 @@
|
||||
path = components/openthread/lib
|
||||
url = ../../espressif/esp-thread-lib.git
|
||||
|
||||
[submodule "components/ieee802154/lib"]
|
||||
path = components/ieee802154/lib
|
||||
url = ../../espressif/esp-ieee802154-lib.git
|
||||
|
||||
[submodule "components/bt/controller/lib_esp32h2/esp32h2-bt-lib"]
|
||||
path = components/bt/controller/lib_esp32h2/esp32h2-bt-lib
|
||||
url = ../../espressif/esp32h2-bt-lib.git
|
||||
|
@ -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
|
||||
*/
|
||||
@ -95,6 +95,7 @@ typedef enum {
|
||||
} ieee802154_ll_rx_abort_reason_t;
|
||||
|
||||
typedef uint32_t ieee802154_ll_rx_abort_events;
|
||||
#define IEEE802154_RX_ABORT_ALL 0x7fffffff
|
||||
|
||||
/**
|
||||
* @brief IEEE802154 transmission failed reason.
|
||||
@ -118,6 +119,7 @@ typedef enum {
|
||||
} ieee802154_ll_tx_abort_reason_t;
|
||||
|
||||
typedef uint32_t ieee802154_ll_tx_abort_events;
|
||||
#define IEEE802154_TX_ABORT_ALL 0x7fffffff
|
||||
|
||||
/**
|
||||
* @brief IEEE802154 CCA mode.
|
||||
@ -168,6 +170,8 @@ typedef enum {
|
||||
IEEE802154_ED_SAMPLE_AVG = 0x01,
|
||||
} ieee802154_ll_ed_sample_mode_t;
|
||||
|
||||
#define IEEE802154_RX_STATUS_RECEIVE_SFD 0x1
|
||||
|
||||
FORCE_INLINE_ATTR void ieee802154_ll_set_cmd(ieee802154_ll_cmd_t cmd)
|
||||
{
|
||||
IEEE802154.cmd.cmd = cmd;
|
||||
@ -193,6 +197,11 @@ FORCE_INLINE_ATTR ieee802154_ll_events ieee802154_ll_get_events(void)
|
||||
return (ieee802154_ll_events)(IEEE802154.event_status.events);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR bool ieee802154_ll_is_current_rx_frame(void)
|
||||
{
|
||||
return (IEEE802154.rx_status.rx_state > IEEE802154_RX_STATUS_RECEIVE_SFD);
|
||||
}
|
||||
|
||||
static inline void ieee802154_ll_enable_rx_abort_events(ieee802154_ll_rx_abort_events events)
|
||||
{
|
||||
IEEE802154.rx_abort_event_en.rx_abort_en |= events;
|
||||
|
@ -41,14 +41,6 @@ menu "IEEE 802.15.4"
|
||||
configure the CCA mode to Carrier sense AND energy above threshold
|
||||
endchoice
|
||||
|
||||
config IEEE802154_RECEIVE_DONE_HANDLER
|
||||
bool "Enable the receive done handler feature"
|
||||
default n
|
||||
help
|
||||
configure the receive done handler feature, when enabled, the user must call the
|
||||
function `esp_ieee802154_receive_handle_done` to inform the 802.15.4 driver that
|
||||
the received frame has been processed, so the frame space could be freed.
|
||||
|
||||
config IEEE802154_CCA_MODE
|
||||
depends on IEEE802154_ENABLED
|
||||
int
|
||||
|
@ -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
|
||||
*/
|
||||
@ -289,6 +289,11 @@ void ieee802154_tx_nums_update(void)
|
||||
s_ieee802154_txrx_statistic.tx.nums++;
|
||||
}
|
||||
|
||||
void ieee802154_tx_deferred_nums_update(void)
|
||||
{
|
||||
s_ieee802154_txrx_statistic.tx.deferred_nums++;
|
||||
}
|
||||
|
||||
void ieee802154_tx_break_coex_nums_update(void)
|
||||
{
|
||||
s_ieee802154_txrx_statistic.tx.abort.tx_coex_break_nums++;
|
||||
@ -302,9 +307,15 @@ void ieee802154_txrx_statistic_print(void)
|
||||
s_ieee802154_txrx_statistic.tx.abort.cca_failed_nums + s_ieee802154_txrx_statistic.tx.abort.cca_busy_nums;
|
||||
|
||||
uint64_t tx_nums = s_ieee802154_txrx_statistic.tx.nums;
|
||||
uint64_t tx_direct_num = tx_nums - s_ieee802154_txrx_statistic.tx.deferred_nums;
|
||||
|
||||
float tx_success_ratio = (tx_nums > 0 ? ((float)tx_success_nums / tx_nums) : 0);
|
||||
float tx_done_ratio = (tx_nums > 0 ? ((float)s_ieee802154_txrx_statistic.tx.done_nums / tx_nums) : 0);
|
||||
float tx_abort_ratio = (tx_nums > 0 ? ((float)tx_abort_nums / tx_nums) : 0);
|
||||
|
||||
float tx_direct_num_ratio = (tx_nums > 0 ? ((float)tx_direct_num / tx_nums) : 0);
|
||||
float tx_deferred_num_ratio = (tx_nums > 0 ? ((float)s_ieee802154_txrx_statistic.tx.deferred_nums / tx_nums) : 0);
|
||||
|
||||
float tx_abort_rx_ack_coex_break_ratio = (tx_nums > 0 ? ((float)s_ieee802154_txrx_statistic.tx.abort.rx_ack_coex_break_nums / tx_nums) : 0);
|
||||
float tx_abort_rx_ack_timeout_ratio = (tx_nums > 0 ? ((float)s_ieee802154_txrx_statistic.tx.abort.rx_ack_timeout_nums / tx_nums) : 0);
|
||||
float tx_abort_tx_coex_break_ratio = (tx_nums > 0 ? ((float)s_ieee802154_txrx_statistic.tx.abort.tx_coex_break_nums / tx_nums) : 0);
|
||||
@ -321,6 +332,10 @@ void ieee802154_txrx_statistic_print(void)
|
||||
|
||||
ESP_LOGW(TAG, "+--------------------+-----------------------------------+--------------------------------------------------+");
|
||||
ESP_LOGW(TAG, "|%-20s|%-10s%-15llu%9.2f%%|%-25s%-15llu%9.2f%%|", "", "Done:", s_ieee802154_txrx_statistic.tx.done_nums, tx_done_ratio*100, "Success:", tx_success_nums, tx_success_ratio*100);
|
||||
ESP_LOGW(TAG, "+ + +--------------------------------------------------+");
|
||||
ESP_LOGW(TAG, "|%-20s|%-35s|%-25s%-15llu%9.2f%%|", "", "", "tx_direct_num:", tx_direct_num, tx_direct_num_ratio*100);
|
||||
ESP_LOGW(TAG, "+ + +--------------------------------------------------+");
|
||||
ESP_LOGW(TAG, "|%-20s|%-35s|%-25s%-15llu%9.2f%%|", "", "", "tx_deferred_num:", s_ieee802154_txrx_statistic.tx.deferred_nums, tx_deferred_num_ratio*100);
|
||||
ESP_LOGW(TAG, "+ +-----------------------------------+--------------------------------------------------+");
|
||||
ESP_LOGW(TAG, "|%-20s|%-35s|%-25s%-15llu%9.2f%%|", "", "", "rx_ack_coex_break:", s_ieee802154_txrx_statistic.tx.abort.rx_ack_coex_break_nums, tx_abort_rx_ack_coex_break_ratio*100);
|
||||
ESP_LOGW(TAG, "+ + +--------------------------------------------------+");
|
||||
|
@ -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
|
||||
*/
|
||||
@ -47,7 +47,6 @@ IEEE802154_STATIC volatile ieee802154_state_t s_ieee802154_state;
|
||||
static uint8_t *s_tx_frame = NULL;
|
||||
#define IEEE802154_RX_FRAME_SIZE (127 + 1 + 1) // +1: len, +1: for dma test
|
||||
|
||||
#if CONFIG_IEEE802154_RECEIVE_DONE_HANDLER
|
||||
// +1: for the stub buffer when the valid buffers are full.
|
||||
//
|
||||
// |--------------------VB[0]--------------------|
|
||||
@ -62,10 +61,6 @@ static uint8_t *s_tx_frame = NULL;
|
||||
// STUB : Stub buffer, used when all valid buffers are under processing, the received frame will be dropped.
|
||||
static uint8_t s_rx_frame[CONFIG_IEEE802154_RX_BUFFER_SIZE + 1][IEEE802154_RX_FRAME_SIZE];
|
||||
static esp_ieee802154_frame_info_t s_rx_frame_info[CONFIG_IEEE802154_RX_BUFFER_SIZE + 1];
|
||||
#else
|
||||
static uint8_t s_rx_frame[CONFIG_IEEE802154_RX_BUFFER_SIZE][IEEE802154_RX_FRAME_SIZE];
|
||||
static esp_ieee802154_frame_info_t s_rx_frame_info[CONFIG_IEEE802154_RX_BUFFER_SIZE];
|
||||
#endif
|
||||
|
||||
static uint8_t s_rx_index = 0;
|
||||
static uint8_t s_enh_ack_frame[128];
|
||||
@ -75,8 +70,16 @@ static intr_handle_t s_ieee802154_isr_handle = NULL;
|
||||
|
||||
static esp_err_t ieee802154_sleep_init(void);
|
||||
static void next_operation(void);
|
||||
static esp_err_t ieee802154_transmit_internal(const uint8_t *frame, bool cca);
|
||||
|
||||
#if !CONFIG_IEEE802154_TEST
|
||||
typedef struct {
|
||||
const uint8_t *frame;
|
||||
bool cca;
|
||||
} pending_tx_t;
|
||||
static pending_tx_t s_pending_tx = { 0 };
|
||||
#endif
|
||||
|
||||
#if CONFIG_IEEE802154_RECEIVE_DONE_HANDLER
|
||||
static void ieee802154_receive_done(uint8_t *data, esp_ieee802154_frame_info_t *frame_info)
|
||||
{
|
||||
// If the RX done packet is written in the stub buffer, drop it silently.
|
||||
@ -104,7 +107,7 @@ static void ieee802154_transmit_done(const uint8_t *frame, const uint8_t *ack, e
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t ieee802154_receive_handle_done(uint8_t *data)
|
||||
esp_err_t ieee802154_receive_handle_done(const uint8_t *data)
|
||||
{
|
||||
uint16_t size = data - &s_rx_frame[0][0];
|
||||
if ((size % IEEE802154_RX_FRAME_SIZE) != 0
|
||||
@ -114,18 +117,6 @@ esp_err_t ieee802154_receive_handle_done(uint8_t *data)
|
||||
s_rx_frame_info[size / IEEE802154_RX_FRAME_SIZE].process = false;
|
||||
return ESP_OK;
|
||||
}
|
||||
#else
|
||||
static void ieee802154_receive_done(uint8_t *data, esp_ieee802154_frame_info_t *frame_info)
|
||||
{
|
||||
esp_ieee802154_receive_done(data, frame_info);
|
||||
}
|
||||
|
||||
static void ieee802154_transmit_done(const uint8_t *frame, const uint8_t *ack, esp_ieee802154_frame_info_t *ack_frame_info)
|
||||
{
|
||||
esp_ieee802154_transmit_done(frame, ack, ack_frame_info);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static IRAM_ATTR void event_end_process(void)
|
||||
{
|
||||
@ -170,8 +161,8 @@ uint8_t ieee802154_get_recent_lqi(void)
|
||||
IEEE802154_STATIC void set_next_rx_buffer(void)
|
||||
{
|
||||
uint8_t* next_rx_buffer = NULL;
|
||||
#if CONFIG_IEEE802154_RECEIVE_DONE_HANDLER
|
||||
uint8_t index = 0;
|
||||
|
||||
if (s_rx_index != CONFIG_IEEE802154_RX_BUFFER_SIZE && s_rx_frame_info[s_rx_index].process == false) {
|
||||
// If buffer is not full, and current index is empty, set it to hardware.
|
||||
next_rx_buffer = s_rx_frame[s_rx_index];
|
||||
@ -195,16 +186,7 @@ IEEE802154_STATIC void set_next_rx_buffer(void)
|
||||
s_rx_index = CONFIG_IEEE802154_RX_BUFFER_SIZE;
|
||||
next_rx_buffer = s_rx_frame[CONFIG_IEEE802154_RX_BUFFER_SIZE];
|
||||
}
|
||||
#else
|
||||
if (s_rx_frame[s_rx_index][0] != 0) {
|
||||
s_rx_index++;
|
||||
if (s_rx_index == CONFIG_IEEE802154_RX_BUFFER_SIZE) {
|
||||
s_rx_index = 0;
|
||||
memset(s_rx_frame[s_rx_index], 0, sizeof(s_rx_frame[s_rx_index]));
|
||||
}
|
||||
}
|
||||
next_rx_buffer = (uint8_t *)&s_rx_frame[s_rx_index];
|
||||
#endif
|
||||
|
||||
ieee802154_ll_set_rx_addr(next_rx_buffer);
|
||||
}
|
||||
|
||||
@ -367,10 +349,21 @@ static void enable_rx(void)
|
||||
|
||||
static IRAM_ATTR void next_operation(void)
|
||||
{
|
||||
if (ieee802154_pib_get_rx_when_idle()) {
|
||||
enable_rx();
|
||||
} else {
|
||||
ieee802154_set_state(IEEE802154_STATE_IDLE);
|
||||
#if !CONFIG_IEEE802154_TEST
|
||||
if (s_pending_tx.frame) {
|
||||
// Here the driver needs to recover the setting of rx aborts, see function `ieee802154_transmit`.
|
||||
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_transmit_internal(s_pending_tx.frame, s_pending_tx.cca);
|
||||
s_pending_tx.frame = NULL;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (ieee802154_pib_get_rx_when_idle()) {
|
||||
enable_rx();
|
||||
} else {
|
||||
ieee802154_set_state(IEEE802154_STATE_IDLE);
|
||||
ieee802154_sleep();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -491,25 +484,24 @@ static IRAM_ATTR void isr_handle_rx_abort(void)
|
||||
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX);
|
||||
#if CONFIG_IEEE802154_TEST
|
||||
esp_ieee802154_receive_failed(rx_status);
|
||||
next_operation();
|
||||
#endif
|
||||
break;
|
||||
case IEEE802154_RX_ABORT_BY_COEX_BREAK:
|
||||
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX);
|
||||
#if CONFIG_IEEE802154_TEST
|
||||
esp_ieee802154_receive_failed(rx_status);
|
||||
#endif
|
||||
break;
|
||||
case IEEE802154_RX_ABORT_BY_ED_ABORT:
|
||||
case IEEE802154_RX_ABORT_BY_ED_COEX_REJECT:
|
||||
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_ED || s_ieee802154_state == IEEE802154_STATE_CCA);
|
||||
esp_ieee802154_ed_failed(rx_status);
|
||||
next_operation();
|
||||
break;
|
||||
case IEEE802154_RX_ABORT_BY_TX_ACK_TIMEOUT:
|
||||
case IEEE802154_RX_ABORT_BY_TX_ACK_COEX_BREAK:
|
||||
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX_ACK || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK);
|
||||
#if !CONFIG_IEEE802154_TEST
|
||||
ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]);
|
||||
next_operation();
|
||||
#else
|
||||
esp_ieee802154_receive_failed(rx_status);
|
||||
#endif
|
||||
@ -518,7 +510,6 @@ static IRAM_ATTR void isr_handle_rx_abort(void)
|
||||
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK);
|
||||
#if !CONFIG_IEEE802154_TEST
|
||||
ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]);
|
||||
next_operation();
|
||||
#else
|
||||
esp_ieee802154_receive_failed(rx_status);
|
||||
#endif
|
||||
@ -526,6 +517,7 @@ static IRAM_ATTR void isr_handle_rx_abort(void)
|
||||
default:
|
||||
IEEE802154_ASSERT(false);
|
||||
}
|
||||
next_operation();
|
||||
}
|
||||
|
||||
static IRAM_ATTR void isr_handle_tx_abort(void)
|
||||
@ -802,7 +794,7 @@ IEEE802154_STATIC void tx_init(const uint8_t *frame)
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t ieee802154_transmit(const uint8_t *frame, bool cca)
|
||||
static inline esp_err_t ieee802154_transmit_internal(const uint8_t *frame, bool cca)
|
||||
{
|
||||
IEEE802154_RF_ENABLE();
|
||||
ieee802154_enter_critical();
|
||||
@ -819,10 +811,32 @@ esp_err_t ieee802154_transmit(const uint8_t *frame, bool cca)
|
||||
}
|
||||
|
||||
ieee802154_exit_critical();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t ieee802154_transmit(const uint8_t *frame, bool cca)
|
||||
{
|
||||
#if !CONFIG_IEEE802154_TEST
|
||||
ieee802154_enter_critical();
|
||||
if ((s_ieee802154_state == IEEE802154_STATE_RX && ieee802154_ll_is_current_rx_frame())
|
||||
|| s_ieee802154_state == IEEE802154_STATE_TX_ACK || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK) {
|
||||
// If the current radio is processing an RX frame or sending an ACK, do not shut down the ongoing process.
|
||||
// Instead, defer the transmission of the pending TX frame.
|
||||
// Once the current process is completed, the pending transmit frame will be initiated.
|
||||
s_pending_tx.frame = frame;
|
||||
s_pending_tx.cca = cca;
|
||||
IEEE802154_TX_DEFERRED_NUMS_UPDATE();
|
||||
// Here we enable all rx interrupts due to the driver needs to know when the current RX has finished.
|
||||
// Will recover the setting of rx abort in function `next_operation`.
|
||||
ieee802154_ll_enable_rx_abort_events(IEEE802154_RX_ABORT_ALL);
|
||||
ieee802154_exit_critical();
|
||||
return ESP_OK;
|
||||
}
|
||||
ieee802154_exit_critical();
|
||||
#endif
|
||||
return ieee802154_transmit_internal(frame, cca);
|
||||
}
|
||||
|
||||
static inline bool is_target_time_expired(uint32_t target, uint32_t now)
|
||||
{
|
||||
return (((now - target) & (1 << 31)) == 0);
|
||||
|
@ -338,12 +338,10 @@ uint8_t esp_ieee802154_get_recent_lqi(void)
|
||||
return ieee802154_get_recent_lqi();
|
||||
}
|
||||
|
||||
#if CONFIG_IEEE802154_RECEIVE_DONE_HANDLER
|
||||
esp_err_t esp_ieee802154_receive_handle_done(uint8_t *frame)
|
||||
esp_err_t esp_ieee802154_receive_handle_done(const uint8_t *frame)
|
||||
{
|
||||
return ieee802154_receive_handle_done(frame);
|
||||
}
|
||||
#endif
|
||||
|
||||
__attribute__((weak)) void esp_ieee802154_receive_done(uint8_t *data, esp_ieee802154_frame_info_t *frame_info)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -115,18 +115,20 @@ esp_err_t esp_ieee802154_sleep(void);
|
||||
/**
|
||||
* @brief Set the IEEE 802.15.4 Radio to receive state.
|
||||
*
|
||||
* @note Radio will continue receiving until it receives a valid frame.
|
||||
* Refer to `esp_ieee802154_receive_done()`.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failure due to invalid state.
|
||||
*
|
||||
* Note: Radio will continue receiving until it receives a valid frame.
|
||||
* Ref to esp_ieee802154_receive_done().
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ieee802154_receive(void);
|
||||
|
||||
/**
|
||||
* @brief Transmit the given frame.
|
||||
* The transmit result will be reported via `esp_ieee802154_transmit_done()`
|
||||
* or `esp_ieee802154_transmit_failed()`.
|
||||
*
|
||||
* @param[in] frame The pointer to the frame, the frame format:
|
||||
* |-----------------------------------------------------------------------|
|
||||
@ -138,9 +140,6 @@ esp_err_t esp_ieee802154_receive(void);
|
||||
* - ESP_OK on success.
|
||||
* - ESP_FAIL on failure due to invalid state.
|
||||
*
|
||||
* Note: The transmit result will be reported via esp_ieee802154_transmit_done()
|
||||
* or esp_ieee802154_transmit_failed().
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ieee802154_transmit(const uint8_t *frame, bool cca);
|
||||
|
||||
@ -453,35 +452,31 @@ bool esp_ieee802154_get_rx_when_idle(void);
|
||||
*/
|
||||
esp_err_t esp_ieee802154_energy_detect(uint32_t duration);
|
||||
|
||||
#if CONFIG_IEEE802154_RECEIVE_DONE_HANDLER
|
||||
/**
|
||||
* @brief Notify the IEEE 802.15.4 Radio that the frame is handled done by upper layer.
|
||||
*
|
||||
* @param[in] frame The pointer to the frame which was passed from the function esp_ieee802154_receive_done.
|
||||
* or ack frame from esp_ieee802154_transmit_done.
|
||||
* @param[in] frame The pointer to the frame which was passed from the function `esp_ieee802154_receive_done()`
|
||||
* or ack frame from `esp_ieee802154_transmit_done()`.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL if frame is invalid.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ieee802154_receive_handle_done(uint8_t *frame);
|
||||
#endif
|
||||
esp_err_t esp_ieee802154_receive_handle_done(const uint8_t *frame);
|
||||
|
||||
/** Below are the events generated by IEEE 802.15.4 subsystem, which are in ISR context **/
|
||||
/**
|
||||
* @brief A Frame was received.
|
||||
*
|
||||
* @note User must call the function `esp_ieee802154_receive_handle_done()` to notify 802.15.4 driver after the received frame is handled.
|
||||
*
|
||||
* @param[in] frame The point to the received frame, frame format:
|
||||
* |-----------------------------------------------------------------------|
|
||||
* | Len | MHR | MAC Payload (no FCS) |
|
||||
* |-----------------------------------------------------------------------|
|
||||
* @param[in] frame_info More information of the received frame, refer to esp_ieee802154_frame_info_t.
|
||||
*
|
||||
* Note: If configuration `IEEE802154_RECEIVE_DONE_HANDLER` is enabled, then the user must call the function
|
||||
* `esp_ieee802154_receive_handle_done()` to inform 802.15.4 driver that the received frame is handled.
|
||||
* See `esp_ieee802154_receive_handle_done()` for more informations.
|
||||
*
|
||||
*/
|
||||
extern void esp_ieee802154_receive_done(uint8_t *frame, esp_ieee802154_frame_info_t *frame_info);
|
||||
|
||||
@ -494,27 +489,22 @@ extern void esp_ieee802154_receive_sfd_done(void);
|
||||
/**
|
||||
* @brief The Frame Transmission succeeded.
|
||||
*
|
||||
* @note If the ack frame is not null, user must call the function `esp_ieee802154_receive_handle_done()` to notify 802.15.4 driver
|
||||
* after the ack frame is handled.
|
||||
*
|
||||
* @param[in] frame The pointer to the transmitted frame.
|
||||
* @param[in] ack The received ACK frame, it could be NULL if the transmitted frame's AR bit is not set.
|
||||
* @param[in] ack_frame_info More information of the ACK frame, refer to esp_ieee802154_frame_info_t.
|
||||
*
|
||||
* Note: refer to esp_ieee802154_transmit().
|
||||
*
|
||||
* If configuration `IEEE802154_RECEIVE_DONE_HANDLER` is enabled and ack frame is not null, then after the upper layer has processed the frame,
|
||||
* the user must call the function `esp_ieee802154_receive_handle_done()` to inform 802.15.4 driver that the ack frame is handled.
|
||||
* See `esp_ieee802154_receive_handle_done()` for more informations.
|
||||
*
|
||||
*/
|
||||
extern void esp_ieee802154_transmit_done(const uint8_t *frame, const uint8_t *ack, esp_ieee802154_frame_info_t *ack_frame_info);
|
||||
|
||||
/**
|
||||
* @brief The Frame Transmission failed.
|
||||
* @brief The Frame Transmission failed. Refer to `esp_ieee802154_transmit()`.
|
||||
*
|
||||
* @param[in] frame The pointer to the frame.
|
||||
* @param[in] error The transmission failure reason, refer to esp_ieee802154_tx_error_t.
|
||||
*
|
||||
* Note: refer to esp_ieee802154_transmit().
|
||||
*
|
||||
*/
|
||||
extern void esp_ieee802154_transmit_failed(const uint8_t *frame, esp_ieee802154_tx_error_t error);
|
||||
|
||||
@ -525,32 +515,31 @@ extern void esp_ieee802154_transmit_failed(const uint8_t *frame, esp_ieee802154_
|
||||
extern void esp_ieee802154_transmit_sfd_done(uint8_t *frame);
|
||||
|
||||
/**
|
||||
* @brief The energy detection done.
|
||||
* @brief The energy detection done. Refer to `esp_ieee802154_energy_detect()`.
|
||||
*
|
||||
* @param[in] power The detected power level, in dBm.
|
||||
*
|
||||
* Note: refer to esp_ieee802154_energy_detect().
|
||||
*
|
||||
*/
|
||||
extern void esp_ieee802154_energy_detect_done(int8_t power);
|
||||
|
||||
/**
|
||||
* @brief Set the IEEE 802.15.4 Radio to receive state at a specific time.
|
||||
*
|
||||
* @note Radio will start receiving after the timestamp, and continue receiving until it receives a valid frame.
|
||||
* Refer to `esp_ieee802154_receive_done()`.
|
||||
*
|
||||
* @param[in] time A specific timestamp for starting receiving.
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failure due to invalid state.
|
||||
*
|
||||
* Note: Radio will start receiving after the timestamp, and continue receiving until it receives a valid frame.
|
||||
* Ref to esp_ieee802154_receive_done().
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ieee802154_receive_at(uint32_t time);
|
||||
|
||||
/**
|
||||
* @brief Transmit the given frame at a specific time.
|
||||
* The transmit result will be reported via `esp_ieee802154_transmit_done()`
|
||||
* or `esp_ieee802154_transmit_failed()`.
|
||||
*
|
||||
* @param[in] frame The pointer to the frame. Refer to `esp_ieee802154_transmit()`.
|
||||
* @param[in] cca Perform CCA before transmission if it's true, otherwise transmit the frame directly.
|
||||
@ -560,9 +549,6 @@ esp_err_t esp_ieee802154_receive_at(uint32_t time);
|
||||
* - ESP_OK on success.
|
||||
* - ESP_FAIL on failure due to invalid state.
|
||||
*
|
||||
* Note: The transmit result will be reported via esp_ieee802154_transmit_done()
|
||||
* or esp_ieee802154_transmit_failed().
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ieee802154_transmit_at(const uint8_t *frame, bool cca, uint32_t time);
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
Subproject commit 102b03c8095de8a337c293f79dce189be63186f3
|
@ -22,6 +22,10 @@ entries:
|
||||
esp_ieee802154_timer: ieee802154_timer0_stop (noflash)
|
||||
esp_ieee802154_timer: ieee802154_timer1_stop (noflash)
|
||||
esp_ieee802154_util: ieee802154_etm_channel_clear (noflash)
|
||||
|
||||
if IEEE802154_DEBUG = y:
|
||||
esp_ieee802154_debug (noflash)
|
||||
|
||||
if IEEE802154_TIMING_OPTIMIZATION = y:
|
||||
esp_ieee802154_dev: set_next_rx_buffer (noflash)
|
||||
esp_ieee802154_dev: stop_rx (noflash)
|
||||
|
@ -110,7 +110,6 @@ esp_err_t ieee802154_transmit(const uint8_t *frame, bool cca);
|
||||
*/
|
||||
esp_err_t ieee802154_receive(void);
|
||||
|
||||
#if CONFIG_IEEE802154_RECEIVE_DONE_HANDLER
|
||||
/**
|
||||
* @brief Notify the IEEE 802.15.4 Radio that the frame is handled done by upper layer.
|
||||
*
|
||||
@ -122,8 +121,7 @@ esp_err_t ieee802154_receive(void);
|
||||
* - ESP_FAIL if frame is invalid.
|
||||
*
|
||||
*/
|
||||
esp_err_t ieee802154_receive_handle_done(uint8_t* frame);
|
||||
#endif
|
||||
esp_err_t ieee802154_receive_handle_done(const uint8_t* frame);
|
||||
|
||||
/**
|
||||
* @brief Transmit the given frame at a specific time.
|
||||
|
@ -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
|
||||
*/
|
||||
@ -185,6 +185,7 @@ void ieee802154_assert_print(void);
|
||||
typedef struct ieee802154_txrx_statistic{
|
||||
struct {
|
||||
uint64_t nums;
|
||||
uint64_t deferred_nums;
|
||||
uint64_t done_nums;
|
||||
struct {
|
||||
uint64_t rx_ack_coex_break_nums; // IEEE802154_RX_ACK_ABORT_COEX_CNT_REG
|
||||
@ -218,6 +219,10 @@ typedef struct ieee802154_txrx_statistic{
|
||||
ieee802154_txrx_statistic(a);\
|
||||
} while(0)
|
||||
|
||||
#define IEEE802154_TX_DEFERRED_NUMS_UPDATE() do { \
|
||||
ieee802154_tx_deferred_nums_update();\
|
||||
} while(0)
|
||||
|
||||
#define IEEE802154_TX_NUMS_UPDATE() do { \
|
||||
ieee802154_tx_nums_update();\
|
||||
} while(0)
|
||||
@ -230,10 +235,12 @@ void ieee802154_txrx_statistic_clear(void);
|
||||
void ieee802154_txrx_statistic_print(void);
|
||||
void ieee802154_txrx_statistic(ieee802154_ll_events events);
|
||||
void ieee802154_tx_nums_update(void);
|
||||
void ieee802154_tx_deferred_nums_update(void);
|
||||
void ieee802154_tx_break_coex_nums_update(void);
|
||||
#else
|
||||
#define IEEE802154_TXRX_STATISTIC(a)
|
||||
#define IEEE802154_TX_NUMS_UPDATE()
|
||||
#define IEEE802154_TX_DEFERRED_NUMS_UPDATE()
|
||||
#define IEEE802154_TXRX_STATISTIC_CLEAR()
|
||||
#define IEEE802154_TX_BREAK_COEX_NUMS_UPDATE()
|
||||
#endif // CONFIG_IEEE802154_TXRX_STATISTIC
|
||||
|
@ -875,6 +875,7 @@ void esp_ieee802154_transmit_done(const uint8_t *frame, const uint8_t *ack, esp_
|
||||
ack[idx], ack[idx+1], ack[idx+2], ack[idx+3],
|
||||
ack[idx+4], ack[idx+5], ack[idx+6], ack[idx+7]);
|
||||
}
|
||||
esp_ieee802154_receive_handle_done(ack);
|
||||
}
|
||||
}
|
||||
|
||||
@ -886,6 +887,7 @@ void esp_ieee802154_receive_done(uint8_t *frame, esp_ieee802154_frame_info_t *fr
|
||||
frame[idx], frame[idx+1], frame[idx+2], frame[idx+3],
|
||||
frame[idx+4], frame[idx+5], frame[idx+6], frame[idx+7]);
|
||||
}
|
||||
esp_ieee802154_receive_handle_done(frame);
|
||||
}
|
||||
|
||||
void esp_ieee802154_energy_detect_done(int8_t power)
|
||||
|
@ -4,7 +4,7 @@ if(${idf_target} STREQUAL "linux")
|
||||
return() # This component is not supported by the POSIX/Linux simulator
|
||||
endif()
|
||||
|
||||
if(CONFIG_OPENTHREAD_ENABLED OR CONFIG_IDF_DOC_BUILD)
|
||||
if(CONFIG_OPENTHREAD_ENABLED OR CONFIG_IDF_DOC_BUILD OR CONFIG_OPENTHREAD_SPINEL_ONLY)
|
||||
|
||||
set(public_include_dirs
|
||||
"include"
|
||||
@ -149,6 +149,11 @@ if(CONFIG_OPENTHREAD_ENABLED)
|
||||
-Wno-maybe-uninitialized)
|
||||
endif()
|
||||
|
||||
if(CONFIG_OPENTHREAD_NCP_VENDOR_HOOK)
|
||||
list(APPEND src_dirs
|
||||
"src/ncp")
|
||||
endif()
|
||||
|
||||
if(NOT CONFIG_OPENTHREAD_DNS64_CLIENT)
|
||||
list(APPEND exclude_srcs
|
||||
"src/esp_openthread_dns64.c")
|
||||
@ -171,6 +176,48 @@ if(CONFIG_OPENTHREAD_ENABLED)
|
||||
elseif(CONFIG_OPENTHREAD_RADIO)
|
||||
set(device_type "OPENTHREAD_RADIO=1")
|
||||
endif()
|
||||
elseif(CONFIG_OPENTHREAD_SPINEL_ONLY)
|
||||
|
||||
set(src_dirs
|
||||
"src/spinel"
|
||||
"src/port"
|
||||
"openthread/src/lib/spinel"
|
||||
"openthread/src/lib/hdlc"
|
||||
"openthread/src/lib/platform"
|
||||
"openthread/src/core/api"
|
||||
"openthread/src/core/common"
|
||||
"openthread/src/core/mac")
|
||||
|
||||
set(private_include_dirs
|
||||
"private_include"
|
||||
"openthread/src"
|
||||
"openthread/src/core"
|
||||
"openthread/src/lib"
|
||||
"openthread/src/lib/hdlc"
|
||||
"openthread/src/lib/spinel")
|
||||
|
||||
file(GLOB_RECURSE exclude_srcs_list
|
||||
"src/port/*"
|
||||
"openthread/src/core/api/*.cpp"
|
||||
"openthread/src/core/common/*"
|
||||
"openthread/src/core/mac/*")
|
||||
|
||||
list(REMOVE_ITEM exclude_srcs_list
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/port/esp_openthread_alarm.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/port/esp_openthread_logging.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/openthread/src/core/api/error_api.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/openthread/src/core/api/logging_api.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/openthread/src/core/common/error.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/openthread/src/core/common/error.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/openthread/src/core/common/log.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/openthread/src/core/common/log.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/openthread/src/core/common/logging.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/openthread/src/core/common/string.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/openthread/src/core/common/string.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/openthread/src/core/mac/mac_frame.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/openthread/src/core/mac/mac_frame.hpp")
|
||||
|
||||
list(APPEND exclude_srcs ${exclude_srcs_list})
|
||||
|
||||
endif()
|
||||
|
||||
@ -201,13 +248,15 @@ idf_component_register(SRC_DIRS "${src_dirs}"
|
||||
PRIV_REQUIRES console esp_event esp_partition esp_timer
|
||||
ieee802154 mbedtls nvs_flash)
|
||||
|
||||
if(CONFIG_OPENTHREAD_ENABLED)
|
||||
if(CONFIG_OPENTHREAD_ENABLED OR CONFIG_OPENTHREAD_SPINEL_ONLY)
|
||||
if(CONFIG_OPENTHREAD_RADIO)
|
||||
set(CONFIG_FILE_TYPE "radio")
|
||||
elseif(CONFIG_OPENTHREAD_FTD)
|
||||
set(CONFIG_FILE_TYPE "ftd")
|
||||
elseif(CONFIG_OPENTHREAD_MTD)
|
||||
set(CONFIG_FILE_TYPE "mtd")
|
||||
elseif(CONFIG_OPENTHREAD_SPINEL_ONLY)
|
||||
set(CONFIG_FILE_TYPE "spinel")
|
||||
endif()
|
||||
|
||||
target_compile_definitions(
|
||||
|
@ -114,6 +114,7 @@ menu "OpenThread"
|
||||
Select this to use the native 15.4 radio.
|
||||
|
||||
config OPENTHREAD_RADIO_SPINEL_UART
|
||||
select UART_ISR_IN_IRAM
|
||||
bool "Connect via UART"
|
||||
help
|
||||
Select this to connect to a Radio Co-Processor via UART.
|
||||
@ -157,6 +158,7 @@ menu "OpenThread"
|
||||
default OPENTHREAD_RCP_UART
|
||||
|
||||
config OPENTHREAD_RCP_UART
|
||||
select UART_ISR_IN_IRAM
|
||||
bool "UART RCP"
|
||||
help
|
||||
Select this to enable UART connection to host.
|
||||
@ -168,6 +170,13 @@ menu "OpenThread"
|
||||
Select this to enable SPI connection to host.
|
||||
endchoice
|
||||
|
||||
config OPENTHREAD_NCP_VENDOR_HOOK
|
||||
bool "Enable vendor command for RCP"
|
||||
depends on OPENTHREAD_RADIO
|
||||
default n
|
||||
help
|
||||
Select this to enable OpenThread NCP vendor commands.
|
||||
|
||||
config OPENTHREAD_CLI
|
||||
bool "Enable Openthread Command-Line Interface"
|
||||
depends on OPENTHREAD_ENABLED
|
||||
@ -253,7 +262,7 @@ menu "OpenThread"
|
||||
|
||||
config OPENTHREAD_SPINEL_RX_FRAME_BUFFER_SIZE
|
||||
int "The size of openthread spinel rx frame buffer"
|
||||
depends on OPENTHREAD_ENABLED
|
||||
depends on OPENTHREAD_ENABLED || OPENTHREAD_SPINEL_ONLY
|
||||
default 1024
|
||||
range 512 8192
|
||||
|
||||
@ -286,7 +295,7 @@ menu "OpenThread"
|
||||
config OPENTHREAD_UART_BUFFER_SIZE
|
||||
int "The uart received buffer size of openthread"
|
||||
depends on OPENTHREAD_ENABLED
|
||||
default 256
|
||||
default 768
|
||||
range 128 1024
|
||||
help
|
||||
Set the OpenThread UART buffer size.
|
||||
@ -362,4 +371,38 @@ menu "OpenThread"
|
||||
Select this option to enable the radio statistics feature, you can use radio command to print some radio
|
||||
Statistics informations.
|
||||
|
||||
config OPENTHREAD_SPINEL_ONLY
|
||||
bool "Enable OpenThread External Radio Spinel feature"
|
||||
default n
|
||||
help
|
||||
Select this option to enable the OpenThread Radio Spinel for external protocol stack, such as Zigbee.
|
||||
|
||||
config OPENTHREAD_RX_ON_WHEN_IDLE
|
||||
bool "Enable OpenThread radio capibility rx on when idle"
|
||||
default y if !ESP_COEX_SW_COEXIST_ENABLE
|
||||
default n if ESP_COEX_SW_COEXIST_ENABLE
|
||||
help
|
||||
Select this option to enable OpenThread radio capibility rx on when idle. Do not support this feature when
|
||||
SW coexistence is enabled.
|
||||
|
||||
menu "Thread Address Query Config"
|
||||
config OPENTHREAD_ADDRESS_QUERY_TIMEOUT
|
||||
int "Timeout value (in seconds) for a address notification response after sending an address query."
|
||||
depends on OPENTHREAD_FTD || OPENTHREAD_MTD
|
||||
default 3
|
||||
range 1 10
|
||||
|
||||
config OPENTHREAD_ADDRESS_QUERY_RETRY_DELAY
|
||||
int "Initial retry delay for address query (in seconds)."
|
||||
depends on OPENTHREAD_FTD || OPENTHREAD_MTD
|
||||
default 15
|
||||
range 1 120
|
||||
|
||||
config OPENTHREAD_ADDRESS_QUERY_MAX_RETRY_DELAY
|
||||
int "Maximum retry delay for address query (in seconds)."
|
||||
depends on OPENTHREAD_FTD || OPENTHREAD_MTD
|
||||
default 120
|
||||
range OPENTHREAD_ADDRESS_QUERY_RETRY_DELAY 960
|
||||
endmenu
|
||||
|
||||
endmenu
|
||||
|
395
components/openthread/include/esp_radio_spinel.h
Normal file
395
components/openthread/include/esp_radio_spinel.h
Normal file
@ -0,0 +1,395 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/select.h>
|
||||
#include "esp_ieee802154_types.h"
|
||||
#include "driver/uart.h"
|
||||
#include "soc/gpio_num.h"
|
||||
|
||||
#define ESP_SPINEL_LOG_TAG "ESP_RADIO_SPINEL"
|
||||
|
||||
#define SPINEL_PROP_VENDOR_ESP_SET_COORDINATOR (SPINEL_PROP_VENDOR_ESP__BEGIN + 1) /* Vendor command for coordinator.*/
|
||||
|
||||
#define SPINEL_PROP_VENDOR_ESP_SET_PENDINGMODE (SPINEL_PROP_VENDOR_ESP__BEGIN + 2) /* Vendor command for pending mode.*/
|
||||
|
||||
typedef enum {
|
||||
ESP_RADIO_SPINEL_ZIGBEE = 0x0, /* The index of Zigbee.*/
|
||||
ESP_RADIO_SPINEL_OPENTHREAD = 0x1, /* The index of OpenThread.*/
|
||||
ESP_RADIO_SPINEL_MAX,
|
||||
} esp_radio_spinel_idx_t; /* The index of 802.15.4 related protocol stack for ESP radio spinel.*/
|
||||
|
||||
typedef struct {
|
||||
fd_set read_fds; /* The read file descriptors.*/
|
||||
fd_set write_fds; /* The write file descriptors.*/
|
||||
fd_set error_fds; /* The error file descriptors.*/
|
||||
int max_fd; /* The max file descriptor.*/
|
||||
struct timeval timeout; /* The timeout.*/
|
||||
} esp_radio_spinel_mainloop_context_t;
|
||||
|
||||
typedef struct {
|
||||
uart_port_t port; /*!< UART port number */
|
||||
uart_config_t uart_config; /*!< UART configuration, see uart_config_t docs */
|
||||
gpio_num_t rx_pin; /*!< UART RX pin */
|
||||
gpio_num_t tx_pin; /*!< UART TX pin */
|
||||
} esp_radio_spinel_uart_config_t; /*This structure represents a context for ESP radio spinel. */
|
||||
|
||||
typedef void (*esp_radio_spinel_rcp_failure_handler)(void); /* The handler for rcp failure.*/
|
||||
typedef esp_err_t (*esp_radio_spinel_uart_init_handler)(const esp_radio_spinel_uart_config_t *uart_config_t, int *uart_fd); /* The handler for UART initialization.*/
|
||||
typedef esp_err_t (*esp_radio_spinel_uart_deinit_handler)(const esp_radio_spinel_uart_config_t *uart_config_t, int *uart_fd); /* The handler for UART deinitialization.*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*receive_done)(const uint8_t *frame, esp_ieee802154_frame_info_t *frame_info); /* Callback for Receive Done.*/
|
||||
void (*transmit_done)(const uint8_t *frame, const uint8_t *ack, esp_ieee802154_frame_info_t *ack_frame_info); /* Callback for Transmit Done.*/
|
||||
void (*transmit_failed)(esp_ieee802154_tx_error_t error); /* Callback for Transmit Failed.*/
|
||||
void (*energy_scan_done)(int8_t max_rssi); /* Callback for Energy Scan Done.*/
|
||||
void (*transmit_started)(const uint8_t *frame); /* Callback for Transmit Started.*/
|
||||
void (*switchover_done)(bool success); /* Callback for Switchover Done.*/
|
||||
|
||||
#if OPENTHREAD_CONFIG_DIAG_ENABLE
|
||||
void (*diag_receive_done)(const uint8_t *frame, esp_ieee802154_frame_info_t *frame_info); /* Callback for Receive Done (diag).*/
|
||||
void (*diag_transmit_done)(const uint8_t *frame, esp_ieee802154_frame_info_t *frame_info); /* Callback for Transmit Done (diag).*/
|
||||
void (*diag_transmit_failed)(esp_ieee802154_tx_error_t error); /* Callback for Transmit Failed (diag).*/
|
||||
#endif // OPENTHREAD_CONFIG_DIAG_ENABLE
|
||||
} esp_radio_spinel_callbacks_t; /* ESP Radio Spinel Callbacks.*/
|
||||
|
||||
/**
|
||||
* @brief Set callkbacks of ESP radio spinel.
|
||||
*
|
||||
* @note This function should be called before `esp_radio_spinel_init`.
|
||||
*
|
||||
* @param[in] aCallbacks The callbacks struct.
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
*/
|
||||
void esp_radio_spinel_set_callbacks(const esp_radio_spinel_callbacks_t aCallbacks, esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Enable the UART interface for ESP radio spinel
|
||||
*
|
||||
* @note This function should be called before `esp_radio_spinel_init`.
|
||||
*
|
||||
* @param[in] radio_uart_config The config of UART for radio spinel.
|
||||
* @param[in] aUartInitHandler The function for UART initialization
|
||||
* @param[in] aUartDeinitHandler The function for UART deinitialization
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failures
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_radio_spinel_uart_interface_enable(const esp_radio_spinel_uart_config_t *radio_uart_config,
|
||||
esp_radio_spinel_uart_init_handler aUartInitHandler,
|
||||
esp_radio_spinel_uart_deinit_handler aUartDeinitHandler,
|
||||
esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Initialize ESP radio spinel.
|
||||
*
|
||||
* @note This function should be called after `esp_radio_spinel_set_callbacks` and `esp_radio_spinel_uart_interface_enable`.
|
||||
*
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
*/
|
||||
void esp_radio_spinel_init(esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Enavle ESP radio spinel.
|
||||
*
|
||||
* @note This function should be called after `esp_radio_spinel_init`.
|
||||
*
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failures
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_radio_spinel_enable(esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Set the pending mode.
|
||||
*
|
||||
* @param[in] pending_mode The pending mode.
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failures
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_radio_spinel_set_pending_mode(esp_ieee802154_pending_mode_t pending_mode, esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Get the EUI-64.
|
||||
*
|
||||
* @param[in] eui64 A pointer to the EUI-64.
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failures
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_radio_spinel_get_eui64(uint8_t *eui64, esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Set the panid.
|
||||
*
|
||||
* @param[in] panid The panid.
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failures
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_radio_spinel_set_panid(uint16_t panid, esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Set the short address.
|
||||
*
|
||||
* @param[in] short_address The short address.
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failures
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_radio_spinel_set_short_address(uint16_t short_address, esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Set the extended address.
|
||||
*
|
||||
* @param[in] ext_address The extended address.
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failures
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_radio_spinel_set_extended_address(uint8_t *ext_address, esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Set the coordinator mode.
|
||||
*
|
||||
* @param[in] enable Enable or disable the coordinator mode.
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failures
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_radio_spinel_set_pan_coord(bool enable, esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Enable the RCP reception.
|
||||
*
|
||||
* @param[in] channel The channel of reception.
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failures
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_radio_spinel_receive(uint8_t channel, esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Perform the energy scan.
|
||||
*
|
||||
* @param[in] scan_channel The channel of energy scan (usually the range is 11~26, scan all channels if it's set to 0).
|
||||
* @param[in] scan_duration The duration for energy scan.
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failures
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_radio_spinel_energy_scan(uint8_t scan_channel, uint16_t scan_duration, esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Perform the transmission.
|
||||
*
|
||||
* @param[in] frame A pointer to the frame.
|
||||
* @param[in] channel The channel to use for transmitting.
|
||||
* @param[in] cca Perform clear channel assessment(if it's true) or not(if it's false)
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failures
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_radio_spinel_transmit(uint8_t *frame, uint8_t channel, bool cca, esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Clear all short addresses from the source address match table.
|
||||
*
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failures
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_radio_spinel_clear_short_entries(esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Add a short address to the source address match table.
|
||||
*
|
||||
* @param[in] short_address The short address to be added.
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failures
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_radio_spinel_add_short_entry(uint16_t short_address, esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Clear the pending table, remove all extended/long addresses.
|
||||
*
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failures
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_radio_spinel_clear_extended_entries(esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Add an extended address to the source address match table.
|
||||
*
|
||||
* @param[in] ext_address The extended address to be added.
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failures
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_radio_spinel_add_extended_entry(uint8_t *ext_address, esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Sets the status of promiscuous mode.
|
||||
*
|
||||
* @param[in] enable Whether to enable or disable promiscuous mode.
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failures
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_radio_spinel_set_promiscuous_mode(bool enable, esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Update the ESP radio spinel.
|
||||
*
|
||||
* @param[in] mainloop_context The context for ESP radio spinel.
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
*/
|
||||
void esp_radio_spinel_radio_update(esp_radio_spinel_mainloop_context_t *mainloop_context, esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Process the ESP radio spinel.
|
||||
*
|
||||
* @param[in] mainloop_context The context for ESP radio spinel.
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
*/
|
||||
void esp_radio_spinel_radio_process(esp_radio_spinel_mainloop_context_t *mainloop_context, esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Switch the radio state to Sleep.
|
||||
*
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failures
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_radio_spinel_sleep(esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Set the radio's transmit power in dBm.
|
||||
*
|
||||
* @param[in] power The transmit power in dBm.
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failures
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_radio_spinel_set_tx_power(int8_t power, esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Get the radio's transmit power in dBm.
|
||||
*
|
||||
* @param[in] power A pointer to the transmit power.
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failures
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_radio_spinel_get_tx_power(int8_t *power, esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Register a handler to process the RCP failure.
|
||||
*
|
||||
* @param[in] handler The RCP failure handler.
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
*/
|
||||
void esp_radio_spinel_register_rcp_failure_handler(esp_radio_spinel_rcp_failure_handler handler, esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize the RCP.
|
||||
*
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failures
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_radio_spinel_rcp_deinit(esp_radio_spinel_idx_t idx);
|
||||
|
||||
/**
|
||||
* @brief Get the version of RCP.
|
||||
*
|
||||
* @param[in] running_rcp_version A pointer to the RCP version string.
|
||||
* @param[in] idx The index of 802.15.4 related protocol stack.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL on failures
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_radio_spinel_rcp_version_get(char *running_rcp_version, esp_radio_spinel_idx_t idx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1 +1 @@
|
||||
Subproject commit e0969fc15c1991d91446a0dc5e4625ed2c0bb014
|
||||
Subproject commit fcee30db4b7342de4df9105bdd049a09d2d63187
|
@ -1 +1 @@
|
||||
Subproject commit 41ef80717f4b757440125932723cc8721ef42f7f
|
||||
Subproject commit 456c448284486abe2a9118a9fdaa468fe2383fcd
|
15
components/openthread/private_include/esp_openthread_ncp.h
Normal file
15
components/openthread/private_include/esp_openthread_ncp.h
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <spinel.h>
|
||||
|
||||
#if CONFIG_OPENTHREAD_NCP_VENDOR_HOOK
|
||||
|
||||
#define SPINEL_PROP_VENDOR_ESP_SET_COORDINATOR (SPINEL_PROP_VENDOR_ESP__BEGIN + 1)
|
||||
|
||||
#define SPINEL_PROP_VENDOR_ESP_SET_PENDINGMODE (SPINEL_PROP_VENDOR_ESP__BEGIN + 2)
|
||||
|
||||
#endif
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace esp {
|
||||
namespace radio_spinel {
|
||||
|
||||
/**
|
||||
* This class defines an template to adapt both UartSpinelInterface and SpiSpinelInterface.
|
||||
*
|
||||
*/
|
||||
template <typename InterfaceType> class SpinelInterfaceAdapter {
|
||||
public:
|
||||
SpinelInterfaceAdapter(void) {}
|
||||
|
||||
~SpinelInterfaceAdapter(void) {}
|
||||
|
||||
InterfaceType &GetSpinelInterface(void) { return mSpinelInterface; }
|
||||
|
||||
private:
|
||||
InterfaceType mSpinelInterface;
|
||||
};
|
||||
|
||||
} // namespace radio_spinel
|
||||
} // namespace esp
|
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_radio_spinel.h"
|
||||
#include "lib/spinel/spinel_interface.hpp"
|
||||
#include "lib/hdlc/hdlc.hpp"
|
||||
#include "openthread/error.h"
|
||||
|
||||
namespace esp {
|
||||
namespace radio_spinel {
|
||||
|
||||
/**
|
||||
* This class defines an UART interface to the Radio Co-processor (RCP).
|
||||
*
|
||||
*/
|
||||
class UartSpinelInterface : public ot::Spinel::SpinelInterface {
|
||||
public:
|
||||
/**
|
||||
* @brief This constructor of object.
|
||||
*/
|
||||
UartSpinelInterface(void);
|
||||
|
||||
/**
|
||||
* @brief This destructor of the object.
|
||||
*
|
||||
*/
|
||||
~UartSpinelInterface(void);
|
||||
|
||||
/**
|
||||
* Initializes the interface to the Radio Co-processor (RCP).
|
||||
*
|
||||
* @note This method should be called before reading and sending spinel frames to the interface.
|
||||
*
|
||||
* @param[in] aCallback Callback on frame received
|
||||
* @param[in] aCallbackContext Callback context
|
||||
* @param[in] aFrameBuffer A reference to a `RxFrameBuffer` object.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The interface is initialized successfully
|
||||
* @retval OT_ERROR_ALREADY The interface is already initialized.
|
||||
* @retval OT_ERROR_FAILED Failed to initialize the interface.
|
||||
*
|
||||
*/
|
||||
otError Init(ReceiveFrameCallback aCallback, void *aCallbackContext, RxFrameBuffer &aFrameBuffer);
|
||||
|
||||
/**
|
||||
* Deinitializes the interface to the RCP.
|
||||
*
|
||||
*/
|
||||
void Deinit(void);
|
||||
|
||||
/**
|
||||
* Encodes and sends a spinel frame to Radio Co-processor (RCP) over the socket.
|
||||
*
|
||||
* @param[in] aFrame A pointer to buffer containing the spinel frame to send.
|
||||
* @param[in] aLength The length (number of bytes) in the frame.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully encoded and sent the spinel frame.
|
||||
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
|
||||
* @retval OT_ERROR_NO_BUFS Insufficient buffer space available to encode the frame.
|
||||
* @retval OT_ERROR_FAILED Failed to call the SPI driver to send the frame.
|
||||
*
|
||||
*/
|
||||
otError SendFrame(const uint8_t *aFrame, uint16_t aLength);
|
||||
|
||||
/**
|
||||
* Waits for receiving part or all of spinel frame within specified interval.
|
||||
*
|
||||
* @param[in] aTimeout The timeout value in microseconds.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Part or all of spinel frame is received.
|
||||
* @retval OT_ERROR_RESPONSE_TIMEOUT No spinel frame is received within @p aTimeout.
|
||||
*
|
||||
*/
|
||||
otError WaitForFrame(uint64_t aTimeoutUs);
|
||||
|
||||
/**
|
||||
* Updates the file descriptor sets with file descriptors used by the radio driver.
|
||||
*
|
||||
* @param[in,out] aMainloopContext A pointer to the mainloop context.
|
||||
*
|
||||
*/
|
||||
void UpdateFdSet(void *aMainloopContext);
|
||||
|
||||
/**
|
||||
* Performs radio driver processing.
|
||||
*
|
||||
* @param[in] aMainloopContext A pointer to the mainloop context.
|
||||
*
|
||||
*/
|
||||
void Process(const void *aMainloopContext);
|
||||
|
||||
/**
|
||||
* Returns the bus speed between the host and the radio.
|
||||
*
|
||||
* @returns Bus speed in bits/second.
|
||||
*
|
||||
*/
|
||||
uint32_t GetBusSpeed(void) const;
|
||||
|
||||
/**
|
||||
* Hardware resets the RCP.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully reset the RCP.
|
||||
* @retval OT_ERROR_NOT_IMPLEMENT The hardware reset is not implemented.
|
||||
*
|
||||
*/
|
||||
otError HardwareReset(void);
|
||||
|
||||
/**
|
||||
* Returns the RCP interface metrics.
|
||||
*
|
||||
* @returns The RCP interface metrics.
|
||||
*
|
||||
*/
|
||||
const otRcpInterfaceMetrics *GetRcpInterfaceMetrics(void) const { return &mInterfaceMetrics; }
|
||||
|
||||
/**
|
||||
* This methods registers the callback for RCP failure.
|
||||
*
|
||||
* @param[in] handler The RCP failure handler.
|
||||
*
|
||||
*/
|
||||
void RegisterRcpFailureHandler(esp_radio_spinel_rcp_failure_handler handler) { mRcpFailureHandler = handler; }
|
||||
|
||||
/**
|
||||
* This method is called when RCP is reset to recreate the connection with it.
|
||||
* Intentionally empty.
|
||||
*
|
||||
*/
|
||||
otError ResetConnection(void) { return OT_ERROR_NONE; }
|
||||
|
||||
/**
|
||||
* @brief This method enable the HDLC interface.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_NO_MEM if allocation has failed
|
||||
* - ESP_ERROR on failure
|
||||
*/
|
||||
esp_err_t Enable(const esp_radio_spinel_uart_config_t &radio_uart_config);
|
||||
|
||||
/**
|
||||
* @brief This method disable the HDLC interface.
|
||||
*
|
||||
*/
|
||||
esp_err_t Disable(void);
|
||||
|
||||
void RegisterUartInitHandler(esp_radio_spinel_uart_init_handler handler) { mUartInitHandler = handler; }
|
||||
|
||||
void RegisterUartDeinitHandler(esp_radio_spinel_uart_deinit_handler handler) { mUartDeinitHandler = handler; }
|
||||
|
||||
private:
|
||||
|
||||
enum {
|
||||
/**
|
||||
* Maximum wait time in Milliseconds for socket to become writable (see `SendFrame`).
|
||||
*
|
||||
*/
|
||||
kMaxWaitTime = 2000,
|
||||
};
|
||||
|
||||
esp_err_t InitUart(const esp_radio_spinel_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);
|
||||
|
||||
ReceiveFrameCallback m_receiver_frame_callback;
|
||||
void *m_receiver_frame_context;
|
||||
RxFrameBuffer *m_receive_frame_buffer;
|
||||
|
||||
ot::Hdlc::Decoder m_hdlc_decoder;
|
||||
uint8_t *m_uart_rx_buffer;
|
||||
|
||||
esp_radio_spinel_uart_config_t m_uart_config;
|
||||
int m_uart_fd;
|
||||
|
||||
otRcpInterfaceMetrics mInterfaceMetrics;
|
||||
|
||||
// Non-copyable, intentionally not implemented.
|
||||
UartSpinelInterface(const UartSpinelInterface &);
|
||||
UartSpinelInterface &operator=(const UartSpinelInterface &);
|
||||
|
||||
esp_radio_spinel_rcp_failure_handler mRcpFailureHandler;
|
||||
esp_radio_spinel_uart_init_handler mUartInitHandler;
|
||||
esp_radio_spinel_uart_deinit_handler mUartDeinitHandler;
|
||||
|
||||
ot::Spinel::FrameBuffer<kMaxFrameSize> encoder_buffer;
|
||||
};
|
||||
|
||||
} // namespace radio_spinel
|
||||
} // namespace esp
|
@ -195,6 +195,8 @@ private:
|
||||
UartSpinelInterface &operator=(const UartSpinelInterface &);
|
||||
|
||||
esp_openthread_rcp_failure_handler mRcpFailureHandler;
|
||||
|
||||
ot::Spinel::FrameBuffer<kMaxFrameSize> encoder_buffer;
|
||||
};
|
||||
|
||||
} // namespace openthread
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -590,4 +590,34 @@
|
||||
#define OPENTHREAD_CONFIG_RADIO_STATS_ENABLE 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_TIMEOUT
|
||||
*
|
||||
* The timeout value (in seconds) waiting for a address notification response after sending an address query.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_TIMEOUT
|
||||
#define OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_TIMEOUT CONFIG_OPENTHREAD_ADDRESS_QUERY_TIMEOUT
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_INITIAL_RETRY_DELAY
|
||||
*
|
||||
* Initial retry delay for address query (in seconds).
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_INITIAL_RETRY_DELAY
|
||||
#define OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_INITIAL_RETRY_DELAY CONFIG_OPENTHREAD_ADDRESS_QUERY_RETRY_DELAY
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_MAX_RETRY_DELAY
|
||||
*
|
||||
* Maximum retry delay for address query (in seconds).
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_MAX_RETRY_DELAY
|
||||
#define OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_MAX_RETRY_DELAY CONFIG_OPENTHREAD_ADDRESS_QUERY_MAX_RETRY_DELAY
|
||||
#endif
|
||||
|
||||
#define OPENTHREAD_FTD 1
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -274,4 +274,34 @@
|
||||
#define OPENTHREAD_CONFIG_RADIO_STATS_ENABLE 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_TIMEOUT
|
||||
*
|
||||
* The timeout value (in seconds) waiting for a address notification response after sending an address query.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_TIMEOUT
|
||||
#define OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_TIMEOUT CONFIG_OPENTHREAD_ADDRESS_QUERY_TIMEOUT
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_INITIAL_RETRY_DELAY
|
||||
*
|
||||
* Initial retry delay for address query (in seconds).
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_INITIAL_RETRY_DELAY
|
||||
#define OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_INITIAL_RETRY_DELAY CONFIG_OPENTHREAD_ADDRESS_QUERY_RETRY_DELAY
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_MAX_RETRY_DELAY
|
||||
*
|
||||
* Maximum retry delay for address query (in seconds).
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_MAX_RETRY_DELAY
|
||||
#define OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_MAX_RETRY_DELAY CONFIG_OPENTHREAD_ADDRESS_QUERY_MAX_RETRY_DELAY
|
||||
#endif
|
||||
|
||||
#define OPENTHREAD_MTD 1
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -218,3 +218,15 @@
|
||||
#define OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 1
|
||||
#endif
|
||||
#endif //CONFIG_OPENTHREAD_LINK_METRICS
|
||||
|
||||
#if CONFIG_OPENTHREAD_NCP_VENDOR_HOOK
|
||||
/**
|
||||
* @def OPENTHREAD_ENABLE_NCP_VENDOR_HOOK
|
||||
*
|
||||
* Define as 1 to support ESP OpenThread NCP vendor commands
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_ENABLE_NCP_VENDOR_HOOK
|
||||
#define OPENTHREAD_ENABLE_NCP_VENDOR_HOOK 1
|
||||
#endif
|
||||
#endif //CONFIG_OPENTHREAD_NCP_VENDOR_HOOK
|
||||
|
@ -1,16 +1,10 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file includes compile-time configuration constants for OpenThread.
|
||||
*/
|
||||
|
||||
#ifndef OPENTHREAD_SPINEL_CONFIG_H_
|
||||
#define OPENTHREAD_SPINEL_CONFIG_H_
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
|
||||
@ -30,6 +24,7 @@
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT
|
||||
// TZ-567: Set OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT to 3 after adding rcp failure notification mechanism
|
||||
#define OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT 0
|
||||
#endif
|
||||
|
||||
@ -43,4 +38,11 @@
|
||||
#define OPENTHREAD_SPINEL_CONFIG_RCP_CUSTOM_RESTORATION 0
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_SPINEL_CONFIG_H_
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_PLATFORM_RADIO_SPINEL_RX_FRAME_BUFFER_SIZE
|
||||
*
|
||||
* Specifies the rx frame buffer size used by `SpinelInterface` in RCP host code. This is applicable/used when
|
||||
* `RadioSpinel` platform is used.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_CONFIG_PLATFORM_RADIO_SPINEL_RX_FRAME_BUFFER_SIZE CONFIG_OPENTHREAD_SPINEL_RX_FRAME_BUFFER_SIZE
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -20,8 +20,10 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "linenoise/linenoise.h"
|
||||
|
||||
#define OT_CLI_MAX_LINE_LENGTH 256
|
||||
#include "esp_console.h"
|
||||
#define OT_CLI_MAX_LINE_LENGTH 256
|
||||
#define ESP_CONSOLE_PREFIX "esp "
|
||||
#define ESP_CONSOLE_PREFIX_LENGTH 4
|
||||
|
||||
static TaskHandle_t s_cli_task;
|
||||
|
||||
@ -63,7 +65,13 @@ esp_err_t esp_openthread_cli_input(const char *line)
|
||||
|
||||
static void ot_cli_loop(void *context)
|
||||
{
|
||||
int ret = 0;
|
||||
const char *prompt = "> ";
|
||||
esp_console_config_t console_config = ESP_CONSOLE_CONFIG_DEFAULT();
|
||||
console_config.max_cmdline_length = OT_CLI_MAX_LINE_LENGTH;
|
||||
|
||||
console_config.hint_color = -1;
|
||||
ret = esp_console_init(&console_config);
|
||||
|
||||
linenoiseSetMultiLine(true);
|
||||
linenoiseHistorySetMaxLen(100);
|
||||
@ -78,9 +86,23 @@ static void ot_cli_loop(void *context)
|
||||
char *line = linenoise(prompt);
|
||||
if (line && strnlen(line, OT_CLI_MAX_LINE_LENGTH)) {
|
||||
printf("\r\n");
|
||||
esp_openthread_cli_input(line);
|
||||
if (memcmp(line, ESP_CONSOLE_PREFIX, ESP_CONSOLE_PREFIX_LENGTH) == 0) {
|
||||
esp_err_t err = esp_console_run(line + ESP_CONSOLE_PREFIX_LENGTH, &ret);
|
||||
if (err == ESP_ERR_NOT_FOUND) {
|
||||
printf("Unrecognized command\n");
|
||||
} else if (err == ESP_ERR_INVALID_ARG) {
|
||||
// command was empty
|
||||
printf("Command is empty\n");
|
||||
} else if (err == ESP_OK && ret != ESP_OK) {
|
||||
printf("Command returned non-zero error code: 0x%x (%s)\n", ret, esp_err_to_name(ret));
|
||||
} else if (err != ESP_OK) {
|
||||
printf("Internal error: %s\n", esp_err_to_name(err));
|
||||
}
|
||||
} else {
|
||||
esp_openthread_cli_input(line);
|
||||
xTaskNotifyWait(0, 0, NULL, portMAX_DELAY);
|
||||
}
|
||||
linenoiseHistoryAdd(line);
|
||||
xTaskNotifyWait(0, 0, NULL, portMAX_DELAY);
|
||||
}
|
||||
linenoiseFree(line);
|
||||
}
|
||||
|
111
components/openthread/src/ncp/esp_openthread_ncp.cpp
Normal file
111
components/openthread/src/ncp/esp_openthread_ncp.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#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
|
||||
|
||||
#if CONFIG_OPENTHREAD_RCP_UART
|
||||
extern "C" {
|
||||
static int NcpSend(const uint8_t *aBuf, uint16_t aBufLength)
|
||||
{
|
||||
IgnoreError(otPlatUartSend(aBuf, aBufLength));
|
||||
return aBufLength;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
extern "C" void otAppNcpInit(otInstance *aInstance)
|
||||
{
|
||||
#if CONFIG_OPENTHREAD_RCP_SPI
|
||||
otNcpSpiInit(aInstance);
|
||||
#else
|
||||
IgnoreError(otPlatUartEnable());
|
||||
|
||||
otNcpHdlcInit(aInstance, NcpSend);
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace ot {
|
||||
namespace Ncp {
|
||||
|
||||
otError NcpBase::VendorCommandHandler(uint8_t aHeader, unsigned int aCommand)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
otPlatLog(OT_LOG_LEVEL_WARN, OT_LOG_REGION_NCP, "VendorCommandHandler Not Implemented");
|
||||
|
||||
switch (aCommand)
|
||||
{
|
||||
|
||||
default:
|
||||
error = PrepareLastStatusResponse(aHeader, SPINEL_STATUS_INVALID_COMMAND);
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void NcpBase::VendorHandleFrameRemovedFromNcpBuffer(Spinel::Buffer::FrameTag aFrameTag)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aFrameTag);
|
||||
}
|
||||
|
||||
otError NcpBase::VendorGetPropertyHandler(spinel_prop_key_t aPropKey)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
switch (aPropKey)
|
||||
{
|
||||
|
||||
default:
|
||||
error = OT_ERROR_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
otError NcpBase::VendorSetPropertyHandler(spinel_prop_key_t aPropKey)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
switch (aPropKey)
|
||||
{
|
||||
|
||||
// TZ-566: Add mechanism to allow users to register callback functions.
|
||||
case SPINEL_PROP_VENDOR_ESP_SET_COORDINATOR: {
|
||||
bool coordinator = false;
|
||||
mDecoder.ReadBool(coordinator);
|
||||
esp_ieee802154_set_coordinator(coordinator);
|
||||
break;
|
||||
}
|
||||
case SPINEL_PROP_VENDOR_ESP_SET_PENDINGMODE: {
|
||||
|
||||
int32_t pending_mode = 0;
|
||||
mDecoder.ReadInt32(pending_mode);
|
||||
esp_ieee802154_set_pending_mode(static_cast<esp_ieee802154_pending_mode_t>(pending_mode));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
error = OT_ERROR_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
|
||||
#endif // #if OPENTHREAD_ENABLE_NCP_VENDOR_HOOK
|
33
components/openthread/src/ncp/esp_openthread_ncp_hdlc.cpp
Normal file
33
components/openthread/src/ncp/esp_openthread_ncp_hdlc.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "common/new.hpp"
|
||||
#include "ncp_hdlc.hpp"
|
||||
|
||||
#if OPENTHREAD_ENABLE_NCP_VENDOR_HOOK
|
||||
|
||||
namespace ot {
|
||||
namespace Ncp {
|
||||
|
||||
static OT_DEFINE_ALIGNED_VAR(sNcpRaw, sizeof(NcpHdlc), uint64_t);
|
||||
|
||||
extern "C" void otNcpHdlcInit(otInstance *aInstance, otNcpHdlcSendCallback aSendCallback)
|
||||
{
|
||||
NcpHdlc *ncpHdlc = nullptr;
|
||||
Instance *instance = static_cast<Instance *>(aInstance);
|
||||
|
||||
ncpHdlc = new (&sNcpRaw) NcpHdlc(instance, aSendCallback);
|
||||
|
||||
if (ncpHdlc == nullptr || ncpHdlc != NcpBase::GetNcpInstance())
|
||||
{
|
||||
OT_ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
|
||||
#endif // #if OPENTHREAD_ENABLE_NCP_VENDOR_HOOK
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -174,9 +174,7 @@ esp_err_t esp_openthread_radio_process(otInstance *aInstance, const esp_openthre
|
||||
otPlatRadioTxDone(aInstance, &s_transmit_frame, NULL, OT_ERROR_NONE);
|
||||
} else {
|
||||
otPlatRadioTxDone(aInstance, &s_transmit_frame, &s_ack_frame, OT_ERROR_NONE);
|
||||
#if CONFIG_IEEE802154_RECEIVE_DONE_HANDLER
|
||||
esp_ieee802154_receive_handle_done(s_ack_frame.mPsdu - 1);
|
||||
#endif
|
||||
esp_ieee802154_receive_handle_done(s_ack_frame.mPsdu - 1);
|
||||
s_ack_frame.mPsdu = NULL;
|
||||
}
|
||||
}
|
||||
@ -228,9 +226,7 @@ esp_err_t esp_openthread_radio_process(otInstance *aInstance, const esp_openthre
|
||||
{
|
||||
otPlatRadioReceiveDone(aInstance, &s_receive_frame[s_recv_queue.head], OT_ERROR_NONE);
|
||||
}
|
||||
#if CONFIG_IEEE802154_RECEIVE_DONE_HANDLER
|
||||
esp_ieee802154_receive_handle_done(s_receive_frame[s_recv_queue.head].mPsdu - 1);
|
||||
#endif
|
||||
s_receive_frame[s_recv_queue.head].mPsdu = NULL;
|
||||
s_recv_queue.head = (s_recv_queue.head + 1) % CONFIG_IEEE802154_RX_BUFFER_SIZE;
|
||||
s_recv_queue.used--;
|
||||
@ -347,7 +343,11 @@ int8_t otPlatRadioGetRssi(otInstance *aInstance)
|
||||
|
||||
otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
|
||||
{
|
||||
// FIXME: Remove `CONFIG_OPENTHREAD_RX_ON_WHEN_IDLE` when JIRA: TZ-609 fixed.
|
||||
return (otRadioCaps)(OT_RADIO_CAPS_ENERGY_SCAN |
|
||||
#if CONFIG_OPENTHREAD_RX_ON_WHEN_IDLE
|
||||
OT_RADIO_CAPS_RX_ON_WHEN_IDLE |
|
||||
#endif
|
||||
OT_RADIO_CAPS_TRANSMIT_SEC | OT_RADIO_CAPS_RECEIVE_TIMING | OT_RADIO_CAPS_TRANSMIT_TIMING |
|
||||
OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_SLEEP_TO_TX);
|
||||
}
|
||||
@ -774,3 +774,11 @@ otError otPlatRadioSetChannelMaxTransmitPower(otInstance *aInstance, uint8_t aCh
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
#if CONFIG_OPENTHREAD_RX_ON_WHEN_IDLE
|
||||
void otPlatRadioSetRxOnWhenIdle(otInstance *aInstance, bool aEnable)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
esp_ieee802154_set_rx_when_idle(aEnable);
|
||||
}
|
||||
#endif
|
||||
|
@ -1,11 +1,12 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "esp_openthread_radio.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_openthread_border_router.h"
|
||||
@ -112,7 +113,9 @@ esp_err_t esp_openthread_rcp_init(void)
|
||||
#endif // CONFIG_OPENTHREAD_RADIO_SPINEL_UART
|
||||
|
||||
ESP_RETURN_ON_FALSE(s_radio.Enable(esp_openthread_get_instance()) == OT_ERROR_NONE, ESP_FAIL, OT_PLAT_LOG_TAG, "Fail to enable radio");
|
||||
#if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0
|
||||
s_radio.RestoreProperties();
|
||||
#endif
|
||||
return esp_openthread_platform_workflow_register(&esp_openthread_radio_update, &esp_openthread_radio_process,
|
||||
radiospinel_workflow);
|
||||
}
|
||||
@ -410,3 +413,10 @@ otError otPlatRadioConfigureEnhAckProbing(otInstance *aInstance, otLinkMetrics a
|
||||
return s_radio.ConfigureEnhAckProbing(aLinkMetrics, aShortAddress, *aExtAddress);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_OPENTHREAD_RX_ON_WHEN_IDLE
|
||||
void otPlatRadioSetRxOnWhenIdle(otInstance *aInstance, bool aEnable)
|
||||
{
|
||||
s_radio.SetRxOnWhenIdle(aEnable);
|
||||
}
|
||||
#endif
|
||||
|
@ -86,7 +86,7 @@ esp_err_t UartSpinelInterface::Disable(void)
|
||||
otError UartSpinelInterface::SendFrame(const uint8_t *frame, uint16_t length)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
ot::Spinel::FrameBuffer<kMaxFrameSize> encoder_buffer;
|
||||
encoder_buffer.Clear();
|
||||
ot::Hdlc::Encoder hdlc_encoder(encoder_buffer);
|
||||
|
||||
SuccessOrExit(error = hdlc_encoder.BeginFrame());
|
||||
|
354
components/openthread/src/spinel/esp_radio_spinel.cpp
Normal file
354
components/openthread/src/spinel/esp_radio_spinel.cpp
Normal file
@ -0,0 +1,354 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "esp_check.h"
|
||||
#include "esp_log.h"
|
||||
#include "platform/exit_code.h"
|
||||
#include "radio_spinel.hpp"
|
||||
#include "esp_radio_spinel.h"
|
||||
#include "esp_radio_spinel_adapter.hpp"
|
||||
#include "esp_radio_spinel_uart_interface.hpp"
|
||||
|
||||
using ot::Spinel::RadioSpinel;
|
||||
using ot::Spinel::RadioSpinelCallbacks;
|
||||
using esp::radio_spinel::SpinelInterfaceAdapter;
|
||||
using esp::radio_spinel::UartSpinelInterface;
|
||||
|
||||
static SpinelInterfaceAdapter<UartSpinelInterface> s_spinel_interface[ot::Spinel::kSpinelHeaderMaxNumIid];
|
||||
static RadioSpinel s_radio[ot::Spinel::kSpinelHeaderMaxNumIid];
|
||||
static esp_radio_spinel_callbacks_t s_esp_radio_spinel_callbacks[ot::Spinel::kSpinelHeaderMaxNumIid];
|
||||
otRadioFrame s_transmit_frame;
|
||||
|
||||
static esp_radio_spinel_idx_t get_index_from_instance(otInstance *instance)
|
||||
{
|
||||
// TZ-563: Implement the function to get the esp radio spinel idx from otInstance for multipan rcp
|
||||
return ESP_RADIO_SPINEL_ZIGBEE;
|
||||
}
|
||||
|
||||
static otInstance* get_instance_from_index(esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
// TZ-563: Implement the function to get otInstance pointer from esp radio spinel idx
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ReceiveDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError)
|
||||
{
|
||||
esp_radio_spinel_idx_t idx = get_index_from_instance(aInstance);
|
||||
assert(s_esp_radio_spinel_callbacks[idx].receive_done);
|
||||
uint8_t *frame = (uint8_t *)malloc(aFrame->mLength + 1);
|
||||
esp_ieee802154_frame_info_t frame_info;
|
||||
if (frame) {
|
||||
frame[0] = aFrame->mLength;
|
||||
memcpy((void *)(frame + 1), aFrame->mPsdu, frame[0]);
|
||||
frame_info.rssi = aFrame->mInfo.mRxInfo.mRssi;
|
||||
frame_info.timestamp = aFrame->mInfo.mRxInfo.mTimestamp;
|
||||
frame_info.pending = aFrame->mInfo.mRxInfo.mAckedWithFramePending;
|
||||
s_esp_radio_spinel_callbacks[idx].receive_done(frame, &frame_info);
|
||||
free(frame);
|
||||
} else {
|
||||
ESP_LOGE(ESP_SPINEL_LOG_TAG, "Fail to alloc memory for frame");
|
||||
}
|
||||
}
|
||||
|
||||
void TransmitDone(otInstance *aInstance, otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError)
|
||||
{
|
||||
esp_radio_spinel_idx_t idx = get_index_from_instance(aInstance);
|
||||
assert(s_esp_radio_spinel_callbacks[idx].transmit_done && s_esp_radio_spinel_callbacks[idx].transmit_failed);
|
||||
if (aError == OT_ERROR_NONE) {
|
||||
uint8_t *frame = (uint8_t *)malloc(aFrame->mLength + 1);
|
||||
uint8_t *ack = nullptr;
|
||||
if (frame) {
|
||||
esp_ieee802154_frame_info_t ack_info;
|
||||
frame[0] = aFrame->mLength;
|
||||
memcpy((void *)(frame + 1), aFrame->mPsdu, frame[0]);
|
||||
if (aAckFrame) {
|
||||
ack = (uint8_t *)malloc(aAckFrame->mLength + 1);
|
||||
if (ack) {
|
||||
ack[0] = aAckFrame->mLength;
|
||||
memcpy((void *)(ack + 1), aAckFrame->mPsdu, ack[0]);
|
||||
} else {
|
||||
ESP_LOGE(ESP_SPINEL_LOG_TAG, "Fail to alloc memory for ack");
|
||||
}
|
||||
}
|
||||
s_esp_radio_spinel_callbacks[idx].transmit_done(frame, ack, &ack_info);
|
||||
free(frame);
|
||||
free(ack);
|
||||
} else {
|
||||
ESP_LOGE(ESP_SPINEL_LOG_TAG, "Fail to alloc memory for frame");
|
||||
}
|
||||
} else {
|
||||
switch (aError) {
|
||||
case OT_ERROR_CHANNEL_ACCESS_FAILURE:
|
||||
s_esp_radio_spinel_callbacks[idx].transmit_failed(ESP_IEEE802154_TX_ERR_CCA_BUSY);
|
||||
break;
|
||||
case OT_ERROR_NO_ACK:
|
||||
s_esp_radio_spinel_callbacks[idx].transmit_failed(ESP_IEEE802154_TX_ERR_NO_ACK);
|
||||
break;
|
||||
default:
|
||||
s_esp_radio_spinel_callbacks[idx].transmit_failed(ESP_IEEE802154_TX_ERR_ABORT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnergyScanDone(otInstance *aInstance, int8_t aMaxRssi)
|
||||
{
|
||||
esp_radio_spinel_idx_t idx = get_index_from_instance(aInstance);
|
||||
assert(s_esp_radio_spinel_callbacks[idx].energy_scan_done);
|
||||
s_esp_radio_spinel_callbacks[idx].energy_scan_done(aMaxRssi);
|
||||
}
|
||||
|
||||
void TxStarted(otInstance *aInstance, otRadioFrame *aFrame)
|
||||
{
|
||||
esp_radio_spinel_idx_t idx = get_index_from_instance(aInstance);
|
||||
assert(s_esp_radio_spinel_callbacks[idx].transmit_started);
|
||||
uint8_t *frame = (uint8_t *)malloc(aFrame->mLength + 1);
|
||||
if (frame) {
|
||||
frame[0] = aFrame->mLength;
|
||||
memcpy((void *)(frame + 1), aFrame->mPsdu, frame[0]);
|
||||
s_esp_radio_spinel_callbacks[idx].transmit_started(frame);
|
||||
free(frame);
|
||||
} else {
|
||||
ESP_LOGE(ESP_SPINEL_LOG_TAG, "Fail to alloc memory for frame");
|
||||
}
|
||||
}
|
||||
|
||||
void SwitchoverDone(otInstance *aInstance, bool aSuccess)
|
||||
{
|
||||
esp_radio_spinel_idx_t idx = get_index_from_instance(aInstance);
|
||||
assert(s_esp_radio_spinel_callbacks[idx].switchover_done);
|
||||
s_esp_radio_spinel_callbacks[idx].switchover_done(aSuccess);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_DIAG_ENABLE
|
||||
void DiagReceiveDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError)
|
||||
{
|
||||
esp_radio_spinel_idx_t idx = get_index_from_instance(aInstance);
|
||||
assert(s_esp_radio_spinel_callbacks[idx].diag_receive_done);
|
||||
uint8_t *frame = (uint8_t *)malloc(aFrame->mLength + 1);
|
||||
esp_ieee802154_frame_info_t frame_info;
|
||||
if (frame) {
|
||||
frame[0] = aFrame->mLength;
|
||||
memcpy((void *)(frame + 1), aFrame->mPsdu, frame[0]);
|
||||
frame_info.rssi = aFrame->mInfo.mRxInfo.mRssi;
|
||||
frame_info.timestamp = aFrame->mInfo.mRxInfo.mTimestamp;
|
||||
frame_info.pending = aFrame->mInfo.mRxInfo.mAckedWithFramePending;
|
||||
s_esp_radio_spinel_callbacks[idx].diag_receive_done(frame, &frame_info);
|
||||
free(frame);
|
||||
} else {
|
||||
ESP_LOGE(ESP_SPINEL_LOG_TAG, "Fail to alloc memory for frame");
|
||||
}
|
||||
}
|
||||
|
||||
void DiagTransmitDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError)
|
||||
{
|
||||
esp_radio_spinel_idx_t idx = get_index_from_instance(aInstance);
|
||||
assert(s_esp_radio_spinel_callbacks[idx].diag_transmit_done && s_esp_radio_spinel_callbacks[idx].diag_transmit_failed);
|
||||
if (aError == OT_ERROR_NONE) {
|
||||
uint8_t *frame = (uint8_t *)malloc(aFrame->mLength + 1);
|
||||
if (frame) {
|
||||
esp_ieee802154_frame_info_t ack_info;
|
||||
frame[0] = aFrame->mLength;
|
||||
memcpy((void *)(frame + 1), aFrame->mPsdu, frame[0]);
|
||||
s_esp_radio_spinel_callbacks[idx].diag_transmit_done(frame, &ack_info);
|
||||
free(frame);
|
||||
} else {
|
||||
ESP_LOGE(ESP_SPINEL_LOG_TAG, "Fail to alloc memory for frame");
|
||||
}
|
||||
} else {
|
||||
switch (aError) {
|
||||
case OT_ERROR_CHANNEL_ACCESS_FAILURE:
|
||||
s_esp_radio_spinel_callbacks[idx].diag_transmit_failed(ESP_IEEE802154_TX_ERR_CCA_BUSY);
|
||||
break;
|
||||
case OT_ERROR_NO_ACK:
|
||||
s_esp_radio_spinel_callbacks[idx].diag_transmit_failed(ESP_IEEE802154_TX_ERR_NO_ACK);
|
||||
break;
|
||||
default:
|
||||
s_esp_radio_spinel_callbacks[idx].diag_transmit_failed(ESP_IEEE802154_TX_ERR_CCA_BUSY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_DIAG_ENABLE
|
||||
|
||||
|
||||
void esp_radio_spinel_set_callbacks(const esp_radio_spinel_callbacks_t aCallbacks, esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
s_esp_radio_spinel_callbacks[idx] = aCallbacks;
|
||||
RadioSpinelCallbacks Callbacks;
|
||||
Callbacks.mReceiveDone = ReceiveDone;
|
||||
Callbacks.mTransmitDone = TransmitDone;
|
||||
Callbacks.mEnergyScanDone = EnergyScanDone;
|
||||
Callbacks.mTxStarted = TxStarted;
|
||||
Callbacks.mSwitchoverDone = SwitchoverDone;
|
||||
#if OPENTHREAD_CONFIG_DIAG_ENABLE
|
||||
Callbacks.mDiagReceiveDone = DiagReceiveDone;
|
||||
Callbacks.mDiagTransmitDone = DiagTransmitDone;
|
||||
#endif // OPENTHREAD_CONFIG_DIAG_ENABLE
|
||||
|
||||
s_radio[idx].SetCallbacks(Callbacks);
|
||||
}
|
||||
|
||||
esp_err_t esp_radio_spinel_uart_interface_enable(const esp_radio_spinel_uart_config_t *radio_uart_config,
|
||||
esp_radio_spinel_uart_init_handler aUartInitHandler,
|
||||
esp_radio_spinel_uart_deinit_handler aUartDeinitHandler,
|
||||
esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(aUartInitHandler != nullptr, ESP_FAIL, ESP_SPINEL_LOG_TAG, "UartInitHandler can not be set to NULL");
|
||||
ESP_RETURN_ON_FALSE(aUartDeinitHandler != nullptr, ESP_FAIL, ESP_SPINEL_LOG_TAG, "UartDeinitHandler can not be set to NULL");
|
||||
s_spinel_interface[idx].GetSpinelInterface().RegisterUartInitHandler(aUartInitHandler);
|
||||
s_spinel_interface[idx].GetSpinelInterface().RegisterUartDeinitHandler(aUartDeinitHandler);
|
||||
ESP_RETURN_ON_FALSE(s_spinel_interface[idx].GetSpinelInterface().Enable(*radio_uart_config) == OT_ERROR_NONE, ESP_FAIL, ESP_SPINEL_LOG_TAG, "Spinel UART interface failed to enable");
|
||||
ESP_LOGI(ESP_SPINEL_LOG_TAG, "Spinel UART interface has been successfully enabled");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void esp_radio_spinel_init(esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
spinel_iid_t iidList[ot::Spinel::kSpinelHeaderMaxNumIid];
|
||||
|
||||
// Multipan is not currently supported
|
||||
iidList[0] = 0;
|
||||
s_radio[idx].Init(s_spinel_interface[idx].GetSpinelInterface(), /*reset_radio=*/true, /*skip_rcp_compatibility_check=*/false, iidList, ot::Spinel::kSpinelHeaderMaxNumIid);
|
||||
}
|
||||
|
||||
esp_err_t esp_radio_spinel_enable(esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
otInstance *instance = get_instance_from_index(idx);
|
||||
return (s_radio[idx].Enable(instance) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_radio_spinel_set_pending_mode(esp_ieee802154_pending_mode_t pending_mode, esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
return (s_radio[idx].Set(SPINEL_PROP_VENDOR_ESP_SET_PENDINGMODE, SPINEL_DATATYPE_INT32_S, static_cast<int32_t>(pending_mode)) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_radio_spinel_get_eui64(uint8_t *eui64, esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
return (s_radio[idx].GetIeeeEui64(eui64) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_radio_spinel_set_panid(uint16_t panid, esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
return (s_radio[idx].SetPanId(panid) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_radio_spinel_set_short_address(uint16_t short_address, esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
return (s_radio[idx].SetShortAddress(short_address) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_radio_spinel_set_extended_address(uint8_t *ext_address, esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
otExtAddress aExtAddress;
|
||||
memcpy(aExtAddress.m8, (void *)ext_address, OT_EXT_ADDRESS_SIZE);
|
||||
return (s_radio[idx].SetExtendedAddress(aExtAddress) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_radio_spinel_set_pan_coord(bool enable, esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
return (s_radio[idx].Set(SPINEL_PROP_VENDOR_ESP_SET_COORDINATOR, SPINEL_DATATYPE_BOOL_S, enable) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_radio_spinel_receive(uint8_t channel, esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
return (s_radio[idx].Receive(channel) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_radio_spinel_energy_scan(uint8_t scan_channel, uint16_t scan_duration, esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
return (s_radio[idx].EnergyScan(scan_channel, scan_duration) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_radio_spinel_transmit(uint8_t *frame, uint8_t channel, bool cca, esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
s_transmit_frame.mLength = frame[0];
|
||||
s_transmit_frame.mPsdu = frame + 1;
|
||||
s_transmit_frame.mInfo.mTxInfo.mCsmaCaEnabled = cca;
|
||||
s_transmit_frame.mChannel = channel;
|
||||
s_transmit_frame.mInfo.mTxInfo.mRxChannelAfterTxDone = channel;
|
||||
return (s_radio[idx].Transmit(s_transmit_frame) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_radio_spinel_clear_short_entries(esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
return (s_radio[idx].ClearSrcMatchShortEntries() == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_radio_spinel_add_short_entry(uint16_t short_address, esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
return (s_radio[idx].AddSrcMatchShortEntry(short_address) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_radio_spinel_clear_extended_entries(esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
return (s_radio[idx].ClearSrcMatchExtEntries() == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_radio_spinel_add_extended_entry(uint8_t *ext_address, esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
otExtAddress aExtAddress;
|
||||
memcpy(aExtAddress.m8, (void *)ext_address, OT_EXT_ADDRESS_SIZE);
|
||||
return (s_radio[idx].AddSrcMatchExtEntry(aExtAddress) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_radio_spinel_set_promiscuous_mode(bool enable, esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
return (s_radio[idx].SetPromiscuous(enable) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
void esp_radio_spinel_radio_update(esp_radio_spinel_mainloop_context_t *mainloop_context, esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
s_spinel_interface[idx].GetSpinelInterface().UpdateFdSet(static_cast<void *>(mainloop_context));
|
||||
}
|
||||
|
||||
void esp_radio_spinel_radio_process(esp_radio_spinel_mainloop_context_t *mainloop_context, esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
s_radio[idx].Process(static_cast<void *>(mainloop_context));
|
||||
}
|
||||
|
||||
esp_err_t esp_radio_spinel_sleep(esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
return (s_radio[idx].Sleep() == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_radio_spinel_set_tx_power(int8_t power, esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
return (s_radio[idx].SetTransmitPower(power) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_radio_spinel_get_tx_power(int8_t *power, esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
int8_t aPower;
|
||||
error = s_radio[idx].GetTransmitPower(aPower);
|
||||
*power = aPower;
|
||||
return (error == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
void esp_radio_spinel_register_rcp_failure_handler(esp_radio_spinel_rcp_failure_handler handler, esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
s_spinel_interface[idx].GetSpinelInterface().RegisterRcpFailureHandler(handler);
|
||||
}
|
||||
|
||||
esp_err_t esp_radio_spinel_rcp_deinit(esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
if (s_radio[idx].IsEnabled()) {
|
||||
ESP_RETURN_ON_FALSE(s_radio[idx].Sleep() == OT_ERROR_NONE, ESP_ERR_INVALID_STATE, ESP_SPINEL_LOG_TAG, "Radio fails to sleep");
|
||||
ESP_RETURN_ON_FALSE(s_radio[idx].Disable() == OT_ERROR_NONE, ESP_ERR_INVALID_STATE, ESP_SPINEL_LOG_TAG, "Fail to disable radio");
|
||||
}
|
||||
ESP_RETURN_ON_FALSE(s_spinel_interface[idx].GetSpinelInterface().Disable() == OT_ERROR_NONE, ESP_ERR_INVALID_STATE, ESP_SPINEL_LOG_TAG, "Fail to deinitialize UART");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_radio_spinel_rcp_version_get(char *running_rcp_version, esp_radio_spinel_idx_t idx)
|
||||
{
|
||||
const char *rcp_version = s_radio[idx].GetVersion();
|
||||
ESP_RETURN_ON_FALSE(rcp_version != nullptr, ESP_FAIL, ESP_SPINEL_LOG_TAG, "Fail to get rcp version");
|
||||
strcpy(running_rcp_version, rcp_version);
|
||||
return ESP_OK;
|
||||
}
|
@ -0,0 +1,300 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "esp_radio_spinel_uart_interface.hpp"
|
||||
#include <errno.h>
|
||||
#include <sys/unistd.h>
|
||||
#include "esp_check.h"
|
||||
#include "esp_openthread_common_macro.h"
|
||||
#include "openthread/platform/time.h"
|
||||
#include "hdlc.hpp"
|
||||
|
||||
namespace esp {
|
||||
namespace radio_spinel {
|
||||
|
||||
UartSpinelInterface::UartSpinelInterface(void)
|
||||
: m_receiver_frame_callback(nullptr)
|
||||
, m_receiver_frame_context(nullptr)
|
||||
, m_receive_frame_buffer(nullptr)
|
||||
, m_uart_fd(-1)
|
||||
, mRcpFailureHandler(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
UartSpinelInterface::~UartSpinelInterface(void)
|
||||
{
|
||||
Deinit();
|
||||
}
|
||||
|
||||
otError UartSpinelInterface::Init(ReceiveFrameCallback aCallback, void *aCallbackContext, RxFrameBuffer &aFrameBuffer)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
m_receiver_frame_callback = aCallback;
|
||||
m_receiver_frame_context = aCallbackContext;
|
||||
m_receive_frame_buffer = &aFrameBuffer;
|
||||
m_hdlc_decoder.Init(aFrameBuffer, HandleHdlcFrame, this);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void UartSpinelInterface::Deinit(void)
|
||||
{
|
||||
m_receiver_frame_callback = nullptr;
|
||||
m_receiver_frame_context = nullptr;
|
||||
m_receive_frame_buffer = nullptr;
|
||||
}
|
||||
|
||||
esp_err_t UartSpinelInterface::Enable(const esp_radio_spinel_uart_config_t &radio_uart_config)
|
||||
{
|
||||
esp_err_t error = ESP_OK;
|
||||
m_uart_rx_buffer = static_cast<uint8_t *>(heap_caps_malloc(kMaxFrameSize, MALLOC_CAP_8BIT));
|
||||
if (m_uart_rx_buffer == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
error = InitUart(radio_uart_config);
|
||||
if (error == ESP_OK) {
|
||||
ESP_LOGI(ESP_SPINEL_LOG_TAG, "spinel UART interface initialization completed");
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
esp_err_t UartSpinelInterface::Disable(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;
|
||||
encoder_buffer.Clear();
|
||||
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) {
|
||||
ESP_LOGE(ESP_SPINEL_LOG_TAG, "send radio frame failed");
|
||||
} else {
|
||||
ESP_LOGD(ESP_SPINEL_LOG_TAG, "sent radio frame");
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void UartSpinelInterface::Process(const void *aMainloopContext)
|
||||
{
|
||||
if (FD_ISSET(m_uart_fd, &((esp_radio_spinel_mainloop_context_t *)aMainloopContext)->read_fds)) {
|
||||
ESP_LOGD(ESP_SPINEL_LOG_TAG, "radio uart read event");
|
||||
TryReadAndDecode();
|
||||
}
|
||||
}
|
||||
|
||||
int UartSpinelInterface::TryReadAndDecode(void)
|
||||
{
|
||||
uint8_t buffer[UART_HW_FIFO_LEN(m_uart_config.port)];
|
||||
ssize_t rval;
|
||||
do {
|
||||
rval = read(m_uart_fd, buffer, sizeof(buffer));
|
||||
if (rval > 0) {
|
||||
m_hdlc_decoder.Decode(buffer, static_cast<uint16_t>(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<time_t>(remain / 1000000);
|
||||
timeout.tv_usec = static_cast<suseconds_t>(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<uint16_t>(rval);
|
||||
aFrame += static_cast<uint16_t>(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<time_t>(timeout_us / US_PER_S);
|
||||
timeout.tv_usec = static_cast<suseconds_t>(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<UartSpinelInterface *>(context)->HandleHdlcFrame(error);
|
||||
}
|
||||
|
||||
void UartSpinelInterface::HandleHdlcFrame(otError error)
|
||||
{
|
||||
if (error == OT_ERROR_NONE) {
|
||||
ESP_LOGD(ESP_SPINEL_LOG_TAG, "received hdlc radio frame");
|
||||
m_receiver_frame_callback(m_receiver_frame_context);
|
||||
} else {
|
||||
ESP_LOGE(ESP_SPINEL_LOG_TAG, "dropping radio frame: %s", otThreadErrorToString(error));
|
||||
m_receive_frame_buffer->DiscardFrame();
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t UartSpinelInterface::InitUart(const esp_radio_spinel_uart_config_t &radio_uart_config)
|
||||
{
|
||||
if (mUartInitHandler) {
|
||||
m_uart_config = radio_uart_config;
|
||||
return mUartInitHandler(&m_uart_config, &m_uart_fd);
|
||||
} else {
|
||||
ESP_LOGE(ESP_SPINEL_LOG_TAG, "None mUartInitHandler");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t UartSpinelInterface::DeinitUart(void)
|
||||
{
|
||||
if (mUartDeinitHandler) {
|
||||
return mUartDeinitHandler(&m_uart_config, &m_uart_fd);
|
||||
} else {
|
||||
ESP_LOGE(ESP_SPINEL_LOG_TAG, "None mUartDeinitHandler");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t UartSpinelInterface::TryRecoverUart(void)
|
||||
{
|
||||
ESP_RETURN_ON_ERROR(DeinitUart(), ESP_SPINEL_LOG_TAG, "DeInitUart failed");
|
||||
ESP_RETURN_ON_ERROR(InitUart(m_uart_config), ESP_SPINEL_LOG_TAG, "InitUart failed");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
otError UartSpinelInterface::HardwareReset(void)
|
||||
{
|
||||
if (mRcpFailureHandler) {
|
||||
mRcpFailureHandler();
|
||||
TryRecoverUart();
|
||||
}
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
void UartSpinelInterface::UpdateFdSet(void *aMainloopContext)
|
||||
{
|
||||
// Register only READ events for radio UART and always wait
|
||||
// for a radio WRITE to complete.
|
||||
FD_SET(m_uart_fd, &((esp_radio_spinel_mainloop_context_t *)aMainloopContext)->read_fds);
|
||||
if (m_uart_fd > ((esp_radio_spinel_mainloop_context_t *)aMainloopContext)->max_fd) {
|
||||
((esp_radio_spinel_mainloop_context_t *)aMainloopContext)->max_fd = m_uart_fd;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t UartSpinelInterface::GetBusSpeed(void) const
|
||||
{
|
||||
return m_uart_config.uart_config.baud_rate;
|
||||
}
|
||||
} // namespace radio_spinel
|
||||
} // namespace esp
|
@ -65,6 +65,9 @@ WIFI_DOCS = ['api-guides/wifi.rst',
|
||||
'api-reference/network/esp_dpp.rst',
|
||||
'migration-guides/release-5.x/5.2/wifi.rst']
|
||||
|
||||
IEEE802154_DOCS = ['migration-guides/release-5.x/5.1/ieee802154.rst',
|
||||
'migration-guides/release-5.x/5.2/ieee802154.rst']
|
||||
|
||||
NAN_DOCS = ['api-reference/network/esp_nan.rst']
|
||||
|
||||
WIFI_MESH_DOCS = ['api-guides/esp-wifi-mesh.rst',
|
||||
@ -187,6 +190,7 @@ conditional_include_dict = {'SOC_BT_SUPPORTED':BT_DOCS,
|
||||
'SOC_BLUFI_SUPPORTED':BLUFI_DOCS,
|
||||
'SOC_WIFI_SUPPORTED':WIFI_DOCS,
|
||||
'SOC_BT_CLASSIC_SUPPORTED':CLASSIC_BT_DOCS,
|
||||
'SOC_IEEE802154_SUPPORTED':IEEE802154_DOCS,
|
||||
'SOC_SUPPORT_COEXISTENCE':COEXISTENCE_DOCS,
|
||||
'SOC_PSRAM_DMA_CAPABLE':MM_SYNC_DOCS,
|
||||
'SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE':MM_SYNC_DOCS,
|
||||
|
13
docs/en/migration-guides/release-5.x/5.1/ieee802154.rst
Normal file
13
docs/en/migration-guides/release-5.x/5.1/ieee802154.rst
Normal file
@ -0,0 +1,13 @@
|
||||
IEEE 802.15.4
|
||||
=============
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
Receive Handle Done
|
||||
-------------------
|
||||
|
||||
.. note::
|
||||
|
||||
It is required since IDF v5.1.3 release.
|
||||
|
||||
User must call the function :cpp:func:`esp_ieee802154_receive_handle_done` to notify 802.15.4 driver after the received frame is handled. Otherwise the frame buffer will not be freed for future use.
|
@ -7,6 +7,7 @@ Migration from 5.0 to 5.1
|
||||
:maxdepth: 1
|
||||
|
||||
gcc
|
||||
:SOC_IEEE802154_SUPPORTED: ieee802154
|
||||
peripherals
|
||||
storage
|
||||
networking
|
||||
|
9
docs/en/migration-guides/release-5.x/5.2/ieee802154.rst
Normal file
9
docs/en/migration-guides/release-5.x/5.2/ieee802154.rst
Normal file
@ -0,0 +1,9 @@
|
||||
IEEE 802.15.4
|
||||
=============
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
Receive Handle Done
|
||||
-------------------
|
||||
|
||||
User must call the function :cpp:func:`esp_ieee802154_receive_handle_done` to notify 802.15.4 driver after the received frame is handled. Otherwise the frame buffer will not be freed for future use.
|
@ -8,6 +8,7 @@ Migration from 5.1 to 5.2
|
||||
|
||||
bluetooth-classic
|
||||
gcc
|
||||
:SOC_IEEE802154_SUPPORTED: ieee802154
|
||||
peripherals
|
||||
protocols
|
||||
storage
|
||||
|
13
docs/zh_CN/migration-guides/release-5.x/5.1/ieee802154.rst
Normal file
13
docs/zh_CN/migration-guides/release-5.x/5.1/ieee802154.rst
Normal file
@ -0,0 +1,13 @@
|
||||
IEEE 802.15.4
|
||||
=============
|
||||
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
Receive Handle Done
|
||||
-------------------
|
||||
|
||||
.. note::
|
||||
|
||||
这个功能仅包括在 IDF v5.1.3 以及之后的发布中。
|
||||
|
||||
当收到的数据帧被处理后, 用户需要调用函数 :cpp:func:`esp_ieee802154_receive_handle_done` 通知 802.15.4 驱动层,否则这个数据空间将不会被释放。
|
@ -7,6 +7,7 @@
|
||||
:maxdepth: 1
|
||||
|
||||
gcc
|
||||
:SOC_IEEE802154_SUPPORTED: ieee802154
|
||||
peripherals
|
||||
storage
|
||||
networking
|
||||
|
@ -0,0 +1,9 @@
|
||||
IEEE 802.15.4
|
||||
=============
|
||||
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
Receive Handle Done
|
||||
-------------------
|
||||
|
||||
当收到的数据帧被处理后, 用户需要调用函数 :cpp:func:`esp_ieee802154_receive_handle_done` 通知 802.15.4 驱动层,否则这个数据空间将不会被释放。
|
@ -8,6 +8,7 @@
|
||||
|
||||
bluetooth-classic
|
||||
gcc
|
||||
:SOC_IEEE802154_SUPPORTED: ieee802154
|
||||
peripherals
|
||||
protocols
|
||||
storage
|
||||
|
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
# !/usr/bin/env python3
|
||||
# this file defines some functions for testing cli and br under pytest framework
|
||||
|
@ -1,7 +1,7 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
espressif/esp_ot_cli_extension:
|
||||
version: "~0.4.0"
|
||||
version: "~1.0.0"
|
||||
idf:
|
||||
version: ">=4.1.0"
|
||||
iperf:
|
||||
|
@ -33,10 +33,3 @@ CONFIG_LWIP_IPV6_NUM_ADDRESSES=8
|
||||
CONFIG_LWIP_MULTICAST_PING=y
|
||||
CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_CUSTOM=y
|
||||
# end of lwIP
|
||||
|
||||
#
|
||||
# IEEE 802.15.4
|
||||
#
|
||||
CONFIG_IEEE802154_ENABLED=y
|
||||
CONFIG_IEEE802154_RECEIVE_DONE_HANDLER=y
|
||||
# end of IEEE 802.15.4
|
||||
|
@ -30,12 +30,6 @@ CONFIG_LOG_BOOTLOADER_LEVEL_ERROR=y
|
||||
CONFIG_LOG_BOOTLOADER_LEVEL_INFO=n
|
||||
# End of deprecated options
|
||||
|
||||
#
|
||||
# IEEE 802.15.4
|
||||
#
|
||||
CONFIG_IEEE802154_RECEIVE_DONE_HANDLER=y
|
||||
# end of IEEE 802.15.4
|
||||
|
||||
#
|
||||
# Configurations for optimizing the size of ot_rcp firmware
|
||||
#
|
||||
|
@ -1,10 +1,12 @@
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
# !/usr/bin/env python3
|
||||
|
||||
|
||||
import copy
|
||||
import os.path
|
||||
import re
|
||||
import secrets
|
||||
import subprocess
|
||||
import threading
|
||||
import time
|
||||
@ -94,9 +96,9 @@ def test_thread_connect(dut:Tuple[IdfDut, IdfDut, IdfDut]) -> None:
|
||||
ocf.init_thread(br)
|
||||
for cli in cli_list:
|
||||
ocf.init_thread(cli)
|
||||
br_ot_para = default_br_ot_para
|
||||
br_ot_para = copy.copy(default_br_ot_para)
|
||||
ocf.joinThreadNetwork(br, br_ot_para)
|
||||
cli_ot_para = default_cli_ot_para
|
||||
cli_ot_para = copy.copy(default_cli_ot_para)
|
||||
cli_ot_para.dataset = ocf.getDataset(br)
|
||||
try:
|
||||
order = 0
|
||||
@ -127,12 +129,14 @@ def test_thread_connect(dut:Tuple[IdfDut, IdfDut, IdfDut]) -> None:
|
||||
def formBasicWiFiThreadNetwork(br:IdfDut, cli:IdfDut) -> None:
|
||||
ocf.init_thread(br)
|
||||
ocf.init_thread(cli)
|
||||
ocf.joinWiFiNetwork(br, default_br_wifi_para)
|
||||
ocf.joinThreadNetwork(br, default_br_ot_para)
|
||||
ot_para = default_cli_ot_para
|
||||
ot_para.dataset = ocf.getDataset(br)
|
||||
ot_para.exaddr = '7766554433221101'
|
||||
ocf.joinThreadNetwork(cli, ot_para)
|
||||
otbr_wifi_para = copy.copy(default_br_wifi_para)
|
||||
ocf.joinWiFiNetwork(br, otbr_wifi_para)
|
||||
otbr_thread_para = copy.copy(default_br_ot_para)
|
||||
ocf.joinThreadNetwork(br, otbr_thread_para)
|
||||
otcli_thread_para = copy.copy(default_cli_ot_para)
|
||||
otcli_thread_para.dataset = ocf.getDataset(br)
|
||||
otcli_thread_para.exaddr = '7766554433221101'
|
||||
ocf.joinThreadNetwork(cli, otcli_thread_para)
|
||||
ocf.wait(cli,10)
|
||||
|
||||
|
||||
@ -572,6 +576,7 @@ def test_TCP_NAT64(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> N
|
||||
def test_ot_sleepy_device(dut: Tuple[IdfDut, IdfDut]) -> None:
|
||||
leader = dut[0]
|
||||
sleepy_device = dut[1]
|
||||
fail_info = re.compile(r'Core\W*?\d\W*?register dump')
|
||||
try:
|
||||
ocf.init_thread(leader)
|
||||
time.sleep(3)
|
||||
@ -583,13 +588,22 @@ def test_ot_sleepy_device(dut: Tuple[IdfDut, IdfDut]) -> None:
|
||||
leader_para.setpskc('104810e2315100afd6bc9215a6bfac53')
|
||||
ocf.joinThreadNetwork(leader, leader_para)
|
||||
ocf.wait(leader, 5)
|
||||
output = sleepy_device.expect(pexpect.TIMEOUT, timeout=5)
|
||||
assert not bool(fail_info.search(str(output)))
|
||||
ocf.clean_buffer(sleepy_device)
|
||||
sleepy_device.serial.hard_reset()
|
||||
sleepy_device.expect('detached -> child', timeout=20)
|
||||
sleepy_device.expect('PMU_SLEEP_PD_TOP: True', timeout=10)
|
||||
sleepy_device.expect('PMU_SLEEP_PD_MODEM: True', timeout=20)
|
||||
info = sleepy_device.expect(r'(.+)detached -> child', timeout=20)[1].decode(errors='replace')
|
||||
assert not bool(fail_info.search(str(info)))
|
||||
info = sleepy_device.expect(r'(.+)PMU_SLEEP_PD_TOP: True', timeout=10)[1].decode(errors='replace')
|
||||
assert not bool(fail_info.search(str(info)))
|
||||
info = sleepy_device.expect(r'(.+)PMU_SLEEP_PD_MODEM: True', timeout=20)[1].decode(errors='replace')
|
||||
assert not bool(fail_info.search(str(info)))
|
||||
output = sleepy_device.expect(pexpect.TIMEOUT, timeout=20)
|
||||
assert not bool(fail_info.search(str(output)))
|
||||
ocf.clean_buffer(sleepy_device)
|
||||
ocf.execute_command(leader, 'factoryreset')
|
||||
output = sleepy_device.expect(pexpect.TIMEOUT, timeout=5)
|
||||
assert 'rst:' not in str(output) and 'boot:' not in str(output)
|
||||
assert not bool(fail_info.search(str(output)))
|
||||
finally:
|
||||
ocf.execute_command(leader, 'factoryreset')
|
||||
time.sleep(3)
|
||||
@ -670,3 +684,60 @@ def test_NAT64_DNS(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> N
|
||||
ocf.execute_command(br, 'factoryreset')
|
||||
ocf.execute_command(cli, 'factoryreset')
|
||||
time.sleep(3)
|
||||
|
||||
|
||||
# Case 13: Meshcop discovery of Border Router
|
||||
@pytest.mark.supported_targets
|
||||
@pytest.mark.esp32c6
|
||||
@pytest.mark.openthread_br
|
||||
@pytest.mark.flaky(reruns=1, reruns_delay=1)
|
||||
@pytest.mark.parametrize(
|
||||
'config, count, app_path, target', [
|
||||
('rcp|br', 2,
|
||||
f'{os.path.join(os.path.dirname(__file__), "ot_rcp")}'
|
||||
f'|{os.path.join(os.path.dirname(__file__), "ot_br")}',
|
||||
'esp32c6|esp32s3'),
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
def test_br_meshcop(Init_interface:bool, Init_avahi:bool, dut: Tuple[IdfDut, IdfDut]) -> None:
|
||||
br = dut[1]
|
||||
assert Init_interface
|
||||
assert Init_avahi
|
||||
dut[0].serial.stop_redirect_thread()
|
||||
|
||||
result = None
|
||||
output_bytes = b''
|
||||
try:
|
||||
ocf.init_thread(br)
|
||||
br_wifi_para = copy.copy(default_br_wifi_para)
|
||||
ipv4_address = ocf.joinWiFiNetwork(br, br_wifi_para)[0]
|
||||
br_thread_para = copy.copy(default_br_ot_para)
|
||||
networkname = 'OTCI-' + str(secrets.token_hex(1))
|
||||
br_thread_para.setnetworkname(networkname)
|
||||
ocf.joinThreadNetwork(br, br_thread_para)
|
||||
ocf.wait(br, 10)
|
||||
assert ocf.is_joined_wifi_network(br)
|
||||
command = 'timeout 3 avahi-browse -r _meshcop._udp'
|
||||
try:
|
||||
result = subprocess.run(command, capture_output=True, check=True, shell=True)
|
||||
if result:
|
||||
output_bytes = result.stdout
|
||||
except subprocess.CalledProcessError as e:
|
||||
output_bytes = e.stdout
|
||||
finally:
|
||||
print('out_bytes: ', output_bytes)
|
||||
output_str = str(output_bytes)
|
||||
print('out_str: ', output_str)
|
||||
|
||||
assert 'hostname = [esp-ot-br.local]' in str(output_str)
|
||||
assert ('address = [' + ipv4_address + ']') in str(output_str)
|
||||
assert 'dn=DefaultDomain' in str(output_str)
|
||||
assert 'tv=1.3.0' in str(output_str)
|
||||
assert ('nn=' + networkname) in str(output_str)
|
||||
assert 'mn=BorderRouter' in str(output_str)
|
||||
assert 'vn=OpenThread' in str(output_str)
|
||||
assert 'rv=1' in str(output_str)
|
||||
finally:
|
||||
ocf.execute_command(br, 'factoryreset')
|
||||
time.sleep(3)
|
||||
|
@ -54,7 +54,7 @@ I (660) ESP_ZB_GATEWAY: status: -1
|
||||
I (670) ESP_ZB_GATEWAY: Zigbee stack initialized
|
||||
I (680) ESP_ZB_GATEWAY: Zigbee rcp device booted
|
||||
I (1280) ESP_ZB_GATEWAY: Start network formation
|
||||
I (3060) ESP_ZB_GATEWAY: Formed network successfully (ieee extended address: f9:54:2d:01:a0:03:f7:84, PAN ID: 0x8651)
|
||||
I (3060) ESP_ZB_GATEWAY: Formed network successfully (Extended PAN ID: f9:54:2d:01:a0:03:f7:84, PAN ID: 0x8651, Channel:13, Short Address: 0x0000)
|
||||
I (4060) ESP_ZB_GATEWAY: status: 0
|
||||
I (4400) ESP_ZB_GATEWAY: Network steering started
|
||||
```
|
||||
|
@ -1,38 +1,15 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: LicenseRef-Included
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* Zigbee Gateway Example
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Espressif Systems
|
||||
* integrated circuit in a product or a software update for such product,
|
||||
* must reproduce the above copyright notice, this list of conditions and
|
||||
* the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* 4. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* Unless required by applicable law or agreed to in writing, this
|
||||
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
@ -108,8 +85,13 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct)
|
||||
case ESP_ZB_BDB_SIGNAL_DEVICE_FIRST_START:
|
||||
case ESP_ZB_BDB_SIGNAL_DEVICE_REBOOT:
|
||||
if (err_status == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Start network formation");
|
||||
esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_NETWORK_FORMATION);
|
||||
ESP_LOGI(TAG, "Device started up in %s factory-reset mode", esp_zb_bdb_is_factory_new() ? "" : "non");
|
||||
if (esp_zb_bdb_is_factory_new()) {
|
||||
ESP_LOGI(TAG, "Start network formation");
|
||||
esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_NETWORK_FORMATION);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Device rebooted");
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize Zigbee stack (status: %s)", esp_err_to_name(err_status));
|
||||
}
|
||||
@ -118,10 +100,10 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct)
|
||||
if (err_status == ESP_OK) {
|
||||
esp_zb_ieee_addr_t ieee_address;
|
||||
esp_zb_get_long_address(ieee_address);
|
||||
ESP_LOGI(TAG, "Formed network successfully (ieee_address: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 0x%04hx, Channel:%d)",
|
||||
ESP_LOGI(TAG, "Formed network successfully (Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 0x%04hx, Channel:%d, Short Address: 0x%04hx)",
|
||||
ieee_address[7], ieee_address[6], ieee_address[5], ieee_address[4],
|
||||
ieee_address[3], ieee_address[2], ieee_address[1], ieee_address[0],
|
||||
esp_zb_get_pan_id(), esp_zb_get_current_channel());
|
||||
esp_zb_get_pan_id(), esp_zb_get_current_channel(), esp_zb_get_short_address());
|
||||
esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_NETWORK_STEERING);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Restart network formation (status: %s)", esp_err_to_name(err_status));
|
||||
@ -137,6 +119,15 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct)
|
||||
dev_annce_params = (esp_zb_zdo_signal_device_annce_params_t *)esp_zb_app_signal_get_params(p_sg_p);
|
||||
ESP_LOGI(TAG, "New device commissioned or rejoined (short: 0x%04hx)", dev_annce_params->device_short_addr);
|
||||
break;
|
||||
case ESP_ZB_NWK_SIGNAL_PERMIT_JOIN_STATUS:
|
||||
if (err_status == ESP_OK) {
|
||||
if (*(uint8_t *)esp_zb_app_signal_get_params(p_sg_p)) {
|
||||
ESP_LOGI(TAG, "Network(0x%04hx) is open for %d seconds", esp_zb_get_pan_id(), *(uint8_t *)esp_zb_app_signal_get_params(p_sg_p));
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Network(0x%04hx) closed, devices joining not allowed.", esp_zb_get_pan_id());
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ESP_LOGI(TAG, "ZDO signal: %s (0x%x), status: %s", esp_zb_zdo_signal_to_string(sig_type), sig_type,
|
||||
esp_err_to_name(err_status));
|
||||
@ -146,10 +137,9 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct)
|
||||
|
||||
static void esp_zb_task(void *pvParameters)
|
||||
{
|
||||
/* initialize Zigbee stack with Zigbee coordinator config */
|
||||
/* initialize Zigbee stack */
|
||||
esp_zb_cfg_t zb_nwk_cfg = ESP_ZB_ZC_CONFIG();
|
||||
esp_zb_init(&zb_nwk_cfg);
|
||||
/* initiate Zigbee Stack start without zb_send_no_autostart_signal auto-start */
|
||||
esp_zb_set_primary_network_channel_set(ESP_ZB_PRIMARY_CHANNEL_MASK);
|
||||
ESP_ERROR_CHECK(esp_zb_start(false));
|
||||
esp_zb_main_loop_iteration();
|
||||
@ -161,7 +151,7 @@ void app_main(void)
|
||||
.radio_config = ESP_ZB_DEFAULT_RADIO_CONFIG(),
|
||||
.host_config = ESP_ZB_DEFAULT_HOST_CONFIG(),
|
||||
};
|
||||
/* load Zigbee gateway platform config to initialization */
|
||||
|
||||
ESP_ERROR_CHECK(esp_zb_platform_config(&config));
|
||||
ESP_ERROR_CHECK(nvs_flash_init());
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
|
@ -1,38 +1,15 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: LicenseRef-Included
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* Zigbee Gateway Example
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Espressif Systems
|
||||
* integrated circuit in a product or a software update for such product,
|
||||
* must reproduce the above copyright notice, this list of conditions and
|
||||
* the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* 4. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* Unless required by applicable law or agreed to in writing, this
|
||||
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include "esp_err.h"
|
||||
|
@ -1,7 +1,7 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
espressif/esp-zboss-lib: "~0.7.0"
|
||||
espressif/esp-zigbee-lib: "~0.9.0"
|
||||
espressif/esp-zboss-lib: "1.0.9"
|
||||
espressif/esp-zigbee-lib: "1.0.9"
|
||||
## Required IDF version
|
||||
idf:
|
||||
version: ">=5.0.0"
|
||||
|
@ -2,6 +2,7 @@
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
nvs, data, nvs, 0x9000, 0x6000,
|
||||
phy_init, data, phy, 0xf000, 0x1000,
|
||||
factory, app, factory, 0x10000, 1150K,
|
||||
zb_storage, data, fat, , 16K,
|
||||
zb_fct, data, fat, , 1K,
|
||||
factory, app, factory, 0x10000, 1400K,
|
||||
zb_storage, data, fat, 0x16e000,16K,
|
||||
zb_fct, data, fat, 0x172000,1K,
|
||||
rcp_fw, data, spiffs, 0x173000,500k,
|
||||
|
|
@ -22,8 +22,7 @@ CONFIG_MBEDTLS_KEY_EXCHANGE_ECJPAKE=y
|
||||
CONFIG_MBEDTLS_ECJPAKE_C=y
|
||||
# end of mbedTLS
|
||||
|
||||
CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=n
|
||||
CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=n
|
||||
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=4096
|
||||
|
||||
#
|
||||
# Zboss
|
||||
|
@ -1,38 +1,15 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: LicenseRef-Included
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* Zigbee RCP Example
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Espressif Systems
|
||||
* integrated circuit in a product or a software update for such product,
|
||||
* must reproduce the above copyright notice, this list of conditions and
|
||||
* the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* 4. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* Unless required by applicable law or agreed to in writing, this
|
||||
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
@ -1,38 +1,15 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: LicenseRef-Included
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* Zigbee RCP Example
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Espressif Systems
|
||||
* integrated circuit in a product or a software update for such product,
|
||||
* must reproduce the above copyright notice, this list of conditions and
|
||||
* the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* 4. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* Unless required by applicable law or agreed to in writing, this
|
||||
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
#include "esp_zigbee_core.h"
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
espressif/esp-zboss-lib: "~0.7.0"
|
||||
espressif/esp-zigbee-lib: "~0.9.0"
|
||||
espressif/esp-zboss-lib: "1.0.9"
|
||||
espressif/esp-zigbee-lib: "1.0.9"
|
||||
## Required IDF version
|
||||
idf:
|
||||
version: ">=5.0.0"
|
||||
|
@ -2,5 +2,5 @@
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
nvs, data, nvs, 0x9000, 0x6000,
|
||||
phy_init, data, phy, 0xf000, 0x1000,
|
||||
factory, app, factory, 0x10000, 550K,
|
||||
factory, app, factory, 0x10000, 548K,
|
||||
zb_storage, data, fat, 0x9a000, 16K,
|
||||
|
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Partition Table
|
||||
#
|
||||
CONFIG_PARTITION_TABLE_SINGLE_APP=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||
|
@ -11,7 +11,7 @@ The ESP Zigbee SDK provides more examples and tools for productization:
|
||||
|
||||
## Hardware Required
|
||||
|
||||
* One development board with ESP32-H2 SoC acting as Zigbee end device (loaded with HA_on_off_light example)
|
||||
* One development board with ESP32-H2 SoC acting as Zigbee end-device (loaded with HA_on_off_light example)
|
||||
* A USB cable for power supply and programming
|
||||
* Choose another ESP32-H2 as Zigbee coordinator (see [HA_on_off_switch example](../HA_on_off_switch))
|
||||
|
||||
@ -33,18 +33,25 @@ Build the project, flash it to the board, and start the monitor tool to view the
|
||||
|
||||
As you run the example, you will see the following log:
|
||||
|
||||
light bulb:
|
||||
```
|
||||
I (918) ESP_ZB_LIGHT: status: 255
|
||||
I (901) ESP_ZB_LIGHT: Zigbee stack initialized
|
||||
I (901) ESP_ZB_LIGHT: Start network steering
|
||||
I (2611) ESP_ZB_LIGHT: Joined network successfully (Extended PAN ID: aa:98:48:01:a0:03:f7:84, PAN ID: 0x0e8b)
|
||||
I (5651) ESP_ZB_LIGHT: on/off light set to 1
|
||||
I (6631) ESP_ZB_LIGHT: on/off light set to 0
|
||||
I (7331) ESP_ZB_LIGHT: on/off light set to 1
|
||||
I (8251) ESP_ZB_LIGHT: on/off light set to 0
|
||||
I (9111) ESP_ZB_LIGHT: on/off light set to 1
|
||||
I (9671) ESP_ZB_LIGHT: on/off light set to 0
|
||||
I (394) main_task: Calling app_main()
|
||||
I (404) gpio: GPIO[8]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
|
||||
I (404) phy_init: phy_version 220,2dbbbe7,Sep 25 2023,20:39:25
|
||||
I (464) phy: libbtbb version: 90c587c, Sep 25 2023, 20:39:57
|
||||
I (474) ESP_ZB_COLOR_DIMM_LIGHT: ZDO signal: ZDO Config Ready (0x17), status: ESP_FAIL
|
||||
I (474) ESP_ZB_COLOR_DIMM_LIGHT: Zigbee stack initialized
|
||||
I (484) ESP_ZB_COLOR_DIMM_LIGHT: Start network steering
|
||||
I (484) main_task: Returned from app_main()
|
||||
I (9614) ESP_ZB_COLOR_DIMM_LIGHT: ZDO signal: NWK Permit Join (0x36), status: ESP_OK
|
||||
I (9834) ESP_ZB_COLOR_DIMM_LIGHT: ZDO signal: NWK Permit Join (0x36), status: ESP_OK
|
||||
I (9834) ESP_ZB_COLOR_DIMM_LIGHT: Joined network successfully (Extended PAN ID: 60:55:f9:00:00:f6:07:b4, PAN ID: 0x2a74, Channel:13)
|
||||
I (32944) ESP_ZB_COLOR_DIMM_LIGHT: Received message: endpoint(10), cluster(0x6), attribute(0x0), data size(1)
|
||||
I (32944) ESP_ZB_COLOR_DIMM_LIGHT: Light sets to On
|
||||
I (33984) ESP_ZB_COLOR_DIMM_LIGHT: Received message: endpoint(10), cluster(0x6), attribute(0x0), data size(1)
|
||||
I (33984) ESP_ZB_COLOR_DIMM_LIGHT: Light sets to Off
|
||||
I (35304) ESP_ZB_COLOR_DIMM_LIGHT: ZDO signal: NLME Status Indication (0x32), status: ESP_OK
|
||||
I (35534) ESP_ZB_COLOR_DIMM_LIGHT: Received message: endpoint(10), cluster(0x6), attribute(0x0), data size(1)
|
||||
I (35534) ESP_ZB_COLOR_DIMM_LIGHT: Light sets to On
|
||||
```
|
||||
|
||||
## Light Control Functions
|
||||
|
@ -1,38 +1,15 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: LicenseRef-Included
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* Zigbee HA_on_off_light Example
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Espressif Systems
|
||||
* integrated circuit in a product or a software update for such product,
|
||||
* must reproduce the above copyright notice, this list of conditions and
|
||||
* the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* 4. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* Unless required by applicable law or agreed to in writing, this
|
||||
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
@ -67,8 +44,13 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct)
|
||||
case ESP_ZB_BDB_SIGNAL_DEVICE_FIRST_START:
|
||||
case ESP_ZB_BDB_SIGNAL_DEVICE_REBOOT:
|
||||
if (err_status == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Start network steering");
|
||||
esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_NETWORK_STEERING);
|
||||
ESP_LOGI(TAG, "Device started up in %s factory-reset mode", esp_zb_bdb_is_factory_new() ? "" : "non");
|
||||
if (esp_zb_bdb_is_factory_new()) {
|
||||
ESP_LOGI(TAG, "Start network steering");
|
||||
esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_NETWORK_STEERING);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Device rebooted");
|
||||
}
|
||||
} else {
|
||||
/* commissioning failed */
|
||||
ESP_LOGW(TAG, "Failed to initialize Zigbee stack (status: %s)", esp_err_to_name(err_status));
|
||||
@ -78,10 +60,10 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct)
|
||||
if (err_status == ESP_OK) {
|
||||
esp_zb_ieee_addr_t extended_pan_id;
|
||||
esp_zb_get_extended_pan_id(extended_pan_id);
|
||||
ESP_LOGI(TAG, "Joined network successfully (Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 0x%04hx, Channel:%d)",
|
||||
ESP_LOGI(TAG, "Joined network successfully (Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 0x%04hx, Channel:%d, Short Address: 0x%04hx)",
|
||||
extended_pan_id[7], extended_pan_id[6], extended_pan_id[5], extended_pan_id[4],
|
||||
extended_pan_id[3], extended_pan_id[2], extended_pan_id[1], extended_pan_id[0],
|
||||
esp_zb_get_pan_id(), esp_zb_get_current_channel());
|
||||
esp_zb_get_pan_id(), esp_zb_get_current_channel(), esp_zb_get_short_address());
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Network steering was not successful (status: %s)", esp_err_to_name(err_status));
|
||||
esp_zb_scheduler_alarm((esp_zb_callback_t)bdb_start_top_level_commissioning_cb, ESP_ZB_BDB_MODE_NETWORK_STEERING, 1000);
|
||||
@ -100,14 +82,13 @@ static esp_err_t zb_attribute_handler(const esp_zb_zcl_set_attr_value_message_t
|
||||
bool light_state = 0;
|
||||
|
||||
ESP_RETURN_ON_FALSE(message, ESP_FAIL, TAG, "Empty message");
|
||||
ESP_RETURN_ON_FALSE(message->info.status == ESP_ZB_ZCL_STATUS_SUCCESS, ESP_ERR_INVALID_ARG, TAG,
|
||||
"Received message: error status(%d)", message->info.status);
|
||||
ESP_LOGI(TAG, "Received message: endpoint(%d), cluster(0x%x), attribute(0x%x), data size(%d)",
|
||||
message->info.dst_endpoint, message->info.cluster, message->attribute.id, message->attribute.data.size);
|
||||
ESP_RETURN_ON_FALSE(message->info.status == ESP_ZB_ZCL_STATUS_SUCCESS, ESP_ERR_INVALID_ARG, TAG, "Received message: error status(%d)",
|
||||
message->info.status);
|
||||
ESP_LOGI(TAG, "Received message: endpoint(%d), cluster(0x%x), attribute(0x%x), data size(%d)", message->info.dst_endpoint, message->info.cluster,
|
||||
message->attribute.id, message->attribute.data.size);
|
||||
if (message->info.dst_endpoint == HA_ESP_LIGHT_ENDPOINT) {
|
||||
if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_ON_OFF) {
|
||||
if (message->attribute.id == ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID &&
|
||||
message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_BOOL) {
|
||||
if (message->attribute.id == ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_BOOL) {
|
||||
light_state = message->attribute.data.value ? *(bool *)message->attribute.data.value : light_state;
|
||||
ESP_LOGI(TAG, "Light sets to %s", light_state ? "On" : "Off");
|
||||
light_driver_set_power(light_state);
|
||||
|
@ -1,49 +1,27 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: LicenseRef-Included
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* Zigbee HA_on_off_light Example
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Espressif Systems
|
||||
* integrated circuit in a product or a software update for such product,
|
||||
* must reproduce the above copyright notice, this list of conditions and
|
||||
* the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* 4. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* Unless required by applicable law or agreed to in writing, this
|
||||
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include "esp_zigbee_core.h"
|
||||
#include "light_driver.h"
|
||||
|
||||
/* Zigbee configuration */
|
||||
#define INSTALLCODE_POLICY_ENABLE false /* enable the install code policy for security */
|
||||
#define INSTALLCODE_POLICY_ENABLE false /* enable the install code policy for security */
|
||||
#define ED_AGING_TIMEOUT ESP_ZB_ED_AGING_TIMEOUT_64MIN
|
||||
#define ED_KEEP_ALIVE 3000 /* 3000 millisecond */
|
||||
#define HA_ESP_LIGHT_ENDPOINT 10 /* esp light bulb device endpoint, used to process light controlling commands */
|
||||
#define HA_ESP_LIGHT_ENDPOINT 10 /* esp light bulb device endpoint, used to process light controlling commands */
|
||||
#define ESP_ZB_PRIMARY_CHANNEL_MASK ESP_ZB_TRANSCEIVER_ALL_CHANNELS_MASK /* Zigbee primary channel mask use in the example */
|
||||
|
||||
#define ESP_ZB_ZED_CONFIG() \
|
||||
{ \
|
||||
.esp_zb_role = ESP_ZB_DEVICE_TYPE_ED, \
|
||||
|
@ -1,7 +1,7 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
espressif/esp-zigbee-lib: "~0.9.0"
|
||||
espressif/esp-zboss-lib: "~0.7.0"
|
||||
espressif/esp-zboss-lib: "1.0.9"
|
||||
espressif/esp-zigbee-lib: "1.0.9"
|
||||
espressif/led_strip: "~2.0.0"
|
||||
## Required IDF version
|
||||
idf:
|
||||
|
@ -2,6 +2,6 @@
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
nvs, data, nvs, 0x9000, 0x6000,
|
||||
phy_init, data, phy, 0xf000, 0x1000,
|
||||
factory, app, factory, 0x10000, 650K,
|
||||
zb_storage, data, fat, 0xb3000, 16K,
|
||||
zb_fct, data, fat, 0xb7000, 1K,
|
||||
factory, app, factory, 0x10000, 900K,
|
||||
zb_storage, data, fat, 0xf1000, 16K,
|
||||
zb_fct, data, fat, 0xf5000, 1K,
|
||||
|
|
@ -22,8 +22,6 @@ CONFIG_MBEDTLS_KEY_EXCHANGE_ECJPAKE=y
|
||||
CONFIG_MBEDTLS_ECJPAKE_C=y
|
||||
# end of mbedTLS
|
||||
|
||||
CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=n
|
||||
|
||||
#
|
||||
# Zboss
|
||||
#
|
||||
|
@ -33,30 +33,32 @@ Build the project, flash it to the board, and start the monitor tool to view the
|
||||
|
||||
As you run the example, you will see the following log:
|
||||
|
||||
light switch:
|
||||
```
|
||||
I (318) gpio: GPIO[9]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:2
|
||||
I (328) system_api: Base MAC address is not set
|
||||
I (328) system_api: read default base MAC address from EFUSE
|
||||
I (408) phy: libbtbb version: 6c47ec3, Mar 16 2022, 18:54:24
|
||||
I (408) phy: phy_version: 101, bb2a234, Mar 16 2022, 18:54:11
|
||||
I (818) ESP_ZB_ON_OFF_SWITCH: status: 255
|
||||
I (818) ESP_ZB_ON_OFF_SWITCH: Zigbee stack initialized
|
||||
I (818) ESP_ZB_ON_OFF_SWITCH: Start network formation
|
||||
I (1318) ESP_ZB_ON_OFF_SWITCH: Formed network successfully (Extended PAN ID: ff:fc:7c:c0:f0:bd:97:10, PAN ID: 0x88e7)
|
||||
I (1778) ESP_ZB_ON_OFF_SWITCH: status: 0
|
||||
I (5528) ESP_ZB_ON_OFF_SWITCH: status: 0
|
||||
I (6038) ESP_ZB_ON_OFF_SWITCH: status: 0
|
||||
I (6068) ESP_ZB_ON_OFF_SWITCH: New device commissioned or rejoined (short: 0x2878)
|
||||
I (6098) ESP_ZB_ON_OFF_SWITCH: User find cb: address:0x2878, endpoint:10
|
||||
I (6638) ESP_ZB_ON_OFF_SWITCH: status: 0
|
||||
I (6678) ESP_ZB_ON_OFF_SWITCH: status: 0
|
||||
I (8168) ESP_ZB_ON_OFF_SWITCH: send move to on_off toggle command
|
||||
I (8898) ESP_ZB_ON_OFF_SWITCH: send move to on_off toggle command
|
||||
I (9458) ESP_ZB_ON_OFF_SWITCH: send move to on_off toggle command
|
||||
I (10088) ESP_ZB_ON_OFF_SWITCH: send move to on_off toggle command
|
||||
I (10588) ESP_ZB_ON_OFF_SWITCH: send move to on_off toggle command
|
||||
I (11098) ESP_ZB_ON_OFF_SWITCH: send move to on_off toggle command
|
||||
I (388) main_task: Calling app_main()
|
||||
I (398) gpio: GPIO[9]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:2
|
||||
I (398) phy_init: phy_version 220,2dbbbe7,Sep 25 2023,20:39:25
|
||||
I (478) phy: libbtbb version: 90c587c, Sep 25 2023, 20:39:57
|
||||
I (488) ESP_ZB_ON_OFF_SWITCH: ZDO signal: ZDO Config Ready (0x17), status: ESP_FAIL
|
||||
I (488) ESP_ZB_ON_OFF_SWITCH: Zigbee stack initialized
|
||||
I (488) ESP_ZB_ON_OFF_SWITCH: Start network formation
|
||||
I (498) main_task: Returned from app_main()
|
||||
I (998) ESP_ZB_ON_OFF_SWITCH: ZDO signal: NWK Permit Join (0x36), status: ESP_OK
|
||||
I (998) ESP_ZB_ON_OFF_SWITCH: Formed network successfully (Extended PAN ID: 60:55:f9:00:00:f6:07:b4, PAN ID: 0x2a74, Channel:13)
|
||||
I (1468) ESP_ZB_ON_OFF_SWITCH: ZDO signal: NWK Permit Join (0x36), status: ESP_OK
|
||||
I (1468) ESP_ZB_ON_OFF_SWITCH: Network steering started
|
||||
I (14228) ESP_ZB_ON_OFF_SWITCH: ZDO signal: NWK Device Associated (0x12), status: ESP_OK
|
||||
I (14728) ESP_ZB_ON_OFF_SWITCH: ZDO signal: ZDO Device Update (0x30), status: ESP_OK
|
||||
I (14788) ESP_ZB_ON_OFF_SWITCH: New device commissioned or rejoined (short: 0xe399)
|
||||
I (14858) ESP_ZB_ON_OFF_SWITCH: Found light
|
||||
I (14858) ESP_ZB_ON_OFF_SWITCH: Try to bind On/Off
|
||||
I (14858) ESP_ZB_ON_OFF_SWITCH: Bound successfully!
|
||||
I (14858) ESP_ZB_ON_OFF_SWITCH: The light originating from address(0xe399) on endpoint(10)
|
||||
I (15338) ESP_ZB_ON_OFF_SWITCH: ZDO signal: ZDO Device Authorized (0x2f), status: ESP_OK
|
||||
I (15408) ESP_ZB_ON_OFF_SWITCH: ZDO signal: NWK Permit Join (0x36), status: ESP_OK
|
||||
I (35838) ESP_ZB_ON_OFF_SWITCH: ZDO signal: NLME Status Indication (0x32), status: ESP_OK
|
||||
I (38548) ESP_ZB_ON_OFF_SWITCH: Send 'on_off toggle' command
|
||||
I (39598) ESP_ZB_ON_OFF_SWITCH: Send 'on_off toggle' command
|
||||
I (41148) ESP_ZB_ON_OFF_SWITCH: Send 'on_off toggle' command
|
||||
```
|
||||
|
||||
## Light Control Functions
|
||||
|
@ -1,38 +1,15 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: LicenseRef-Included
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* Zigbee HA_on_off_switch Example
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Espressif Systems
|
||||
* integrated circuit in a product or a software update for such product,
|
||||
* must reproduce the above copyright notice, this list of conditions and
|
||||
* the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* 4. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* Unless required by applicable law or agreed to in writing, this
|
||||
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include "string.h"
|
||||
@ -82,8 +59,7 @@ static void bind_cb(esp_zb_zdp_status_t zdo_status, void *user_ctx)
|
||||
ESP_LOGI(TAG, "Bound successfully!");
|
||||
if (user_ctx) {
|
||||
light_bulb_device_params_t *light = (light_bulb_device_params_t *)user_ctx;
|
||||
ESP_LOGI(TAG, "The light originating from address(0x%x) on endpoint(%d)", light->short_addr,
|
||||
light->endpoint);
|
||||
ESP_LOGI(TAG, "The light originating from address(0x%x) on endpoint(%d)", light->short_addr, light->endpoint);
|
||||
free(light);
|
||||
}
|
||||
}
|
||||
@ -124,8 +100,13 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct)
|
||||
case ESP_ZB_BDB_SIGNAL_DEVICE_FIRST_START:
|
||||
case ESP_ZB_BDB_SIGNAL_DEVICE_REBOOT:
|
||||
if (err_status == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Start network formation");
|
||||
esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_NETWORK_FORMATION);
|
||||
ESP_LOGI(TAG, "Device started up in %s factory-reset mode", esp_zb_bdb_is_factory_new() ? "" : "non");
|
||||
if (esp_zb_bdb_is_factory_new()) {
|
||||
ESP_LOGI(TAG, "Start network formation");
|
||||
esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_NETWORK_FORMATION);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Device rebooted");
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize Zigbee stack (status: %s)", esp_err_to_name(err_status));
|
||||
}
|
||||
@ -134,10 +115,10 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct)
|
||||
if (err_status == ESP_OK) {
|
||||
esp_zb_ieee_addr_t extended_pan_id;
|
||||
esp_zb_get_extended_pan_id(extended_pan_id);
|
||||
ESP_LOGI(TAG, "Formed network successfully (Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 0x%04hx, Channel:%d)",
|
||||
ESP_LOGI(TAG, "Formed network successfully (Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 0x%04hx, Channel:%d, Short Address: 0x%04hx)",
|
||||
extended_pan_id[7], extended_pan_id[6], extended_pan_id[5], extended_pan_id[4],
|
||||
extended_pan_id[3], extended_pan_id[2], extended_pan_id[1], extended_pan_id[0],
|
||||
esp_zb_get_pan_id(), esp_zb_get_current_channel());
|
||||
esp_zb_get_pan_id(), esp_zb_get_current_channel(), esp_zb_get_short_address());
|
||||
esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_NETWORK_STEERING);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Restart network formation (status: %s)", esp_err_to_name(err_status));
|
||||
@ -157,6 +138,15 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct)
|
||||
cmd_req.addr_of_interest = dev_annce_params->device_short_addr;
|
||||
esp_zb_zdo_find_on_off_light(&cmd_req, user_find_cb, NULL);
|
||||
break;
|
||||
case ESP_ZB_NWK_SIGNAL_PERMIT_JOIN_STATUS:
|
||||
if (err_status == ESP_OK) {
|
||||
if (*(uint8_t *)esp_zb_app_signal_get_params(p_sg_p)) {
|
||||
ESP_LOGI(TAG, "Network(0x%04hx) is open for %d seconds", esp_zb_get_pan_id(), *(uint8_t *)esp_zb_app_signal_get_params(p_sg_p));
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Network(0x%04hx) closed, devices joining not allowed.", esp_zb_get_pan_id());
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ESP_LOGI(TAG, "ZDO signal: %s (0x%x), status: %s", esp_zb_zdo_signal_to_string(sig_type), sig_type,
|
||||
esp_err_to_name(err_status));
|
||||
|
@ -1,47 +1,24 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: LicenseRef-Included
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* Zigbee HA_on_off_switch Example
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Espressif Systems
|
||||
* integrated circuit in a product or a software update for such product,
|
||||
* must reproduce the above copyright notice, this list of conditions and
|
||||
* the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* 4. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* Unless required by applicable law or agreed to in writing, this
|
||||
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
#include "esp_zigbee_core.h"
|
||||
#include "switch_driver.h"
|
||||
|
||||
/* Zigbee configuration */
|
||||
#define MAX_CHILDREN 10 /* the max amount of connected devices */
|
||||
#define INSTALLCODE_POLICY_ENABLE false /* enable the install code policy for security */
|
||||
#define HA_ONOFF_SWITCH_ENDPOINT 1 /* esp light switch device endpoint */
|
||||
#define ESP_ZB_PRIMARY_CHANNEL_MASK ESP_ZB_TRANSCEIVER_ALL_CHANNELS_MASK /* Zigbee primary channel mask use in the example */
|
||||
#define INSTALLCODE_POLICY_ENABLE false /* enable the install code policy for security */
|
||||
#define HA_ONOFF_SWITCH_ENDPOINT 1 /* esp light switch device endpoint */
|
||||
#define ESP_ZB_PRIMARY_CHANNEL_MASK (1l << 13) /* Zigbee primary channel mask use in the example */
|
||||
|
||||
#define ESP_ZB_ZC_CONFIG() \
|
||||
{ \
|
||||
|
@ -1,7 +1,7 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
espressif/esp-zigbee-lib: "~0.9.0"
|
||||
espressif/esp-zboss-lib: "~0.7.0"
|
||||
espressif/esp-zboss-lib: "1.0.9"
|
||||
espressif/esp-zigbee-lib: "1.0.9"
|
||||
## Required IDF version
|
||||
idf:
|
||||
version: ">=5.0.0"
|
||||
|
@ -2,6 +2,6 @@
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
nvs, data, nvs, 0x9000, 0x6000,
|
||||
phy_init, data, phy, 0xf000, 0x1000,
|
||||
factory, app, factory, 0x10000, 650K,
|
||||
zb_storage, data, fat, 0xb3000, 16K,
|
||||
zb_fct, data, fat, 0xb7000, 1K,
|
||||
factory, app, factory, 0x10000, 900K,
|
||||
zb_storage, data, fat, 0xf1000, 16K,
|
||||
zb_fct, data, fat, 0xf5000, 1K,
|
||||
|
|
@ -22,8 +22,6 @@ CONFIG_MBEDTLS_KEY_EXCHANGE_ECJPAKE=y
|
||||
CONFIG_MBEDTLS_ECJPAKE_C=y
|
||||
# end of mbedTLS
|
||||
|
||||
CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=n
|
||||
|
||||
#
|
||||
# Zboss
|
||||
#
|
||||
|
@ -20,7 +20,6 @@ submodules:
|
||||
- "/components/esp_phy/lib/"
|
||||
- "/components/esp_wifi/lib/"
|
||||
- "/components/heap/tlsf/"
|
||||
- "/components/ieee802154/lib/"
|
||||
- "/components/json/cJSON/"
|
||||
- "/components/lwip/lwip/"
|
||||
- "/components/mbedtls/mbedtls/"
|
||||
|
@ -18,7 +18,6 @@ skip:
|
||||
- "components/esp_phy/lib"
|
||||
- "components/esp_wifi/lib"
|
||||
- "components/esp_wifi/lib_esp32"
|
||||
- "components/ieee802154/lib"
|
||||
- "components/json/cJSON"
|
||||
- "components/lwip/lwip"
|
||||
- "components/mbedtls/mbedtls"
|
||||
|
Loading…
x
Reference in New Issue
Block a user