This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit ac75328e122bd4b3fb0a2076cc80663a5230abc8 Author: raiden00pl <[email protected]> AuthorDate: Fri Oct 16 17:11:02 2026 +0200 arch/arm/nrf52: fix ACK handling While waiting for an ACK, nrf52_radioi8_state_rx() skips the frame filter but still sent an ACK for every received frame with the AR field set, also for frames addressed to other devices. Any received frame with a length of 5 was taken as the ACK, without checking the frame type, the FCS or the sequence number, and any other frame ended the wait with NO_ACK and left the ACK wait timer running. Ignore frames that are not a valid ACK and keep waiting (IEEE 802.15.4-2011 5.1.6.2), and fail the attempt on an ACK with another sequence number (5.1.6.4.3). The ACK wait was 44 symbols. 6.4.3 defines macAckWaitDuration as aUnitBackoffPeriod + aTurnaroundTime + phySHRDuration + ceiling(6 * phySymbolsPerOctet), 54 symbols for the 2.4 GHz O-QPSK PHY. Assisted-by: Claude Code Signed-off-by: raiden00pl <[email protected]> --- arch/arm/src/nrf52/nrf52_ieee802154_radio.c | 31 ++++++++++++++++++++++------- arch/arm/src/nrf52/nrf52_ieee802154_radio.h | 13 +++++++----- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/arch/arm/src/nrf52/nrf52_ieee802154_radio.c b/arch/arm/src/nrf52/nrf52_ieee802154_radio.c index 77b71110d6b..282a8aeb3f0 100644 --- a/arch/arm/src/nrf52/nrf52_ieee802154_radio.c +++ b/arch/arm/src/nrf52/nrf52_ieee802154_radio.c @@ -1748,9 +1748,12 @@ static void nrf52_radioi8_state_rx(struct nrf52_radioi8_dev_s *dev) } #endif - /* Start ACK handling now - this must be done in isr */ + /* Start ACK handling now - this must be done in isr. Frames are not + * filtered while we wait for our ACK, so they are not acknowledged. + */ - if (dev->state.rxmode == NRF52_RXMODE_NORMAL && + if (dev->radio->state.waitack == false && + dev->state.rxmode == NRF52_RXMODE_NORMAL && rxbuf[1] & IEEE802154_FRAMECTRL_ACKREQ && rxbuf[0] != IEEE802154_ACK_FRAME_SIZE) { @@ -1776,10 +1779,21 @@ static void nrf52_radioi8_state_rx(struct nrf52_radioi8_dev_s *dev) } } - /* We wait for TX ACK and this frame is ACK - confirm TX to MAC */ + /* We wait for TX ACK and this is not a valid ACK frame - ignore it and + * keep waiting for the ACK (IEEE 802.15.4-2011 5.1.6.2, 5.1.6.4.3). + */ + + else if (rxbuf[0] != IEEE802154_ACK_FRAME_SIZE || + (rxbuf[1] & IEEE802154_FRAMECTRL_FTYPE) != IEEE802154_FRAME_ACK || + !NRF52_RADIO_GETREG(dev->radio->lower, + NRF52_RADIO_CRCSTATUS_OFFSET)) + { + dev->macops.rxenable((struct ieee802154_radio_s *)dev, true); + } + + /* We wait for TX ACK and this is our ACK - confirm TX to MAC */ - else if (rxbuf[0] == IEEE802154_ACK_FRAME_SIZE && - dev->radio->state.waitack == true) + else if (rxbuf[3] == dev->radio->txbuf[3]) { nrf52_radioi8_trace_put(RADIO_TRACE_IRQ_RXACKDONE, 0); @@ -1804,13 +1818,16 @@ static void nrf52_radioi8_state_rx(struct nrf52_radioi8_dev_s *dev) } } - /* We wait for TX ACK and this is not ACK - notify TX failure */ + /* We wait for TX ACK and the ACK has another sequence number - notify TX + * failure + */ else { - /* Clear flag */ + /* Clear flag and stop the ACK wait timer */ dev->radio->state.waitack = false; + dev->tim->ops->stop(dev); /* And notify MAC */ diff --git a/arch/arm/src/nrf52/nrf52_ieee802154_radio.h b/arch/arm/src/nrf52/nrf52_ieee802154_radio.h index f5d09166720..6319dce9699 100644 --- a/arch/arm/src/nrf52/nrf52_ieee802154_radio.h +++ b/arch/arm/src/nrf52/nrf52_ieee802154_radio.h @@ -47,11 +47,14 @@ #define IEEE802154_MAX_BE (5) #define IEEE802154_CW0 (2) -/* ACK_SYM + turnaround symbols + backoff */ - -#define IEEE802154_ACK_WAIT (12+ \ - IEEE802154_TURN_AROUND_TIME+ \ - IEEE802154_UNIT_BACKOFF_PERIOD) +/* macAckWaitDuration: aUnitBackoffPeriod + aTurnaroundTime + + * phySHRDuration (10) + ceiling(6 * phySymbolsPerOctet (2)), in symbols + * (IEEE 802.15.4-2011 6.4.3) + */ + +#define IEEE802154_ACK_WAIT (IEEE802154_UNIT_BACKOFF_PERIOD + \ + IEEE802154_TURN_AROUND_TIME + \ + 10 + 12) /**************************************************************************** * Public Types
