diff --git a/lib/src/rlc/rlc_am_nr.cc b/lib/src/rlc/rlc_am_nr.cc index acbebbfed..ce0f98079 100644 --- a/lib/src/rlc/rlc_am_nr.cc +++ b/lib/src/rlc/rlc_am_nr.cc @@ -773,15 +773,10 @@ void rlc_am_nr_tx::handle_control_pdu(uint8_t* payload, uint32_t nof_bytes) log_rlc_am_nr_status_pdu_to_string(logger.info, "RX status PDU: %s", &status, parent->rb_name); /* - * - if the SN of the corresponding RLC SDU falls within the range - * TX_Next_Ack <= SN < = the highest SN of the AMD PDU among the AMD PDUs submitted to lower layer: - * - consider the RLC SDU or the RLC SDU segment for which a negative acknowledgement was received for - * retransmission. + * Sanity check the received status report. + * Checking if the ACK_SN is inside the the TX_WINDOW makes sure we discard out of order status reports + * Checking if ACK_SN > Tx_Next makes sure we do not receive a ACK/NACK for something we did not TX */ - uint32_t stop_sn = status.nacks.size() == 0 - ? status.ack_sn - : status.nacks[0].nack_sn; // Stop processing ACKs at the first NACK, if it exists. - if (not inside_tx_window(status.ack_sn)) { RlcInfo("Received ACK with SN outside of TX_WINDOW, ignoring status report. ACK_SN=%d, TX_NEXT_ACK=%d.", status.ack_sn, @@ -789,12 +784,11 @@ void rlc_am_nr_tx::handle_control_pdu(uint8_t* payload, uint32_t nof_bytes) info_state(); return; } - if (tx_mod_base_nr(stop_sn) > tx_mod_base_nr(st.tx_next)) { - RlcWarning( - "Received ACK or NACK with SN larger than TX_NEXT, ignoring status report. SN=%d, TX_NEXT_ACK=%d, TX_NEXT=%d", - stop_sn, - st.tx_next_ack, - st.tx_next); + if (tx_mod_base_nr(status.ack_sn) > tx_mod_base_nr(st.tx_next)) { + RlcWarning("Received ACK with SN larger than TX_NEXT, ignoring status report. SN=%d, TX_NEXT_ACK=%d, TX_NEXT=%d", + status.ack_sn, + st.tx_next_ack, + st.tx_next); info_state(); return; } @@ -805,7 +799,6 @@ void rlc_am_nr_tx::handle_control_pdu(uint8_t* payload, uint32_t nof_bytes) * number equal to POLL_SN: * - if t-PollRetransmit is running: * - stop and reset t-PollRetransmit. - * */ if (tx_mod_base_nr(st.poll_sn) <= tx_mod_base_nr(status.ack_sn)) { if (poll_retransmit_timer.is_running()) { @@ -818,7 +811,16 @@ void rlc_am_nr_tx::handle_control_pdu(uint8_t* payload, uint32_t nof_bytes) RlcDebug("POLL_SN=%d > ACK_SN=%d. Not stopping t-PollRetransmit ", st.poll_sn, status.ack_sn); } + /* + * - if the SN of the corresponding RLC SDU falls within the range + * TX_Next_Ack <= SN < = the highest SN of the AMD PDU among the AMD PDUs submitted to lower layer: + * - consider the RLC SDU or the RLC SDU segment for which a negative acknowledgement was received for + * retransmission. + */ // Process ACKs + uint32_t stop_sn = status.nacks.size() == 0 + ? status.ack_sn + : status.nacks[0].nack_sn; // Stop processing ACKs at the first NACK, if it exists. for (uint32_t sn = st.tx_next_ack; tx_mod_base_nr(sn) < tx_mod_base_nr(stop_sn); sn = (sn + 1) % mod_nr) { if (tx_window->has_sn(sn)) { notify_info_vec.push_back((*tx_window)[sn].pdcp_sn); diff --git a/lib/test/rlc/rlc_am_nr_test.cc b/lib/test/rlc/rlc_am_nr_test.cc index b9e6b3eeb..25ca15fae 100644 --- a/lib/test/rlc/rlc_am_nr_test.cc +++ b/lib/test/rlc/rlc_am_nr_test.cc @@ -2726,7 +2726,7 @@ int rx_nack_range_no_so_test(rlc_am_nr_sn_size_t sn_size) // Deliver dummy status report with nack range betwen PDU 6 and 10. rlc_am_nr_status_pdu_t status(sn_size); - status.ack_sn = 16; + status.ack_sn = 5; rlc_status_nack_t nack = {}; nack.nack_sn = 1; nack.has_nack_range = true; @@ -2818,7 +2818,7 @@ int rx_nack_range_with_so_test(rlc_am_nr_sn_size_t sn_size) // Deliver dummy status report with nack range betwen PDU 6 and 10. rlc_am_nr_status_pdu_t status(sn_size); - status.ack_sn = 16; + status.ack_sn = 5; rlc_status_nack_t nack = {}; nack.nack_sn = 1;