diff --git a/lib/test/rlc/CMakeLists.txt b/lib/test/rlc/CMakeLists.txt index 6b0f6bf45..dc57c224e 100644 --- a/lib/test/rlc/CMakeLists.txt +++ b/lib/test/rlc/CMakeLists.txt @@ -16,9 +16,13 @@ add_executable(rlc_am_control_test rlc_am_control_test.cc) target_link_libraries(rlc_am_control_test srsran_rlc srsran_phy) add_lte_test(rlc_am_control_test rlc_am_control_test) -add_executable(rlc_am_test rlc_am_test.cc) -target_link_libraries(rlc_am_test srsran_rlc srsran_phy srsran_common) -add_lte_test(rlc_am_test rlc_am_test) +add_executable(rlc_am_lte_test rlc_am_lte_test.cc) +target_link_libraries(rlc_am_lte_test srsran_rlc srsran_phy srsran_common) +add_lte_test(rlc_am_lte_test rlc_am_lte_test) + +add_executable(rlc_am_nr_test rlc_am_nr_test.cc) +target_link_libraries(rlc_am_nr_test srsran_rlc srsran_phy srsran_common) +add_nr_test(rlc_am_nr_test rlc_am_nr_test) add_executable(rlc_am_nr_pdu_test rlc_am_nr_pdu_test.cc) target_link_libraries(rlc_am_nr_pdu_test srsran_rlc srsran_phy) diff --git a/lib/test/rlc/rlc_am_test.cc b/lib/test/rlc/rlc_am_lte_test.cc similarity index 98% rename from lib/test/rlc/rlc_am_test.cc rename to lib/test/rlc/rlc_am_lte_test.cc index 8b020ba67..d7dbc71af 100644 --- a/lib/test/rlc/rlc_am_test.cc +++ b/lib/test/rlc/rlc_am_lte_test.cc @@ -10,6 +10,7 @@ * */ +#include "rlc_test_common.h" #include "srsran/common/buffer_pool.h" #include "srsran/common/rlc_pcap.h" #include "srsran/common/test_common.h" @@ -25,63 +26,6 @@ using namespace srsue; using namespace srsran; -bool rx_is_tx(const rlc_bearer_metrics_t& rlc1_metrics, const rlc_bearer_metrics_t& rlc2_metrics) -{ - if (rlc1_metrics.num_tx_pdu_bytes != rlc2_metrics.num_rx_pdu_bytes) { - return false; - } - - if (rlc2_metrics.num_tx_pdu_bytes != rlc1_metrics.num_rx_pdu_bytes) { - return false; - } - return true; -} - -class rlc_am_tester : public pdcp_interface_rlc, public rrc_interface_rlc -{ -public: - rlc_am_tester(rlc_pcap* pcap_ = NULL) : pcap(pcap_) {} - - // PDCP interface - void write_pdu(uint32_t lcid, unique_byte_buffer_t sdu) - { - assert(lcid == 1); - sdus.push_back(std::move(sdu)); - } - void write_pdu_bcch_bch(unique_byte_buffer_t sdu) {} - void write_pdu_bcch_dlsch(unique_byte_buffer_t sdu) {} - void write_pdu_pcch(unique_byte_buffer_t sdu) {} - void write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t pdu) {} - void notify_delivery(uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sn_vec) - { - assert(lcid == 1); - for (uint32_t pdcp_sn : pdcp_sn_vec) { - if (notified_counts.find(pdcp_sn) == notified_counts.end()) { - notified_counts[pdcp_sn] = 0; - } - notified_counts[pdcp_sn] += 1; - } - } - void notify_failure(uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sn_vec) - { - assert(lcid == 1); - // TODO - } - - // RRC interface - void max_retx_attempted() { max_retx_triggered = true; } - void protocol_failure() { protocol_failure_triggered = true; } - - const char* get_rb_name(uint32_t lcid) { return ""; } - - std::vector sdus; - rlc_pcap* pcap = nullptr; - bool max_retx_triggered = false; - bool protocol_failure_triggered = false; - - std::map notified_counts; // Map of PDCP SNs to number of notifications -}; - class ul_writer : public thread { public: diff --git a/lib/test/rlc/rlc_am_nr_test.cc b/lib/test/rlc/rlc_am_nr_test.cc new file mode 100644 index 000000000..039901cee --- /dev/null +++ b/lib/test/rlc/rlc_am_nr_test.cc @@ -0,0 +1,109 @@ +/** + * + * \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 "rlc_test_common.h" +#include "srsran/common/buffer_pool.h" +#include "srsran/common/rlc_pcap.h" +#include "srsran/common/test_common.h" +#include "srsran/common/threads.h" +#include "srsran/interfaces/ue_pdcp_interfaces.h" +#include "srsran/interfaces/ue_rrc_interfaces.h" +#include "srsran/rlc/rlc_am_nr.h" + +#define NBUFS 5 +#define HAVE_PCAP 0 +#define SDU_SIZE 500 + +using namespace srsue; +using namespace srsran; + +int basic_test_tx(rlc_am_nr* rlc, byte_buffer_t pdu_bufs[NBUFS]) +{ + // Push 5 SDUs into RLC1 + unique_byte_buffer_t sdu_bufs[NBUFS]; + for (int i = 0; i < NBUFS; i++) { + sdu_bufs[i] = srsran::make_byte_buffer(); + sdu_bufs[i]->msg[0] = i; // Write the index into the buffer + sdu_bufs[i]->N_bytes = 1; // Give each buffer a size of 1 byte + sdu_bufs[i]->md.pdcp_sn = i; // PDCP SN for notifications + rlc->write_sdu(std::move(sdu_bufs[i])); + } + + TESTASSERT(13 == rlc->get_buffer_state()); // 2 Bytes for fixed header + 6 for LIs + 5 for payload + + // Read 5 PDUs from RLC1 (1 byte each) + for (int i = 0; i < NBUFS; i++) { + uint32_t len = rlc->read_pdu(pdu_bufs[i].msg, 3); // 2 bytes for header + 1 byte payload + pdu_bufs[i].N_bytes = len; + TESTASSERT(3 == len); + } + + TESTASSERT(0 == rlc->get_buffer_state()); + return SRSRAN_SUCCESS; +} + +int basic_test() +{ + rlc_am_tester tester; + timer_handler timers(8); + byte_buffer_t pdu_bufs[NBUFS]; + + rlc_am_nr rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am_nr rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + + // before configuring entity + TESTASSERT(0 == rlc1.get_buffer_state()); + + if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { + return -1; + } + + if (not rlc2.configure(rlc_config_t::default_rlc_am_config())) { + return -1; + } + + // basic_test_tx(&rlc1, pdu_bufs); + return SRSRAN_SUCCESS; +} + +int main(int argc, char** argv) +{ + // Setup the log message spy to intercept error and warning log entries from RLC + if (!srslog::install_custom_sink(srsran::log_sink_message_spy::name(), + std::unique_ptr( + new srsran::log_sink_message_spy(srslog::get_default_log_formatter())))) { + return SRSRAN_ERROR; + } + + auto* spy = static_cast(srslog::find_sink(srsran::log_sink_message_spy::name())); + if (spy == nullptr) { + return SRSRAN_ERROR; + } + srslog::set_default_sink(*spy); + + auto& logger_rlc1 = srslog::fetch_basic_logger("RLC_NR_AM_1", *spy, false); + auto& logger_rlc2 = srslog::fetch_basic_logger("RLC_NR_AM_2", *spy, false); + logger_rlc1.set_hex_dump_max_size(100); + logger_rlc2.set_hex_dump_max_size(100); + logger_rlc1.set_level(srslog::basic_levels::debug); + logger_rlc2.set_level(srslog::basic_levels::debug); + + // start log backend + srslog::init(); + + if (basic_test()) { + printf("basic_test failed\n"); + exit(-1); + }; + + return SRSRAN_SUCCESS; +} diff --git a/lib/test/rlc/rlc_test_common.h b/lib/test/rlc/rlc_test_common.h index 494a09a60..519103243 100644 --- a/lib/test/rlc/rlc_test_common.h +++ b/lib/test/rlc/rlc_test_common.h @@ -14,8 +14,10 @@ #define SRSRAN_RLC_TEST_COMMON_H #include "srsran/common/byte_buffer.h" +#include "srsran/common/rlc_pcap.h" #include "srsran/interfaces/ue_pdcp_interfaces.h" #include "srsran/interfaces/ue_rrc_interfaces.h" +#include "srsran/rlc/rlc_metrics.h" #include namespace srsran { @@ -23,10 +25,10 @@ namespace srsran { class rlc_um_tester : public srsue::pdcp_interface_rlc, public srsue::rrc_interface_rlc { public: - rlc_um_tester() {} + rlc_um_tester() = default; // PDCP interface - void write_pdu(uint32_t lcid, unique_byte_buffer_t sdu) + void write_pdu(uint32_t lcid, unique_byte_buffer_t sdu) final { // check length if (lcid != 3 && sdu->N_bytes != expected_sdu_len) { @@ -47,16 +49,16 @@ public: // srsran_vec_fprint_byte(stdout, sdu->msg, sdu->N_bytes); sdus.push_back(std::move(sdu)); } - void write_pdu_bcch_bch(unique_byte_buffer_t sdu) {} - void write_pdu_bcch_dlsch(unique_byte_buffer_t sdu) {} - void write_pdu_pcch(unique_byte_buffer_t sdu) {} - void write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t sdu) { sdus.push_back(std::move(sdu)); } - void notify_delivery(uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sns) {} - void notify_failure(uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sns) {} + void write_pdu_bcch_bch(unique_byte_buffer_t sdu) final {} + void write_pdu_bcch_dlsch(unique_byte_buffer_t sdu) final {} + void write_pdu_pcch(unique_byte_buffer_t sdu) final {} + void write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t sdu) final { sdus.push_back(std::move(sdu)); } + void notify_delivery(uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sns) final {} + void notify_failure(uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sns) final {} // RRC interface - void max_retx_attempted() {} - void protocol_failure() {} + void max_retx_attempted() final {} + void protocol_failure() final {} const char* get_rb_name(uint32_t lcid) { return ""; } void set_expected_sdu_len(uint32_t len) { expected_sdu_len = len; } @@ -67,6 +69,62 @@ public: uint32_t expected_sdu_len = 0; }; +class rlc_am_tester : public srsue::pdcp_interface_rlc, public srsue::rrc_interface_rlc +{ +public: + rlc_am_tester(rlc_pcap* pcap_ = NULL) : pcap(pcap_) {} + + // PDCP interface + void write_pdu(uint32_t lcid, unique_byte_buffer_t sdu) + { + assert(lcid == 1); + sdus.push_back(std::move(sdu)); + } + void write_pdu_bcch_bch(unique_byte_buffer_t sdu) {} + void write_pdu_bcch_dlsch(unique_byte_buffer_t sdu) {} + void write_pdu_pcch(unique_byte_buffer_t sdu) {} + void write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t pdu) {} + void notify_delivery(uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sn_vec) + { + assert(lcid == 1); + for (uint32_t pdcp_sn : pdcp_sn_vec) { + if (notified_counts.find(pdcp_sn) == notified_counts.end()) { + notified_counts[pdcp_sn] = 0; + } + notified_counts[pdcp_sn] += 1; + } + } + void notify_failure(uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sn_vec) + { + assert(lcid == 1); + // TODO + } + + // RRC interface + void max_retx_attempted() { max_retx_triggered = true; } + void protocol_failure() { protocol_failure_triggered = true; } + + const char* get_rb_name(uint32_t lcid) { return ""; } + + std::vector sdus; + rlc_pcap* pcap = nullptr; + bool max_retx_triggered = false; + bool protocol_failure_triggered = false; + + std::map notified_counts; // Map of PDCP SNs to number of notifications +}; + +bool rx_is_tx(const rlc_bearer_metrics_t& rlc1_metrics, const rlc_bearer_metrics_t& rlc2_metrics) +{ + if (rlc1_metrics.num_tx_pdu_bytes != rlc2_metrics.num_rx_pdu_bytes) { + return false; + } + + if (rlc2_metrics.num_tx_pdu_bytes != rlc1_metrics.num_rx_pdu_bytes) { + return false; + } + return true; +} } // namespace srsran #endif // SRSRAN_RLC_TEST_COMMON_H