lib,rlc_am_lte: added fix for full tx window with wraparround

master
Pedro Alvarez 2 years ago
parent b001d6c10e
commit e4207b177f

@ -361,10 +361,7 @@ void rlc_am_lte_tx::retransmit_pdu(uint32_t sn)
bool rlc_am_lte_tx::window_full() bool rlc_am_lte_tx::window_full()
{ {
if ((vt_s - vt_a) >= RLC_AM_WINDOW_SIZE) { return TX_MOD_BASE(vt_s) >= RLC_AM_WINDOW_SIZE;
return true;
}
return false;
}; };
/** /**

@ -3927,6 +3927,152 @@ bool full_window_check_test()
return SRSRAN_SUCCESS; return SRSRAN_SUCCESS;
} }
bool full_window_check_wraparound_test()
{
rlc_config_t config = rlc_config_t::default_rlc_am_config();
// [I] SRB1 configured: t_poll_retx=65, poll_pdu=-1, poll_byte=-1, max_retx_thresh=6, t_reordering=55,
// t_status_prohibit=0
config.am.t_poll_retx = 65;
config.am.poll_pdu = -1;
config.am.poll_byte = -1;
config.am.max_retx_thresh = 6;
config.am.t_reordering = 55;
config.am.t_status_prohibit = 55;
#if HAVE_PCAP
rlc_pcap pcap;
pcap.open("rlc_am_poll_rext_expiry_test.pcap", config);
rlc_am_tester tester(true, &pcap);
#else
rlc_am_tester tester(true, NULL);
#endif
uint32_t pdcp_count = 0;
srsran::timer_handler timers(8);
rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers);
rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers);
srslog::fetch_basic_logger("RLC_AM_1").set_hex_dump_max_size(100);
srslog::fetch_basic_logger("RLC_AM_2").set_hex_dump_max_size(100);
srslog::fetch_basic_logger("RLC").set_hex_dump_max_size(100);
if (not rlc1.configure(config)) {
return -1;
}
if (not rlc2.configure(config)) {
return -1;
}
// Advance vt_a to 512 and vt_s to 512 as well.
{
// Initial Tx
uint32_t num_tx_pdus = 512;
for (uint32_t i = 0; i < num_tx_pdus; ++i) {
// Write SDU
unique_byte_buffer_t sdu = srsran::make_byte_buffer();
TESTASSERT(sdu != nullptr);
sdu->N_bytes = 1;
sdu->msg[0] = i;
sdu->md.pdcp_sn = pdcp_count++;
rlc1.write_sdu(std::move(sdu));
unique_byte_buffer_t pdu = srsran::make_byte_buffer();
TESTASSERT(pdu != nullptr);
pdu->N_bytes = rlc1.read_pdu(pdu->msg, 3);
TESTASSERT(pdu->N_bytes == 3);
}
// ACK all SNs to advance the TX window.
rlc_status_pdu_t status = {};
status.ack_sn = num_tx_pdus;
status.N_nack = 0;
unique_byte_buffer_t status_buf = srsran::make_byte_buffer();
TESTASSERT(status_buf != nullptr);
rlc_am_write_status_pdu(&status, status_buf.get());
rlc1.write_pdu(status_buf->msg, status_buf->N_bytes);
}
// Advance vt_a and vt_s to 1023
{
// Initial Tx
uint32_t num_tx_pdus = 511;
for (uint32_t i = 0; i < num_tx_pdus; ++i) {
// Write SDU
unique_byte_buffer_t sdu = srsran::make_byte_buffer();
TESTASSERT(sdu != nullptr);
sdu->N_bytes = 1;
sdu->msg[0] = i;
sdu->md.pdcp_sn = pdcp_count++;
rlc1.write_sdu(std::move(sdu));
unique_byte_buffer_t pdu = srsran::make_byte_buffer();
TESTASSERT(pdu != nullptr);
pdu->N_bytes = rlc1.read_pdu(pdu->msg, 3);
TESTASSERT(pdu->N_bytes == 3);
}
// ACK all SNs to advance the TX window.
rlc_status_pdu_t status = {};
status.ack_sn = 512 + num_tx_pdus;
status.N_nack = 0;
unique_byte_buffer_t status_buf = srsran::make_byte_buffer();
TESTASSERT(status_buf != nullptr);
rlc_am_write_status_pdu(&status, status_buf.get());
rlc1.write_pdu(status_buf->msg, status_buf->N_bytes);
}
// Now, fill up the window
{
// Initial Tx
uint32_t num_tx_pdus = 512;
for (uint32_t i = 0; i < num_tx_pdus; ++i) {
// Write SDU
unique_byte_buffer_t sdu = srsran::make_byte_buffer();
TESTASSERT(sdu != nullptr);
sdu->N_bytes = 1;
sdu->msg[0] = i;
sdu->md.pdcp_sn = pdcp_count++;
rlc1.write_sdu(std::move(sdu));
unique_byte_buffer_t pdu = srsran::make_byte_buffer();
TESTASSERT(pdu != nullptr);
pdu->N_bytes = rlc1.read_pdu(pdu->msg, 3);
TESTASSERT(pdu->N_bytes == 3);
}
}
{
// Tx one more to check the window is full
unique_byte_buffer_t sdu = srsran::make_byte_buffer();
TESTASSERT(sdu != nullptr);
sdu->N_bytes = 1;
sdu->msg[0] = 0;
sdu->md.pdcp_sn = pdcp_count++;
rlc1.write_sdu(std::move(sdu));
unique_byte_buffer_t pdu = srsran::make_byte_buffer();
TESTASSERT(pdu != nullptr);
pdu->N_bytes = rlc1.read_pdu(pdu->msg, 3);
TESTASSERT(pdu->N_bytes == 3);
// If the TX window is full, we should RETX SN=1023
rlc_amd_pdu_header_t header = {};
rlc_am_read_data_pdu_header(&pdu->msg, &pdu->N_bytes, &header);
TESTASSERT_EQ(header.sn, 1023);
TESTASSERT_EQ(header.N_li, 0);
TESTASSERT_EQ(header.fi, 0);
}
#if HAVE_PCAP
pcap.close();
#endif
return SRSRAN_SUCCESS;
}
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
// Setup the log message spy to intercept error and warning log entries from RLC // Setup the log message spy to intercept error and warning log entries from RLC
@ -4141,5 +4287,10 @@ int main(int argc, char** argv)
printf("full_window_check_test failed\n"); printf("full_window_check_test failed\n");
exit(-1); exit(-1);
}; };
if (full_window_check_wraparound_test()) {
printf("full_window_check_wraparound_test failed\n");
exit(-1);
};
return SRSRAN_SUCCESS; return SRSRAN_SUCCESS;
} }

Loading…
Cancel
Save