@@ -191,8 +191,12 @@ class rlc_tx_am_test : public ::testing::Test, public ::testing::WithParamInterf
191191 // / \param[in] pdu_size Maximum size of each PDU that is read from RLC AM entity
192192 // / \param[in] n_sdus Number of SDUs to push into RLC AM entity
193193 // / \param[in] sdu_size Size of each SDU that is pushed into RLC AM entity
194- void
195- tx_segmented_pdus (byte_buffer_chain* out_pdus, uint32_t n_pdus, uint32_t pdu_size, uint32_t n_sdus, uint32_t sdu_size)
194+ void tx_segmented_pdus (byte_buffer_chain* out_pdus,
195+ uint32_t n_pdus,
196+ uint32_t pdu_size,
197+ uint32_t n_sdus,
198+ uint32_t sdu_size,
199+ uint32_t expect_remaining_bytes = 0 )
196200 {
197201 uint32_t header_min_size = sn_size == rlc_am_sn_size::size12bits ? 2 : 3 ;
198202 uint32_t header_so_size = 2 ;
@@ -278,7 +282,7 @@ class rlc_tx_am_test : public ::testing::Test, public ::testing::WithParamInterf
278282 sdu_so += out_pdus[i].length () - header_size;
279283 }
280284 }
281- EXPECT_EQ (rlc->get_buffer_state (), 0 );
285+ EXPECT_EQ (rlc->get_buffer_state (), expect_remaining_bytes );
282286 EXPECT_EQ (tester->bsr , expect_buffer_state); // pull_pdu does not push BSR to lower layer
283287 EXPECT_EQ (tester->bsr_count , n_bsr);
284288 }
@@ -947,6 +951,56 @@ TEST_P(rlc_tx_am_test, retx_pdu_last_segment_without_segmentation)
947951 EXPECT_EQ (tester->highest_delivered_pdcp_sn_list .front (), 2 );
948952}
949953
954+ TEST_P (rlc_tx_am_test, retx_sn_under_segmentation)
955+ {
956+ const uint32_t n_sdus = 5 ;
957+ const uint32_t sdu_size = 9 ;
958+
959+ const uint32_t n_splits = 3 ;
960+
961+ const uint32_t n_pdus = n_sdus * n_splits - 1 ;
962+ const uint32_t header_size = (sn_size == rlc_am_sn_size::size12bits ? 2 : 3 );
963+ const uint32_t so_size = 2 ;
964+ const uint32_t pdu_size = header_size + so_size + (sdu_size / n_splits);
965+ byte_buffer_chain pdus[n_pdus];
966+
967+ const uint32_t unsent_sdu_bytes = sdu_size / n_splits - so_size; // subtract 2 extra bytes from 1st segment (no SO)
968+ tx_segmented_pdus (pdus, n_pdus, pdu_size, n_sdus, sdu_size, unsent_sdu_bytes + header_size + so_size);
969+
970+ // NACK SN=4 2:65535 => this SN is currently under segmentation; ReTx only the parts that haven't been sent yet.
971+ rlc_am_status_nack nack = {};
972+ nack.nack_sn = 4 ;
973+ nack.has_so = true ;
974+ nack.so_start = so_size + (sdu_size / n_splits); // assume 1st segment is received properly
975+ nack.so_end = nack.so_end_of_sdu ; // the rest is missing
976+ {
977+ rlc_am_status_pdu status_pdu (sn_size);
978+ status_pdu.ack_sn = n_sdus;
979+ status_pdu.push_nack (nack);
980+ rlc->on_status_pdu (std::move (status_pdu));
981+ }
982+ pcell_worker.run_pending_tasks ();
983+
984+ const uint32_t retx_bytes = sdu_size - nack.so_start - unsent_sdu_bytes;
985+ EXPECT_EQ (rlc->get_buffer_state (), unsent_sdu_bytes + header_size + so_size + header_size + so_size + retx_bytes);
986+
987+ // read the ReTx segment which shall only include bytes that were already sent
988+ std::vector<uint8_t > pdu_buf;
989+ size_t pdu_len;
990+ pdu_buf.resize (header_size + so_size + retx_bytes);
991+ pdu_len = rlc->pull_pdu (pdu_buf);
992+ pdu_buf.resize (pdu_len);
993+ EXPECT_EQ (pdu_len, header_size + so_size + retx_bytes);
994+
995+ // read the rest of the SDU under segmentation that was not yet sent
996+ EXPECT_EQ (rlc->get_buffer_state (), unsent_sdu_bytes + header_size + so_size);
997+ pdu_buf.resize (unsent_sdu_bytes + header_size + so_size);
998+ pdu_len = rlc->pull_pdu (pdu_buf);
999+ pdu_buf.resize (pdu_len);
1000+
1001+ EXPECT_EQ (rlc->get_buffer_state (), 0 );
1002+ }
1003+
9501004TEST_P (rlc_tx_am_test, retx_pdu_segment_invalid_so_start_and_so_end)
9511005{
9521006 const uint32_t sdu_size = 3 ;
0 commit comments