@@ -178,6 +178,86 @@ TEST_P(pdcp_rx_test, rx_out_of_order)
178178 EXPECT_EQ (test_spy.get_error_counter (), 0 );
179179}
180180
181+ // / Test reception of duplicate PDCP PDUs
182+ TEST_P (pdcp_rx_test, rx_duplicate)
183+ {
184+ init (GetParam ());
185+ auto test_rx_out_of_order = [this ](uint32_t count) {
186+ srsran::test_delimit_logger delimiter (" RX duplicate test. SN_SIZE={} COUNT=[{}, {}]" , sn_size, count + 1 , count);
187+
188+ pdcp_rx->configure_security (sec_cfg, security::integrity_enabled::on, security::ciphering_enabled::on);
189+
190+ byte_buffer test_pdu1;
191+ get_test_pdu (count, test_pdu1);
192+ byte_buffer test_pdu2;
193+ get_test_pdu (count + 1 , test_pdu2);
194+ byte_buffer test_pdu2_dup;
195+ get_test_pdu (count + 1 , test_pdu2_dup);
196+ byte_buffer test_pdu3;
197+ get_test_pdu (count + 2 , test_pdu3);
198+ pdcp_rx_state init_state = {.rx_next = count, .rx_deliv = count, .rx_reord = 0 };
199+ pdcp_rx->set_state (init_state);
200+
201+ pdcp_rx->handle_pdu (byte_buffer_chain::create (std::move (test_pdu2)).value ());
202+
203+ // Wait for crypto and reordering
204+ wait_pending_crypto ();
205+ worker.run_pending_tasks ();
206+ ASSERT_EQ (0 , test_frame->sdu_queue .size ());
207+ // check rx_reord matches rx_next matches count + 2
208+ EXPECT_EQ (pdcp_rx->get_state ().rx_reord , count + 2 );
209+ EXPECT_EQ (pdcp_rx->get_state ().rx_reord , pdcp_rx->get_state ().rx_next );
210+
211+ pdcp_rx->handle_pdu (byte_buffer_chain::create (std::move (test_pdu3)).value ());
212+
213+ // Wait for crypto and reordering
214+ wait_pending_crypto ();
215+ worker.run_pending_tasks ();
216+ ASSERT_EQ (0 , test_frame->sdu_queue .size ());
217+ // check rx_reord still maches count + 2, i.e did not change because t_reord is already running; rx_next moved on
218+ EXPECT_EQ (pdcp_rx->get_state ().rx_reord , count + 2 );
219+ EXPECT_EQ (pdcp_rx->get_state ().rx_next , count + 3 );
220+
221+ // Send the duplicate
222+ pdcp_rx->handle_pdu (byte_buffer_chain::create (std::move (test_pdu2_dup)).value ());
223+
224+ // Wait for crypto and reordering
225+ wait_pending_crypto ();
226+ worker.run_pending_tasks ();
227+ ASSERT_EQ (0 , test_frame->sdu_queue .size ());
228+ // check rx_reord still maches count + 2
229+ EXPECT_EQ (pdcp_rx->get_state ().rx_reord , count + 2 );
230+ EXPECT_EQ (pdcp_rx->get_state ().rx_next , count + 3 );
231+
232+ pdcp_rx->handle_pdu (byte_buffer_chain::create (std::move (test_pdu1)).value ());
233+
234+ // Wait for crypto and reordering
235+ wait_pending_crypto ();
236+ worker.run_pending_tasks ();
237+ ASSERT_EQ (3 , test_frame->sdu_queue .size ());
238+ while (not test_frame->sdu_queue .empty ()) {
239+ ASSERT_EQ (test_frame->sdu_queue .front (), sdu1);
240+ test_frame->sdu_queue .pop ();
241+ }
242+ };
243+
244+ if (sn_size == pdcp_sn_size::size12bits) {
245+ test_rx_out_of_order (0 );
246+ test_rx_out_of_order (2047 );
247+ test_rx_out_of_order (4095 );
248+ } else if (sn_size == pdcp_sn_size::size18bits) {
249+ test_rx_out_of_order (0 );
250+ test_rx_out_of_order (131071 );
251+ test_rx_out_of_order (262143 );
252+ } else {
253+ FAIL ();
254+ }
255+
256+ // No warnings or errors
257+ EXPECT_EQ (test_spy.get_warning_counter (), 0 );
258+ EXPECT_EQ (test_spy.get_error_counter (), 0 );
259+ }
260+
181261// / Test out of order reception of PDUs.
182262// / The out-of-order PDU is received after the t-Reordering expires.
183263TEST_P (pdcp_rx_test, rx_reordering_timer)
0 commit comments