mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
feat(802.15.4): add multipan pending table support
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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,18 +112,25 @@ 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;
|
||||
@@ -137,7 +144,7 @@ bool ieee802154_ack_config_pending_bit(const uint8_t *frame)
|
||||
pending_bit = ieee802154_is_data_request(frame);
|
||||
}
|
||||
|
||||
ieee802154_ll_pending_mode_t pending_mode = ieee802154_pib_get_pending_mode();
|
||||
ieee802154_ll_pending_mode_t pending_mode = ieee802154_pib_get_pending_mode(inf_index);
|
||||
|
||||
switch (pending_mode) {
|
||||
case IEEE802154_AUTO_PENDING_DISABLE:
|
||||
@@ -148,13 +155,13 @@ bool ieee802154_ack_config_pending_bit(const uint8_t *frame)
|
||||
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) {
|
||||
pending_bit = ieee802154_addr_in_pending_table(addr, src_mode == IEEE802154_FRAME_SRC_MODE_SHORT);
|
||||
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 = !(src_mode == IEEE802154_FRAME_SRC_MODE_SHORT && ieee802154_addr_in_pending_table(addr, src_mode == IEEE802154_FRAME_SRC_MODE_SHORT));
|
||||
pending_bit = !(src_mode == IEEE802154_FRAME_SRC_MODE_SHORT && ieee802154_addr_in_pending_table(inf_index, addr, src_mode == IEEE802154_FRAME_SRC_MODE_SHORT));
|
||||
break;
|
||||
default:
|
||||
IEEE802154_ASSERT(false);
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
@@ -144,12 +144,93 @@ 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];
|
||||
|
||||
#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;
|
||||
s_rx_frame_info[s_rx_index].lqi = lqi;
|
||||
@@ -436,12 +517,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();
|
||||
|
||||
@@ -333,6 +333,9 @@ uint8_t ieee802154_frame_get_dst_addr(const uint8_t *frame, uint8_t *addr)
|
||||
|
||||
uint8_t offset = ieee802154_frame_address_offset(frame);
|
||||
uint8_t dst_mode = dst_addr_mode(frame);
|
||||
if (dst_mode == IEEE802154_FRAME_DST_MODE_NONE) {
|
||||
return dst_mode;
|
||||
}
|
||||
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");
|
||||
@@ -357,6 +360,10 @@ uint8_t ieee802154_frame_get_src_addr(const uint8_t *frame, uint8_t *addr)
|
||||
uint8_t src_mode = src_addr_mode(frame);
|
||||
uint8_t addr_size;
|
||||
|
||||
if (src_mode == IEEE802154_FRAME_SRC_MODE_NONE) {
|
||||
return src_mode;
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
addr_size = (src_mode == IEEE802154_FRAME_SRC_MODE_SHORT) ? IEEE802154_FRAME_SHORT_ADDR_SIZE : IEEE802154_FRAME_EXT_ADDR_SIZE;
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 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"
|
||||
@@ -74,7 +75,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();
|
||||
}
|
||||
@@ -231,15 +239,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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,40 +163,40 @@ 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);
|
||||
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);
|
||||
ieee802154_ll_set_multipan_ext_addr(index, ext_addr);
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -208,10 +208,43 @@ 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)
|
||||
@@ -266,12 +299,12 @@ esp_err_t esp_ieee802154_set_extended_address(const uint8_t *ext_addr)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -359,17 +392,17 @@ esp_err_t esp_ieee802154_set_transmit_security(uint8_t *frame, uint8_t *key, uin
|
||||
|
||||
esp_err_t esp_ieee802154_add_pending_addr(const uint8_t *addr, bool is_short)
|
||||
{
|
||||
return ieee802154_add_pending_addr(addr, is_short);
|
||||
return ieee802154_add_pending_addr(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);
|
||||
return ieee802154_clear_pending_addr(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(0, is_short);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
@@ -756,6 +756,80 @@ esp_err_t esp_ieee802154_event_callback_list_register(esp_ieee802154_event_cb_li
|
||||
*/
|
||||
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
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
@@ -40,7 +41,7 @@ typedef struct {
|
||||
* - ESP_FAIL on failure due to the table is full.
|
||||
*
|
||||
*/
|
||||
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.
|
||||
@@ -53,7 +54,7 @@ esp_err_t ieee802154_add_pending_addr(const uint8_t *addr, bool is_short);
|
||||
* - ESP_FAIL on failure if the given address is not present in the pending table.
|
||||
*
|
||||
*/
|
||||
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,7 +62,7 @@ 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.
|
||||
@@ -72,7 +73,7 @@ void ieee802154_reset_pending_table(bool is_short);
|
||||
* - True 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
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
@@ -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,7 +257,7 @@ 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.
|
||||
|
||||
Reference in New Issue
Block a user