diff --git a/lib/include/srslte/upper/rlc_am_lte.h b/lib/include/srslte/upper/rlc_am_lte.h index 015e24583..101902f90 100644 --- a/lib/include/srslte/upper/rlc_am_lte.h +++ b/lib/include/srslte/upper/rlc_am_lte.h @@ -40,11 +40,10 @@ struct rlc_amd_rx_pdu_segments_t { }; struct rlc_amd_tx_pdu_t { - rlc_amd_pdu_header_t header; - unique_byte_buffer_t buf; - uint32_t retx_count; - bool is_acked; - std::array pdcp_tx_counts; + rlc_amd_pdu_header_t header; + unique_byte_buffer_t buf; + uint32_t retx_count; + bool is_acked; }; struct rlc_amd_retx_t { @@ -62,8 +61,6 @@ struct rlc_sn_info_t { struct pdcp_sdu_info_t { uint32_t sn; bool fully_txed; // Boolean indicating if the SDU is fully transmitted. - uint32_t acked_bytes; // For metrics - uint32_t total_bytes; // For metrics std::vector rlc_sn_info_list; // List of RLC PDUs in transit and whether they have been acked or not. }; diff --git a/lib/src/upper/rlc_am_lte.cc b/lib/src/upper/rlc_am_lte.cc index fc475c5b1..0a8f75b61 100644 --- a/lib/src/upper/rlc_am_lte.cc +++ b/lib/src/upper/rlc_am_lte.cc @@ -359,7 +359,6 @@ int rlc_am_lte::rlc_am_lte_tx::write_sdu(unique_byte_buffer_t sdu) // Get SDU info pdcp_sdu_info_t info = {}; info.sn = sdu->md.pdcp_sn; - info.total_bytes = sdu->N_bytes; // Store SDU uint8_t* msg_ptr = sdu->msg; @@ -848,9 +847,6 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt log->debug("%s Building PDU - pdu_space: %d, head_len: %d \n", RB_NAME, pdu_space, head_len); - // Helper to keep track of the PDCP counts for each RLC PDU - std::array pdcp_tx_counts = {}; - // Check for SDU segment if (tx_sdu != NULL) { to_move = ((pdu_space - head_len) >= tx_sdu->N_bytes) ? tx_sdu->N_bytes : pdu_space - head_len; @@ -860,7 +856,6 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt pdu->N_bytes += to_move; tx_sdu->N_bytes -= to_move; tx_sdu->msg += to_move; - pdcp_tx_counts[0] = tx_sdu->md.pdcp_sn; undelivered_sdu_info_queue[tx_sdu->md.pdcp_sn].rlc_sn_info_list.push_back({header.sn, false}); if (tx_sdu->N_bytes == 0) { log->debug("%s Complete SDU scheduled for tx.\n", RB_NAME); @@ -902,7 +897,6 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt pdu->N_bytes += to_move; tx_sdu->N_bytes -= to_move; tx_sdu->msg += to_move; - pdcp_tx_counts[header.N_li] = tx_sdu->md.pdcp_sn; undelivered_sdu_info_queue[tx_sdu->md.pdcp_sn].rlc_sn_info_list.push_back({header.sn, false}); if (tx_sdu->N_bytes == 0) { log->debug("%s Complete SDU scheduled for tx. PDCP SN=%d\n", RB_NAME, tx_sdu->md.pdcp_sn); @@ -953,12 +947,11 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt vt_s = (vt_s + 1) % MOD; // Place PDU in tx_window, write header and TX - tx_window[header.sn].buf = std::move(pdu); - tx_window[header.sn].header = header; - tx_window[header.sn].is_acked = false; - tx_window[header.sn].retx_count = 0; - tx_window[header.sn].pdcp_tx_counts = pdcp_tx_counts; - const byte_buffer_t* buffer_ptr = tx_window[header.sn].buf.get(); + tx_window[header.sn].buf = std::move(pdu); + tx_window[header.sn].header = header; + tx_window[header.sn].is_acked = false; + tx_window[header.sn].retx_count = 0; + const byte_buffer_t* buffer_ptr = tx_window[header.sn].buf.get(); uint8_t* ptr = payload; rlc_am_write_data_pdu_header(&header, &ptr); @@ -1085,10 +1078,6 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no void rlc_am_lte::rlc_am_lte_tx::update_notification_ack_info(const rlc_amd_tx_pdu_t& tx_pdu, std::vector& notify_info_vec) { - // Notify PDCP of the number of bytes succesfully delivered - uint32_t total_acked_bytes = 0; - uint32_t nof_bytes = 0; - // Iterate over all undelivered SDUs for (auto& info_it : undelivered_sdu_info_queue) { // Iterate over all SNs that diff --git a/lib/test/upper/CMakeLists.txt b/lib/test/upper/CMakeLists.txt index d5ccb8028..f70da8aba 100644 --- a/lib/test/upper/CMakeLists.txt +++ b/lib/test/upper/CMakeLists.txt @@ -18,10 +18,6 @@ add_executable(rlc_am_test rlc_am_test.cc) target_link_libraries(rlc_am_test srslte_upper srslte_phy srslte_common) add_test(rlc_am_test rlc_am_test) -add_executable(rlc_am_notify_pdcp_test rlc_am_notify_pdcp_test.cc) -target_link_libraries(rlc_am_notify_pdcp_test srslte_upper srslte_phy) -add_test(rlc_am_notify_pdcp_test rlc_am_notify_pdcp_test) - if (ENABLE_5GNR) add_executable(rlc_am_nr_pdu_test rlc_am_nr_pdu_test.cc) target_link_libraries(rlc_am_nr_pdu_test srslte_upper srslte_phy) diff --git a/lib/test/upper/rlc_am_notify_pdcp_test.cc b/lib/test/upper/rlc_am_notify_pdcp_test.cc deleted file mode 100644 index 213c6673d..000000000 --- a/lib/test/upper/rlc_am_notify_pdcp_test.cc +++ /dev/null @@ -1,505 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2021 Software Radio Systems Limited - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the distribution. - * - */ - -#include "srslte/common/test_common.h" -#include "srslte/upper/rlc_am_lte.h" -#include - -srslte::log_ref rlc_log("RLC"); - -class pdcp_tester : public srsue::pdcp_interface_rlc -{ -public: - std::map notified_counts; // Map of PDCP Tx count to acknoledged bytes - // PDCP interface - void write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu) {} - void write_pdu_bcch_bch(srslte::unique_byte_buffer_t sdu) {} - void write_pdu_bcch_dlsch(srslte::unique_byte_buffer_t sdu) {} - void write_pdu_pcch(srslte::unique_byte_buffer_t sdu) {} - void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu) {} - void notify_delivery(uint32_t lcid, const std::vector& pdcp_sn_vec) - { - for (uint32_t pdcp_sn : pdcp_sn_vec) { - if (notified_counts.find(pdcp_sn) == notified_counts.end()) { - notified_counts[pdcp_sn] = 0; - } - assert(lcid == 1); - notified_counts[pdcp_sn] += 1; - } - } -}; - -class rrc_tester : public srsue::rrc_interface_rlc -{ - void max_retx_attempted() {} - std::string get_rb_name(uint32_t lcid) { return "DRB1"; } - void write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t pdu) {} -}; - -// Simple test of a single TX PDU and an imediate ACK -int simple_sdu_notify_test() -{ - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); - pdcp_tester pdcp; - rrc_tester rrc; - srslte::timer_handler timers(8); - srslte::rlc_am_lte rlc(rlc_log, 1, &pdcp, &rrc, &timers); - - uint8_t sdu[] = {0x22, 0x40}; - uint32_t SDU_LEN = 2; - - srslte::unique_byte_buffer_t sdu_buf = allocate_unique_buffer(*pool); - srslte::unique_byte_buffer_t pdu_buf = allocate_unique_buffer(*pool); - srslte::unique_byte_buffer_t sta_buf = allocate_unique_buffer(*pool); - - if (not rlc.configure(srslte::rlc_config_t::default_rlc_am_config())) { - return -1; - } - - // Write SDU into RLC entity - memcpy(sdu_buf->msg, &sdu[0], SDU_LEN); - sdu_buf->N_bytes = SDU_LEN; - sdu_buf->md.pdcp_sn = 10; - rlc.write_sdu(std::move(sdu_buf)); - - TESTASSERT(4 == rlc.get_buffer_state()); // 2 bytes for header + 2 bytes for payload - - // Read 1 PDUs from RLC1 (4 bytes) - uint32_t len = rlc.read_pdu(pdu_buf->msg, 4); - pdu_buf->N_bytes = len; - TESTASSERT(0 == rlc.get_buffer_state()); - - // Feed ack to PDU - srslte::rlc_status_pdu_t s1; - s1.ack_sn = 1; - s1.N_nack = 0; - - sta_buf->N_bytes = srslte::rlc_am_write_status_pdu(&s1, sta_buf->msg); - rlc.write_pdu(sta_buf->msg, sta_buf->N_bytes); - - // Check PDCP notifications - TESTASSERT(pdcp.notified_counts.size() == 1); - TESTASSERT(pdcp.notified_counts.find(10) != pdcp.notified_counts.end()); - TESTASSERT(pdcp.notified_counts[10] == 1); - - return SRSLTE_SUCCESS; -} - -// Test of a single SDU transmitted over 2 PDUs. -// Both PDUs are ACKed in the same status PDU. -int two_pdus_notify_test() -{ - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); - pdcp_tester pdcp; - rrc_tester rrc; - srslte::timer_handler timers(8); - srslte::rlc_am_lte rlc(rlc_log, 1, &pdcp, &rrc, &timers); - - uint8_t sdu[] = {0x22, 0x40, 0x30, 0x21, 0x50}; - uint32_t SDU_LEN = 5; - - srslte::unique_byte_buffer_t sdu_buf = allocate_unique_buffer(*pool); - srslte::unique_byte_buffer_t pdu1_buf = allocate_unique_buffer(*pool); - srslte::unique_byte_buffer_t pdu2_buf = allocate_unique_buffer(*pool); - srslte::unique_byte_buffer_t sta_buf = allocate_unique_buffer(*pool); - - if (not rlc.configure(srslte::rlc_config_t::default_rlc_am_config())) { - return -1; - } - - // Write SDU into RLC entity - memcpy(sdu_buf->msg, &sdu[0], SDU_LEN); - sdu_buf->N_bytes = SDU_LEN; - sdu_buf->md.pdcp_sn = 10; - rlc.write_sdu(std::move(sdu_buf)); - - TESTASSERT(7 == rlc.get_buffer_state()); // 2 bytes for header + 5 for payload - - // Read first PDU from RLC1 (3 bytes of data) - pdu1_buf->N_bytes = rlc.read_pdu(pdu1_buf->msg, 5); // Read - TESTASSERT(4 == rlc.get_buffer_state()); // 2 bytes for header + 2 for payload - - // Read second PDUs from RLC1 (3 bytes of data) - pdu2_buf->N_bytes = rlc.read_pdu(pdu2_buf->msg, 4); // 2 bytes for header + 2 for payload - TESTASSERT(0 == rlc.get_buffer_state()); - - // Feed ack of PDU1 to RLC - srslte::rlc_status_pdu_t s1; - s1.ack_sn = 1; - s1.N_nack = 0; - - sta_buf->N_bytes = srslte::rlc_am_write_status_pdu(&s1, sta_buf->msg); - rlc.write_pdu(sta_buf->msg, sta_buf->N_bytes); - TESTASSERT(pdcp.notified_counts.size() == 0); - - // Feed ack of PDU2 to RLC - srslte::rlc_status_pdu_t s2; - s2.ack_sn = 2; - s2.N_nack = 0; - - sta_buf->N_bytes = srslte::rlc_am_write_status_pdu(&s2, sta_buf->msg); - rlc.write_pdu(sta_buf->msg, sta_buf->N_bytes); - - // Check PDCP notifications - TESTASSERT(pdcp.notified_counts.size() == 1); - TESTASSERT(pdcp.notified_counts.find(10) != pdcp.notified_counts.end()); - TESTASSERT(pdcp.notified_counts[10] == 1); - - return SRSLTE_SUCCESS; -} - -// Test of a two SDUs transmitted over a single PDU. -// Two SDUs -> K=1 (even number of LIs) -// The PDU is ACKed imediatly. -int two_sdus_notify_test() -{ - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); - pdcp_tester pdcp; - rrc_tester rrc; - srslte::timer_handler timers(8); - srslte::rlc_am_lte rlc(rlc_log, 1, &pdcp, &rrc, &timers); - - uint8_t sdu1[] = {0x22, 0x40, 0x30, 0x21, 0x50}; - uint32_t SDU1_LEN = 5; - - uint8_t sdu2[] = {0x22, 0x40}; - uint32_t SDU2_LEN = 2; - srslte::unique_byte_buffer_t sdu1_buf = allocate_unique_buffer(*pool); - srslte::unique_byte_buffer_t sdu2_buf = allocate_unique_buffer(*pool); - srslte::unique_byte_buffer_t pdu_buf = allocate_unique_buffer(*pool); - srslte::unique_byte_buffer_t sta_buf = allocate_unique_buffer(*pool); - - if (not rlc.configure(srslte::rlc_config_t::default_rlc_am_config())) { - return -1; - } - - // Write SDU into RLC entity - memcpy(sdu1_buf->msg, &sdu1[0], SDU1_LEN); - sdu1_buf->N_bytes = SDU1_LEN; - sdu1_buf->md.pdcp_sn = 10; - rlc.write_sdu(std::move(sdu1_buf)); - TESTASSERT(7 == rlc.get_buffer_state()); - - memcpy(sdu2_buf->msg, &sdu2[0], SDU2_LEN); - sdu2_buf->N_bytes = SDU2_LEN; - sdu2_buf->md.pdcp_sn = 13; - rlc.write_sdu(std::move(sdu2_buf)); - TESTASSERT(11 == rlc.get_buffer_state()); // 2 bytes for header, 2 bytes for Li, and 7 for data - - // Read PDU from RLC1 (7 bytes of data) - pdu_buf->N_bytes = rlc.read_pdu(pdu_buf->msg, 11); // 2 bytes for fixed header + 2 bytes for one LI - // + 7 bytes for payload - - TESTASSERT(0 == rlc.get_buffer_state()); - - // Feed ack of PDU1 to RLC - srslte::rlc_status_pdu_t s1; - s1.ack_sn = 1; - s1.N_nack = 0; - - sta_buf->N_bytes = srslte::rlc_am_write_status_pdu(&s1, sta_buf->msg); - rlc.write_pdu(sta_buf->msg, sta_buf->N_bytes); - - // Check PDCP notifications - TESTASSERT(pdcp.notified_counts.size() == 2); - TESTASSERT(pdcp.notified_counts.find(10) != pdcp.notified_counts.end()); - TESTASSERT(pdcp.notified_counts[10] == 1); - TESTASSERT(pdcp.notified_counts.find(13) != pdcp.notified_counts.end()); - TESTASSERT(pdcp.notified_counts[13] == 1); - - return SRSLTE_SUCCESS; -} - -// Test of a three SDUs transmitted over a single PDU. -// The PDU is ACKed imediatly. -int three_sdus_notify_test() -{ - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); - pdcp_tester pdcp; - rrc_tester rrc; - srslte::timer_handler timers(8); - srslte::rlc_am_lte rlc(rlc_log, 1, &pdcp, &rrc, &timers); - - uint8_t sdu1[] = {0x22, 0x40, 0x30, 0x21, 0x50}; - uint32_t SDU1_LEN = 5; - - uint8_t sdu2[] = {0x22, 0x40}; - uint32_t SDU2_LEN = 2; - - uint8_t sdu3[] = {0x22, 0x40, 0x00}; - uint32_t SDU3_LEN = 3; - - srslte::unique_byte_buffer_t sdu1_buf = allocate_unique_buffer(*pool); - srslte::unique_byte_buffer_t sdu2_buf = allocate_unique_buffer(*pool); - srslte::unique_byte_buffer_t sdu3_buf = allocate_unique_buffer(*pool); - srslte::unique_byte_buffer_t pdu_buf = allocate_unique_buffer(*pool); - srslte::unique_byte_buffer_t sta_buf = allocate_unique_buffer(*pool); - - if (not rlc.configure(srslte::rlc_config_t::default_rlc_am_config())) { - return -1; - } - - // Write SDU into RLC entity - memcpy(sdu1_buf->msg, &sdu1[0], SDU1_LEN); - sdu1_buf->N_bytes = SDU1_LEN; - sdu1_buf->md.pdcp_sn = 10; - rlc.write_sdu(std::move(sdu1_buf)); - TESTASSERT(7 == rlc.get_buffer_state()); - - memcpy(sdu2_buf->msg, &sdu2[0], SDU2_LEN); - sdu2_buf->N_bytes = SDU2_LEN; - sdu2_buf->md.pdcp_sn = 13; - rlc.write_sdu(std::move(sdu2_buf)); - - memcpy(sdu3_buf->msg, &sdu3[0], SDU3_LEN); - sdu3_buf->N_bytes = SDU3_LEN; - sdu3_buf->md.pdcp_sn = 14; - rlc.write_sdu(std::move(sdu3_buf)); - - TESTASSERT(15 == rlc.get_buffer_state()); // 2 bytes for fixed header, 3 bytes for two LIs, 10 for data - - // Read PDU from RLC1 (10 bytes of data) - pdu_buf->N_bytes = rlc.read_pdu(pdu_buf->msg, 15); // 2 bytes for fixed header + 5 bytes for three LIs - // + 10 bytes for payload - - TESTASSERT(0 == rlc.get_buffer_state()); - - // Feed ack of PDU1 to RLC - srslte::rlc_status_pdu_t s1; - s1.ack_sn = 1; - s1.N_nack = 0; - - sta_buf->N_bytes = srslte::rlc_am_write_status_pdu(&s1, sta_buf->msg); - rlc.write_pdu(sta_buf->msg, sta_buf->N_bytes); - - // Check PDCP notifications - TESTASSERT(pdcp.notified_counts.size() == 3); - TESTASSERT(pdcp.notified_counts.find(10) != pdcp.notified_counts.end()); - TESTASSERT(pdcp.notified_counts.find(13) != pdcp.notified_counts.end()); - TESTASSERT(pdcp.notified_counts.find(14) != pdcp.notified_counts.end()); - TESTASSERT(pdcp.notified_counts[10] == 1); - TESTASSERT(pdcp.notified_counts[13] == 1); - TESTASSERT(pdcp.notified_counts[14] == 1); - - return SRSLTE_SUCCESS; -} - -// Test notification of an RTXED SDU. -int rtxed_sdu_notify_test() -{ - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); - pdcp_tester pdcp; - rrc_tester rrc; - srslte::timer_handler timers(8); - srslte::rlc_am_lte rlc(rlc_log, 1, &pdcp, &rrc, &timers); - - uint8_t sdu[] = {0x22, 0x40, 0x30, 0x21, 0x50}; - uint32_t SDU_LEN = 5; - - srslte::unique_byte_buffer_t sdu_buf = allocate_unique_buffer(*pool); - srslte::unique_byte_buffer_t pdu_buf = allocate_unique_buffer(*pool); - srslte::unique_byte_buffer_t sta_buf = allocate_unique_buffer(*pool); - - if (not rlc.configure(srslte::rlc_config_t::default_rlc_am_config())) { - return -1; - } - - // Write SDU into RLC entity - memcpy(sdu_buf->msg, &sdu[0], SDU_LEN); - sdu_buf->N_bytes = SDU_LEN; - sdu_buf->md.pdcp_sn = 10; - rlc.write_sdu(std::move(sdu_buf)); - TESTASSERT(7 == rlc.get_buffer_state()); - - // Read first PDU from RLC (5 bytes of data) - pdu_buf->N_bytes = rlc.read_pdu(pdu_buf->msg, 7); // 2 bytes for fixed header + 5 bytes for payload - TESTASSERT(0 == rlc.get_buffer_state()); - - // Feed Nack of PDU1 to RLC - srslte::rlc_status_pdu_t s1; - s1.ack_sn = 1; - s1.N_nack = 1; - s1.nacks[0].nack_sn = 0; - - sta_buf->N_bytes = srslte::rlc_am_write_status_pdu(&s1, sta_buf->msg); - rlc.write_pdu(sta_buf->msg, sta_buf->N_bytes); - TESTASSERT(7 == rlc.get_buffer_state()); - - // Check PDCP notifications - TESTASSERT(pdcp.notified_counts.empty()); - - // Read rtxed PDU from RLC (5 bytes of data) - pdu_buf->N_bytes = rlc.read_pdu(pdu_buf->msg, 7); // 2 bytes for fixed header + 5 bytes for payload - TESTASSERT(0 == rlc.get_buffer_state()); - - // Feed ack of PDU1 to RLC - srslte::rlc_status_pdu_t s2; - s2.ack_sn = 1; - s2.N_nack = 0; - sta_buf->N_bytes = srslte::rlc_am_write_status_pdu(&s2, sta_buf->msg); - rlc.write_pdu(sta_buf->msg, sta_buf->N_bytes); - TESTASSERT(0 == rlc.get_buffer_state()); - - // Check PDCP notifications - TESTASSERT(pdcp.notified_counts.size() == 1); - TESTASSERT(pdcp.notified_counts.find(10) != pdcp.notified_counts.end()); - TESTASSERT(pdcp.notified_counts[10] == 1); - - return SRSLTE_SUCCESS; -} - -// Test out of order ACK for PDUs. -// Two PDDs are transmitted for one SDU, and ack arrives out of order -int two_sdus_out_of_order_ack_notify_test() -{ - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); - pdcp_tester pdcp; - rrc_tester rrc; - srslte::timer_handler timers(8); - srslte::rlc_am_lte rlc(rlc_log, 1, &pdcp, &rrc, &timers); - - uint8_t sdu[] = {0x22, 0x40, 0x30, 0x21, 0x50}; - uint32_t SDU_LEN = 5; - - srslte::unique_byte_buffer_t sdu_buf = allocate_unique_buffer(*pool); - srslte::unique_byte_buffer_t pdu1_buf = allocate_unique_buffer(*pool); - srslte::unique_byte_buffer_t pdu2_buf = allocate_unique_buffer(*pool); - srslte::unique_byte_buffer_t sta_buf = allocate_unique_buffer(*pool); - - if (not rlc.configure(srslte::rlc_config_t::default_rlc_am_config())) { - return -1; - } - - // Write SDU into RLC entity - memcpy(sdu_buf->msg, &sdu[0], SDU_LEN); - sdu_buf->N_bytes = SDU_LEN; - sdu_buf->md.pdcp_sn = 10; - rlc.write_sdu(std::move(sdu_buf)); - - TESTASSERT(7 == rlc.get_buffer_state()); // 2 bytes for header + 5 for payload - - // Read first PDU from RLC1 (3 bytes of data) - pdu1_buf->N_bytes = rlc.read_pdu(pdu1_buf->msg, 5); // Read - TESTASSERT(4 == rlc.get_buffer_state()); // 2 bytes for header + 2 for payload - - // Read second PDUs from RLC1 (3 bytes of data) - pdu2_buf->N_bytes = rlc.read_pdu(pdu2_buf->msg, 4); // 2 bytes for header + 2 for payload - TESTASSERT(0 == rlc.get_buffer_state()); - - // Ack of PDU2 to RLC, with PDU1 with NACK - srslte::rlc_status_nack_t nack = {}; - nack.nack_sn = 0; - - srslte::rlc_status_pdu_t s2; - s2.ack_sn = 2; - s2.N_nack = 1; - s2.nacks[0] = nack; - - // Write second ack - sta_buf->N_bytes = srslte::rlc_am_write_status_pdu(&s2, sta_buf->msg); - rlc.write_pdu(sta_buf->msg, sta_buf->N_bytes); - - // Check PDCP notifications. No notification should be available yet. - TESTASSERT(pdcp.notified_counts.size() == 0); - - // Ack all of PDUs to RLC - srslte::rlc_status_pdu_t s1; - s1.ack_sn = 2; - s1.N_nack = 0; - - // Write ack for all PDUs - sta_buf->N_bytes = srslte::rlc_am_write_status_pdu(&s1, sta_buf->msg); - rlc.write_pdu(sta_buf->msg, sta_buf->N_bytes); - - // Check PDCP notifications - TESTASSERT(pdcp.notified_counts.size() == 1); - TESTASSERT(pdcp.notified_counts.find(10) != pdcp.notified_counts.end()); - std::cout << pdcp.notified_counts[10] << std::endl; - TESTASSERT(pdcp.notified_counts[10] == 1); - return SRSLTE_SUCCESS; -} - -// Test out-of-order ack of a single SDU transmitted over 2 PDUs. -int two_pdus_out_of_order_ack_notify_test() -{ - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); - pdcp_tester pdcp; - rrc_tester rrc; - srslte::timer_handler timers(8); - srslte::rlc_am_lte rlc(rlc_log, 1, &pdcp, &rrc, &timers); - - uint8_t sdu[] = {0x22, 0x40, 0x30, 0x21, 0x50}; - uint32_t SDU_LEN = 5; - - srslte::unique_byte_buffer_t sdu_buf = allocate_unique_buffer(*pool); - srslte::unique_byte_buffer_t pdu1_buf = allocate_unique_buffer(*pool); - srslte::unique_byte_buffer_t pdu2_buf = allocate_unique_buffer(*pool); - srslte::unique_byte_buffer_t sta_buf = allocate_unique_buffer(*pool); - - if (not rlc.configure(srslte::rlc_config_t::default_rlc_am_config())) { - return -1; - } - - // Write SDU into RLC entity - memcpy(sdu_buf->msg, &sdu[0], SDU_LEN); - sdu_buf->N_bytes = SDU_LEN; - sdu_buf->md.pdcp_sn = 10; - rlc.write_sdu(std::move(sdu_buf)); - - TESTASSERT(7 == rlc.get_buffer_state()); // 2 bytes for header + 5 for payload - - // Read first PDU from RLC1 (3 bytes of data) - pdu1_buf->N_bytes = rlc.read_pdu(pdu1_buf->msg, 5); // Read - TESTASSERT(4 == rlc.get_buffer_state()); // 2 bytes for header + 2 for payload - - // Read second PDUs from RLC1 (3 bytes of data) - pdu2_buf->N_bytes = rlc.read_pdu(pdu2_buf->msg, 4); // 2 bytes for header + 2 for payload - TESTASSERT(0 == rlc.get_buffer_state()); - - // Feed ack of PDU1 to RLC - srslte::rlc_status_pdu_t s1; - s1.ack_sn = 1; - s1.N_nack = 0; - - sta_buf->N_bytes = srslte::rlc_am_write_status_pdu(&s1, sta_buf->msg); - rlc.write_pdu(sta_buf->msg, sta_buf->N_bytes); - TESTASSERT(pdcp.notified_counts.size() == 0); - - // Feed ack of PDU2 to RLC - srslte::rlc_status_pdu_t s2; - s2.ack_sn = 2; - s2.N_nack = 0; - - sta_buf->N_bytes = srslte::rlc_am_write_status_pdu(&s2, sta_buf->msg); - rlc.write_pdu(sta_buf->msg, sta_buf->N_bytes); - - // Check PDCP notifications - TESTASSERT(pdcp.notified_counts.size() == 1); - TESTASSERT(pdcp.notified_counts.find(10) != pdcp.notified_counts.end()); - TESTASSERT(pdcp.notified_counts[10] == 1); - - return SRSLTE_SUCCESS; -} - -int main(int argc, char** argv) -{ - srslte::byte_buffer_pool::get_instance(); - TESTASSERT(simple_sdu_notify_test() == SRSLTE_SUCCESS); - TESTASSERT(two_sdus_notify_test() == SRSLTE_SUCCESS); - TESTASSERT(three_sdus_notify_test() == SRSLTE_SUCCESS); - TESTASSERT(two_pdus_notify_test() == SRSLTE_SUCCESS); - TESTASSERT(rtxed_sdu_notify_test() == SRSLTE_SUCCESS); - TESTASSERT(two_pdus_out_of_order_ack_notify_test() == SRSLTE_SUCCESS); - TESTASSERT(two_sdus_out_of_order_ack_notify_test() == SRSLTE_SUCCESS); - srslte::byte_buffer_pool::cleanup(); - return SRSLTE_SUCCESS; -} diff --git a/lib/test/upper/rlc_am_test.cc b/lib/test/upper/rlc_am_test.cc index 823f6b868..cc30f5f69 100644 --- a/lib/test/upper/rlc_am_test.cc +++ b/lib/test/upper/rlc_am_test.cc @@ -194,7 +194,6 @@ int basic_test() rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); // Check PDCP notifications - std::cout << tester.notified_counts.size() << std::endl; TESTASSERT(tester.notified_counts.size() == 5); for (uint16_t i = 0; i < tester.n_sdus; i++) { TESTASSERT(tester.sdus[i]->N_bytes == 1);