From 4e2f7cf02975be4e927da8c34a2ce6b5c80823bd Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 4 Apr 2022 11:28:29 +0100 Subject: [PATCH] lib,rlc_am_nr: make sure that we RETX the segments if we get a NACK for an SDU that was already segmented --- lib/src/rlc/rlc_am_nr.cc | 34 ++++++++++++++++++++++++++-------- lib/test/rlc/rlc_stress_test.h | 3 +++ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/lib/src/rlc/rlc_am_nr.cc b/lib/src/rlc/rlc_am_nr.cc index a53f2e558..10e75d054 100644 --- a/lib/src/rlc/rlc_am_nr.cc +++ b/lib/src/rlc/rlc_am_nr.cc @@ -663,6 +663,9 @@ uint32_t rlc_am_nr_tx::build_retx_pdu_with_segmentation(rlc_amd_retx_nr_t& retx, } else { RlcDebug("Could not find segment. SN=%d, SO=%d length=%d", retx.sn, retx.current_so, retx.segment_length); } + for (auto it : tx_pdu.segment_list) { + RlcDebug("Changed segments! SN=%d, SO=%d length=%d", retx.sn, it.so, it.payload_len); + } } // Update retx queue @@ -843,14 +846,29 @@ void rlc_am_nr_tx::handle_control_pdu(uint8_t* payload, uint32_t nof_bytes) // NACK'ing full SDU. // add to retx queue if it's not already there if (not retx_queue->has_sn(nack_sn)) { - rlc_amd_retx_nr_t& retx = retx_queue->push(); - retx.sn = nack_sn; - retx.is_segment = false; - retx.so_start = 0; - retx.current_so = 0; - retx.segment_length = pdu.sdu_buf->N_bytes; - retx_sn_set.insert(nack_sn); - RlcInfo("Scheduled RETX of SDU SN=%d", retx.sn); + // Have we segmented the SDU alreaty? + if ((*tx_window)[nack_sn].segment_list.empty()) { + rlc_amd_retx_nr_t& retx = retx_queue->push(); + retx.sn = nack_sn; + retx.is_segment = false; + retx.so_start = 0; + retx.current_so = 0; + retx.segment_length = pdu.sdu_buf->N_bytes; + retx_sn_set.insert(nack_sn); + RlcInfo("Scheduled RETX of SDU SN=%d", retx.sn); + } else { + RlcInfo("Scheduled RETX of SDU SN=%d", nack_sn); + retx_sn_set.insert(nack_sn); + for (auto segm : (*tx_window)[nack_sn].segment_list) { + rlc_amd_retx_nr_t& retx = retx_queue->push(); + retx.sn = nack_sn; + retx.is_segment = true; + retx.so_start = segm.so; + retx.current_so = segm.so; + retx.segment_length = segm.payload_len; + RlcInfo("Scheduled RETX of SDU Segment. SN=%d, SO=%d, len=%d", retx.sn, segm.so, segm.payload_len); + } + } } else { RlcInfo("RETX queue already has NACK_SN. SDU SN=%d, Tx_Next_Ack=%d, Tx_Next=%d", status.nacks[nack_idx].nack_sn, diff --git a/lib/test/rlc/rlc_stress_test.h b/lib/test/rlc/rlc_stress_test.h index 7237e56c6..da824c02d 100644 --- a/lib/test/rlc/rlc_stress_test.h +++ b/lib/test/rlc/rlc_stress_test.h @@ -246,6 +246,9 @@ public: // RRC interface void max_retx_attempted() final { + fprintf( + stderr, + "Maximum number of RLC retransmission reached. Consider increasing threshold or lowering channel drop rate."); logger.error( "Maximum number of RLC retransmission reached. Consider increasing threshold or lowering channel drop rate."); std::this_thread::sleep_for(std::chrono::seconds(1));