mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-29 20:05:09 +00:00
Merge branch 'feat/update_ot_jan2026_v6.0' into 'release/v6.0'
feat(openthread): update OT to 9b887f6bd (v6.0) See merge request espressif/esp-idf!46758
This commit is contained in:
@@ -8,8 +8,4 @@
|
||||
|
||||
#include "hal/ieee802154_common_ll.h"
|
||||
|
||||
#define IEEE802154_TXPOWER_VALUE_MAX 20
|
||||
#define IEEE802154_TXPOWER_VALUE_MIN -15
|
||||
#define IEEE802154_TXPOWER_INDEX_MIN 3
|
||||
|
||||
#define IEEE802154_RSSI_COMPENSATION_VALUE 0
|
||||
|
||||
@@ -8,8 +8,4 @@
|
||||
|
||||
#include "hal/ieee802154_common_ll.h"
|
||||
|
||||
#define IEEE802154_TXPOWER_VALUE_MAX 20
|
||||
#define IEEE802154_TXPOWER_VALUE_MIN -15
|
||||
#define IEEE802154_TXPOWER_INDEX_MIN 3
|
||||
|
||||
#define IEEE802154_RSSI_COMPENSATION_VALUE 0
|
||||
|
||||
@@ -14,10 +14,6 @@ extern "C" {
|
||||
|
||||
extern uint32_t bt_bb_get_rssi_comp(void);
|
||||
|
||||
#define IEEE802154_TXPOWER_VALUE_MAX 20
|
||||
#define IEEE802154_TXPOWER_VALUE_MIN -24
|
||||
#define IEEE802154_TXPOWER_INDEX_MIN 0
|
||||
|
||||
#define IEEE802154_RSSI_COMPENSATION_VALUE bt_bb_get_rssi_comp()
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -414,6 +414,11 @@ static inline void ieee802154_ll_set_pending_mode(bool enable)
|
||||
IEEE802154.conf.pending_enhance = enable;
|
||||
}
|
||||
|
||||
static inline bool ieee802154_ll_get_pending_mode(void)
|
||||
{
|
||||
return IEEE802154.conf.pending_enhance;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void ieee802154_ll_set_pending_bit(bool pending)
|
||||
{
|
||||
IEEE802154.pending_cfg.pending = pending;
|
||||
|
||||
+1
-1
Submodule components/esp_phy/lib updated: 3d57415af6...ac744ff2c5
@@ -72,6 +72,16 @@ menu "IEEE 802.15.4"
|
||||
help
|
||||
Enable IEEE802154 multi-pan
|
||||
|
||||
config IEEE802154_INTERFACE_NUM
|
||||
int "Number of IEEE802154 interfaces"
|
||||
depends on IEEE802154_ENABLED
|
||||
range 1 1 if !IEEE802154_MULTI_PAN_ENABLE
|
||||
range 1 4 if IEEE802154_MULTI_PAN_ENABLE
|
||||
default 1 if !IEEE802154_MULTI_PAN_ENABLE
|
||||
default 2 if IEEE802154_MULTI_PAN_ENABLE
|
||||
help
|
||||
Number of IEEE802154 interfaces
|
||||
|
||||
config IEEE802154_TIMING_OPTIMIZATION
|
||||
bool "Enable throughput optimization"
|
||||
depends on IEEE802154_ENABLED
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "esp_ieee802154_types.h"
|
||||
#include "esp_ieee802154_util.h"
|
||||
|
||||
static ieee802154_pending_table_t ieee802154_pending_table;
|
||||
static ieee802154_pending_table_t ieee802154_pending_table[CONFIG_IEEE802154_INTERFACE_NUM];
|
||||
|
||||
#define GET_MASK_ITEM_FROM_TABLE(mask, pos) (mask[(pos) / IEEE802154_PENDING_TABLE_MASK_BITS])
|
||||
|
||||
@@ -23,21 +23,21 @@ static ieee802154_pending_table_t ieee802154_pending_table;
|
||||
#define BIT_CLR(mask, pos) (GET_MASK_ITEM_FROM_TABLE(mask, pos) &= ~(1UL << (pos % IEEE802154_PENDING_TABLE_MASK_BITS)))
|
||||
#define BIT_IST(mask, pos) (GET_MASK_ITEM_FROM_TABLE(mask, pos) & (1UL << (pos % IEEE802154_PENDING_TABLE_MASK_BITS)))
|
||||
|
||||
static IRAM_ATTR bool ieee802154_addr_in_pending_table(const uint8_t *addr, bool is_short)
|
||||
static IRAM_ATTR bool ieee802154_addr_in_pending_table(esp_ieee802154_multipan_index_t inf_index, const uint8_t *addr, bool is_short)
|
||||
{
|
||||
bool ret = false;
|
||||
if (is_short) {
|
||||
for (uint8_t index = 0; index < CONFIG_IEEE802154_PENDING_TABLE_SIZE; index++) {
|
||||
if (BIT_IST(ieee802154_pending_table.short_addr_mask, index) &&
|
||||
memcmp(addr, ieee802154_pending_table.short_addr[index], IEEE802154_FRAME_SHORT_ADDR_SIZE) == 0) {
|
||||
if (BIT_IST(ieee802154_pending_table[inf_index].short_addr_mask, index) &&
|
||||
memcmp(addr, ieee802154_pending_table[inf_index].short_addr[index], IEEE802154_FRAME_SHORT_ADDR_SIZE) == 0) {
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (uint8_t index = 0; index < CONFIG_IEEE802154_PENDING_TABLE_SIZE; index++) {
|
||||
if (BIT_IST(ieee802154_pending_table.ext_addr_mask, index) &&
|
||||
memcmp(addr, ieee802154_pending_table.ext_addr[index], IEEE802154_FRAME_EXT_ADDR_SIZE) == 0) {
|
||||
if (BIT_IST(ieee802154_pending_table[inf_index].ext_addr_mask, index) &&
|
||||
memcmp(addr, ieee802154_pending_table[inf_index].ext_addr[index], IEEE802154_FRAME_EXT_ADDR_SIZE) == 0) {
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
@@ -46,63 +46,63 @@ static IRAM_ATTR bool ieee802154_addr_in_pending_table(const uint8_t *addr, bool
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t ieee802154_add_pending_addr(const uint8_t *addr, bool is_short)
|
||||
esp_err_t ieee802154_add_pending_addr(esp_ieee802154_multipan_index_t inf_index, const uint8_t *addr, bool is_short)
|
||||
{
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
int8_t first_empty_index = -1;
|
||||
if (is_short) {
|
||||
for (uint8_t index = 0; index < CONFIG_IEEE802154_PENDING_TABLE_SIZE; index++) {
|
||||
if (!BIT_IST(ieee802154_pending_table.short_addr_mask, index)) {
|
||||
if (!BIT_IST(ieee802154_pending_table[inf_index].short_addr_mask, index)) {
|
||||
// record the first empty index
|
||||
first_empty_index = (first_empty_index == -1 ? index : first_empty_index);
|
||||
} else if (memcmp(addr, ieee802154_pending_table.short_addr[index], IEEE802154_FRAME_SHORT_ADDR_SIZE) == 0) {
|
||||
} else if (memcmp(addr, ieee802154_pending_table[inf_index].short_addr[index], IEEE802154_FRAME_SHORT_ADDR_SIZE) == 0) {
|
||||
// The address is in the table already.
|
||||
ret = ESP_OK;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (first_empty_index != -1) {
|
||||
memcpy(ieee802154_pending_table.short_addr[first_empty_index], addr, IEEE802154_FRAME_SHORT_ADDR_SIZE);
|
||||
BIT_SET(ieee802154_pending_table.short_addr_mask, first_empty_index);
|
||||
memcpy(ieee802154_pending_table[inf_index].short_addr[first_empty_index], addr, IEEE802154_FRAME_SHORT_ADDR_SIZE);
|
||||
BIT_SET(ieee802154_pending_table[inf_index].short_addr_mask, first_empty_index);
|
||||
ret = ESP_OK;
|
||||
}
|
||||
} else {
|
||||
for (uint8_t index = 0; index < CONFIG_IEEE802154_PENDING_TABLE_SIZE; index++) {
|
||||
if (!BIT_IST(ieee802154_pending_table.ext_addr_mask, index)) {
|
||||
if (!BIT_IST(ieee802154_pending_table[inf_index].ext_addr_mask, index)) {
|
||||
first_empty_index = (first_empty_index == -1 ? index : first_empty_index);
|
||||
} else if (memcmp(addr, ieee802154_pending_table.ext_addr[index], IEEE802154_FRAME_EXT_ADDR_SIZE) == 0) {
|
||||
} else if (memcmp(addr, ieee802154_pending_table[inf_index].ext_addr[index], IEEE802154_FRAME_EXT_ADDR_SIZE) == 0) {
|
||||
// The address is already in the pending table.
|
||||
ret = ESP_OK;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (first_empty_index != -1) {
|
||||
memcpy(ieee802154_pending_table.ext_addr[first_empty_index], addr, IEEE802154_FRAME_EXT_ADDR_SIZE);
|
||||
BIT_SET(ieee802154_pending_table.ext_addr_mask, first_empty_index);
|
||||
memcpy(ieee802154_pending_table[inf_index].ext_addr[first_empty_index], addr, IEEE802154_FRAME_EXT_ADDR_SIZE);
|
||||
BIT_SET(ieee802154_pending_table[inf_index].ext_addr_mask, first_empty_index);
|
||||
ret = ESP_OK;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t ieee802154_clear_pending_addr(const uint8_t *addr, bool is_short)
|
||||
esp_err_t ieee802154_clear_pending_addr(esp_ieee802154_multipan_index_t inf_index, const uint8_t *addr, bool is_short)
|
||||
{
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
// Consider this function may be called in ISR, only clear the mask bits for finishing the process quickly.
|
||||
if (is_short) {
|
||||
for (uint8_t index = 0; index < CONFIG_IEEE802154_PENDING_TABLE_SIZE; index++) {
|
||||
if (BIT_IST(ieee802154_pending_table.short_addr_mask, index) &&
|
||||
memcmp(addr, ieee802154_pending_table.short_addr[index], IEEE802154_FRAME_SHORT_ADDR_SIZE) == 0) {
|
||||
BIT_CLR(ieee802154_pending_table.short_addr_mask, index);
|
||||
if (BIT_IST(ieee802154_pending_table[inf_index].short_addr_mask, index) &&
|
||||
memcmp(addr, ieee802154_pending_table[inf_index].short_addr[index], IEEE802154_FRAME_SHORT_ADDR_SIZE) == 0) {
|
||||
BIT_CLR(ieee802154_pending_table[inf_index].short_addr_mask, index);
|
||||
ret = ESP_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (uint8_t index = 0; index < CONFIG_IEEE802154_PENDING_TABLE_SIZE; index++) {
|
||||
if (BIT_IST(ieee802154_pending_table.ext_addr_mask, index) &&
|
||||
memcmp(addr, ieee802154_pending_table.ext_addr[index], IEEE802154_FRAME_EXT_ADDR_SIZE) == 0) {
|
||||
BIT_CLR(ieee802154_pending_table.ext_addr_mask, index);
|
||||
if (BIT_IST(ieee802154_pending_table[inf_index].ext_addr_mask, index) &&
|
||||
memcmp(addr, ieee802154_pending_table[inf_index].ext_addr[index], IEEE802154_FRAME_EXT_ADDR_SIZE) == 0) {
|
||||
BIT_CLR(ieee802154_pending_table[inf_index].ext_addr_mask, index);
|
||||
ret = ESP_OK;
|
||||
break;
|
||||
}
|
||||
@@ -112,26 +112,42 @@ esp_err_t ieee802154_clear_pending_addr(const uint8_t *addr, bool is_short)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ieee802154_reset_pending_table(bool is_short)
|
||||
void ieee802154_reset_pending_table(esp_ieee802154_multipan_index_t inf_index, bool is_short)
|
||||
{
|
||||
// Consider this function may be called in ISR, only clear the mask bits for finishing the process quickly.
|
||||
if (is_short) {
|
||||
memset(ieee802154_pending_table.short_addr_mask, 0, IEEE802154_PENDING_TABLE_MASK_SIZE);
|
||||
memset(ieee802154_pending_table[inf_index].short_addr_mask, 0, IEEE802154_PENDING_TABLE_MASK_SIZE);
|
||||
} else {
|
||||
memset(ieee802154_pending_table.ext_addr_mask, 0, IEEE802154_PENDING_TABLE_MASK_SIZE);
|
||||
memset(ieee802154_pending_table[inf_index].ext_addr_mask, 0, IEEE802154_PENDING_TABLE_MASK_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
bool ieee802154_ack_config_pending_bit(const uint8_t *frame)
|
||||
bool ieee802154_ack_config_pending_bit(const uint8_t *frame, const esp_ieee802154_frame_info_t *frame_info)
|
||||
{
|
||||
esp_ieee802154_multipan_index_t inf_index = 0;
|
||||
#if CONFIG_IEEE802154_MULTI_PAN_ENABLE
|
||||
inf_index = frame_info->mpf_index;
|
||||
if (inf_index >= ESP_IEEE802154_MULTIPAN_MAX || inf_index < ESP_IEEE802154_MULTIPAN_0) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
bool pending_bit = false;
|
||||
uint8_t addr[IEEE802154_FRAME_EXT_ADDR_SIZE] = {0};
|
||||
uint8_t src_mode = 0;
|
||||
// Only set the HW pending bit for the frames with version 0b00 or 0b01.
|
||||
bool set_to_hw = (ieee802154_frame_get_version(frame) <= IEEE802154_FRAME_VERSION_1);
|
||||
|
||||
ieee802154_ll_pending_mode_t pending_mode = ieee802154_pib_get_pending_mode();
|
||||
// Check whether the frame is a Data Request.
|
||||
if (ieee802154_ll_get_pending_mode()) {
|
||||
pending_bit = ieee802154_is_data_request(frame);
|
||||
}
|
||||
|
||||
ieee802154_ll_pending_mode_t pending_mode = ieee802154_pib_get_pending_mode(inf_index);
|
||||
|
||||
src_mode = ieee802154_frame_get_src_addr(frame, addr);
|
||||
if (src_mode == IEEE802154_FRAME_INVALID_VALUE) {
|
||||
goto exit;
|
||||
}
|
||||
switch (pending_mode) {
|
||||
case IEEE802154_AUTO_PENDING_DISABLE:
|
||||
// HW will check whether the frame is data request or not
|
||||
@@ -139,19 +155,14 @@ bool ieee802154_ack_config_pending_bit(const uint8_t *frame)
|
||||
break;
|
||||
case IEEE802154_AUTO_PENDING_ENABLE:
|
||||
case IEEE802154_AUTO_PENDING_ENHANCED:
|
||||
src_mode = ieee802154_frame_get_src_addr(frame, addr);
|
||||
|
||||
if (src_mode == IEEE802154_FRAME_SRC_MODE_SHORT || src_mode == IEEE802154_FRAME_SRC_MODE_EXT) {
|
||||
if (ieee802154_addr_in_pending_table(addr, src_mode == IEEE802154_FRAME_SRC_MODE_SHORT)) {
|
||||
pending_bit = true;
|
||||
}
|
||||
pending_bit = ieee802154_addr_in_pending_table(inf_index, addr, src_mode == IEEE802154_FRAME_SRC_MODE_SHORT);
|
||||
}
|
||||
break;
|
||||
case IEEE802154_AUTO_PENDING_ZIGBEE:
|
||||
// If the address type is short and in pending table, set 'pending_bit' false, otherwise set true.
|
||||
src_mode = ieee802154_frame_get_src_addr(frame, addr);
|
||||
pending_bit = true;
|
||||
if (src_mode == IEEE802154_FRAME_SRC_MODE_SHORT && ieee802154_addr_in_pending_table(addr, src_mode == IEEE802154_FRAME_SRC_MODE_SHORT)) {
|
||||
if (src_mode == IEEE802154_FRAME_SRC_MODE_SHORT && ieee802154_addr_in_pending_table(inf_index, addr, src_mode == IEEE802154_FRAME_SRC_MODE_SHORT)) {
|
||||
pending_bit = false;
|
||||
}
|
||||
break;
|
||||
@@ -159,6 +170,7 @@ bool ieee802154_ack_config_pending_bit(const uint8_t *frame)
|
||||
IEEE802154_ASSERT(false);
|
||||
}
|
||||
|
||||
exit:
|
||||
if (set_to_hw) {
|
||||
ieee802154_ll_set_pending_bit(pending_bit);
|
||||
}
|
||||
|
||||
@@ -77,6 +77,16 @@ static char *ieee802154_state_string[] = {
|
||||
"ED",
|
||||
"CCA",
|
||||
};
|
||||
|
||||
static char *ieee802154_state_to_string(ieee802154_state_t state)
|
||||
{
|
||||
char *state_string = "INVALID";
|
||||
if (state < sizeof(ieee802154_state_string) / sizeof(ieee802154_state_string[0])) {
|
||||
state_string = ieee802154_state_string[state];
|
||||
}
|
||||
return state_string;
|
||||
}
|
||||
|
||||
#endif // CONFIG_IEEE802154_RECORD_STATE
|
||||
|
||||
#if CONFIG_IEEE802154_RECORD_CMD
|
||||
@@ -126,7 +136,7 @@ static char *ieee802154_get_cmd_string(ieee802154_ll_cmd_t cmd)
|
||||
#endif // CONFIG_IEEE802154_RECORD_CMD
|
||||
|
||||
#if CONFIG_IEEE802154_RECORD_EVENT || CONFIG_IEEE802154_RECORD_ABORT
|
||||
static char *ieee80154_rx_abort_reason_string[] = {
|
||||
static char *ieee802154_rx_abort_reason_string[] = {
|
||||
"RSVD", // = 0,
|
||||
"RX_STOP", // = 1,
|
||||
"SFD_TIMEOUT", // = 2,
|
||||
@@ -148,7 +158,7 @@ static char *ieee80154_rx_abort_reason_string[] = {
|
||||
"ED_COEX_REJECT", // = 26,
|
||||
};
|
||||
|
||||
static char *ieee80154_tx_abort_reason_string[] = {
|
||||
static char *ieee802154_tx_abort_reason_string[] = {
|
||||
"RSVD", // = 0,
|
||||
"RX_ACK_STOP", // = 1,
|
||||
"RX_ACK_SFD_TIMEOUT", // = 2,
|
||||
@@ -169,17 +179,47 @@ static char *ieee80154_tx_abort_reason_string[] = {
|
||||
"CCA_BUSY", // = 25,
|
||||
};
|
||||
|
||||
static char *ieee802154_abort_reason_to_string(ieee802154_ll_rx_abort_reason_t reason, bool is_tx_abort)
|
||||
{
|
||||
char *abort_reason_string = "UNKNOWN";
|
||||
if (is_tx_abort) {
|
||||
if (reason < sizeof(ieee802154_tx_abort_reason_string) / sizeof(ieee802154_tx_abort_reason_string[0])) {
|
||||
abort_reason_string = ieee802154_tx_abort_reason_string[reason];
|
||||
}
|
||||
} else {
|
||||
if (reason < sizeof(ieee802154_rx_abort_reason_string) / sizeof(ieee802154_rx_abort_reason_string[0])) {
|
||||
abort_reason_string = ieee802154_rx_abort_reason_string[reason];
|
||||
}
|
||||
}
|
||||
return abort_reason_string;
|
||||
}
|
||||
|
||||
#endif // CONFIG_IEEE802154_RECORD_EVENT
|
||||
|
||||
#if CONFIG_IEEE802154_RECORD
|
||||
#if CONFIG_IEEE802154_RECORD_TXRX_FRAME
|
||||
static void ieee802154_dump_frame_print(const uint8_t *frame)
|
||||
{
|
||||
if (frame == NULL) {
|
||||
ESP_EARLY_LOGW(IEEE802154_TAG, "Invalid frame, frame is NULL");
|
||||
return;
|
||||
}
|
||||
if (frame[0] < IEEE802154_FRAME_MIN_LEN) {
|
||||
ESP_EARLY_LOGW(IEEE802154_TAG, "Invalid frame, frame length is %d", frame[0]);
|
||||
return;
|
||||
}
|
||||
for (uint8_t i = 1; i < frame[0]; i+=8) {
|
||||
uint8_t end = (i + 7 < frame[0]) ? i + 7 : frame[0] - 1;
|
||||
ESP_EARLY_LOGW(IEEE802154_TAG, "frag(%03d:%03d~%03d): %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||
frame[0], i, i+7,
|
||||
frame[i], frame[i+1], frame[i+2], frame[i+3],
|
||||
frame[i+4], frame[i+5], frame[i+6], frame[i+7]);
|
||||
frame[0], i, end,
|
||||
frame[i],
|
||||
(i+1 < frame[0]) ? frame[i+1] : 0,
|
||||
(i+2 < frame[0]) ? frame[i+2] : 0,
|
||||
(i+3 < frame[0]) ? frame[i+3] : 0,
|
||||
(i+4 < frame[0]) ? frame[i+4] : 0,
|
||||
(i+5 < frame[0]) ? frame[i+5] : 0,
|
||||
(i+6 < frame[0]) ? frame[i+6] : 0,
|
||||
(i+7 < frame[0]) ? frame[i+7] : 0);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_IEEE802154_RECORD_TXRX_FRAME
|
||||
@@ -193,14 +233,14 @@ void ieee802154_record_print(void)
|
||||
char abort_log[100] = { 0 };
|
||||
snprintf(event_log, 200,"index %2d: event: 0x%4x, %15s, state:%10s, timestamp: %lld", i, g_ieee802154_probe.event[i].event,
|
||||
ieee802154_get_event_string(g_ieee802154_probe.event[i].event),
|
||||
ieee802154_state_string[g_ieee802154_probe.event[i].state],
|
||||
ieee802154_state_to_string(g_ieee802154_probe.event[i].state),
|
||||
g_ieee802154_probe.event[i].timestamp);
|
||||
if (g_ieee802154_probe.event[i].event == IEEE802154_EVENT_RX_ABORT) {
|
||||
snprintf(abort_log, 100, "rx abort reason: %4x, %20s", g_ieee802154_probe.event[i].abort_reason.rx,
|
||||
ieee80154_rx_abort_reason_string[g_ieee802154_probe.event[i].abort_reason.rx]);
|
||||
ieee802154_abort_reason_to_string(g_ieee802154_probe.event[i].abort_reason.rx, false));
|
||||
} else if (g_ieee802154_probe.event[i].event == IEEE802154_EVENT_TX_ABORT) {
|
||||
snprintf(abort_log, 100, "tx abort reason: %4x, %20s", g_ieee802154_probe.event[i].abort_reason.tx,
|
||||
ieee80154_tx_abort_reason_string[g_ieee802154_probe.event[i].abort_reason.tx]);
|
||||
ieee802154_abort_reason_to_string(g_ieee802154_probe.event[i].abort_reason.tx, true));
|
||||
}
|
||||
ESP_EARLY_LOGW(IEEE802154_TAG, "%s %s", event_log, abort_log);
|
||||
}
|
||||
@@ -212,7 +252,7 @@ void ieee802154_record_print(void)
|
||||
for (uint8_t i = 0; i < IEEE802154_ASSERT_RECORD_STATE_SIZE; i++) {
|
||||
ESP_EARLY_LOGW(IEEE802154_TAG, "index %2d: line:%5lu, state:%10s, timestamp: %lld",
|
||||
i, g_ieee802154_probe.state[i].line,
|
||||
ieee802154_state_string[g_ieee802154_probe.state[i].state],
|
||||
ieee802154_state_to_string(g_ieee802154_probe.state[i].state),
|
||||
g_ieee802154_probe.state[i].timestamp);
|
||||
}
|
||||
ESP_EARLY_LOGW(IEEE802154_TAG,"Print the record state done.");
|
||||
@@ -235,12 +275,12 @@ void ieee802154_record_print(void)
|
||||
if (g_ieee802154_probe.abort[i].is_tx_abort) {
|
||||
ESP_EARLY_LOGW(IEEE802154_TAG, "index %2d: tx abort: %4x, %15s, timestamp: %lld",
|
||||
i, g_ieee802154_probe.abort[i].abort_reason.tx,
|
||||
ieee80154_tx_abort_reason_string[g_ieee802154_probe.abort[i].abort_reason.tx],
|
||||
ieee802154_abort_reason_to_string(g_ieee802154_probe.abort[i].abort_reason.tx, true),
|
||||
g_ieee802154_probe.abort[i].timestamp);
|
||||
} else {
|
||||
ESP_EARLY_LOGW(IEEE802154_TAG, "index %2d: rx abort: %4x, %15s, timestamp: %lld",
|
||||
i, g_ieee802154_probe.abort[i].abort_reason.rx,
|
||||
ieee80154_rx_abort_reason_string[g_ieee802154_probe.abort[i].abort_reason.rx],
|
||||
ieee802154_abort_reason_to_string(g_ieee802154_probe.abort[i].abort_reason.rx, false),
|
||||
g_ieee802154_probe.abort[i].timestamp);
|
||||
}
|
||||
}
|
||||
@@ -418,14 +458,19 @@ static uint64_t s_rx_buffer_used_water_level[IEEE802154_RX_BUFFER_USED_TOTAL_LEV
|
||||
void ieee802154_rx_buffer_statistic_is_free(bool is_free)
|
||||
{
|
||||
if (is_free) {
|
||||
s_rx_buffer_used_nums--;
|
||||
if (s_rx_buffer_used_nums > 0) {
|
||||
s_rx_buffer_used_nums--;
|
||||
}
|
||||
} else {
|
||||
s_rx_buffer_used_nums++;
|
||||
// (CONFIG_IEEE802154_RX_BUFFER_SIZE + 1) means buffer full.
|
||||
if (s_rx_buffer_used_nums > (CONFIG_IEEE802154_RX_BUFFER_SIZE + 1)) {
|
||||
s_rx_buffer_used_nums = CONFIG_IEEE802154_RX_BUFFER_SIZE + 1;
|
||||
}
|
||||
s_rx_buffer_used_water_level[IEEE802154_RX_BUFFER_GET_USED_LEVEL(s_rx_buffer_used_nums)]++;
|
||||
uint8_t level = IEEE802154_RX_BUFFER_GET_USED_LEVEL(s_rx_buffer_used_nums);
|
||||
if (level <= IEEE802154_RX_BUFFER_USED_TOTAL_LEVEL) {
|
||||
s_rx_buffer_used_water_level[level]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -437,6 +482,7 @@ void ieee802154_rx_buffer_statistic_clear(void)
|
||||
void ieee802154_rx_buffer_statistic_print(void)
|
||||
{
|
||||
uint64_t total_times = 0;
|
||||
float percentage = 0.0f;
|
||||
for (uint8_t i = 0; i < (IEEE802154_RX_BUFFER_USED_TOTAL_LEVEL + 1); i++) {
|
||||
total_times += s_rx_buffer_used_water_level[i];
|
||||
}
|
||||
@@ -445,9 +491,15 @@ void ieee802154_rx_buffer_statistic_print(void)
|
||||
ESP_LOGW(IEEE802154_TAG, "|%25s|%-25llu|", "buffer alloc times:", total_times);
|
||||
ESP_LOGW(IEEE802154_TAG, "+-------------------------+-------------------------+");
|
||||
for (uint8_t i = 0; i < (IEEE802154_RX_BUFFER_USED_TOTAL_LEVEL); i++) {
|
||||
ESP_LOGW(IEEE802154_TAG, "|%4d%%%5s%4d%%%10s|%-15llu%9.2f%%|", ((i) * 100 / IEEE802154_RX_BUFFER_USED_TOTAL_LEVEL), "~", ((i + 1) * 100 / IEEE802154_RX_BUFFER_USED_TOTAL_LEVEL), " used:", s_rx_buffer_used_water_level[i], ((float)s_rx_buffer_used_water_level[i] / (float)total_times)*100);
|
||||
percentage = (total_times > 0) ? ((float)s_rx_buffer_used_water_level[i] / (float)total_times) * 100 : 0.0f;
|
||||
ESP_LOGW(IEEE802154_TAG, "|%4d%%%5s%4d%%%10s|%-15llu%9.2f%%|",
|
||||
((i) * 100 / IEEE802154_RX_BUFFER_USED_TOTAL_LEVEL), "~",
|
||||
((i + 1) * 100 / IEEE802154_RX_BUFFER_USED_TOTAL_LEVEL), " used:",
|
||||
s_rx_buffer_used_water_level[i], percentage);
|
||||
}
|
||||
ESP_LOGW(IEEE802154_TAG, "|%25s|%-15llu%9.2f%%|", "full used:", s_rx_buffer_used_water_level[IEEE802154_RX_BUFFER_USED_TOTAL_LEVEL], ((float)s_rx_buffer_used_water_level[IEEE802154_RX_BUFFER_USED_TOTAL_LEVEL] / (float)total_times)*100);
|
||||
percentage = (total_times > 0) ? ((float)s_rx_buffer_used_water_level[IEEE802154_RX_BUFFER_USED_TOTAL_LEVEL] / (float)total_times) * 100 : 0.0f;
|
||||
ESP_LOGW(IEEE802154_TAG, "|%25s|%-15llu%9.2f%%|", "full used:",
|
||||
s_rx_buffer_used_water_level[IEEE802154_RX_BUFFER_USED_TOTAL_LEVEL], percentage);
|
||||
ESP_LOGW(IEEE802154_TAG, "+-------------------------+-------------------------+");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -48,7 +48,12 @@ extern uint32_t bt_bb_get_cur_rx_info(void);
|
||||
|
||||
IEEE802154_STATIC volatile ieee802154_state_t s_ieee802154_state;
|
||||
static uint8_t *s_tx_frame = NULL;
|
||||
|
||||
#if CONFIG_IEEE802154_TEST
|
||||
#define IEEE802154_RX_FRAME_SIZE (127 + 1 + 1) // +1: len, +1: for dma test
|
||||
#else
|
||||
#define IEEE802154_RX_FRAME_SIZE (127 + 1) // +1: len
|
||||
#endif // CONFIG_IEEE802154_TEST
|
||||
|
||||
// +1: for the stub buffer when the valid buffers are full.
|
||||
//
|
||||
@@ -144,11 +149,101 @@ static IRAM_ATTR void receive_ack_timeout_timer_start(uint32_t duration)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_IEEE802154_MULTI_PAN_ENABLE
|
||||
IEEE802154_STATIC IEEE802154_NOINLINE bool is_broadcast_panid(uint8_t *target_panid)
|
||||
{
|
||||
if (target_panid[0] == 0xff && target_panid[1] == 0xff) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static IEEE802154_NOINLINE bool is_broadcast_addr(uint8_t *dest_addr, uint8_t addr_mode)
|
||||
{
|
||||
uint8_t target[IEEE802154_FRAME_EXT_ADDR_SIZE] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
if (addr_mode == IEEE802154_FRAME_DST_MODE_NONE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t addr_size = (addr_mode == IEEE802154_FRAME_DST_MODE_SHORT) ? IEEE802154_FRAME_SHORT_ADDR_SIZE : IEEE802154_FRAME_EXT_ADDR_SIZE;
|
||||
if (memcmp(dest_addr, target, addr_size) == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
IEEE802154_STATIC IEEE802154_NOINLINE void update_mpf_index(void)
|
||||
{
|
||||
uint8_t *frame = s_rx_frame[s_rx_index];
|
||||
uint8_t frame_type = ieee802154_frame_get_type(frame);
|
||||
s_rx_frame_info[s_rx_index].mpf_index = ESP_IEEE802154_MULTIPAN_MAX;
|
||||
bool is_target_panid_present = false;
|
||||
uint8_t dest_addr_mode = IEEE802154_FRAME_DST_MODE_NONE;
|
||||
uint8_t dest_addr[IEEE802154_FRAME_EXT_ADDR_SIZE] = {0};
|
||||
uint8_t target_panid[IEEE802154_FRAME_PANID_SIZE] = {0};
|
||||
|
||||
// Get dest addr and panid from the raw packet.
|
||||
if (frame_type == IEEE802154_FRAME_TYPE_BEACON) {
|
||||
is_target_panid_present = (ieee802154_frame_get_src_panid(frame, target_panid) == ESP_OK) ? true : false;
|
||||
} else {
|
||||
is_target_panid_present = (ieee802154_frame_get_dest_panid(frame, target_panid) == ESP_OK) ? true : false;
|
||||
}
|
||||
dest_addr_mode = ieee802154_frame_get_dst_addr(frame, dest_addr);
|
||||
// Check is this packet is Broadcast
|
||||
if (is_broadcast_addr(dest_addr, dest_addr_mode) || (is_target_panid_present && is_broadcast_panid(target_panid))) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (esp_ieee802154_multipan_index_t index = 0; index < CONFIG_IEEE802154_INTERFACE_NUM; index++) {
|
||||
if (is_target_panid_present == true) {
|
||||
uint16_t panid = target_panid[1];
|
||||
panid = (panid << 8) | target_panid[0];
|
||||
if (panid != esp_ieee802154_get_multipan_panid(index)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (dest_addr_mode == IEEE802154_FRAME_DST_MODE_SHORT) {
|
||||
uint16_t short_addr = dest_addr[1];
|
||||
short_addr = (short_addr << 8) | dest_addr[0];
|
||||
if (short_addr != esp_ieee802154_get_multipan_short_address(index)) {
|
||||
continue;
|
||||
} else {
|
||||
s_rx_frame_info[s_rx_index].mpf_index = index;
|
||||
return;
|
||||
}
|
||||
} else if (dest_addr_mode == IEEE802154_FRAME_DST_MODE_EXT) {
|
||||
uint8_t ext_addr[IEEE802154_FRAME_EXT_ADDR_SIZE] = {0};
|
||||
esp_ieee802154_get_multipan_extended_address(index, ext_addr);
|
||||
if (memcmp(dest_addr, ext_addr, IEEE802154_FRAME_EXT_ADDR_SIZE) != 0) {
|
||||
continue;
|
||||
} else {
|
||||
s_rx_frame_info[s_rx_index].mpf_index = index;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static IEEE802154_NOINLINE void ieee802154_rx_frame_info_update(void)
|
||||
{
|
||||
uint8_t len = s_rx_frame[s_rx_index][0];
|
||||
int8_t rssi = s_rx_frame[s_rx_index][len - 1]; // crc is not written to rx buffer
|
||||
uint8_t lqi = s_rx_frame[s_rx_index][len];
|
||||
uint8_t len = s_rx_frame[s_rx_index][0] & 0x7f;
|
||||
int8_t rssi = 0;
|
||||
uint8_t lqi = 0;
|
||||
|
||||
if (len < IEEE802154_FRAME_MIN_LEN) {
|
||||
s_rx_frame_info[s_rx_index].channel = 0;
|
||||
s_rx_frame_info[s_rx_index].rssi = 0;
|
||||
s_rx_frame_info[s_rx_index].lqi = 0;
|
||||
return;
|
||||
}
|
||||
rssi = s_rx_frame[s_rx_index][len - 1]; // crc is not written to rx buffer
|
||||
lqi = s_rx_frame[s_rx_index][len];
|
||||
|
||||
#if CONFIG_IEEE802154_MULTI_PAN_ENABLE
|
||||
update_mpf_index();
|
||||
#endif
|
||||
|
||||
s_rx_frame_info[s_rx_index].channel = ieee802154_freq_to_channel(ieee802154_ll_get_freq());
|
||||
s_rx_frame_info[s_rx_index].rssi = rssi + IEEE802154_RSSI_COMPENSATION_VALUE;
|
||||
@@ -436,12 +531,12 @@ static IRAM_ATTR void isr_handle_rx_done(void)
|
||||
&& ieee802154_ll_get_tx_auto_ack()) {
|
||||
extcoex_tx_stage_start();
|
||||
// auto tx ack only works for the frame with version 0b00 and 0b01
|
||||
s_rx_frame_info[s_rx_index].pending = ieee802154_ack_config_pending_bit(s_rx_frame[s_rx_index]);
|
||||
s_rx_frame_info[s_rx_index].pending = ieee802154_ack_config_pending_bit(s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]);
|
||||
ieee802154_set_state(IEEE802154_STATE_TX_ACK);
|
||||
NEEDS_NEXT_OPT(false);
|
||||
} else if (ieee802154_frame_is_ack_required(s_rx_frame[s_rx_index]) && ieee802154_frame_get_version(s_rx_frame[s_rx_index]) == IEEE802154_FRAME_VERSION_2
|
||||
&& ieee802154_ll_get_tx_enhance_ack()) {
|
||||
s_rx_frame_info[s_rx_index].pending = ieee802154_ack_config_pending_bit(s_rx_frame[s_rx_index]);
|
||||
s_rx_frame_info[s_rx_index].pending = ieee802154_ack_config_pending_bit(s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]);
|
||||
// For 2015 enh-ack, SW should generate an enh-ack then send it manually
|
||||
if (ieee802154_inner_enh_ack_generator(s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index], s_enh_ack_frame) == ESP_OK) {
|
||||
extcoex_tx_stage_start();
|
||||
@@ -888,7 +983,6 @@ static inline esp_err_t ieee802154_transmit_internal(const uint8_t *frame, bool
|
||||
|
||||
esp_err_t ieee802154_transmit(const uint8_t *frame, bool cca)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(frame[0] <= 127, ESP_ERR_INVALID_ARG, IEEE802154_TAG, "Invalid frame length.");
|
||||
#if !CONFIG_IEEE802154_TEST
|
||||
ieee802154_enter_critical();
|
||||
if ((s_ieee802154_state == IEEE802154_STATE_RX && ieee802154_ll_is_current_rx_frame())
|
||||
@@ -910,32 +1004,23 @@ esp_err_t ieee802154_transmit(const uint8_t *frame, bool cca)
|
||||
|
||||
esp_err_t ieee802154_transmit_at(const uint8_t *frame, bool cca, uint32_t time)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(frame[0] <= 127, ESP_ERR_INVALID_ARG, IEEE802154_TAG, "Invalid frame length.");
|
||||
uint32_t tx_target_time;
|
||||
uint32_t rampup_time = cca ? IEEE802154_ED_TRIG_TX_RAMPUP_TIME_US : IEEE802154_TX_RAMPUP_TIME_US;
|
||||
uint32_t tx_target_time = (time >= rampup_time) ? time - rampup_time : 0;
|
||||
IEEE802154_RF_ENABLE();
|
||||
tx_init(frame);
|
||||
IEEE802154_SET_TXRX_PTI(IEEE802154_SCENE_TX_AT);
|
||||
if (cca) {
|
||||
ieee802154_ll_set_ed_duration(CCA_DETECTION_TIME);
|
||||
tx_target_time = time - IEEE802154_ED_TRIG_TX_RAMPUP_TIME_US;
|
||||
ieee802154_set_state(IEEE802154_STATE_TX_CCA);
|
||||
ieee802154_enter_critical();
|
||||
ieee802154_etm_set_event_task(IEEE802154_ETM_CHANNEL0, ETM_EVENT_TIMER0_OVERFLOW, ETM_TASK_ED_TRIG_TX);
|
||||
ieee802154_timer0_fire_at(tx_target_time);
|
||||
ieee802154_exit_critical();
|
||||
} else {
|
||||
tx_target_time = time - IEEE802154_TX_RAMPUP_TIME_US;
|
||||
if (ieee802154_frame_get_type(frame) == IEEE802154_FRAME_TYPE_ACK && ieee802154_frame_get_version(frame) == IEEE802154_FRAME_VERSION_2) {
|
||||
ieee802154_set_state(IEEE802154_STATE_TX_ENH_ACK);
|
||||
} else {
|
||||
ieee802154_set_state(IEEE802154_STATE_TX);
|
||||
}
|
||||
ieee802154_enter_critical();
|
||||
ieee802154_etm_set_event_task(IEEE802154_ETM_CHANNEL0, ETM_EVENT_TIMER0_OVERFLOW, ETM_TASK_TX_START);
|
||||
ieee802154_timer0_fire_at(tx_target_time);
|
||||
ieee802154_exit_critical();
|
||||
}
|
||||
|
||||
ieee802154_set_state(cca ? IEEE802154_STATE_TX_CCA : IEEE802154_STATE_TX);
|
||||
ieee802154_enter_critical();
|
||||
ieee802154_etm_set_event_task(IEEE802154_ETM_CHANNEL0, ETM_EVENT_TIMER0_OVERFLOW, cca ? ETM_TASK_ED_TRIG_TX : ETM_TASK_TX_START);
|
||||
ieee802154_timer0_fire_at(tx_target_time);
|
||||
ieee802154_exit_critical();
|
||||
if (time < rampup_time) {
|
||||
// First start the transmit at and then print some logs.
|
||||
ESP_EARLY_LOGE(IEEE802154_TAG, "Time should be longer than %d us to account for the TX ramp-up", rampup_time);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -976,6 +1061,7 @@ IEEE802154_NOINLINE static void ieee802154_start_receive_at(void* ctx)
|
||||
esp_err_t ieee802154_receive_at(uint32_t time, uint32_t duration)
|
||||
{
|
||||
// TODO: Light sleep current optimization, TZ-1613.
|
||||
uint32_t target_time = (time >= IEEE802154_RX_RAMPUP_TIME_US) ? time - IEEE802154_RX_RAMPUP_TIME_US : 0;
|
||||
IEEE802154_RF_ENABLE();
|
||||
ieee802154_enter_critical();
|
||||
rx_init();
|
||||
@@ -984,11 +1070,15 @@ esp_err_t ieee802154_receive_at(uint32_t time, uint32_t duration)
|
||||
ieee802154_set_state(IEEE802154_STATE_RX);
|
||||
ieee802154_etm_set_event_task(IEEE802154_ETM_CHANNEL1, ETM_EVENT_TIMER1_OVERFLOW, ETM_TASK_RX_START);
|
||||
if (duration) {
|
||||
ieee802154_timer1_fire_at_with_callback(time - IEEE802154_RX_RAMPUP_TIME_US, ieee802154_start_receive_at, (void*)(time + duration));
|
||||
ieee802154_timer1_fire_at_with_callback(target_time, ieee802154_start_receive_at, (void*)(time + duration));
|
||||
} else {
|
||||
ieee802154_timer1_fire_at(time - IEEE802154_RX_RAMPUP_TIME_US);
|
||||
ieee802154_timer1_fire_at(target_time);
|
||||
}
|
||||
ieee802154_exit_critical();
|
||||
if (time < IEEE802154_RX_RAMPUP_TIME_US) {
|
||||
// First start the receive at and then print some logs.
|
||||
ESP_EARLY_LOGE(IEEE802154_TAG, "Time should be longer than %d us to account for the RX ramp-up", IEEE802154_RX_RAMPUP_TIME_US);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "esp_ieee802154_dev.h"
|
||||
#include "esp_ieee802154_frame.h"
|
||||
#include "esp_ieee802154_util.h"
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
bool ieee802154_frame_is_security_enabled(const uint8_t *frame)
|
||||
{
|
||||
@@ -42,14 +43,29 @@ IEEE802154_STATIC IEEE802154_INLINE bool is_panid_compression(const uint8_t *fra
|
||||
return frame[IEEE802154_FRAME_PANID_COMP_OFFSET] & IEEE802154_FRAME_PANID_COMP_BIT;
|
||||
}
|
||||
|
||||
IEEE802154_STATIC IEEE802154_INLINE bool is_valid_dst_mode(uint8_t dst_mode)
|
||||
{
|
||||
return (dst_mode == IEEE802154_FRAME_DST_MODE_NONE ||
|
||||
dst_mode == IEEE802154_FRAME_DST_MODE_SHORT ||
|
||||
dst_mode == IEEE802154_FRAME_DST_MODE_EXT);
|
||||
}
|
||||
|
||||
IEEE802154_STATIC IEEE802154_INLINE bool is_valid_src_mode(uint8_t src_mode)
|
||||
{
|
||||
return (src_mode == IEEE802154_FRAME_SRC_MODE_NONE ||
|
||||
src_mode == IEEE802154_FRAME_SRC_MODE_SHORT ||
|
||||
src_mode == IEEE802154_FRAME_SRC_MODE_EXT);
|
||||
}
|
||||
|
||||
IEEE802154_STATIC IEEE802154_NOINLINE bool is_dst_panid_present(const uint8_t *frame)
|
||||
{
|
||||
uint8_t dst_mode = dst_addr_mode(frame);
|
||||
uint8_t src_mode = src_addr_mode(frame);
|
||||
bool dst_panid_present = false;
|
||||
bool panid_compression = is_panid_compression(frame);
|
||||
IEEE802154_RETURN_ON_FALSE_SILENTLY(is_valid_dst_mode(dst_mode) && is_valid_src_mode(src_mode), false);
|
||||
|
||||
if (ieee802154_frame_get_version(frame) == IEEE802154_FRAME_VERSION_2) {
|
||||
uint8_t src_mode = src_addr_mode(frame);
|
||||
bool panid_compression = is_panid_compression(frame);
|
||||
|
||||
if (dst_mode != IEEE802154_FRAME_DST_MODE_NONE) { // dest address is present/short/extended
|
||||
if ((src_mode == IEEE802154_FRAME_SRC_MODE_NONE && panid_compression) ||
|
||||
@@ -74,13 +90,13 @@ IEEE802154_STATIC IEEE802154_NOINLINE bool is_dst_panid_present(const uint8_t *f
|
||||
|
||||
IEEE802154_STATIC IEEE802154_NOINLINE bool is_src_panid_present(const uint8_t *frame)
|
||||
{
|
||||
uint8_t dst_mode = dst_addr_mode(frame);
|
||||
uint8_t src_mode = src_addr_mode(frame);
|
||||
bool panid_compression = is_panid_compression(frame);
|
||||
bool src_panid_present = false;
|
||||
bool panid_compression = is_panid_compression(frame);
|
||||
IEEE802154_RETURN_ON_FALSE_SILENTLY(is_valid_dst_mode(dst_mode) && is_valid_src_mode(src_mode), false);
|
||||
|
||||
if (ieee802154_frame_get_version(frame) == IEEE802154_FRAME_VERSION_2) {
|
||||
uint8_t dst_mode = dst_addr_mode(frame);
|
||||
|
||||
if (src_mode != IEEE802154_FRAME_SRC_MODE_NONE) {
|
||||
if (dst_mode == IEEE802154_FRAME_DST_MODE_EXT && src_mode == IEEE802154_FRAME_SRC_MODE_EXT && !panid_compression) {
|
||||
src_panid_present = false;
|
||||
@@ -101,6 +117,16 @@ IEEE802154_STATIC IEEE802154_NOINLINE bool is_src_panid_present(const uint8_t *f
|
||||
return src_panid_present;
|
||||
}
|
||||
|
||||
uint8_t IEEE802154_INLINE ieee802154_frame_get_type(const uint8_t *frame)
|
||||
{
|
||||
return frame[IEEE802154_FRAME_TYPE_OFFSET] & IEEE802154_FRAME_TYPE_MASK;
|
||||
}
|
||||
|
||||
uint8_t IEEE802154_INLINE ieee802154_frame_get_version(const uint8_t *frame)
|
||||
{
|
||||
return frame[IEEE802154_FRAME_VERSION_OFFSET] & IEEE802154_FRAME_VERSION_MASK;
|
||||
}
|
||||
|
||||
IEEE802154_STATIC uint8_t IEEE802154_INLINE ieee802154_frame_address_offset(const uint8_t *frame)
|
||||
{
|
||||
return IEEE802154_FRAME_PHR_SIZE + IEEE802154_FRAME_FCF_SIZE + (is_dsn_present(frame) ? IEEE802154_FRAME_DSN_SIZE : 0);
|
||||
@@ -109,12 +135,17 @@ IEEE802154_STATIC uint8_t IEEE802154_INLINE ieee802154_frame_address_offset(cons
|
||||
IEEE802154_STATIC IRAM_ATTR uint8_t ieee802154_frame_address_size(const uint8_t *frame)
|
||||
{
|
||||
uint8_t address_size = 0;
|
||||
uint8_t dst_mode = dst_addr_mode(frame);
|
||||
uint8_t src_mode = src_addr_mode(frame);
|
||||
|
||||
ESP_RETURN_ON_FALSE_ISR(is_valid_src_mode(src_mode) && is_valid_dst_mode(dst_mode), IEEE802154_FRAME_INVALID_VALUE, IEEE802154_TAG, "invalid address mode");
|
||||
|
||||
|
||||
if (is_dst_panid_present(frame)) {
|
||||
address_size += IEEE802154_FRAME_PANID_SIZE;
|
||||
}
|
||||
|
||||
switch (dst_addr_mode(frame)) {
|
||||
switch (dst_mode) {
|
||||
case IEEE802154_FRAME_DST_MODE_NONE:
|
||||
break;
|
||||
|
||||
@@ -127,14 +158,14 @@ IEEE802154_STATIC IRAM_ATTR uint8_t ieee802154_frame_address_size(const uint8_t
|
||||
break;
|
||||
|
||||
default:
|
||||
return IEEE802154_FRAME_INVALID_OFFSET;
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_src_panid_present(frame)) {
|
||||
address_size += IEEE802154_FRAME_PANID_SIZE;
|
||||
}
|
||||
|
||||
switch (src_addr_mode(frame)) {
|
||||
switch (src_mode) {
|
||||
case IEEE802154_FRAME_SRC_MODE_NONE:
|
||||
break;
|
||||
|
||||
@@ -147,7 +178,7 @@ IEEE802154_STATIC IRAM_ATTR uint8_t ieee802154_frame_address_size(const uint8_t
|
||||
break;
|
||||
|
||||
default:
|
||||
return IEEE802154_FRAME_INVALID_OFFSET;
|
||||
break;
|
||||
}
|
||||
|
||||
return address_size;
|
||||
@@ -155,12 +186,11 @@ IEEE802154_STATIC IRAM_ATTR uint8_t ieee802154_frame_address_size(const uint8_t
|
||||
|
||||
IEEE802154_STATIC IEEE802154_NOINLINE uint8_t ieee802154_frame_security_header_offset(const uint8_t *frame)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE_ISR(ieee802154_is_supported_frame_type(ieee802154_frame_get_type(frame)), IEEE802154_FRAME_INVALID_ADDR_MODE, IEEE802154_TAG, "invalid frame type");
|
||||
IEEE802154_RETURN_ON_FALSE_SILENTLY(ieee802154_is_supported_frame_type(ieee802154_frame_get_type(frame)), IEEE802154_FRAME_INVALID_VALUE);
|
||||
uint8_t offset = ieee802154_frame_address_offset(frame);
|
||||
IEEE802154_RETURN_ON_FALSE_SILENTLY(offset != IEEE802154_FRAME_INVALID_VALUE, IEEE802154_FRAME_INVALID_VALUE);
|
||||
uint8_t address_size = ieee802154_frame_address_size(frame);
|
||||
|
||||
ESP_RETURN_ON_FALSE_ISR(offset != IEEE802154_FRAME_INVALID_OFFSET, IEEE802154_FRAME_INVALID_OFFSET, IEEE802154_TAG, "invalid offset");
|
||||
ESP_RETURN_ON_FALSE_ISR(address_size != IEEE802154_FRAME_INVALID_OFFSET, IEEE802154_FRAME_INVALID_OFFSET, IEEE802154_TAG, "invalid offset");
|
||||
IEEE802154_RETURN_ON_FALSE_SILENTLY(address_size != IEEE802154_FRAME_INVALID_VALUE, IEEE802154_FRAME_INVALID_VALUE);
|
||||
|
||||
offset += address_size;
|
||||
|
||||
@@ -169,12 +199,12 @@ IEEE802154_STATIC IEEE802154_NOINLINE uint8_t ieee802154_frame_security_header_o
|
||||
|
||||
IEEE802154_STATIC IEEE802154_NOINLINE uint8_t ieee802154_frame_get_security_field_len(const uint8_t *frame)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE_ISR(ieee802154_is_supported_frame_type(ieee802154_frame_get_type(frame)), IEEE802154_FRAME_INVALID_OFFSET, IEEE802154_TAG, "invalid frame type");
|
||||
ESP_RETURN_ON_FALSE_ISR(ieee802154_is_supported_frame_type(ieee802154_frame_get_type(frame)), IEEE802154_FRAME_INVALID_VALUE, IEEE802154_TAG, "invalid frame type");
|
||||
|
||||
uint8_t security_field_len = 0;
|
||||
uint8_t offset = ieee802154_frame_security_header_offset(frame);
|
||||
|
||||
ESP_RETURN_ON_FALSE_ISR(offset != IEEE802154_FRAME_INVALID_OFFSET, IEEE802154_FRAME_INVALID_OFFSET, IEEE802154_TAG, "invalid offset");
|
||||
ESP_RETURN_ON_FALSE_ISR(offset != IEEE802154_FRAME_INVALID_VALUE, IEEE802154_FRAME_INVALID_VALUE, IEEE802154_TAG, "invalid offset");
|
||||
|
||||
security_field_len += IEEE802154_FRAME_SE_HEAD_SIZE;
|
||||
uint8_t security_header = frame[offset];
|
||||
@@ -206,7 +236,9 @@ IEEE802154_STATIC IEEE802154_NOINLINE uint8_t ieee802154_frame_get_security_fiel
|
||||
IEEE802154_STATIC uint8_t ieee802154_frame_ie_header_offset(const uint8_t *frame)
|
||||
{
|
||||
uint8_t offset = ieee802154_frame_security_header_offset(frame);
|
||||
IEEE802154_RETURN_ON_FALSE_SILENTLY(offset != IEEE802154_FRAME_INVALID_VALUE, IEEE802154_FRAME_INVALID_VALUE);
|
||||
uint8_t security_field_len = ieee802154_frame_get_security_field_len(frame);
|
||||
IEEE802154_RETURN_ON_FALSE_SILENTLY(security_field_len != IEEE802154_FRAME_INVALID_VALUE, IEEE802154_FRAME_INVALID_VALUE);
|
||||
|
||||
offset += security_field_len;
|
||||
|
||||
@@ -216,6 +248,7 @@ IEEE802154_STATIC uint8_t ieee802154_frame_ie_header_offset(const uint8_t *frame
|
||||
IEEE802154_STATIC uint8_t ieee802154_frame_get_mic_len(const uint8_t *frame)
|
||||
{
|
||||
uint8_t offset = ieee802154_frame_security_header_offset(frame);
|
||||
IEEE802154_RETURN_ON_FALSE_SILENTLY(offset != IEEE802154_FRAME_INVALID_VALUE, 0);
|
||||
uint8_t mic_len = 0;
|
||||
uint8_t security_header = frame[offset];
|
||||
|
||||
@@ -242,8 +275,10 @@ IEEE802154_STATIC uint8_t ieee802154_frame_get_mic_len(const uint8_t *frame)
|
||||
IEEE802154_STATIC uint8_t ieee802154_frame_get_ie_field_len(const uint8_t *frame)
|
||||
{
|
||||
uint8_t offset = ieee802154_frame_ie_header_offset(frame);
|
||||
IEEE802154_RETURN_ON_FALSE_SILENTLY(offset != IEEE802154_FRAME_INVALID_VALUE, IEEE802154_FRAME_INVALID_VALUE);
|
||||
uint8_t ie_field_len = 0;
|
||||
uint8_t frame_footer_len = ieee802154_frame_get_mic_len(frame) + IEEE802154_FRAME_FCS_SIZE;
|
||||
uint8_t frame_len = frame[0];
|
||||
|
||||
/* If the `offset + frame_footer_len == frame_len`, we exit the `while()`
|
||||
loop. This covers the case where frame contains one or more Header IEs
|
||||
@@ -253,6 +288,9 @@ IEEE802154_STATIC uint8_t ieee802154_frame_get_ie_field_len(const uint8_t *frame
|
||||
footer length. (for details, please reference 2015 - spec table 7 - 6 in page 169) */
|
||||
|
||||
while (frame[0] > offset + ie_field_len + frame_footer_len) {
|
||||
if (offset + ie_field_len + 1 >= frame_len) {
|
||||
break;
|
||||
}
|
||||
uint16_t ie_header = frame[offset + ie_field_len + 1] << 8 | frame[offset + ie_field_len];
|
||||
// Header Termination IE 2 is used in to signal end of the MHR and beginning of the MAC Payload.
|
||||
if ((ie_header & IEEE802154_FRAME_IE_HEAD_ID_MASK) == IEEE802154_IE_TYPE_HT2) {
|
||||
@@ -269,9 +307,12 @@ IEEE802154_STATIC uint8_t ieee802154_frame_get_ie_field_len(const uint8_t *frame
|
||||
IEEE802154_STATIC IRAM_ATTR uint8_t ieee802154_frame_payload_offset(const uint8_t *frame)
|
||||
{
|
||||
uint8_t offset = ieee802154_frame_security_header_offset(frame);
|
||||
IEEE802154_RETURN_ON_FALSE_SILENTLY(offset != IEEE802154_FRAME_INVALID_VALUE, IEEE802154_FRAME_INVALID_VALUE);
|
||||
if (ieee802154_frame_is_security_enabled(frame)) {
|
||||
// skip security field.
|
||||
offset += ieee802154_frame_get_security_field_len(frame);
|
||||
uint8_t security_field_len = ieee802154_frame_get_security_field_len(frame);
|
||||
IEEE802154_RETURN_ON_FALSE_SILENTLY(security_field_len != IEEE802154_FRAME_INVALID_VALUE, IEEE802154_FRAME_INVALID_VALUE);
|
||||
offset += security_field_len;
|
||||
}
|
||||
|
||||
if (ieee802154_frame_get_version(frame) == IEEE802154_FRAME_VERSION_2 && is_ie_present(frame)) {
|
||||
@@ -290,31 +331,44 @@ IEEE802154_STATIC IRAM_ATTR uint8_t ieee802154_frame_payload_offset(const uint8_
|
||||
return offset - 1;
|
||||
}
|
||||
|
||||
uint8_t IEEE802154_INLINE ieee802154_frame_get_type(const uint8_t *frame)
|
||||
bool ieee802154_is_data_request(const uint8_t *frame)
|
||||
{
|
||||
return frame[IEEE802154_FRAME_TYPE_OFFSET] & IEEE802154_FRAME_TYPE_MASK;
|
||||
}
|
||||
if (ieee802154_frame_get_type(frame) != IEEE802154_FRAME_TYPE_COMMAND) {
|
||||
return false;
|
||||
}
|
||||
uint8_t offset = ieee802154_frame_security_header_offset(frame);
|
||||
if (ieee802154_frame_is_security_enabled(frame)) {
|
||||
// skip security field.
|
||||
offset += ieee802154_frame_get_security_field_len(frame);
|
||||
}
|
||||
|
||||
uint8_t IEEE802154_INLINE ieee802154_frame_get_version(const uint8_t *frame)
|
||||
{
|
||||
return frame[IEEE802154_FRAME_VERSION_OFFSET] & IEEE802154_FRAME_VERSION_MASK;
|
||||
if (ieee802154_frame_get_version(frame) == IEEE802154_FRAME_VERSION_2 && is_ie_present(frame)) {
|
||||
// skip IE fields.
|
||||
offset += ieee802154_frame_get_ie_field_len(frame);
|
||||
}
|
||||
if (frame[offset] == IEEE802154_CMD_DATA_REQ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IEEE802154_INLINE ieee802154_frame_is_ack_required(const uint8_t *frame)
|
||||
{
|
||||
return (ieee802154_is_supported_frame_type(ieee802154_frame_get_type(frame))) && (frame[IEEE802154_FRAME_AR_OFFSET] & IEEE802154_FRAME_AR_BIT);
|
||||
IEEE802154_RETURN_ON_FALSE_SILENTLY(ieee802154_is_supported_frame_type(ieee802154_frame_get_type(frame)), false);
|
||||
return (frame[IEEE802154_FRAME_AR_OFFSET] & IEEE802154_FRAME_AR_BIT);
|
||||
}
|
||||
|
||||
uint8_t ieee802154_frame_get_dst_addr(const uint8_t *frame, uint8_t *addr)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE_ISR(ieee802154_is_supported_frame_type(ieee802154_frame_get_type(frame)), IEEE802154_FRAME_INVALID_ADDR_MODE, IEEE802154_TAG, "invalid frame type");
|
||||
ESP_RETURN_ON_FALSE_ISR(ieee802154_is_supported_frame_type(ieee802154_frame_get_type(frame)), IEEE802154_FRAME_INVALID_VALUE, IEEE802154_TAG, "invalid frame type");
|
||||
|
||||
uint8_t offset = ieee802154_frame_address_offset(frame);
|
||||
uint8_t dst_mode = dst_addr_mode(frame);
|
||||
uint8_t addr_size;
|
||||
|
||||
ESP_RETURN_ON_FALSE_ISR(dst_mode == IEEE802154_FRAME_DST_MODE_SHORT || dst_mode == IEEE802154_FRAME_DST_MODE_EXT, dst_mode, IEEE802154_TAG, "invalid address mode");
|
||||
uint8_t addr_size = 0;
|
||||
|
||||
ESP_RETURN_ON_FALSE_ISR(is_valid_dst_mode(dst_mode), IEEE802154_FRAME_INVALID_VALUE, IEEE802154_TAG, "invalid destination address mode");
|
||||
IEEE802154_RETURN_ON_FALSE_SILENTLY(dst_mode != IEEE802154_FRAME_DST_MODE_NONE, IEEE802154_FRAME_DST_MODE_NONE);
|
||||
addr_size = (dst_mode == IEEE802154_FRAME_DST_MODE_SHORT) ? IEEE802154_FRAME_SHORT_ADDR_SIZE : IEEE802154_FRAME_EXT_ADDR_SIZE;
|
||||
|
||||
if (is_dst_panid_present(frame)) {
|
||||
@@ -328,15 +382,16 @@ uint8_t ieee802154_frame_get_dst_addr(const uint8_t *frame, uint8_t *addr)
|
||||
|
||||
uint8_t ieee802154_frame_get_src_addr(const uint8_t *frame, uint8_t *addr)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE_ISR(ieee802154_is_supported_frame_type(ieee802154_frame_get_type(frame)), IEEE802154_FRAME_INVALID_ADDR_MODE, IEEE802154_TAG, "invalid frame type");
|
||||
ESP_RETURN_ON_FALSE_ISR(ieee802154_is_supported_frame_type(ieee802154_frame_get_type(frame)), IEEE802154_FRAME_INVALID_VALUE, IEEE802154_TAG, "invalid frame type");
|
||||
|
||||
uint8_t offset = ieee802154_frame_address_offset(frame);
|
||||
uint8_t dst_mode = dst_addr_mode(frame);
|
||||
uint8_t src_mode = src_addr_mode(frame);
|
||||
uint8_t addr_size;
|
||||
uint8_t addr_size = 0;
|
||||
|
||||
ESP_RETURN_ON_FALSE_ISR(src_mode == IEEE802154_FRAME_SRC_MODE_SHORT || src_mode == IEEE802154_FRAME_SRC_MODE_EXT, src_mode, IEEE802154_TAG, "invalid address mode");
|
||||
ESP_RETURN_ON_FALSE_ISR(is_valid_src_mode(src_mode) && is_valid_dst_mode(dst_mode), IEEE802154_FRAME_INVALID_VALUE, IEEE802154_TAG, "invalid address mode");
|
||||
|
||||
IEEE802154_RETURN_ON_FALSE_SILENTLY(src_mode != IEEE802154_FRAME_SRC_MODE_NONE, IEEE802154_FRAME_SRC_MODE_NONE);
|
||||
addr_size = (src_mode == IEEE802154_FRAME_SRC_MODE_SHORT) ? IEEE802154_FRAME_SHORT_ADDR_SIZE : IEEE802154_FRAME_EXT_ADDR_SIZE;
|
||||
|
||||
if (is_dst_panid_present(frame)) {
|
||||
@@ -367,7 +422,9 @@ uint8_t ieee802154_frame_get_src_addr(const uint8_t *frame, uint8_t *addr)
|
||||
|
||||
uint8_t ieee802154_frame_get_security_payload_offset(uint8_t *frame)
|
||||
{
|
||||
return ieee802154_frame_payload_offset(frame);
|
||||
uint8_t offset = ieee802154_frame_payload_offset(frame);
|
||||
ESP_RETURN_ON_FALSE_ISR(offset != IEEE802154_FRAME_INVALID_VALUE, IEEE802154_FRAME_INVALID_VALUE, IEEE802154_TAG, "invalid offset");
|
||||
return offset;
|
||||
}
|
||||
|
||||
esp_err_t ieee802154_frame_get_dest_panid(const uint8_t *frame, uint8_t *panid)
|
||||
@@ -385,6 +442,7 @@ esp_err_t ieee802154_frame_get_src_panid(const uint8_t *frame, uint8_t *panid)
|
||||
{
|
||||
uint8_t offset = ieee802154_frame_address_offset(frame);
|
||||
uint8_t dst_mode = dst_addr_mode(frame);
|
||||
IEEE802154_RETURN_ON_FALSE_SILENTLY(is_valid_dst_mode(dst_mode), ESP_FAIL);
|
||||
|
||||
if (is_src_panid_present(frame)) {
|
||||
if (is_dst_panid_present(frame)) {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "hal/ieee802154_ll.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_ieee802154_pib.h"
|
||||
@@ -14,6 +15,30 @@
|
||||
static ieee802154_pib_t s_ieee802154_pib;
|
||||
static bool is_pending = false;
|
||||
|
||||
extern const int8_t* bt_bb_get_tx_pwr_table(uint8_t *length);
|
||||
|
||||
static inline int8_t IEEE802154_TXPOWER_VALUE_MAX(void)
|
||||
{
|
||||
uint8_t length = 0;
|
||||
const int8_t *tx_pwr_table = bt_bb_get_tx_pwr_table(&length);
|
||||
if (!tx_pwr_table || length == 0) {
|
||||
ESP_LOGE(IEEE802154_TAG, "Failed to get tx power table");
|
||||
return 0;
|
||||
}
|
||||
return tx_pwr_table[length - 1];
|
||||
}
|
||||
|
||||
static inline int8_t IEEE802154_TXPOWER_VALUE_MIN(void)
|
||||
{
|
||||
uint8_t length = 0;
|
||||
const int8_t *tx_pwr_table = bt_bb_get_tx_pwr_table(&length);
|
||||
if (!tx_pwr_table || length == 0) {
|
||||
ESP_LOGE(IEEE802154_TAG, "Failed to get tx power table");
|
||||
return 0;
|
||||
}
|
||||
return tx_pwr_table[0];
|
||||
}
|
||||
|
||||
static inline void set_pending(void)
|
||||
{
|
||||
is_pending = true;
|
||||
@@ -24,7 +49,7 @@ static inline void clr_pending(void)
|
||||
is_pending = false;
|
||||
}
|
||||
|
||||
bool inline ieee802154_pib_is_pending(void)
|
||||
inline bool ieee802154_pib_is_pending(void)
|
||||
{
|
||||
return is_pending;
|
||||
}
|
||||
@@ -41,22 +66,38 @@ void ieee802154_pib_init(void)
|
||||
s_ieee802154_pib.channel = 11;
|
||||
s_ieee802154_pib.cca_threshold = CONFIG_IEEE802154_CCA_THRESHOLD;
|
||||
s_ieee802154_pib.cca_mode = CONFIG_IEEE802154_CCA_MODE;
|
||||
memset(&s_ieee802154_pib.power_table, IEEE802154_TXPOWER_VALUE_MAX, sizeof(s_ieee802154_pib.power_table));
|
||||
for (int i = 0; i < 16; i++) {
|
||||
s_ieee802154_pib.power_table.channel[i] = IEEE802154_TXPOWER_VALUE_MAX();
|
||||
}
|
||||
|
||||
set_pending();
|
||||
}
|
||||
|
||||
IEEE802154_NOINLINE static uint8_t ieee802154_txpower_convert(int8_t txpower)
|
||||
{
|
||||
uint8_t ieee820154_txpower_index = 0;
|
||||
if (txpower >= IEEE802154_TXPOWER_VALUE_MAX) {
|
||||
ieee820154_txpower_index = 15;
|
||||
} else if (txpower <= IEEE802154_TXPOWER_VALUE_MIN) {
|
||||
ieee820154_txpower_index = IEEE802154_TXPOWER_INDEX_MIN;
|
||||
} else {
|
||||
ieee820154_txpower_index = (uint8_t)((txpower - IEEE802154_TXPOWER_VALUE_MIN) / 3) + IEEE802154_TXPOWER_INDEX_MIN;
|
||||
uint8_t ieee802154_txpower_index = 0;
|
||||
uint8_t length = 0;
|
||||
const int8_t *tx_pwr_table = bt_bb_get_tx_pwr_table(&length);
|
||||
if (!tx_pwr_table || length == 0) {
|
||||
ESP_LOGE(IEEE802154_TAG, "Failed to get tx power table");
|
||||
return 0;
|
||||
}
|
||||
return ieee820154_txpower_index;
|
||||
|
||||
if (txpower <= tx_pwr_table[0]) {
|
||||
ieee802154_txpower_index = 0;
|
||||
} else if (txpower >= tx_pwr_table[length - 1]) {
|
||||
ieee802154_txpower_index = length - 1;
|
||||
} else {
|
||||
uint8_t i = 0;
|
||||
for (i = length-1; i != 0; i--) {
|
||||
if (tx_pwr_table[i] <= txpower) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ieee802154_txpower_index = i;
|
||||
}
|
||||
|
||||
return ieee802154_txpower_index;
|
||||
}
|
||||
|
||||
void ieee802154_pib_update(void)
|
||||
@@ -74,7 +115,14 @@ void ieee802154_pib_update(void)
|
||||
|
||||
ieee802154_ll_set_coordinator(s_ieee802154_pib.coordinator);
|
||||
ieee802154_ll_set_promiscuous(s_ieee802154_pib.promiscuous);
|
||||
ieee802154_ll_set_pending_mode(s_ieee802154_pib.pending_mode == IEEE802154_AUTO_PENDING_ENHANCED);
|
||||
bool target_mode = false;
|
||||
for (int i = 0; i < CONFIG_IEEE802154_INTERFACE_NUM; i++) {
|
||||
if (s_ieee802154_pib.pending_mode[i] == IEEE802154_AUTO_PENDING_ENHANCED || s_ieee802154_pib.pending_mode[i] == IEEE802154_AUTO_PENDING_ZIGBEE) {
|
||||
target_mode = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ieee802154_ll_set_pending_mode(target_mode);
|
||||
|
||||
clr_pending();
|
||||
}
|
||||
@@ -87,7 +135,7 @@ uint8_t ieee802154_pib_get_channel(void)
|
||||
|
||||
void ieee802154_pib_set_channel(uint8_t channel)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(ieee802154_is_valid_channel(channel), , IEEE802154_TAG, "Failed to set channel, reason: Invalid channel: %d", channel);
|
||||
ESP_RETURN_VOID_ON_FALSE(ieee802154_is_valid_channel(channel), IEEE802154_TAG, "Failed to set channel, reason: Invalid channel: %d", channel);
|
||||
if (s_ieee802154_pib.channel != channel) {
|
||||
s_ieee802154_pib.channel = channel;
|
||||
set_pending();
|
||||
@@ -231,15 +279,15 @@ void ieee802154_pib_set_coordinator(bool enable)
|
||||
}
|
||||
}
|
||||
|
||||
ieee802154_ll_pending_mode_t ieee802154_pib_get_pending_mode(void)
|
||||
ieee802154_ll_pending_mode_t ieee802154_pib_get_pending_mode(esp_ieee802154_multipan_index_t inf_index)
|
||||
{
|
||||
return s_ieee802154_pib.pending_mode;
|
||||
return s_ieee802154_pib.pending_mode[inf_index];
|
||||
}
|
||||
|
||||
void ieee802154_pib_set_pending_mode(ieee802154_ll_pending_mode_t pending_mode)
|
||||
void ieee802154_pib_set_pending_mode(esp_ieee802154_multipan_index_t inf_index, ieee802154_ll_pending_mode_t pending_mode)
|
||||
{
|
||||
if (s_ieee802154_pib.pending_mode != pending_mode) {
|
||||
s_ieee802154_pib.pending_mode = pending_mode;
|
||||
if (s_ieee802154_pib.pending_mode[inf_index] != pending_mode) {
|
||||
s_ieee802154_pib.pending_mode[inf_index] = pending_mode;
|
||||
set_pending();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,10 +30,7 @@ void ieee802154_timer0_stop(void)
|
||||
|
||||
esp_err_t ieee802154_timer0_set_threshold(uint32_t value)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE((value < IEEE802154_TIMER0_THRESHOLD), ESP_ERR_INVALID_ARG, IEEE802154_TAG, "invalid timer0 threshold");
|
||||
|
||||
ieee802154_ll_timer0_set_threshold(value);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -56,10 +53,7 @@ void ieee802154_timer1_stop(void)
|
||||
|
||||
esp_err_t ieee802154_timer1_set_threshold(uint32_t value)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE((value < IEEE802154_TIMER1_THRESHOLD), ESP_ERR_INVALID_ARG, IEEE802154_TAG, "invalid timer1 threshold");
|
||||
|
||||
ieee802154_ll_timer1_set_threshold(value);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -8,16 +8,21 @@
|
||||
#include "soc/soc.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#include "hal/ieee802154_ll.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_coex_i154.h"
|
||||
#include "esp_ieee802154_util.h"
|
||||
|
||||
uint8_t ieee802154_freq_to_channel(uint8_t freq)
|
||||
{
|
||||
return (freq - 3) / 5 + IEEE802154_OQPSK_2P4G_CHANNEL_MIN;
|
||||
assert(((freq - 3) % 5) == 0);
|
||||
uint8_t channel = (freq - 3) / 5 + IEEE802154_OQPSK_2P4G_CHANNEL_MIN;
|
||||
assert(ieee802154_is_valid_channel(channel));
|
||||
return channel;
|
||||
}
|
||||
|
||||
uint8_t ieee802154_channel_to_freq(uint8_t channel)
|
||||
{
|
||||
assert(ieee802154_is_valid_channel(channel));
|
||||
return (channel - IEEE802154_OQPSK_2P4G_CHANNEL_MIN) * 5 + 3;
|
||||
}
|
||||
|
||||
@@ -43,7 +48,6 @@ esp_ieee802154_coex_config_t ieee802154_get_coex_config(void)
|
||||
|
||||
void ieee802154_set_txrx_pti(ieee802154_txrx_scene_t txrx_scene)
|
||||
{
|
||||
|
||||
switch (txrx_scene) {
|
||||
case IEEE802154_SCENE_IDLE:
|
||||
esp_coex_ieee802154_txrx_pti_set(s_coex_config.idle);
|
||||
@@ -66,8 +70,9 @@ void ieee802154_set_txrx_pti(ieee802154_txrx_scene_t txrx_scene)
|
||||
// TZ-97: implement these two functions using ETM common interface
|
||||
void ieee802154_etm_channel_clear(uint32_t channel)
|
||||
{
|
||||
assert(channel < 16);
|
||||
if ((REG_READ(ETM_CHEN_AD0_REG) & (1 << channel))) {
|
||||
REG_WRITE(ETM_CHENCLR_AD0_REG, (REG_READ(ETM_CHENCLR_AD0_REG)) | 1 << channel);
|
||||
REG_WRITE(ETM_CHENCLR_AD0_REG, (REG_READ(ETM_CHENCLR_AD0_REG)) | (1 << channel));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,5 +83,11 @@ void ieee802154_etm_set_event_task(uint32_t channel, uint32_t event, uint32_t ta
|
||||
REG_WRITE((ETM_CH0_EVT_ID_REG + ETM_CH_OFFSET * channel), event);
|
||||
REG_WRITE((ETM_CH0_TASK_ID_REG + ETM_CH_OFFSET * channel), task);
|
||||
|
||||
REG_WRITE(ETM_CHENSET_AD0_REG, (REG_READ(ETM_CHENSET_AD0_REG) | 1 << channel));
|
||||
REG_WRITE(ETM_CHENSET_AD0_REG, (REG_READ(ETM_CHENSET_AD0_REG) | (1 << channel)));
|
||||
}
|
||||
|
||||
__attribute__((weak)) const int8_t* bt_bb_get_tx_pwr_table(uint8_t *length)
|
||||
{
|
||||
ESP_LOGE(IEEE802154_TAG, "bt_bb_get_tx_pwr_table is not implemented");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <string.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_ieee802154.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_phy_init.h"
|
||||
#include "esp_ieee802154_ack.h"
|
||||
@@ -26,6 +27,7 @@ esp_err_t esp_ieee802154_event_callback_list_register(esp_ieee802154_event_cb_li
|
||||
{
|
||||
return ieee802154_event_callback_list_register(cb_list);
|
||||
}
|
||||
|
||||
esp_err_t esp_ieee802154_event_callback_list_unregister(void)
|
||||
{
|
||||
return ieee802154_event_callback_list_unregister();
|
||||
@@ -54,6 +56,7 @@ uint8_t esp_ieee802154_get_channel(void)
|
||||
|
||||
esp_err_t esp_ieee802154_set_channel(uint8_t channel)
|
||||
{
|
||||
assert(ieee802154_is_valid_channel(channel));
|
||||
ieee802154_pib_set_channel(channel);
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -66,7 +69,9 @@ int8_t esp_ieee802154_get_txpower(void)
|
||||
esp_err_t esp_ieee802154_set_txpower(int8_t power)
|
||||
{
|
||||
esp_ieee802154_txpower_table_t power_table;
|
||||
memset(&power_table, power, sizeof(power_table));
|
||||
for (int i = 0; i < 16; i++) {
|
||||
power_table.channel[i] = power;
|
||||
}
|
||||
return ieee802154_pib_set_power_table(power_table);
|
||||
}
|
||||
|
||||
@@ -77,6 +82,7 @@ esp_err_t esp_ieee802154_set_power_table(esp_ieee802154_txpower_table_t power_ta
|
||||
|
||||
esp_err_t esp_ieee802154_get_power_table(esp_ieee802154_txpower_table_t *out_power_table)
|
||||
{
|
||||
assert(out_power_table != NULL);
|
||||
return ieee802154_pib_get_power_table(out_power_table);
|
||||
}
|
||||
|
||||
@@ -87,6 +93,7 @@ esp_err_t esp_ieee802154_set_power_with_channel(uint8_t channel, int8_t power)
|
||||
|
||||
esp_err_t esp_ieee802154_get_power_with_channel(uint8_t channel, int8_t *out_power)
|
||||
{
|
||||
assert(out_power != NULL);
|
||||
return ieee802154_pib_get_power_with_channel(channel, out_power);
|
||||
}
|
||||
|
||||
@@ -163,40 +170,42 @@ esp_err_t esp_ieee802154_set_coordinator(bool enable)
|
||||
|
||||
uint16_t esp_ieee802154_get_multipan_panid(esp_ieee802154_multipan_index_t index)
|
||||
{
|
||||
assert(index < ESP_IEEE802154_MULTIPAN_MAX);
|
||||
assert(index < CONFIG_IEEE802154_INTERFACE_NUM);
|
||||
return ieee802154_ll_get_multipan_panid(index);
|
||||
}
|
||||
|
||||
esp_err_t esp_ieee802154_set_multipan_panid(esp_ieee802154_multipan_index_t index, uint16_t panid)
|
||||
{
|
||||
assert(index < ESP_IEEE802154_MULTIPAN_MAX);
|
||||
assert(index < CONFIG_IEEE802154_INTERFACE_NUM);
|
||||
ieee802154_ll_set_multipan_panid(index, panid);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
uint16_t esp_ieee802154_get_multipan_short_address(esp_ieee802154_multipan_index_t index)
|
||||
{
|
||||
assert(index < ESP_IEEE802154_MULTIPAN_MAX);
|
||||
assert(index < CONFIG_IEEE802154_INTERFACE_NUM);
|
||||
return ieee802154_ll_get_multipan_short_addr(index);
|
||||
}
|
||||
|
||||
esp_err_t esp_ieee802154_set_multipan_short_address(esp_ieee802154_multipan_index_t index, uint16_t short_address)
|
||||
{
|
||||
assert(index < ESP_IEEE802154_MULTIPAN_MAX);
|
||||
assert(index < CONFIG_IEEE802154_INTERFACE_NUM);
|
||||
ieee802154_ll_set_multipan_short_addr(index, short_address);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_ieee802154_get_multipan_extended_address(esp_ieee802154_multipan_index_t index, uint8_t *ext_addr)
|
||||
{
|
||||
assert(index < ESP_IEEE802154_MULTIPAN_MAX);
|
||||
assert(index < CONFIG_IEEE802154_INTERFACE_NUM);
|
||||
assert(ext_addr != NULL);
|
||||
ieee802154_ll_get_multipan_ext_addr(index, ext_addr);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_ieee802154_set_multipan_extended_address(esp_ieee802154_multipan_index_t index, const uint8_t *ext_addr)
|
||||
{
|
||||
assert(index < ESP_IEEE802154_MULTIPAN_MAX);
|
||||
assert(index < CONFIG_IEEE802154_INTERFACE_NUM);
|
||||
assert(ext_addr != NULL);
|
||||
ieee802154_ll_set_multipan_ext_addr(index, ext_addr);
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -208,17 +217,50 @@ uint8_t esp_ieee802154_get_multipan_enable(void)
|
||||
|
||||
esp_err_t esp_ieee802154_set_multipan_enable(uint8_t mask)
|
||||
{
|
||||
assert(mask < (1 << ESP_IEEE802154_MULTIPAN_MAX));
|
||||
assert(mask < (1 << CONFIG_IEEE802154_INTERFACE_NUM));
|
||||
ieee802154_ll_set_multipan_enable_mask(mask);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_ieee802154_pending_mode_t esp_ieee802154_multipan_get_pending_mode(esp_ieee802154_multipan_index_t index)
|
||||
{
|
||||
assert(index < CONFIG_IEEE802154_INTERFACE_NUM);
|
||||
return ieee802154_pib_get_pending_mode(index);
|
||||
}
|
||||
|
||||
esp_err_t esp_ieee802154_multipan_set_pending_mode(esp_ieee802154_multipan_index_t inf_index, esp_ieee802154_pending_mode_t pending_mode)
|
||||
{
|
||||
assert(inf_index < CONFIG_IEEE802154_INTERFACE_NUM);
|
||||
ieee802154_pib_set_pending_mode(inf_index, pending_mode);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_ieee802154_multipan_add_pending_addr(esp_ieee802154_multipan_index_t inf_index, const uint8_t *addr, bool is_short)
|
||||
{
|
||||
assert(inf_index < CONFIG_IEEE802154_INTERFACE_NUM);
|
||||
return ieee802154_add_pending_addr(inf_index, addr, is_short);
|
||||
}
|
||||
|
||||
esp_err_t esp_ieee802154_multipan_clear_pending_addr(esp_ieee802154_multipan_index_t inf_index, const uint8_t *addr, bool is_short)
|
||||
{
|
||||
assert(inf_index < CONFIG_IEEE802154_INTERFACE_NUM);
|
||||
return ieee802154_clear_pending_addr(inf_index, addr, is_short);
|
||||
}
|
||||
|
||||
esp_err_t esp_ieee802154_multipan_reset_pending_table(esp_ieee802154_multipan_index_t inf_index, bool is_short)
|
||||
{
|
||||
assert(inf_index < CONFIG_IEEE802154_INTERFACE_NUM);
|
||||
ieee802154_reset_pending_table(inf_index, is_short);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#endif // CONFIG_IEEE802154_MULTI_PAN_ENABLE
|
||||
|
||||
esp_err_t esp_ieee802154_set_ack_timeout(uint32_t timeout)
|
||||
{
|
||||
// Divide by 16 and round it up.
|
||||
uint32_t target_reg_value = (timeout + 15) / 16;
|
||||
if((timeout % 16) != 0) {
|
||||
if ((timeout % 16) != 0) {
|
||||
ESP_LOGW(IEEE802154_TAG, "Ack timeout should be a multiple of 16, input %"PRIu32", will be replaced by %"PRIu32"", timeout, (target_reg_value * 16));
|
||||
}
|
||||
ieee802154_ll_set_ack_timeout(target_reg_value);
|
||||
@@ -254,24 +296,26 @@ esp_err_t esp_ieee802154_set_short_address(uint16_t short_address)
|
||||
|
||||
esp_err_t esp_ieee802154_get_extended_address(uint8_t *ext_addr)
|
||||
{
|
||||
assert(ext_addr != NULL);
|
||||
ieee802154_ll_get_multipan_ext_addr(ESP_IEEE802154_MULTIPAN_0, ext_addr);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_ieee802154_set_extended_address(const uint8_t *ext_addr)
|
||||
{
|
||||
assert(ext_addr != NULL);
|
||||
ieee802154_ll_set_multipan_ext_addr(ESP_IEEE802154_MULTIPAN_0, ext_addr);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_ieee802154_pending_mode_t esp_ieee802154_get_pending_mode(void)
|
||||
{
|
||||
return ieee802154_pib_get_pending_mode();
|
||||
return ieee802154_pib_get_pending_mode(ESP_IEEE802154_MULTIPAN_0);
|
||||
}
|
||||
|
||||
esp_err_t esp_ieee802154_set_pending_mode(esp_ieee802154_pending_mode_t pending_mode)
|
||||
{
|
||||
ieee802154_pib_set_pending_mode(pending_mode);
|
||||
ieee802154_pib_set_pending_mode(ESP_IEEE802154_MULTIPAN_0, pending_mode);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -288,11 +332,15 @@ bool esp_ieee802154_get_rx_when_idle(void)
|
||||
|
||||
esp_err_t esp_ieee802154_transmit(const uint8_t *frame, bool cca)
|
||||
{
|
||||
assert(frame != NULL);
|
||||
assert(frame[0] <= 127);
|
||||
return ieee802154_transmit(frame, cca);
|
||||
}
|
||||
|
||||
esp_err_t esp_ieee802154_transmit_at(const uint8_t *frame, bool cca, uint32_t time)
|
||||
{
|
||||
assert(frame != NULL);
|
||||
assert(frame[0] <= 127);
|
||||
return ieee802154_transmit_at(frame, cca, time);
|
||||
}
|
||||
|
||||
@@ -342,10 +390,12 @@ esp_ieee802154_state_t esp_ieee802154_get_state(void)
|
||||
case IEEE802154_STATE_TX_CCA:
|
||||
case IEEE802154_STATE_CCA:
|
||||
case IEEE802154_STATE_TX:
|
||||
case IEEE802154_STATE_TEST_TX:
|
||||
case IEEE802154_STATE_RX_ACK:
|
||||
return ESP_IEEE802154_RADIO_TRANSMIT;
|
||||
|
||||
default:
|
||||
ESP_LOGE(IEEE802154_TAG, "Invalid state: %d", ieee802154_get_state());
|
||||
assert(false);
|
||||
return ESP_IEEE802154_RADIO_DISABLE;
|
||||
}
|
||||
@@ -353,23 +403,28 @@ esp_ieee802154_state_t esp_ieee802154_get_state(void)
|
||||
|
||||
esp_err_t esp_ieee802154_set_transmit_security(uint8_t *frame, uint8_t *key, uint8_t *addr)
|
||||
{
|
||||
assert(frame != NULL);
|
||||
assert(key != NULL);
|
||||
assert(addr != NULL);
|
||||
ieee802154_transmit_security_config(frame, key, addr);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_ieee802154_add_pending_addr(const uint8_t *addr, bool is_short)
|
||||
{
|
||||
return ieee802154_add_pending_addr(addr, is_short);
|
||||
assert(addr != NULL);
|
||||
return ieee802154_add_pending_addr(ESP_IEEE802154_MULTIPAN_0, addr, is_short);
|
||||
}
|
||||
|
||||
esp_err_t esp_ieee802154_clear_pending_addr(const uint8_t *addr, bool is_short)
|
||||
{
|
||||
return ieee802154_clear_pending_addr(addr, is_short);
|
||||
assert(addr != NULL);
|
||||
return ieee802154_clear_pending_addr(ESP_IEEE802154_MULTIPAN_0, addr, is_short);
|
||||
}
|
||||
|
||||
esp_err_t esp_ieee802154_reset_pending_table(bool is_short)
|
||||
{
|
||||
ieee802154_reset_pending_table(is_short);
|
||||
ieee802154_reset_pending_table(ESP_IEEE802154_MULTIPAN_0, is_short);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -432,6 +487,7 @@ __attribute__((weak)) void esp_ieee802154_ed_failed(uint16_t error)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
__attribute__((weak)) void esp_ieee802154_receive_at_done(void)
|
||||
{
|
||||
|
||||
@@ -439,7 +495,7 @@ __attribute__((weak)) void esp_ieee802154_receive_at_done(void)
|
||||
|
||||
__attribute__((weak)) esp_err_t esp_ieee802154_enh_ack_generator(uint8_t *frame, esp_ieee802154_frame_info_t *frame_info, uint8_t* enhack_frame)
|
||||
{
|
||||
ESP_EARLY_LOGE(IEEE802154_TAG, "Not implement for the enh-ack generating handler");
|
||||
ESP_EARLY_LOGE(IEEE802154_TAG, "Not implemented for the enh-ack generating handler");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -257,10 +257,11 @@ esp_err_t esp_ieee802154_set_short_address(uint16_t short_address);
|
||||
/**
|
||||
* @brief Get the device extended address.
|
||||
*
|
||||
* @param[out] ext_addr The pointer to the device extended address.
|
||||
* @param[out] ext_addr The pointer to the device extended address. Must not be NULL.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success.
|
||||
* - ESP_ERR_INVALID_ARG if ext_addr is NULL.
|
||||
* - ESP_FAIL on failure.
|
||||
*/
|
||||
esp_err_t esp_ieee802154_get_extended_address(uint8_t *ext_addr);
|
||||
@@ -268,10 +269,11 @@ esp_err_t esp_ieee802154_get_extended_address(uint8_t *ext_addr);
|
||||
/**
|
||||
* @brief Set the device extended address.
|
||||
*
|
||||
* @param[in] ext_addr The pointer to the device extended address.
|
||||
* @param[in] ext_addr The pointer to the device extended address. Must not be NULL.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success.
|
||||
* - ESP_ERR_INVALID_ARG if ext_addr is NULL.
|
||||
* - ESP_FAIL on failure.
|
||||
*/
|
||||
esp_err_t esp_ieee802154_set_extended_address(const uint8_t *ext_addr);
|
||||
@@ -324,10 +326,11 @@ esp_err_t esp_ieee802154_set_multipan_short_address(esp_ieee802154_multipan_inde
|
||||
* @brief Get the device extended address for specific interface.
|
||||
*
|
||||
* @param[in] index The interface index.
|
||||
* @param[out] ext_addr The pointer to the device extended address.
|
||||
* @param[out] ext_addr The pointer to the device extended address. Must not be NULL.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success.
|
||||
* - ESP_ERR_INVALID_ARG if ext_addr is NULL.
|
||||
* - ESP_FAIL on failure.
|
||||
*/
|
||||
esp_err_t esp_ieee802154_get_multipan_extended_address(esp_ieee802154_multipan_index_t index, uint8_t *ext_addr);
|
||||
@@ -336,10 +339,11 @@ esp_err_t esp_ieee802154_get_multipan_extended_address(esp_ieee802154_multipan_i
|
||||
* @brief Set the device extended address for specific interface.
|
||||
*
|
||||
* @param[in] index The interface index.
|
||||
* @param[in] ext_addr The pointer to the device extended address.
|
||||
* @param[in] ext_addr The pointer to the device extended address. Must not be NULL.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success.
|
||||
* - ESP_ERR_INVALID_ARG if addr is NULL.
|
||||
* - ESP_FAIL on failure.
|
||||
*/
|
||||
esp_err_t esp_ieee802154_set_multipan_extended_address(esp_ieee802154_multipan_index_t index, const uint8_t *ext_addr);
|
||||
@@ -409,12 +413,13 @@ esp_err_t esp_ieee802154_set_pending_mode(esp_ieee802154_pending_mode_t pending_
|
||||
/**
|
||||
* @brief Add address to the source matching table.
|
||||
*
|
||||
* @param[in] addr The pointer to the address.
|
||||
* @param[in] addr The pointer to the address. Must not be NULL.
|
||||
* @param[in] is_short Short address or Extended address.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success.
|
||||
* - ESP_ERR_NO_MEM if the pending table is full.
|
||||
* - ESP_ERR_INVALID_ARG if addr is NULL.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ieee802154_add_pending_addr(const uint8_t *addr, bool is_short);
|
||||
@@ -422,12 +427,13 @@ esp_err_t esp_ieee802154_add_pending_addr(const uint8_t *addr, bool is_short);
|
||||
/**
|
||||
* @brief Remove address from the source matching table.
|
||||
*
|
||||
* @param[in] addr The pointer to the address.
|
||||
* @param[in] addr The pointer to the address. Must not be NULL.
|
||||
* @param[in] is_short Short address or Extended address.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success.
|
||||
* - ESP_ERR_NOT_FOUND if the address was not found from the source matching table.
|
||||
* - ESP_ERR_INVALID_ARG if addr is NULL.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ieee802154_clear_pending_addr(const uint8_t *addr, bool is_short);
|
||||
@@ -440,6 +446,7 @@ esp_err_t esp_ieee802154_clear_pending_addr(const uint8_t *addr, bool is_short);
|
||||
* @return
|
||||
* - ESP_OK on success.
|
||||
* - ESP_FAIL on failure.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ieee802154_reset_pending_table(bool is_short);
|
||||
|
||||
@@ -459,6 +466,7 @@ int8_t esp_ieee802154_get_cca_threshold(void);
|
||||
* @return
|
||||
* - ESP_OK on success.
|
||||
* - ESP_FAIL on failure.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ieee802154_set_cca_threshold(int8_t cca_threshold);
|
||||
|
||||
@@ -478,6 +486,7 @@ esp_ieee802154_cca_mode_t esp_ieee802154_get_cca_mode(void);
|
||||
* @return
|
||||
* - ESP_OK on success.
|
||||
* - ESP_FAIL on failure.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ieee802154_set_cca_mode(esp_ieee802154_cca_mode_t cca_mode);
|
||||
|
||||
@@ -489,6 +498,7 @@ esp_err_t esp_ieee802154_set_cca_mode(esp_ieee802154_cca_mode_t cca_mode);
|
||||
* @return
|
||||
* - ESP_OK on success.
|
||||
* - ESP_FAIL on failure.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ieee802154_set_rx_when_idle(bool enable);
|
||||
|
||||
@@ -643,12 +653,13 @@ uint8_t esp_ieee802154_get_recent_lqi(void);
|
||||
/**
|
||||
* @brief Set the key and addr for a frame needs to be encrypted by HW.
|
||||
*
|
||||
* @param[in] frame A frame needs to be encrypted. Refer to `esp_ieee802154_transmit()`.
|
||||
* @param[in] key A 16-bytes key for encryption.
|
||||
* @param[in] addr An 8-bytes addr for HW to generate nonce, in general, is the device extended address.
|
||||
* @param[in] frame A frame needs to be encrypted. Refer to `esp_ieee802154_transmit()`. Must not be NULL.
|
||||
* @param[in] key A 16-bytes key for encryption. Must not be NULL.
|
||||
* @param[in] addr An 8-bytes addr for HW to generate nonce, in general, is the device extended address. Must not be NULL.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success.
|
||||
* - ESP_ERR_INVALID_ARG if frame, key, or addr is NULL.
|
||||
* - ESP_FAIL on failure.
|
||||
*/
|
||||
esp_err_t esp_ieee802154_set_transmit_security(uint8_t *frame, uint8_t *key, uint8_t *addr);
|
||||
@@ -657,7 +668,7 @@ esp_err_t esp_ieee802154_set_transmit_security(uint8_t *frame, uint8_t *key, uin
|
||||
* @brief This function will be called when a received frame needs to be acked with Enh-Ack, the upper
|
||||
* layer should generate the Enh-Ack frame in this callback function.
|
||||
*
|
||||
* @param[in] frame The received frame.
|
||||
* @param[in] frame The received frame. Must not be NULL.
|
||||
* @param[in] frame_info The frame information. Refer to `esp_ieee802154_frame_info_t`.
|
||||
* @param[out] enhack_frame The Enh-ack frame need to be generated via this function, HW will send it back after AIFS.
|
||||
*
|
||||
@@ -741,6 +752,7 @@ esp_ieee802154_coex_config_t esp_ieee802154_get_coex_config(void);
|
||||
* @return
|
||||
* - ESP_OK on success.
|
||||
* - ESP_FAIL on failure.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ieee802154_event_callback_list_register(esp_ieee802154_event_cb_list_t cb_list);
|
||||
|
||||
@@ -753,9 +765,84 @@ esp_err_t esp_ieee802154_event_callback_list_register(esp_ieee802154_event_cb_li
|
||||
* @return
|
||||
* - ESP_OK on success.
|
||||
* - ESP_FAIL on failure.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ieee802154_event_callback_list_unregister(void);
|
||||
|
||||
/**
|
||||
* @brief Add a pending address to the multipan table for the specified interface.
|
||||
*
|
||||
* @note This API should be called only when the IEEE 802.15.4 subsystem is enabled.
|
||||
*
|
||||
* @param inf_index Index of the interface.
|
||||
* @param addr Pointer to the address to add.
|
||||
* @param is_short True if the address is a short address, false if extended.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success.
|
||||
* - ESP_FAIL on failure.
|
||||
*/
|
||||
esp_err_t esp_ieee802154_multipan_add_pending_addr(esp_ieee802154_multipan_index_t inf_index, const uint8_t *addr, bool is_short);
|
||||
|
||||
/**
|
||||
* @brief Remove a pending address from the multipan table for the specified interface.
|
||||
*
|
||||
* @note This API should be called only when the IEEE 802.15.4 subsystem is enabled.
|
||||
*
|
||||
* @param inf_index Index of the interface.
|
||||
* @param addr Pointer to the address to remove.
|
||||
* @param is_short True if the address is a short address, false if extended.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success.
|
||||
* - ESP_FAIL on failure.
|
||||
*/
|
||||
esp_err_t esp_ieee802154_multipan_clear_pending_addr(esp_ieee802154_multipan_index_t inf_index, const uint8_t *addr, bool is_short);
|
||||
|
||||
/**
|
||||
* @brief Reset the pending address table for the specified interface.
|
||||
*
|
||||
* @note This API clears all pending addresses of the specified type (short or extended) for the interface.
|
||||
*
|
||||
* @param inf_index Index of the interface.
|
||||
* @param is_short True to reset short addresses, false to reset extended addresses.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success.
|
||||
* - ESP_FAIL on failure.
|
||||
*/
|
||||
esp_err_t esp_ieee802154_multipan_reset_pending_table(esp_ieee802154_multipan_index_t inf_index, bool is_short);
|
||||
|
||||
/**
|
||||
* @brief Get the auto frame pending mode of the specified multipan interface.
|
||||
*
|
||||
* @note This API returns the logical pending mode configured for a given multipan
|
||||
* interface. The value is used by the ACK generation logic together with the
|
||||
* per-interface pending address table.
|
||||
*
|
||||
* @param inf_index Index of the multipan interface.
|
||||
*
|
||||
* @return
|
||||
* - The auto frame pending mode, refer to esp_ieee802154_pending_mode_t.
|
||||
*/
|
||||
esp_ieee802154_pending_mode_t esp_ieee802154_multipan_get_pending_mode(esp_ieee802154_multipan_index_t inf_index);
|
||||
|
||||
/**
|
||||
* @brief Set the auto frame pending mode of the specified multipan interface.
|
||||
*
|
||||
* @note This API configures the logical pending mode for a given multipan interface.
|
||||
* The configured mode is used by the ACK generation logic together with the
|
||||
* per-interface pending address table.
|
||||
*
|
||||
* @param inf_index Index of the multipan interface.
|
||||
* @param pending_mode Pending mode to set for this interface.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success.
|
||||
* - ESP_FAIL on failure.
|
||||
*/
|
||||
esp_err_t esp_ieee802154_multipan_set_pending_mode(esp_ieee802154_multipan_index_t inf_index, esp_ieee802154_pending_mode_t pending_mode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
#define US_PER_SYMBLE 16
|
||||
#define US_PER_SYMBOL 16
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -61,8 +61,8 @@ typedef enum {
|
||||
} esp_ieee802154_pending_mode_t;
|
||||
|
||||
/**
|
||||
* @brief The four groups of mac filter interface index.
|
||||
*/
|
||||
* @brief The four groups of mac filter interface index.
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_IEEE802154_MULTIPAN_0 = 0,
|
||||
ESP_IEEE802154_MULTIPAN_1 = 1,
|
||||
@@ -82,6 +82,7 @@ typedef struct {
|
||||
int8_t rssi; /*!< RSSI */
|
||||
uint8_t lqi; /*!< LQI */
|
||||
uint64_t timestamp; /*!< The timestamp when the frame's SFD field was received */
|
||||
esp_ieee802154_multipan_index_t mpf_index; /*!< Multipan interface that matches the frame, ESP_IEEE802154_MULTIPAN_MAX if none */
|
||||
} esp_ieee802154_frame_info_t;
|
||||
|
||||
/**
|
||||
@@ -142,13 +143,13 @@ typedef esp_err_t (*esp_ieee802154_enh_ack_generator_cb_t)(uint8_t *frame, esp_i
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
esp_ieee802154_receive_done_cb_t rx_done_cb; /*!<The callback to process Rx Done event */
|
||||
esp_ieee802154_receive_sfd_done_cb_t rx_sfd_done_cb; /*!<The callback to process Rx SFD Done event */
|
||||
esp_ieee802154_transmit_done_cb_t tx_done_cb; /*!<The callback to process Tx Done event */
|
||||
esp_ieee802154_transmit_failed_cb_t tx_failed_cb; /*!<The callback to process Tx Failed event */
|
||||
esp_ieee802154_transmit_sfd_done_cb_t tx_sfd_done_cb; /*!<The callback to process Tx SFD Done event */
|
||||
esp_ieee802154_energy_detect_done_cb_t ed_done_cb; /*!<The callback to process ED Done event */
|
||||
esp_ieee802154_enh_ack_generator_cb_t enh_ack_generator_cb; /*!<The callback to process enh-ack generating */
|
||||
esp_ieee802154_receive_done_cb_t rx_done_cb; /*!< The callback to process Rx Done event */
|
||||
esp_ieee802154_receive_sfd_done_cb_t rx_sfd_done_cb; /*!< The callback to process Rx SFD Done event */
|
||||
esp_ieee802154_transmit_done_cb_t tx_done_cb; /*!< The callback to process Tx Done event */
|
||||
esp_ieee802154_transmit_failed_cb_t tx_failed_cb; /*!< The callback to process Tx Failed event */
|
||||
esp_ieee802154_transmit_sfd_done_cb_t tx_sfd_done_cb; /*!< The callback to process Tx SFD Done event */
|
||||
esp_ieee802154_energy_detect_done_cb_t ed_done_cb; /*!< The callback to process ED Done event */
|
||||
esp_ieee802154_enh_ack_generator_cb_t enh_ack_generator_cb; /*!< The callback to process Enh-ack generating */
|
||||
} esp_ieee802154_event_cb_list_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -17,7 +17,11 @@ entries:
|
||||
esp_ieee802154_frame: ieee802154_frame_get_security_payload_offset (noflash)
|
||||
esp_ieee802154_frame: ieee802154_frame_get_src_addr (noflash)
|
||||
esp_ieee802154_frame: ieee802154_frame_security_header_offset (noflash)
|
||||
esp_ieee802154_frame: ieee802154_frame_get_dest_panid (noflash)
|
||||
esp_ieee802154_frame: ieee802154_frame_get_dst_addr (noflash)
|
||||
esp_ieee802154_frame: ieee802154_frame_get_src_panid (noflash)
|
||||
esp_ieee802154_frame: ieee802154_frame_is_security_enabled(noflash)
|
||||
esp_ieee802154_frame: ieee802154_is_data_request (noflash)
|
||||
esp_ieee802154_frame: is_dst_panid_present (noflash)
|
||||
esp_ieee802154_frame: is_src_panid_present (noflash)
|
||||
esp_ieee802154_pib: ieee802154_pib_get_pending_mode (noflash)
|
||||
@@ -73,3 +77,11 @@ entries:
|
||||
esp_ieee802154_timer: isr_handle_timer0_done (noflash)
|
||||
esp_ieee802154_timer: isr_handle_timer1_done (noflash)
|
||||
esp_ieee802154_util: ieee802154_channel_to_freq (noflash)
|
||||
|
||||
if IEEE802154_MULTI_PAN_ENABLE = y:
|
||||
esp_ieee802154: esp_ieee802154_get_multipan_extended_address (noflash)
|
||||
esp_ieee802154: esp_ieee802154_get_multipan_panid (noflash)
|
||||
esp_ieee802154: esp_ieee802154_get_multipan_short_address (noflash)
|
||||
esp_ieee802154_dev: is_broadcast_addr (noflash)
|
||||
esp_ieee802154_dev: is_broadcast_panid (noflash)
|
||||
esp_ieee802154_dev: update_mpf_index (noflash)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <stdbool.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_ieee802154_types.h"
|
||||
#include "esp_ieee802154_frame.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -25,35 +26,37 @@ extern "C" {
|
||||
typedef struct {
|
||||
uint8_t short_addr[CONFIG_IEEE802154_PENDING_TABLE_SIZE][IEEE802154_FRAME_SHORT_ADDR_SIZE]; /*!< Short address table */
|
||||
uint8_t ext_addr[CONFIG_IEEE802154_PENDING_TABLE_SIZE][IEEE802154_FRAME_EXT_ADDR_SIZE]; /*!< Extend address table */
|
||||
uint8_t short_addr_mask[IEEE802154_PENDING_TABLE_MASK_SIZE]; /*!< The mask which the index of short address table is used */
|
||||
uint8_t ext_addr_mask[IEEE802154_PENDING_TABLE_MASK_SIZE]; /*!< The mask which the index of extended address table is used */
|
||||
uint8_t short_addr_mask[IEEE802154_PENDING_TABLE_MASK_SIZE]; /*!< Bit mask to track which indices of the short address table are used */
|
||||
uint8_t ext_addr_mask[IEEE802154_PENDING_TABLE_MASK_SIZE]; /*!< Bit mask to track which indices of the extended address table are used */
|
||||
} ieee802154_pending_table_t;
|
||||
|
||||
/**
|
||||
* @brief Add an address to the pending table.
|
||||
*
|
||||
* @param[in] addr The pointer to the address needs to be added.
|
||||
* @param[in] addr The pointer to the address needs to be added. Must not be NULL.
|
||||
* @param[in] is_short The type of address, true for short address, false for extended.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success.
|
||||
* - ESP_FAIL on failure due to the table is full.
|
||||
* - ESP_ERR_INVALID_ARG if addr is NULL.
|
||||
*
|
||||
*/
|
||||
esp_err_t ieee802154_add_pending_addr(const uint8_t *addr, bool is_short);
|
||||
esp_err_t ieee802154_add_pending_addr(esp_ieee802154_multipan_index_t inf_index, const uint8_t *addr, bool is_short);
|
||||
|
||||
/**
|
||||
* @brief Remove an address in pending table.
|
||||
*
|
||||
* @param[in] addr The pointer to the address needs to be cleared.
|
||||
* @param[in] addr The pointer to the address needs to be cleared. Must not be NULL.
|
||||
* @param[in] is_short The type of address, true for short address, false for extended.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success.
|
||||
* - ESP_FAIL on failure if the given address is not present in the pending table.
|
||||
* - ESP_ERR_INVALID_ARG if addr is NULL.
|
||||
*
|
||||
*/
|
||||
esp_err_t ieee802154_clear_pending_addr(const uint8_t *addr, bool is_short);
|
||||
esp_err_t ieee802154_clear_pending_addr(esp_ieee802154_multipan_index_t inf_index, const uint8_t *addr, bool is_short);
|
||||
|
||||
/**
|
||||
* @brief Reset the pending table, only clear the mask bits for finishing the process quickly.
|
||||
@@ -61,18 +64,18 @@ esp_err_t ieee802154_clear_pending_addr(const uint8_t *addr, bool is_short);
|
||||
* @param[in] is_short The type of address, true for resetting short address table, false for extended.
|
||||
*
|
||||
*/
|
||||
void ieee802154_reset_pending_table(bool is_short);
|
||||
void ieee802154_reset_pending_table(esp_ieee802154_multipan_index_t inf_index, bool is_short);
|
||||
|
||||
/**
|
||||
* @brief Check whether the pending bit should be set or not in the ack frame.
|
||||
*
|
||||
* @param[in] frame The pointer to the received frame.
|
||||
* @param[in] frame The pointer to the received frame. Must not be NULL.
|
||||
*
|
||||
* @return
|
||||
* - True The pending bit should be set, otherwise False.
|
||||
* - True if the pending bit should be set, otherwise false.
|
||||
*
|
||||
*/
|
||||
bool ieee802154_ack_config_pending_bit(const uint8_t *frame);
|
||||
bool ieee802154_ack_config_pending_bit(const uint8_t *frame, const esp_ieee802154_frame_info_t *frame_info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
@@ -15,9 +15,9 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#define IEEE802154_FRAME_MAX_LEN 127
|
||||
#define IEEE802154_FRAME_MIN_LEN 3
|
||||
|
||||
#define IEEE802154_FRAME_INVALID_OFFSET 0xff
|
||||
#define IEEE802154_FRAME_INVALID_ADDR_MODE 0xff
|
||||
#define IEEE802154_FRAME_INVALID_VALUE 0xff
|
||||
|
||||
#define IEEE802154_FRAME_TYPE_OFFSET 1
|
||||
#define IEEE802154_FRAME_TYPE_MASK 0x07
|
||||
@@ -111,7 +111,7 @@ static inline bool ieee802154_is_supported_frame_type(uint8_t frame_type)
|
||||
/**
|
||||
* @brief Get the frame type.
|
||||
*
|
||||
* @param[in] frame The pointer to the frame.
|
||||
* @param[in] frame The pointer to the frame. Must not be NULL.
|
||||
*
|
||||
* @return
|
||||
* - The type of the frame.
|
||||
@@ -122,7 +122,7 @@ uint8_t ieee802154_frame_get_type(const uint8_t *frame);
|
||||
/**
|
||||
* @brief Get the frame version.
|
||||
*
|
||||
* @param[in] frame The pointer to the frame.
|
||||
* @param[in] frame The pointer to the frame. Must not be NULL.
|
||||
*
|
||||
* @return
|
||||
* - The version of the frame.
|
||||
@@ -133,7 +133,7 @@ uint8_t ieee802154_frame_get_version(const uint8_t *frame);
|
||||
/**
|
||||
* @brief Is the frame ack required.
|
||||
*
|
||||
* @param[in] frame The pointer to the frame.
|
||||
* @param[in] frame The pointer to the frame. Must not be NULL.
|
||||
*
|
||||
* @return
|
||||
* - True if the frame is ack required, otherwise false.
|
||||
@@ -154,13 +154,14 @@ bool ieee802154_frame_is_security_enabled(const uint8_t *frame);
|
||||
/**
|
||||
* @brief Get the destination address of the frame.
|
||||
*
|
||||
* @param[in] frame The pointer to the frame.
|
||||
* @param[out] addr The pointer to the address.
|
||||
* @param[in] frame The pointer to the frame. Must not be NULL.
|
||||
* @param[out] addr The pointer to the address. Must not be NULL.
|
||||
*
|
||||
* @return
|
||||
* - IEEE802154_FRAME_DST_MODE_NONE if destination address mode is none.
|
||||
* - IEEE802154_FRAME_DST_MODE_SHORT if destination address mode is short.
|
||||
* - IEEE802154_FRAME_DST_MODE_EXT if destination address mode is extended.
|
||||
* - IEEE802154_FRAME_INVALID_VALUE if frame is NULL, addr is NULL, or frame type is invalid.
|
||||
*
|
||||
*/
|
||||
uint8_t ieee802154_frame_get_dst_addr(const uint8_t *frame, uint8_t *addr);
|
||||
@@ -168,51 +169,60 @@ uint8_t ieee802154_frame_get_dst_addr(const uint8_t *frame, uint8_t *addr);
|
||||
/**
|
||||
* @brief Get the source address of the frame.
|
||||
*
|
||||
* @param[in] frame The pointer to the frame.
|
||||
* @param[out] addr The pointer to the address.
|
||||
* @param[in] frame The pointer to the frame. Must not be NULL.
|
||||
* @param[out] addr The pointer to the address. Must not be NULL.
|
||||
*
|
||||
* @return
|
||||
* - IEEE802154_FRAME_SRC_MODE_NONE if source address mode is none.
|
||||
* - IEEE802154_FRAME_SRC_MODE_SHORT if source address mode is short.
|
||||
* - IEEE802154_FRAME_SRC_MODE_EXT if source address mode is extended.
|
||||
*
|
||||
* - IEEE802154_FRAME_INVALID_VALUE if frame is NULL, addr is NULL, or frame type is invalid.
|
||||
*/
|
||||
uint8_t ieee802154_frame_get_src_addr(const uint8_t *frame, uint8_t *addr);
|
||||
|
||||
/**
|
||||
* @brief Get the offset of the private payload.
|
||||
*
|
||||
* @param[in] frame The pointer to the frame.
|
||||
* @param[in] frame The pointer to the frame. Must not be NULL.
|
||||
*
|
||||
* @return
|
||||
* - The offset of the private payload
|
||||
*
|
||||
* - IEEE802154_FRAME_INVALID_VALUE if frame is NULL, or frame type is invalid.
|
||||
*/
|
||||
uint8_t ieee802154_frame_get_security_payload_offset(uint8_t *frame);
|
||||
|
||||
/**
|
||||
* @brief Get the destination PAN ID of the frame.
|
||||
*
|
||||
* @param[in] frame The pointer to the frame.
|
||||
* @param[out] panid The pointer to the destination PAN ID.
|
||||
* @param[in] frame The pointer to the frame. Must not be NULL.
|
||||
* @param[out] panid The pointer to the destination PAN ID. Must not be NULL.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if destination PAN ID is present, otherwise ESP_FAIL.
|
||||
*
|
||||
* - ESP_FAIL if frame is NULL, panid is NULL, or frame type is invalid.
|
||||
*/
|
||||
esp_err_t ieee802154_frame_get_dest_panid(const uint8_t *frame, uint8_t *panid);
|
||||
|
||||
/**
|
||||
* @brief Get the source PAN ID of the frame.
|
||||
*
|
||||
* @param[in] frame The pointer to the frame.
|
||||
* @param[out] panid The pointer to the source PAN ID.
|
||||
* @param[in] frame The pointer to the frame. Must not be NULL.
|
||||
* @param[out] panid The pointer to the source PAN ID. Must not be NULL.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if source PAN ID is present, otherwise ESP_FAIL.
|
||||
*
|
||||
* - ESP_FAIL if frame is NULL, panid is NULL, or frame type is invalid.
|
||||
*/
|
||||
esp_err_t ieee802154_frame_get_src_panid(const uint8_t *frame, uint8_t *panid);
|
||||
|
||||
/**
|
||||
* @brief Check whether the given frame is a MAC Data Request command.
|
||||
*
|
||||
* @param[in] frame Pointer to the raw MAC frame buffer.
|
||||
*
|
||||
* @return true if the frame is a Data Request command, false otherwise.
|
||||
*/
|
||||
bool ieee802154_is_data_request(const uint8_t *frame);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "hal/ieee802154_ll.h"
|
||||
#include "esp_ieee802154_frame.h"
|
||||
#include "esp_ieee802154_types.h"
|
||||
@@ -28,7 +29,7 @@ typedef struct {
|
||||
bool rx_when_idle; /*!< A flag indicates the device is rx on when idle or not */
|
||||
esp_ieee802154_txpower_table_t power_table; /*!< The power table configuration */
|
||||
uint8_t channel; /*!< Channel configuration */
|
||||
ieee802154_ll_pending_mode_t pending_mode; /*!< Pending mode configuration */
|
||||
ieee802154_ll_pending_mode_t pending_mode[CONFIG_IEEE802154_INTERFACE_NUM]; /*!< Pending mode configuration */
|
||||
int8_t cca_threshold; /*!< CCA threshold */
|
||||
ieee802154_ll_cca_mode_t cca_mode; /*!< CCA mode */
|
||||
} ieee802154_pib_t;
|
||||
@@ -160,7 +161,7 @@ void ieee802154_pib_set_cca_threshold(int8_t cca_threshold);
|
||||
* @return
|
||||
* - The CCA threshold has been set in the PIB.
|
||||
*/
|
||||
int8_t ieee802154_pib_get_cca_threshold(void);
|
||||
int8_t ieee802154_pib_get_cca_threshold(void);
|
||||
|
||||
/**
|
||||
* @brief Set the CCA mode to the PIB.
|
||||
@@ -248,7 +249,7 @@ bool ieee802154_pib_get_coordinator(void);
|
||||
* @param[in] pending_mode The pending mode.
|
||||
*
|
||||
*/
|
||||
void ieee802154_pib_set_pending_mode(ieee802154_ll_pending_mode_t pending_mode);
|
||||
void ieee802154_pib_set_pending_mode(esp_ieee802154_multipan_index_t inf_index, ieee802154_ll_pending_mode_t pending_mode);
|
||||
|
||||
/**
|
||||
* @brief Get the pending mode from the PIB.
|
||||
@@ -256,21 +257,21 @@ void ieee802154_pib_set_pending_mode(ieee802154_ll_pending_mode_t pending_mode);
|
||||
* @return
|
||||
* - The pending mode has been set in the PIB.
|
||||
*/
|
||||
ieee802154_ll_pending_mode_t ieee802154_pib_get_pending_mode(void);
|
||||
ieee802154_ll_pending_mode_t ieee802154_pib_get_pending_mode(esp_ieee802154_multipan_index_t inf_index);
|
||||
|
||||
/**
|
||||
* @brief Configure the radio mode when the radio is going to enter idle to the PIB.
|
||||
*
|
||||
* @param[in] enable True for continuing to receive when the radio is going to enter ilde, otherwise false.
|
||||
* @param[in] enable True for continuing to receive when the radio is going to enter idle, otherwise false.
|
||||
*
|
||||
*/
|
||||
void ieee802154_pib_set_rx_when_idle(bool enable);
|
||||
|
||||
/**
|
||||
* @brief Get the radio mode when the radio is going to enter ilde to the PIB.
|
||||
* @brief Get the radio mode when the radio is going to enter idle to the PIB.
|
||||
*
|
||||
* @return
|
||||
* - True for continuing to receive when the radio is going to enter ilde, otherwise false.
|
||||
* - True for continuing to receive when the radio is going to enter idle, otherwise false.
|
||||
*
|
||||
*/
|
||||
bool ieee802154_pib_get_rx_when_idle(void);
|
||||
|
||||
@@ -23,6 +23,12 @@ extern "C" {
|
||||
#define IEEE802154_OQPSK_2P4G_CHANNEL_MIN 11
|
||||
#define IEEE802154_OQPSK_2P4G_CHANNEL_MAX 26
|
||||
|
||||
#define IEEE802154_RETURN_ON_FALSE_SILENTLY(a, ret) do { \
|
||||
if (unlikely(!(a))) { \
|
||||
return ret; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
static inline bool ieee802154_is_valid_channel(uint8_t channel)
|
||||
{
|
||||
return ((channel <= IEEE802154_OQPSK_2P4G_CHANNEL_MAX) && (channel >= IEEE802154_OQPSK_2P4G_CHANNEL_MIN));
|
||||
|
||||
@@ -5,14 +5,12 @@ if(${idf_target} STREQUAL "linux")
|
||||
endif()
|
||||
|
||||
if(CONFIG_OPENTHREAD_ENABLED OR CONFIG_IDF_DOC_BUILD OR CONFIG_OPENTHREAD_SPINEL_ONLY)
|
||||
|
||||
set(public_include_dirs
|
||||
"include"
|
||||
"openthread/include")
|
||||
endif()
|
||||
|
||||
if(CONFIG_OPENTHREAD_ENABLED)
|
||||
|
||||
set(private_include_dirs
|
||||
"openthread/examples/platforms"
|
||||
"openthread/src"
|
||||
@@ -24,243 +22,18 @@ if(CONFIG_OPENTHREAD_ENABLED)
|
||||
"openthread/src/ncp"
|
||||
"private_include")
|
||||
|
||||
set(src_dirs
|
||||
"src"
|
||||
"src/port"
|
||||
"openthread/examples/platforms/utils"
|
||||
"openthread/src/core/api"
|
||||
"openthread/src/core/common"
|
||||
"openthread/src/core/crypto"
|
||||
"openthread/src/core/diags"
|
||||
"openthread/src/core/instance"
|
||||
"openthread/src/core/mac"
|
||||
"openthread/src/core/radio"
|
||||
"openthread/src/core/thread"
|
||||
"openthread/src/core/utils"
|
||||
"openthread/src/lib/hdlc"
|
||||
"openthread/src/lib/spinel")
|
||||
|
||||
set(exclude_srcs
|
||||
"openthread/examples/platforms/utils/logging_rtt.c"
|
||||
"openthread/examples/platforms/utils/soft_source_match_table.c"
|
||||
"openthread/src/core/instance/extension_example.cpp"
|
||||
"openthread/src/core/crypto/crypto_platform_mbedtls.cpp"
|
||||
"openthread/src/core/api/random_crypto_api.cpp"
|
||||
)
|
||||
|
||||
|
||||
if(CONFIG_OPENTHREAD_FTD OR CONFIG_OPENTHREAD_MTD)
|
||||
list(APPEND src_dirs
|
||||
"openthread/src/core/backbone_router"
|
||||
"openthread/src/core/coap"
|
||||
"openthread/src/core/meshcop"
|
||||
"openthread/src/core/net"
|
||||
"openthread/src/lib/platform")
|
||||
|
||||
if(CONFIG_OPENTHREAD_CLI)
|
||||
list(APPEND src_dirs
|
||||
"openthread/examples/apps/cli"
|
||||
"openthread/src/cli")
|
||||
|
||||
list(APPEND exclude_srcs
|
||||
"openthread/examples/apps/cli/main.c")
|
||||
endif()
|
||||
|
||||
elseif(CONFIG_OPENTHREAD_RADIO)
|
||||
list(APPEND src_dirs
|
||||
"openthread/src/ncp"
|
||||
"openthread/examples/apps/ncp")
|
||||
|
||||
list(APPEND exclude_srcs
|
||||
"src/port/esp_openthread_state.c"
|
||||
"openthread/examples/apps/ncp/main.c"
|
||||
"openthread/src/core/api/backbone_router_api.cpp"
|
||||
"openthread/src/core/api/child_supervision_api.cpp"
|
||||
"openthread/src/core/api/dataset_api.cpp"
|
||||
"openthread/src/core/api/dns_api.cpp"
|
||||
"openthread/src/core/api/entropy_api.cpp"
|
||||
"openthread/src/core/api/heap_api.cpp"
|
||||
"openthread/src/core/api/icmp6_api.cpp"
|
||||
"openthread/src/core/api/ip6_api.cpp"
|
||||
"openthread/src/core/api/link_api.cpp"
|
||||
"openthread/src/core/api/link_metrics_api.cpp"
|
||||
"openthread/src/core/api/message_api.cpp"
|
||||
"openthread/src/core/api/nat64_api.cpp"
|
||||
"openthread/src/core/api/netdata_api.cpp"
|
||||
"openthread/src/core/api/netdiag_api.cpp"
|
||||
"openthread/src/core/api/network_time_api.cpp"
|
||||
"openthread/src/core/api/random_crypto_api.cpp"
|
||||
"openthread/src/core/api/tcp_api.cpp"
|
||||
"openthread/src/core/api/udp_api.cpp"
|
||||
"openthread/src/core/common/heap.cpp"
|
||||
"openthread/src/core/common/heap_string.cpp"
|
||||
"openthread/src/core/common/notifier.cpp"
|
||||
"openthread/src/core/common/settings.cpp"
|
||||
"openthread/src/core/common/time_ticker.cpp"
|
||||
"openthread/src/core/mac/channel_mask.cpp"
|
||||
"openthread/src/core/mac/data_poll_handler.cpp"
|
||||
"openthread/src/core/mac/data_poll_sender.cpp"
|
||||
"openthread/src/core/mac/mac.cpp"
|
||||
"openthread/src/core/mac/mac_filter.cpp"
|
||||
"openthread/src/core/mac/mac_links.cpp"
|
||||
"openthread/src/core/thread/announce_begin_server.cpp"
|
||||
"openthread/src/core/thread/announce_sender.cpp"
|
||||
"openthread/src/core/thread/address_resolver.cpp"
|
||||
"openthread/src/core/thread/child.cpp"
|
||||
"openthread/src/core/thread/child_supervision.cpp"
|
||||
"openthread/src/core/thread/csl_tx_scheduler.cpp"
|
||||
"openthread/src/core/thread/discover_scanner.cpp"
|
||||
"openthread/src/core/thread/energy_scan_server.cpp"
|
||||
"openthread/src/core/thread/indirect_sender.cpp"
|
||||
"openthread/src/core/thread/key_manager.cpp"
|
||||
"openthread/src/core/thread/link_metrics.cpp"
|
||||
"openthread/src/core/thread/lowpan.cpp"
|
||||
"openthread/src/core/thread/mesh_forwarder.cpp"
|
||||
"openthread/src/core/thread/mesh_forwarder_ftd.cpp"
|
||||
"openthread/src/core/thread/mesh_forwarder_mtd.cpp"
|
||||
"openthread/src/core/thread/message_framer.cpp"
|
||||
"openthread/src/core/thread/mle.cpp"
|
||||
"openthread/src/core/thread/mle_ftd.cpp"
|
||||
"openthread/src/core/thread/mle_p2p.cpp"
|
||||
"openthread/src/core/thread/mle_router.cpp"
|
||||
"openthread/src/core/thread/mle_types.cpp"
|
||||
"openthread/src/core/thread/neighbor.cpp"
|
||||
"openthread/src/core/thread/neighbor_table.cpp"
|
||||
"openthread/src/core/thread/network_data.cpp"
|
||||
"openthread/src/core/thread/network_data_leader.cpp"
|
||||
"openthread/src/core/thread/network_data_leader_ftd.cpp"
|
||||
"openthread/src/core/thread/network_data_types.cpp"
|
||||
"openthread/src/core/thread/network_data_service.cpp"
|
||||
"openthread/src/core/thread/network_diagnostic.cpp"
|
||||
"openthread/src/core/thread/network_diagnostic_tlvs.cpp"
|
||||
"openthread/src/core/thread/panid_query_server.cpp"
|
||||
"openthread/src/core/thread/router.cpp"
|
||||
"openthread/src/core/thread/thread_netif.cpp"
|
||||
"openthread/src/core/thread/time_sync_service.cpp"
|
||||
"openthread/src/core/thread/tmf.cpp"
|
||||
"openthread/src/core/thread/topology.cpp"
|
||||
"openthread/src/core/utils/child_supervision.cpp")
|
||||
endif()
|
||||
|
||||
if(CONFIG_OPENTHREAD_RADIO_NATIVE)
|
||||
list(APPEND exclude_srcs
|
||||
"src/port/esp_openthread_radio_spinel.cpp"
|
||||
"src/port/esp_spi_spinel_interface.cpp"
|
||||
"src/port/esp_uart_spinel_interface.cpp"
|
||||
)
|
||||
elseif(CONFIG_OPENTHREAD_RADIO_SPINEL_UART OR CONFIG_OPENTHREAD_RADIO_SPINEL_SPI)
|
||||
list(APPEND exclude_srcs
|
||||
"src/port/esp_openthread_radio.c"
|
||||
"src/port/esp_openthread_sleep.c")
|
||||
elseif(CONFIG_OPENTHREAD_RADIO_154_NONE)
|
||||
list(APPEND exclude_srcs
|
||||
"src/port/esp_openthread_radio_spinel.cpp"
|
||||
"src/port/esp_spi_spinel_interface.cpp"
|
||||
"src/port/esp_uart_spinel_interface.cpp"
|
||||
"src/port/esp_openthread_radio.c"
|
||||
"src/port/esp_openthread_sleep.c"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT CONFIG_OPENTHREAD_RADIO_TREL)
|
||||
list(APPEND exclude_srcs
|
||||
"src/port/esp_openthread_trel.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_OPENTHREAD_BORDER_ROUTER)
|
||||
list(APPEND src_dirs
|
||||
"openthread/src/core/border_router")
|
||||
endif()
|
||||
|
||||
if(CONFIG_OPENTHREAD_FTD)
|
||||
set_source_files_properties("openthread/src/core/net/srp_server.cpp"
|
||||
PROPERTIES COMPILE_FLAGS
|
||||
-Wno-maybe-uninitialized)
|
||||
endif()
|
||||
|
||||
if(CONFIG_OPENTHREAD_NCP_VENDOR_HOOK)
|
||||
list(APPEND src_dirs
|
||||
"src/ncp")
|
||||
if(CONFIG_OPENTHREAD_RCP_UART OR CONFIG_OPENTHREAD_RCP_USB_SERIAL_JTAG)
|
||||
list(APPEND exclude_srcs
|
||||
"src/ncp/esp_openthread_ncp_spi.cpp")
|
||||
elseif(CONFIG_OPENTHREAD_RCP_SPI)
|
||||
list(APPEND exclude_srcs
|
||||
"src/ncp/esp_openthread_ncp_hdlc.cpp")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT CONFIG_OPENTHREAD_DNS64_CLIENT)
|
||||
list(APPEND exclude_srcs
|
||||
"src/esp_openthread_dns64.c")
|
||||
endif()
|
||||
|
||||
if(NOT CONFIG_FREERTOS_USE_TICKLESS_IDLE)
|
||||
list(APPEND exclude_srcs
|
||||
"src/port/esp_openthread_sleep.c")
|
||||
endif()
|
||||
|
||||
if(NOT CONFIG_OPENTHREAD_PLATFORM_MSGPOOL_MANAGEMENT)
|
||||
list(APPEND exclude_srcs
|
||||
"src/port/esp_openthread_messagepool.c")
|
||||
endif()
|
||||
|
||||
if(NOT CONFIG_OPENTHREAD_RCP_SPINEL_CONSOLE)
|
||||
list(APPEND exclude_srcs
|
||||
"src/ncp/esp_openthread_ncp_console.cpp")
|
||||
endif()
|
||||
|
||||
if(CONFIG_OPENTHREAD_FTD)
|
||||
include(srcs_ftd_mtd.cmake)
|
||||
set(device_type "OPENTHREAD_FTD=1")
|
||||
elseif(CONFIG_OPENTHREAD_MTD)
|
||||
include(srcs_ftd_mtd.cmake)
|
||||
set(device_type "OPENTHREAD_MTD=1")
|
||||
elseif(CONFIG_OPENTHREAD_RADIO)
|
||||
include(srcs_radio.cmake)
|
||||
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/include"
|
||||
"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})
|
||||
|
||||
include(srcs_spinel.cmake)
|
||||
endif()
|
||||
|
||||
if(CONFIG_OPENTHREAD_HEADER_CUSTOM)
|
||||
@@ -287,14 +60,49 @@ string(CONCAT OT_FULL_VERSION_STRING
|
||||
"${IDF_VERSION_FOR_OPENTHREAD_PACKAGE}-${OPENTHREAD_VERSION}\; "
|
||||
"${CONFIG_OPENTHREAD_PLATFORM_INFO}\; ${OT_BUILD_TIMESTAMP}")
|
||||
|
||||
idf_component_register(SRC_DIRS "${src_dirs}"
|
||||
EXCLUDE_SRCS "${exclude_srcs}"
|
||||
INCLUDE_DIRS "${public_include_dirs}"
|
||||
PRIV_INCLUDE_DIRS "${private_include_dirs}"
|
||||
REQUIRES esp_netif lwip esp_driver_uart esp_driver_gpio esp_driver_spi esp_driver_usb_serial_jtag
|
||||
LDFRAGMENTS linker.lf
|
||||
PRIV_REQUIRES console esp_coex esp_event esp_partition esp_timer
|
||||
ieee802154 mbedtls nvs_flash)
|
||||
# Register component based on mode
|
||||
if(CONFIG_OPENTHREAD_FTD OR CONFIG_OPENTHREAD_MTD)
|
||||
# FTD/MTD modes use directory-based collection from srcs_ftd_mtd.cmake
|
||||
idf_component_register(SRC_DIRS "${src_dirs}"
|
||||
EXCLUDE_SRCS "${exclude_srcs}"
|
||||
INCLUDE_DIRS "${public_include_dirs}"
|
||||
PRIV_INCLUDE_DIRS "${private_include_dirs}"
|
||||
REQUIRES esp_netif lwip esp_driver_uart esp_driver_gpio esp_driver_spi
|
||||
esp_driver_usb_serial_jtag
|
||||
LDFRAGMENTS linker.lf
|
||||
PRIV_REQUIRES console esp_coex esp_event esp_partition esp_timer
|
||||
ieee802154 mbedtls nvs_flash esp_psram)
|
||||
elseif(CONFIG_OPENTHREAD_RADIO)
|
||||
# RCP mode uses explicit source list from srcs_radio.cmake
|
||||
idf_component_register(SRCS ${rcp_srcs}
|
||||
INCLUDE_DIRS "${public_include_dirs}"
|
||||
PRIV_INCLUDE_DIRS "${private_include_dirs}"
|
||||
REQUIRES esp_netif lwip esp_driver_uart esp_driver_gpio esp_driver_spi
|
||||
esp_driver_usb_serial_jtag
|
||||
LDFRAGMENTS linker.lf
|
||||
PRIV_REQUIRES console esp_coex esp_event esp_partition esp_timer
|
||||
ieee802154 mbedtls nvs_flash esp_psram)
|
||||
elseif(CONFIG_OPENTHREAD_SPINEL_ONLY)
|
||||
# SPINEL_ONLY mode uses explicit source list from srcs_spinel.cmake
|
||||
idf_component_register(SRCS ${spinel_srcs}
|
||||
INCLUDE_DIRS "${public_include_dirs}"
|
||||
PRIV_INCLUDE_DIRS "${private_include_dirs}"
|
||||
REQUIRES esp_netif lwip esp_driver_uart esp_driver_gpio esp_driver_spi
|
||||
esp_driver_usb_serial_jtag
|
||||
LDFRAGMENTS linker.lf
|
||||
PRIV_REQUIRES console esp_coex esp_event esp_partition esp_timer
|
||||
ieee802154 mbedtls nvs_flash esp_psram)
|
||||
else()
|
||||
# This is not supposed to happen, but in older versions of IDF components couldn't be selectively
|
||||
# enabled based on KConfig options so some examples just included openthread for all configs.
|
||||
idf_component_register(INCLUDE_DIRS "${public_include_dirs}"
|
||||
PRIV_INCLUDE_DIRS "${private_include_dirs}"
|
||||
REQUIRES esp_netif lwip esp_driver_uart esp_driver_gpio esp_driver_spi
|
||||
esp_driver_usb_serial_jtag
|
||||
LDFRAGMENTS linker.lf
|
||||
PRIV_REQUIRES console esp_coex esp_event esp_partition esp_timer
|
||||
ieee802154 mbedtls nvs_flash esp_psram)
|
||||
endif()
|
||||
|
||||
if(CONFIG_OPENTHREAD_RADIO_TREL)
|
||||
idf_component_optional_requires(PRIVATE espressif__mdns)
|
||||
|
||||
@@ -436,6 +436,7 @@ menu "OpenThread"
|
||||
|
||||
config OPENTHREAD_PLATFORM_MSGPOOL_MANAGEMENT
|
||||
bool 'Allocate message pool buffer from PSRAM'
|
||||
depends on OPENTHREAD_PLATFORM_MALLOC_CAP_SPIRAM
|
||||
default y
|
||||
help
|
||||
If enabled, the message pool is managed by platform defined logic.
|
||||
@@ -622,5 +623,27 @@ menu "OpenThread"
|
||||
information whenever an OpenThread assert occurs. This can help developers
|
||||
analyze unexpected failures by providing additional MAC layer context.
|
||||
|
||||
config OPENTHREAD_TASK_BLOCK_MONITOR
|
||||
depends on OPENTHREAD_DEBUG
|
||||
bool "Enable OpenThread Task Block Monitor"
|
||||
default n
|
||||
help
|
||||
Enable monitoring of OpenThread tasks to detect if a task is blocked
|
||||
and unable to continue its normal execution loop. Useful for debugging
|
||||
issues where tasks stop progressing due to deadlocks or resource waits.
|
||||
On RISC-V targets, in order to get meaningful backtraces when a task is
|
||||
detected as blocked, ESP_SYSTEM_USE_FRAME_POINTER must be enabled in
|
||||
ESP System Settings -> Backtracing method.
|
||||
|
||||
config OPENTHREAD_TASK_BLOCK_MONITOR_TIMEOUT
|
||||
depends on OPENTHREAD_TASK_BLOCK_MONITOR
|
||||
int "Task Block Monitor Timeout (seconds)"
|
||||
range 1 60
|
||||
default 20
|
||||
help
|
||||
Set the timeout (in seconds) for detecting a blocked task.
|
||||
The timer is started at the beginning of each task main loop
|
||||
and stopped at the end. If the timer expires, the task is considered blocked.
|
||||
|
||||
|
||||
endmenu
|
||||
|
||||
Submodule components/openthread/lib updated: 43142da1e3...c560c3c990
@@ -2,13 +2,13 @@
|
||||
archive: libopenthread.a
|
||||
entries:
|
||||
if OPENTHREAD_TIMING_OPTIMIZATION = y:
|
||||
link_metrics (noflash)
|
||||
link_quality (noflash)
|
||||
mac_frame (noflash)
|
||||
radio (noflash)
|
||||
sub_mac (noflash)
|
||||
|
||||
if OPENTHREAD_TIMING_OPTIMIZATION = y && OPENTHREAD_RADIO = n:
|
||||
link_metrics (noflash)
|
||||
mesh_forwarder (noflash)
|
||||
csl_tx_scheduler (noflash)
|
||||
mac (noflash)
|
||||
|
||||
Submodule components/openthread/openthread updated: 03933d9b76...9b887f6bd1
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <esp_err.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR
|
||||
/**
|
||||
* @brief This function creates the OpenThread task block monitor.
|
||||
* The monitor task periodically checks whether the OpenThread mainloop
|
||||
* has been blocked for more than `CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR_TIMEOUT`
|
||||
* seconds and prints backtraces when a block is detected.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL if the monitor task cannot be created
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_openthread_task_block_monitor_create(void);
|
||||
|
||||
/**
|
||||
* @brief This function deletes the OpenThread task block monitor.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_openthread_task_block_monitor_delete(void);
|
||||
|
||||
/**
|
||||
* @brief This function enables or disables the OpenThread task block monitor.
|
||||
*
|
||||
* @note When enabled, the latest mainloop activity timestamp is updated and the
|
||||
* monitor task starts checking for blocking. When disabled, monitoring is
|
||||
* temporarily stopped.
|
||||
*
|
||||
* @param[in] enable True to enable the monitor, false to disable it.
|
||||
*
|
||||
*/
|
||||
void esp_openthread_task_block_monitor_set(bool enable);
|
||||
#endif // CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -99,6 +99,16 @@
|
||||
#define OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 0
|
||||
#endif // CONFIG_OPENTHREAD_RADIO_TREL
|
||||
|
||||
#if CONFIG_OPENTHREAD_RADIO_TREL
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_TREL_USE_HEAP_ENABLE
|
||||
*
|
||||
* Set to 1 to allow TREL modules to use heap allocated objects (e.g. for the TREL peer table).
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_CONFIG_TREL_USE_HEAP_ENABLE 1
|
||||
#endif // CONFIG_OPENTHREAD_RADIO_TREL
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
|
||||
*
|
||||
@@ -879,7 +889,7 @@
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_MARK_ECN_INTERVAL
|
||||
* @def OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_MARK_ECN_INTERVAL
|
||||
*
|
||||
* Specifies the time-in-queue threshold interval in milliseconds to mark ECN on a message if it is ECN-capable or
|
||||
* drop the message if not ECN-capable.
|
||||
@@ -888,10 +898,34 @@
|
||||
#define OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_MARK_ECN_INTERVAL 1000
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_PLATFORM_MAC_KEYS_EXPORTABLE_ENABLE
|
||||
*
|
||||
* Define to 1 if you want to make MAC keys exportable.
|
||||
*/
|
||||
#define OPENTHREAD_CONFIG_PLATFORM_MAC_KEYS_EXPORTABLE_ENABLE 1
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_CRYPTO_LIB
|
||||
*
|
||||
* Selects the crypto backend library for OpenThread.
|
||||
*
|
||||
* There are several options available
|
||||
* - @sa OPENTHREAD_CONFIG_CRYPTO_LIB_MBEDTLS
|
||||
* - @sa OPENTHREAD_CONFIG_CRYPTO_LIB_PSA
|
||||
* - @sa OPENTHREAD_CONFIG_CRYPTO_LIB_PLATFORM
|
||||
*/
|
||||
#define OPENTHREAD_CONFIG_CRYPTO_LIB OPENTHREAD_CONFIG_CRYPTO_LIB_PSA
|
||||
// TODO: Remove when https://github.com/openthread/openthread/pull/12638 is merged
|
||||
#define OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE 1
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_MESHCOP_STEERING_DATA_API_ENABLE
|
||||
*
|
||||
* Define as 1 to enable the MeshCoP Steering Data public APIs (in `openthread/steering_data.h`).
|
||||
*/
|
||||
#define OPENTHREAD_CONFIG_MESHCOP_STEERING_DATA_API_ENABLE 1
|
||||
|
||||
#ifndef OPENTHREAD_CONFIG_THREAD_VERSION
|
||||
#define OPENTHREAD_CONFIG_THREAD_VERSION OT_THREAD_VERSION_1_4
|
||||
#endif
|
||||
|
||||
#define OPENTHREAD_CONFIG_PLATFORM_MAC_KEYS_EXPORTABLE_ENABLE 1
|
||||
|
||||
#define OPENTHREAD_CONFIG_CRYPTO_LIB OPENTHREAD_CONFIG_CRYPTO_LIB_PSA
|
||||
|
||||
@@ -494,6 +494,34 @@
|
||||
#define OPENTHREAD_CONFIG_PARENT_SEARCH_RSS_THRESHOLD CONFIG_OPENTHREAD_PARENT_SEARCH_RSS_THRESHOLD
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_PLATFORM_MAC_KEYS_EXPORTABLE_ENABLE
|
||||
*
|
||||
* Define to 1 if you want to make MAC keys exportable.
|
||||
*/
|
||||
#define OPENTHREAD_CONFIG_PLATFORM_MAC_KEYS_EXPORTABLE_ENABLE 1
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_CRYPTO_LIB
|
||||
*
|
||||
* Selects the crypto backend library for OpenThread.
|
||||
*
|
||||
* There are several options available
|
||||
* - @sa OPENTHREAD_CONFIG_CRYPTO_LIB_MBEDTLS
|
||||
* - @sa OPENTHREAD_CONFIG_CRYPTO_LIB_PSA
|
||||
* - @sa OPENTHREAD_CONFIG_CRYPTO_LIB_PLATFORM
|
||||
*/
|
||||
#define OPENTHREAD_CONFIG_CRYPTO_LIB OPENTHREAD_CONFIG_CRYPTO_LIB_PSA
|
||||
// TODO: Remove when https://github.com/openthread/openthread/pull/12638 is merged
|
||||
#define OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE 1
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_MESHCOP_STEERING_DATA_API_ENABLE
|
||||
*
|
||||
* Define as 1 to enable the MeshCoP Steering Data public APIs (in `openthread/steering_data.h`).
|
||||
*/
|
||||
#define OPENTHREAD_CONFIG_MESHCOP_STEERING_DATA_API_ENABLE 1
|
||||
|
||||
#ifndef OPENTHREAD_CONFIG_THREAD_VERSION
|
||||
#define OPENTHREAD_CONFIG_THREAD_VERSION OT_THREAD_VERSION_1_4
|
||||
#endif
|
||||
|
||||
@@ -5,4 +5,4 @@ supplier: 'Organization: Espressif Systems (Shanghai) CO LTD'
|
||||
originator: 'Organization: Google LLC'
|
||||
description: OpenThread released by Google is an open-source implementation of the Thread networking
|
||||
url: https://github.com/espressif/openthread
|
||||
hash: 03933d9b76cb7075cc29a6648b42b217971f82a5
|
||||
hash: 9b887f6bd1437170fc9bcb726f32185ccb3cb841
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "esp_openthread_platform.h"
|
||||
#include "esp_openthread_sleep.h"
|
||||
#include "esp_openthread_state.h"
|
||||
#include "esp_openthread_debug.h"
|
||||
#include "esp_openthread_task_queue.h"
|
||||
#include "esp_openthread_types.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
@@ -27,7 +28,6 @@
|
||||
#include "openthread/netdata.h"
|
||||
#include "openthread/tasklet.h"
|
||||
#include "openthread/thread.h"
|
||||
#include <cstddef>
|
||||
|
||||
#if CONFIG_OPENTHREAD_FTD
|
||||
#include "openthread/dataset_ftd.h"
|
||||
@@ -186,6 +186,10 @@ esp_err_t esp_openthread_launch_mainloop(void)
|
||||
esp_err_t error = ESP_OK;
|
||||
s_ot_mainloop_running = true;
|
||||
|
||||
#if CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR
|
||||
ESP_ERROR_CHECK(esp_openthread_task_block_monitor_create());
|
||||
#endif
|
||||
|
||||
while (s_ot_mainloop_running) {
|
||||
FD_ZERO(&mainloop.read_fds);
|
||||
FD_ZERO(&mainloop.write_fds);
|
||||
@@ -206,8 +210,14 @@ esp_err_t esp_openthread_launch_mainloop(void)
|
||||
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE && CONFIG_OPENTHREAD_RADIO_NATIVE */
|
||||
esp_openthread_lock_release();
|
||||
|
||||
if (select(mainloop.max_fd + 1, &mainloop.read_fds, &mainloop.write_fds, &mainloop.error_fds,
|
||||
&mainloop.timeout) >= 0) {
|
||||
#if CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR
|
||||
esp_openthread_task_block_monitor_set(false);
|
||||
#endif
|
||||
int result = select(mainloop.max_fd + 1, &mainloop.read_fds, &mainloop.write_fds, &mainloop.error_fds, &mainloop.timeout);
|
||||
#if CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR
|
||||
esp_openthread_task_block_monitor_set(true);
|
||||
#endif
|
||||
if (result >= 0) {
|
||||
esp_openthread_lock_acquire(portMAX_DELAY);
|
||||
error = esp_openthread_platform_process(instance, &mainloop);
|
||||
while (otTaskletsArePending(instance)) {
|
||||
@@ -224,6 +234,9 @@ esp_err_t esp_openthread_launch_mainloop(void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR
|
||||
ESP_ERROR_CHECK(esp_openthread_task_block_monitor_delete());
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -183,7 +183,21 @@ static esp_err_t openthread_netif_transmit(void *handle, void *buffer, size_t le
|
||||
otError ot_error = OT_ERROR_NONE;
|
||||
|
||||
esp_openthread_task_switching_lock_acquire(portMAX_DELAY);
|
||||
otMessage *message = otIp6NewMessage(esp_openthread_get_instance(), NULL);
|
||||
|
||||
otMessageSettings settings = {};
|
||||
switch (otThreadGetDeviceRole(esp_openthread_get_instance()))
|
||||
{
|
||||
case OT_DEVICE_ROLE_DISABLED:
|
||||
settings.mLinkSecurityEnabled = false;
|
||||
settings.mPriority = OT_MESSAGE_PRIORITY_LOW;
|
||||
break;
|
||||
default:
|
||||
settings.mLinkSecurityEnabled = true;
|
||||
settings.mPriority = OT_MESSAGE_PRIORITY_NORMAL;
|
||||
break;
|
||||
}
|
||||
|
||||
otMessage *message = otIp6NewMessage(esp_openthread_get_instance(), &settings);
|
||||
if (message == NULL) {
|
||||
ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to allocate OpenThread message");
|
||||
ExitNow(error = ESP_ERR_NO_MEM);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -179,11 +179,21 @@ esp_err_t esp_openthread_platform_deinit(void)
|
||||
esp_openthread_task_queue_deinit();
|
||||
esp_openthread_radio_deinit();
|
||||
|
||||
if (get_host_connection_mode() == HOST_CONNECTION_MODE_RCP_SPI){
|
||||
esp_openthread_host_connection_mode_t host_mode = get_host_connection_mode();
|
||||
switch (host_mode) {
|
||||
#if CONFIG_OPENTHREAD_RCP_SPI
|
||||
case HOST_CONNECTION_MODE_RCP_SPI:
|
||||
esp_openthread_spi_slave_deinit();
|
||||
} else if (get_host_connection_mode() == HOST_CONNECTION_MODE_CLI_UART ||
|
||||
get_host_connection_mode() == HOST_CONNECTION_MODE_RCP_UART) {
|
||||
break;
|
||||
#endif
|
||||
#if CONFIG_OPENTHREAD_RCP_UART || CONFIG_OPENTHREAD_CONSOLE_TYPE_UART
|
||||
case HOST_CONNECTION_MODE_RCP_UART:
|
||||
case HOST_CONNECTION_MODE_CLI_UART:
|
||||
esp_openthread_uart_deinit();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
esp_openthread_lock_deinit();
|
||||
@@ -217,6 +227,6 @@ uint32_t esp_openthread_get_alloc_caps(void)
|
||||
#if CONFIG_OPENTHREAD_PLATFORM_MALLOC_CAP_SPIRAM
|
||||
(MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||
#else
|
||||
(MALLOC_CAP_DEFAULT | MALLOC_CAP_8BIT);
|
||||
(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "esp_check.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_debug_helpers.h"
|
||||
#include "esp_openthread_debug.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#if CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR
|
||||
|
||||
#include "esp_private/eh_frame_parser.h"
|
||||
#include "esp_private/esp_system_attr.h"
|
||||
#include "esp_private/esp_cpu_internal.h"
|
||||
#include "esp_private/fp_unwind.h"
|
||||
#include "esp_private/panic_internal.h"
|
||||
#include "freertos/freertos_debug.h"
|
||||
|
||||
static const char *TAG = "OT_DEBUG";
|
||||
static TaskHandle_t s_ot_task_block_monitor_task = NULL;
|
||||
static atomic_llong s_ot_task_block_monitor_latest_time = 0;
|
||||
static atomic_bool s_ot_task_block_monitor_active = false;
|
||||
static const int64_t s_ot_task_block_monitor_timeout = CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR_TIMEOUT * 1000000;
|
||||
static bool is_backtrace_printed = false;
|
||||
|
||||
#if CONFIG_IDF_TARGET_ARCH_RISCV
|
||||
static esp_err_t ESP_SYSTEM_IRAM_ATTR esp_task_backtrace_print(TaskHandle_t target_task)
|
||||
{
|
||||
TaskSnapshot_t snapshot = {};
|
||||
void *frame = NULL;
|
||||
|
||||
vTaskGetSnapshot(target_task, &snapshot);
|
||||
|
||||
frame = snapshot.pxTopOfStack;
|
||||
char *name = pcTaskGetName(target_task);
|
||||
|
||||
ESP_LOGI(TAG, "Target Task Backtrace: %s", name ? name : "No Name");
|
||||
|
||||
#if CONFIG_ESP_SYSTEM_USE_EH_FRAME
|
||||
esp_eh_frame_print_backtrace(frame);
|
||||
#elif CONFIG_ESP_SYSTEM_USE_FRAME_POINTER
|
||||
esp_fp_print_backtrace(frame);
|
||||
#else
|
||||
esp_cpu_frame_t backtrace_frame = {};
|
||||
const int current_core = xPortGetCoreID();
|
||||
memset(&backtrace_frame, 0, sizeof(esp_cpu_frame_t));
|
||||
memcpy(&backtrace_frame, frame, sizeof(esp_cpu_frame_t));
|
||||
|
||||
panic_prepare_frame_from_ctx(&backtrace_frame);
|
||||
panic_print_registers(&backtrace_frame, current_core);
|
||||
|
||||
esp_rom_printf("\r\n");
|
||||
esp_rom_printf("Please enable CONFIG_ESP_SYSTEM_USE_FRAME_POINTER option to have a full backtrace.\r\n");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void ot_debug_monitor_task(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
while (true) {
|
||||
if (atomic_load(&s_ot_task_block_monitor_active)) {
|
||||
int64_t elapsed = esp_timer_get_time() - atomic_load(&s_ot_task_block_monitor_latest_time);
|
||||
if (elapsed > s_ot_task_block_monitor_timeout && !is_backtrace_printed) {
|
||||
is_backtrace_printed = true;
|
||||
ESP_LOGW(TAG,
|
||||
"OpenThread mainloop blocked for more than %d seconds, printing all tasks backtrace",
|
||||
CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR_TIMEOUT);
|
||||
#if CONFIG_IDF_TARGET_ARCH_XTENSA
|
||||
esp_backtrace_print_all_tasks(10);
|
||||
#elif CONFIG_IDF_TARGET_ARCH_RISCV
|
||||
TaskHandle_t handle = xTaskGetHandle(CONFIG_OPENTHREAD_TASK_NAME);
|
||||
if (handle) {
|
||||
esp_task_backtrace_print(handle);
|
||||
}
|
||||
#endif
|
||||
} else if (elapsed <= s_ot_task_block_monitor_timeout) {
|
||||
is_backtrace_printed = false;
|
||||
}
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t esp_openthread_task_block_monitor_create(void)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(s_ot_task_block_monitor_task == NULL, ESP_OK, TAG, "Task block monitor already created");
|
||||
|
||||
BaseType_t ret = xTaskCreate(ot_debug_monitor_task, "ot_task_monitor", 3072, NULL, CONFIG_OPENTHREAD_TASK_PRIORITY, &s_ot_task_block_monitor_task);
|
||||
ESP_RETURN_ON_FALSE(ret == pdPASS, ESP_FAIL, TAG, "Failed to create OpenThread task block monitor");
|
||||
|
||||
ESP_LOGI(TAG, "OpenThread task block monitor created");
|
||||
esp_openthread_task_block_monitor_set(true);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_openthread_task_block_monitor_delete(void)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(s_ot_task_block_monitor_task != NULL, ESP_OK, TAG, "Task block monitor not created");
|
||||
|
||||
esp_openthread_task_block_monitor_set(false);
|
||||
vTaskDelete(s_ot_task_block_monitor_task);
|
||||
s_ot_task_block_monitor_task = NULL;
|
||||
|
||||
ESP_LOGI(TAG, "OpenThread task block monitor deleted");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void esp_openthread_task_block_monitor_set(bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
atomic_store(&s_ot_task_block_monitor_latest_time, esp_timer_get_time());
|
||||
atomic_store(&s_ot_task_block_monitor_active, true);
|
||||
} else {
|
||||
atomic_store(&s_ot_task_block_monitor_active, false);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR
|
||||
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "esp_openthread.h"
|
||||
#include "esp_openthread_platform.h"
|
||||
|
||||
#include "openthread/platform/memory.h"
|
||||
|
||||
@@ -12,10 +13,10 @@
|
||||
|
||||
void *otPlatCAlloc(size_t num, size_t size)
|
||||
{
|
||||
return calloc(num, size);
|
||||
return heap_caps_calloc_prefer(num, size, 3, esp_openthread_get_alloc_caps(), MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
}
|
||||
|
||||
void otPlatFree(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
heap_caps_free(ptr);
|
||||
}
|
||||
|
||||
@@ -1,35 +1,48 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
#include "esp_openthread_common_macro.h"
|
||||
#include "esp_openthread_platform.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_psram.h"
|
||||
#include "openthread/instance.h"
|
||||
#include "openthread/platform/messagepool.h"
|
||||
|
||||
int s_buffer_pool_head = -1;
|
||||
otMessageBuffer **s_buffer_pool_pointer = NULL;
|
||||
otMessageBuffer *s_buffer_pool = NULL;
|
||||
// Fallback buffer count at runtime for non-PSRAM targets (matches Kconfig default)
|
||||
#define OT_MSGPOOL_NUM_BUFFERS_NO_PSRAM 65
|
||||
|
||||
static int s_buffer_pool_head = -1;
|
||||
static otMessageBuffer **s_buffer_pool_pointer = NULL;
|
||||
static otMessageBuffer *s_buffer_pool = NULL;
|
||||
|
||||
void otPlatMessagePoolInit(otInstance *aInstance, uint16_t aMinNumFreeBuffers, size_t aBufferSize)
|
||||
{
|
||||
otMessageBuffer *buffer_pool = (otMessageBuffer *)heap_caps_calloc(aMinNumFreeBuffers, aBufferSize, MALLOC_CAP_SPIRAM);
|
||||
s_buffer_pool_pointer = (otMessageBuffer **)heap_caps_calloc(aMinNumFreeBuffers, sizeof(otMessageBuffer **), MALLOC_CAP_SPIRAM);
|
||||
uint16_t num_buffers = aMinNumFreeBuffers;
|
||||
|
||||
if (!esp_psram_is_initialized() && num_buffers > OT_MSGPOOL_NUM_BUFFERS_NO_PSRAM) {
|
||||
ESP_LOGW(OT_PLAT_LOG_TAG, "PSRAM not available, reducing message pool from %u to %u buffers",
|
||||
num_buffers, OT_MSGPOOL_NUM_BUFFERS_NO_PSRAM);
|
||||
num_buffers = OT_MSGPOOL_NUM_BUFFERS_NO_PSRAM;
|
||||
}
|
||||
|
||||
otMessageBuffer *buffer_pool = (otMessageBuffer *)heap_caps_calloc_prefer(num_buffers, aBufferSize, 3, esp_openthread_get_alloc_caps(), MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
s_buffer_pool_pointer = (otMessageBuffer **)heap_caps_calloc_prefer(num_buffers, sizeof(otMessageBuffer **), 3, esp_openthread_get_alloc_caps(), MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
if (buffer_pool == NULL || s_buffer_pool_pointer == NULL) {
|
||||
ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to create message buffer pool");
|
||||
assert(false);
|
||||
}
|
||||
for (uint16_t i = 0; i < aMinNumFreeBuffers; i++) {
|
||||
for (uint16_t i = 0; i < num_buffers; i++) {
|
||||
s_buffer_pool_pointer[i] = buffer_pool + i * aBufferSize / sizeof(otMessageBuffer);
|
||||
}
|
||||
s_buffer_pool_head = aMinNumFreeBuffers - 1;
|
||||
s_buffer_pool_head = num_buffers - 1;
|
||||
s_buffer_pool = buffer_pool;
|
||||
ESP_LOGI(OT_PLAT_LOG_TAG, "Create message buffer pool successfully, size %d", aMinNumFreeBuffers*aBufferSize);
|
||||
ESP_LOGI(OT_PLAT_LOG_TAG, "Create message buffer pool successfully, size %d", num_buffers * aBufferSize);
|
||||
}
|
||||
|
||||
otMessageBuffer *otPlatMessagePoolNew(otInstance *aInstance)
|
||||
|
||||
@@ -413,7 +413,7 @@ void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
|
||||
otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration)
|
||||
{
|
||||
esp_ieee802154_set_channel(aScanChannel);
|
||||
esp_ieee802154_energy_detect(aScanDuration * US_PER_MS / US_PER_SYMBLE);
|
||||
esp_ieee802154_energy_detect(aScanDuration * US_PER_MS / US_PER_SYMBOL);
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Source files for FTD (Full Thread Device) and MTD (Minimal Thread Device) modes.
|
||||
# Uses directory-based collection with exclusions.
|
||||
|
||||
set(src_dirs
|
||||
"src"
|
||||
"src/port"
|
||||
"openthread/examples/platforms/utils"
|
||||
"openthread/src/core/api"
|
||||
"openthread/src/core/common"
|
||||
"openthread/src/core/crypto"
|
||||
"openthread/src/core/diags"
|
||||
"openthread/src/core/instance"
|
||||
"openthread/src/core/mac"
|
||||
"openthread/src/core/radio"
|
||||
"openthread/src/core/thread"
|
||||
"openthread/src/core/utils"
|
||||
"openthread/src/lib/hdlc"
|
||||
"openthread/src/lib/spinel"
|
||||
"openthread/src/core/backbone_router"
|
||||
"openthread/src/core/coap"
|
||||
"openthread/src/core/meshcop"
|
||||
"openthread/src/core/net"
|
||||
"openthread/src/lib/platform"
|
||||
)
|
||||
|
||||
set(exclude_srcs
|
||||
"openthread/examples/platforms/utils/logging_rtt.c"
|
||||
"openthread/examples/platforms/utils/soft_source_match_table.c"
|
||||
"openthread/src/core/instance/extension_example.cpp"
|
||||
"openthread/src/core/crypto/crypto_platform_mbedtls.cpp"
|
||||
"openthread/src/core/api/random_crypto_api.cpp"
|
||||
)
|
||||
|
||||
# CLI sources
|
||||
if(CONFIG_OPENTHREAD_CLI)
|
||||
list(APPEND src_dirs
|
||||
"openthread/examples/apps/cli"
|
||||
"openthread/src/cli")
|
||||
list(APPEND exclude_srcs
|
||||
"openthread/examples/apps/cli/main.c")
|
||||
endif()
|
||||
|
||||
# Radio interface exclusions
|
||||
if(CONFIG_OPENTHREAD_RADIO_NATIVE)
|
||||
list(APPEND exclude_srcs
|
||||
"src/port/esp_openthread_radio_spinel.cpp"
|
||||
"src/port/esp_spi_spinel_interface.cpp"
|
||||
"src/port/esp_uart_spinel_interface.cpp")
|
||||
elseif(CONFIG_OPENTHREAD_RADIO_SPINEL_UART OR CONFIG_OPENTHREAD_RADIO_SPINEL_SPI)
|
||||
list(APPEND exclude_srcs
|
||||
"src/port/esp_openthread_radio.c"
|
||||
"src/port/esp_openthread_sleep.c")
|
||||
elseif(CONFIG_OPENTHREAD_RADIO_154_NONE)
|
||||
list(APPEND exclude_srcs
|
||||
"src/port/esp_openthread_radio_spinel.cpp"
|
||||
"src/port/esp_spi_spinel_interface.cpp"
|
||||
"src/port/esp_uart_spinel_interface.cpp"
|
||||
"src/port/esp_openthread_radio.c"
|
||||
"src/port/esp_openthread_sleep.c")
|
||||
endif()
|
||||
|
||||
# TREL
|
||||
if(NOT CONFIG_OPENTHREAD_RADIO_TREL)
|
||||
list(APPEND exclude_srcs
|
||||
"src/port/esp_openthread_trel.c")
|
||||
endif()
|
||||
|
||||
# Border router
|
||||
if(CONFIG_OPENTHREAD_BORDER_ROUTER)
|
||||
list(APPEND src_dirs
|
||||
"openthread/src/core/border_router")
|
||||
endif()
|
||||
|
||||
# FTD-specific
|
||||
if(CONFIG_OPENTHREAD_FTD)
|
||||
set_source_files_properties("openthread/src/core/net/srp_server.cpp"
|
||||
PROPERTIES COMPILE_FLAGS
|
||||
-Wno-maybe-uninitialized)
|
||||
endif()
|
||||
|
||||
# NCP vendor hook
|
||||
if(CONFIG_OPENTHREAD_NCP_VENDOR_HOOK)
|
||||
list(APPEND src_dirs
|
||||
"src/ncp")
|
||||
if(CONFIG_OPENTHREAD_RCP_UART OR CONFIG_OPENTHREAD_RCP_USB_SERIAL_JTAG)
|
||||
list(APPEND exclude_srcs
|
||||
"src/ncp/esp_openthread_ncp_spi.cpp")
|
||||
elseif(CONFIG_OPENTHREAD_RCP_SPI)
|
||||
list(APPEND exclude_srcs
|
||||
"src/ncp/esp_openthread_ncp_hdlc.cpp")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Optional features
|
||||
if(NOT CONFIG_OPENTHREAD_DNS64_CLIENT)
|
||||
list(APPEND exclude_srcs
|
||||
"src/esp_openthread_dns64.c")
|
||||
endif()
|
||||
|
||||
if(NOT CONFIG_FREERTOS_USE_TICKLESS_IDLE)
|
||||
list(APPEND exclude_srcs
|
||||
"src/port/esp_openthread_sleep.c")
|
||||
endif()
|
||||
|
||||
if(NOT CONFIG_OPENTHREAD_PLATFORM_MSGPOOL_MANAGEMENT)
|
||||
list(APPEND exclude_srcs
|
||||
"src/port/esp_openthread_messagepool.c")
|
||||
endif()
|
||||
|
||||
if(NOT CONFIG_OPENTHREAD_RCP_SPINEL_CONSOLE)
|
||||
list(APPEND exclude_srcs
|
||||
"src/ncp/esp_openthread_ncp_console.cpp")
|
||||
endif()
|
||||
@@ -0,0 +1,97 @@
|
||||
# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Source files for RCP (Radio Co-Processor) mode.
|
||||
# Uses explicit whitelist to avoid including non-RCP-compatible files.
|
||||
# This prevents new OpenThread files from breaking RCP builds.
|
||||
|
||||
set(rcp_srcs
|
||||
# OpenThread core - RADIO_COMMON_SOURCES from openthread/src/core/CMakeLists.txt
|
||||
# No need for crypto/crypto_platform_mbedtls.cpp because we use esp-idf implementation
|
||||
openthread/src/core/api/diags_api.cpp
|
||||
openthread/src/core/api/error_api.cpp
|
||||
openthread/src/core/api/instance_api.cpp
|
||||
openthread/src/core/api/link_raw_api.cpp
|
||||
openthread/src/core/api/logging_api.cpp
|
||||
openthread/src/core/api/random_noncrypto_api.cpp
|
||||
openthread/src/core/api/tasklet_api.cpp
|
||||
openthread/src/core/common/binary_search.cpp
|
||||
openthread/src/core/common/error.cpp
|
||||
openthread/src/core/common/frame_builder.cpp
|
||||
openthread/src/core/common/log.cpp
|
||||
openthread/src/core/common/random.cpp
|
||||
openthread/src/core/common/string.cpp
|
||||
openthread/src/core/common/tasklet.cpp
|
||||
openthread/src/core/common/timer.cpp
|
||||
openthread/src/core/common/uptime.cpp
|
||||
openthread/src/core/crypto/aes_ccm.cpp
|
||||
openthread/src/core/crypto/aes_ecb.cpp
|
||||
openthread/src/core/crypto/crypto_platform_psa.cpp
|
||||
openthread/src/core/crypto/storage.cpp
|
||||
openthread/src/core/diags/factory_diags.cpp
|
||||
openthread/src/core/instance/instance.cpp
|
||||
openthread/src/core/mac/link_raw.cpp
|
||||
openthread/src/core/mac/mac_frame.cpp
|
||||
openthread/src/core/mac/mac_header_ie.cpp
|
||||
openthread/src/core/mac/mac_types.cpp
|
||||
openthread/src/core/mac/sub_mac.cpp
|
||||
openthread/src/core/mac/sub_mac_callbacks.cpp
|
||||
openthread/src/core/mac/sub_mac_csl_receiver.cpp
|
||||
openthread/src/core/mac/sub_mac_wed.cpp
|
||||
openthread/src/core/radio/radio.cpp
|
||||
openthread/src/core/radio/radio_callbacks.cpp
|
||||
openthread/src/core/radio/radio_platform.cpp
|
||||
openthread/src/core/thread/link_quality.cpp
|
||||
openthread/src/core/utils/otns.cpp
|
||||
openthread/src/core/utils/parse_cmdline.cpp
|
||||
openthread/src/core/utils/power_calibration.cpp
|
||||
# Platform utils
|
||||
openthread/examples/platforms/utils/mac_frame.cpp
|
||||
# HDLC library
|
||||
openthread/src/lib/hdlc/hdlc.cpp
|
||||
# Spinel library
|
||||
openthread/src/lib/spinel/spinel.c
|
||||
openthread/src/lib/spinel/spinel_buffer.cpp
|
||||
openthread/src/lib/spinel/spinel_decoder.cpp
|
||||
openthread/src/lib/spinel/spinel_encoder.cpp
|
||||
# NCP
|
||||
openthread/src/ncp/changed_props_set.cpp
|
||||
openthread/src/ncp/ncp_base.cpp
|
||||
openthread/src/ncp/ncp_base_dispatcher.cpp
|
||||
openthread/src/ncp/ncp_base_radio.cpp
|
||||
openthread/examples/apps/ncp/ncp.c
|
||||
# ESP port
|
||||
src/port/esp_openthread_alarm.c
|
||||
src/port/esp_openthread_logging.c
|
||||
src/port/esp_openthread_misc.c
|
||||
src/port/esp_openthread_radio.c
|
||||
src/port/esp_openthread_settings.c
|
||||
# ESP sources
|
||||
src/esp_openthread.cpp
|
||||
src/esp_openthread_lock.c
|
||||
src/esp_openthread_platform.cpp
|
||||
src/esp_openthread_task_queue.c
|
||||
# ESP NCP
|
||||
src/ncp/esp_openthread_ncp.cpp
|
||||
)
|
||||
|
||||
# Conditional sources based on host connection mode
|
||||
if(CONFIG_OPENTHREAD_RCP_UART OR CONFIG_OPENTHREAD_RCP_USB_SERIAL_JTAG)
|
||||
list(APPEND rcp_srcs
|
||||
openthread/src/ncp/ncp_hdlc.cpp
|
||||
src/port/esp_openthread_uart.c)
|
||||
if(CONFIG_OPENTHREAD_NCP_VENDOR_HOOK)
|
||||
list(APPEND rcp_srcs src/ncp/esp_openthread_ncp_hdlc.cpp)
|
||||
endif()
|
||||
elseif(CONFIG_OPENTHREAD_RCP_SPI)
|
||||
list(APPEND rcp_srcs
|
||||
openthread/src/ncp/ncp_spi.cpp
|
||||
src/port/esp_openthread_spi_slave.c)
|
||||
if(CONFIG_OPENTHREAD_NCP_VENDOR_HOOK)
|
||||
list(APPEND rcp_srcs src/ncp/esp_openthread_ncp_spi.cpp)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CONFIG_OPENTHREAD_NCP_VENDOR_HOOK AND CONFIG_OPENTHREAD_RCP_SPINEL_CONSOLE)
|
||||
list(APPEND rcp_srcs src/ncp/esp_openthread_ncp_console.cpp)
|
||||
endif()
|
||||
@@ -0,0 +1,45 @@
|
||||
# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Source files for SPINEL_ONLY mode.
|
||||
# Minimal build for host-side spinel communication.
|
||||
# Uses explicit whitelist for clarity.
|
||||
|
||||
set(private_include_dirs
|
||||
"private_include"
|
||||
"openthread/src"
|
||||
"openthread/src/core"
|
||||
"openthread/src/include"
|
||||
"openthread/src/lib"
|
||||
"openthread/src/lib/hdlc"
|
||||
"openthread/src/lib/spinel"
|
||||
)
|
||||
|
||||
set(spinel_srcs
|
||||
# ESP spinel sources
|
||||
src/spinel/esp_radio_spinel.cpp
|
||||
src/spinel/esp_radio_spinel_uart_interface.cpp
|
||||
# ESP port (minimal)
|
||||
src/port/esp_openthread_alarm.c
|
||||
src/port/esp_openthread_logging.c
|
||||
# OpenThread spinel library
|
||||
openthread/src/lib/spinel/spinel.c
|
||||
openthread/src/lib/spinel/spinel_buffer.cpp
|
||||
openthread/src/lib/spinel/spinel_decoder.cpp
|
||||
openthread/src/lib/spinel/spinel_encoder.cpp
|
||||
openthread/src/lib/spinel/spinel_helper.cpp
|
||||
openthread/src/lib/spinel/radio_spinel.cpp
|
||||
openthread/src/lib/spinel/spinel_driver.cpp
|
||||
openthread/src/lib/spinel/logger.cpp
|
||||
# OpenThread HDLC library
|
||||
openthread/src/lib/hdlc/hdlc.cpp
|
||||
# OpenThread platform library
|
||||
openthread/src/lib/platform/exit_code.c
|
||||
# OpenThread core (minimal)
|
||||
openthread/src/core/api/error_api.cpp
|
||||
openthread/src/core/api/logging_api.cpp
|
||||
openthread/src/core/common/error.cpp
|
||||
openthread/src/core/common/log.cpp
|
||||
openthread/src/core/common/string.cpp
|
||||
openthread/src/core/mac/mac_frame.cpp
|
||||
)
|
||||
@@ -25,6 +25,8 @@ examples/openthread/ot_br:
|
||||
enable:
|
||||
- if: ((SOC_WIFI_SUPPORTED == 1 and IDF_TARGET != "esp32c61") or IDF_TARGET == "esp32p4") and CONFIG_NAME != "native_radio"
|
||||
- if: SOC_WIFI_SUPPORTED == 1 and (SOC_IEEE802154_SUPPORTED == 1 and CONFIG_NAME == "native_radio")
|
||||
disable:
|
||||
- if: IDF_TARGET in ["esp32", "esp32s2", "esp32s3"] and CONFIG_NAME == "br_debug_riscv"
|
||||
disable_test:
|
||||
- if: IDF_TARGET not in ["esp32s3"]
|
||||
reason: only test on esp32s3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# 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, 1900K,
|
||||
nvs, data, nvs, , 0x6000,
|
||||
phy_init, data, phy, , 0x1000,
|
||||
factory, app, factory, , 2000K,
|
||||
|
||||
|
@@ -0,0 +1,2 @@
|
||||
CONFIG_OPENTHREAD_DEBUG=y
|
||||
CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR=y
|
||||
@@ -0,0 +1,3 @@
|
||||
CONFIG_ESP_SYSTEM_USE_FRAME_POINTER=y
|
||||
CONFIG_OPENTHREAD_DEBUG=y
|
||||
CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR=y
|
||||
@@ -4,7 +4,6 @@
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||
CONFIG_PARTITION_TABLE_MD5=y
|
||||
# end of Partition Table
|
||||
|
||||
@@ -58,3 +57,8 @@ CONFIG_EXAMPLE_CONNECT_THREAD=n
|
||||
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3584
|
||||
CONFIG_ESP_MAIN_TASK_STACK_SIZE=6144
|
||||
# end of ESP System Settings
|
||||
|
||||
#
|
||||
# Serial flasher config
|
||||
#
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
|
||||
@@ -5,3 +5,5 @@ CONFIG_OPENTHREAD_BORDER_ROUTER_AUTO_START=y
|
||||
# Enable PPP support as a workaround to ensure LWIP thread-lib compatibility for Ethernet builds
|
||||
CONFIG_LWIP_PPP_SUPPORT=y
|
||||
CONFIG_LWIP_PPP_SERVER_SUPPORT=y
|
||||
# Increase size of bootloader due to frame pointer. Only overflowed on P4.
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x9000
|
||||
|
||||
Reference in New Issue
Block a user