diff --git a/components/hal/include/hal/ieee802154_common_ll.h b/components/hal/include/hal/ieee802154_common_ll.h index 1fe732f2c4..9f20e517ea 100644 --- a/components/hal/include/hal/ieee802154_common_ll.h +++ b/components/hal/include/hal/ieee802154_common_ll.h @@ -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; diff --git a/components/ieee802154/driver/esp_ieee802154_ack.c b/components/ieee802154/driver/esp_ieee802154_ack.c index cb21dd72a0..5b03c7e707 100644 --- a/components/ieee802154/driver/esp_ieee802154_ack.c +++ b/components/ieee802154/driver/esp_ieee802154_ack.c @@ -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 */ @@ -130,6 +130,13 @@ bool ieee802154_ack_config_pending_bit(const uint8_t *frame) // 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); + // Check SW should check whether the frame is data request or not. + bool sw_check_data_req = ieee802154_ll_get_pending_mode(); + + if (sw_check_data_req) { + pending_bit = ieee802154_is_data_request(frame); + } + ieee802154_ll_pending_mode_t pending_mode = ieee802154_pib_get_pending_mode(); switch (pending_mode) { @@ -140,20 +147,14 @@ bool ieee802154_ack_config_pending_bit(const uint8_t *frame) 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(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)) { - pending_bit = false; - } + pending_bit = !(src_mode == IEEE802154_FRAME_SRC_MODE_SHORT && ieee802154_addr_in_pending_table(addr, src_mode == IEEE802154_FRAME_SRC_MODE_SHORT)); break; default: IEEE802154_ASSERT(false); diff --git a/components/ieee802154/driver/esp_ieee802154_frame.c b/components/ieee802154/driver/esp_ieee802154_frame.c index 07573d15f6..79642c9bad 100644 --- a/components/ieee802154/driver/esp_ieee802154_frame.c +++ b/components/ieee802154/driver/esp_ieee802154_frame.c @@ -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 */ @@ -290,6 +290,28 @@ IEEE802154_STATIC IRAM_ATTR uint8_t ieee802154_frame_payload_offset(const uint8_ return offset - 1; } +bool ieee802154_is_data_request(const uint8_t *frame) +{ + if (ieee802154_frame_get_type(frame) != IEEE802154_FRAME_TYPE_COMMAND) { + return false; + } + uint8_t offset = ieee802154_frame_security_header_offset(frame); + if (is_security_enabled(frame)) { + // skip security field. + offset += ieee802154_frame_get_security_field_len(frame); + } + + 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; +} + uint8_t IEEE802154_INLINE ieee802154_frame_get_type(const uint8_t *frame) { return frame[IEEE802154_FRAME_TYPE_OFFSET] & IEEE802154_FRAME_TYPE_MASK; diff --git a/components/ieee802154/private_include/esp_ieee802154_frame.h b/components/ieee802154/private_include/esp_ieee802154_frame.h index fea20ca9c0..c46fb31e71 100644 --- a/components/ieee802154/private_include/esp_ieee802154_frame.h +++ b/components/ieee802154/private_include/esp_ieee802154_frame.h @@ -203,6 +203,15 @@ esp_err_t ieee802154_frame_get_dest_panid(const uint8_t *frame, uint8_t *panid); * */ 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