From d1d8500ce5df66111e711059c76e21c8bc7997e4 Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Wed, 5 May 2021 15:41:12 +0200 Subject: [PATCH] Add testcase for reconfiguration --- .../srsran/interfaces/ue_rrc_interfaces.h | 4 +- lib/src/asn1/rrc_nr_utils.cc | 2 +- lib/src/upper/rlc.cc | 2 + srsue/hdr/stack/rrc/rrc_nr.h | 27 ++- srsue/src/stack/rrc/rrc_nr.cc | 30 +-- srsue/src/stack/rrc/test/rrc_meas_test.cc | 4 +- srsue/src/stack/rrc/test/ue_rrc_nr_test.cc | 181 +++++++++++++++++- 7 files changed, 212 insertions(+), 38 deletions(-) diff --git a/lib/include/srsran/interfaces/ue_rrc_interfaces.h b/lib/include/srsran/interfaces/ue_rrc_interfaces.h index f26d98ae4..c4f20d2c8 100644 --- a/lib/include/srsran/interfaces/ue_rrc_interfaces.h +++ b/lib/include/srsran/interfaces/ue_rrc_interfaces.h @@ -100,8 +100,8 @@ public: class rrc_nr_interface_rrc { public: - virtual void get_eutra_nr_capabilities(srsran::byte_buffer_t* eutra_nr_caps) = 0; - virtual void get_nr_capabilities(srsran::byte_buffer_t* nr_cap) = 0; + virtual int get_eutra_nr_capabilities(srsran::byte_buffer_t* eutra_nr_caps) = 0; + virtual int get_nr_capabilities(srsran::byte_buffer_t* nr_cap) = 0; virtual void phy_set_cells_to_meas(uint32_t carrier_freq_r15) = 0; virtual void phy_meas_stop() = 0; virtual bool rrc_reconfiguration(bool endc_release_and_add_r15, diff --git a/lib/src/asn1/rrc_nr_utils.cc b/lib/src/asn1/rrc_nr_utils.cc index 71746d106..ca5021b80 100644 --- a/lib/src/asn1/rrc_nr_utils.cc +++ b/lib/src/asn1/rrc_nr_utils.cc @@ -111,7 +111,7 @@ rlc_config_t make_rlc_config_t(const rlc_cfg_c& asn1_type) case rlc_cfg_c::types_opts::um_uni_dir_dl: case rlc_cfg_c::types_opts::um_uni_dir_ul: rlc_cfg.rlc_mode = rlc_mode_t::um; - rlc_cfg.um_nr.t_reassembly_ms = asn1_type.um_bi_dir().dl_um_rlc.t_reassembly.value; + rlc_cfg.um_nr.t_reassembly_ms = asn1_type.um_bi_dir().dl_um_rlc.t_reassembly.value.to_number(); rlc_cfg.um_nr.sn_field_length = (rlc_um_nr_sn_size_t)asn1_type.um_bi_dir().dl_um_rlc.sn_field_len.value; rlc_cfg.um_nr.mod = (rlc_cfg.um_nr.sn_field_length == rlc_um_nr_sn_size_t::size6bits) ? 64 : 4096; rlc_cfg.um_nr.UM_Window_Size = (rlc_cfg.um_nr.sn_field_length == rlc_um_nr_sn_size_t::size6bits) ? 32 : 2048; diff --git a/lib/src/upper/rlc.cc b/lib/src/upper/rlc.cc index d24dae789..8f71b0fa0 100644 --- a/lib/src/upper/rlc.cc +++ b/lib/src/upper/rlc.cc @@ -464,6 +464,8 @@ void rlc::add_bearer(uint32_t lcid, const rlc_config_t& cnfg) logger.info("Added %s radio bearer with LCID %d in %s", to_string(cnfg.rat), lcid, to_string(cnfg.rlc_mode)); rlc_entity = NULL; + } else { + logger.info("LCID %d already exists", lcid); } // configure and add to array diff --git a/srsue/hdr/stack/rrc/rrc_nr.h b/srsue/hdr/stack/rrc/rrc_nr.h index 6cd4db138..5e4f3e6ff 100644 --- a/srsue/hdr/stack/rrc/rrc_nr.h +++ b/srsue/hdr/stack/rrc/rrc_nr.h @@ -62,16 +62,16 @@ public: rrc_nr(srsran::task_sched_handle task_sched_); ~rrc_nr(); - void init(phy_interface_rrc_nr* phy_, - mac_interface_rrc_nr* mac_, - rlc_interface_rrc* rlc_, - pdcp_interface_rrc* pdcp_, - gw_interface_rrc* gw_, - rrc_eutra_interface_rrc_nr* rrc_eutra_, - usim_interface_rrc_nr* usim_, - srsran::timer_handler* timers_, - stack_interface_rrc* stack_, - const rrc_nr_args_t& args_); + int init(phy_interface_rrc_nr* phy_, + mac_interface_rrc_nr* mac_, + rlc_interface_rrc* rlc_, + pdcp_interface_rrc* pdcp_, + gw_interface_rrc* gw_, + rrc_eutra_interface_rrc_nr* rrc_eutra_, + usim_interface_rrc_nr* usim_, + srsran::timer_handler* timers_, + stack_interface_rrc* stack_, + const rrc_nr_args_t& args_); void stop(); void init_core_less(); @@ -118,8 +118,8 @@ public: void notify_pdcp_integrity_error(uint32_t lcid) final; // RRC (LTE) interface - void get_eutra_nr_capabilities(srsran::byte_buffer_t* eutra_nr_caps); - void get_nr_capabilities(srsran::byte_buffer_t* eutra_nr_caps); + int get_eutra_nr_capabilities(srsran::byte_buffer_t* eutra_nr_caps); + int get_nr_capabilities(srsran::byte_buffer_t* eutra_nr_caps); void phy_meas_stop(); void phy_set_cells_to_meas(uint32_t carrier_freq_r15); bool rrc_reconfiguration(bool endc_release_and_add_r15, @@ -175,9 +175,6 @@ private: rrc_nr_args_t args = {}; - // RRC constants and timers - srsran::timer_handler* timers = nullptr; - const char* get_rb_name(uint32_t lcid) final; bool add_lcid_drb(uint32_t lcid, uint32_t drb_id); diff --git a/srsue/src/stack/rrc/rrc_nr.cc b/srsue/src/stack/rrc/rrc_nr.cc index ad9ddebba..01a5bb5c5 100644 --- a/srsue/src/stack/rrc/rrc_nr.cc +++ b/srsue/src/stack/rrc/rrc_nr.cc @@ -35,16 +35,16 @@ rrc_nr::rrc_nr(srsran::task_sched_handle task_sched_) : rrc_nr::~rrc_nr() = default; -void rrc_nr::init(phy_interface_rrc_nr* phy_, - mac_interface_rrc_nr* mac_, - rlc_interface_rrc* rlc_, - pdcp_interface_rrc* pdcp_, - gw_interface_rrc* gw_, - rrc_eutra_interface_rrc_nr* rrc_eutra_, - usim_interface_rrc_nr* usim_, - srsran::timer_handler* timers_, - stack_interface_rrc* stack_, - const rrc_nr_args_t& args_) +int rrc_nr::init(phy_interface_rrc_nr* phy_, + mac_interface_rrc_nr* mac_, + rlc_interface_rrc* rlc_, + pdcp_interface_rrc* pdcp_, + gw_interface_rrc* gw_, + rrc_eutra_interface_rrc_nr* rrc_eutra_, + usim_interface_rrc_nr* usim_, + srsran::timer_handler* timers_, + stack_interface_rrc* stack_, + const rrc_nr_args_t& args_) { phy = phy_; rlc = rlc_; @@ -53,12 +53,12 @@ void rrc_nr::init(phy_interface_rrc_nr* phy_, mac = mac_; rrc_eutra = rrc_eutra_; usim = usim_; - timers = timers_; stack = stack_; args = args_; running = true; sim_measurement_timer = task_sched.get_unique_timer(); + return SRSRAN_SUCCESS; } void rrc_nr::stop() @@ -208,7 +208,7 @@ void rrc_nr::write_pdu_pcch(srsran::unique_byte_buffer_t pdu) {} void rrc_nr::write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t pdu) {} void rrc_nr::notify_pdcp_integrity_error(uint32_t lcid) {} -void rrc_nr::get_eutra_nr_capabilities(srsran::byte_buffer_t* eutra_nr_caps_pdu) +int rrc_nr::get_eutra_nr_capabilities(srsran::byte_buffer_t* eutra_nr_caps_pdu) { struct ue_mrdc_cap_s mrdc_cap; @@ -334,7 +334,7 @@ void rrc_nr::get_eutra_nr_capabilities(srsran::byte_buffer_t* eutra_nr_caps_pdu) logger.debug( eutra_nr_caps_pdu->msg, eutra_nr_caps_pdu->N_bytes, "EUTRA-NR capabilities (%u B)", eutra_nr_caps_pdu->N_bytes); - return; + return SRSRAN_SUCCESS; } bool rrc_nr::rrc_reconfiguration(bool endc_release_and_add_r15, @@ -361,7 +361,7 @@ bool rrc_nr::rrc_reconfiguration(bool endc_release_and_add_r15, return true; } -void rrc_nr::get_nr_capabilities(srsran::byte_buffer_t* nr_caps_pdu) +int rrc_nr::get_nr_capabilities(srsran::byte_buffer_t* nr_caps_pdu) { struct ue_nr_cap_s nr_cap; @@ -404,7 +404,7 @@ void rrc_nr::get_nr_capabilities(srsran::byte_buffer_t* nr_caps_pdu) #endif logger.debug(nr_caps_pdu->msg, nr_caps_pdu->N_bytes, "NR capabilities (%u B)", nr_caps_pdu->N_bytes); - return; + return SRSRAN_SUCCESS; }; void rrc_nr::phy_meas_stop() diff --git a/srsue/src/stack/rrc/test/rrc_meas_test.cc b/srsue/src/stack/rrc/test/rrc_meas_test.cc index 60ae59593..7c3756d58 100644 --- a/srsue/src/stack/rrc/test/rrc_meas_test.cc +++ b/srsue/src/stack/rrc/test/rrc_meas_test.cc @@ -167,8 +167,8 @@ class rrc_nr_test final : public srsue::rrc_nr_interface_rrc { public: ~rrc_nr_test() = default; - void get_eutra_nr_capabilities(srsran::byte_buffer_t* eutra_nr_caps) override{}; - void get_nr_capabilities(srsran::byte_buffer_t* nr_cap) override{}; + int get_eutra_nr_capabilities(srsran::byte_buffer_t* eutra_nr_caps) override { return SRSRAN_SUCCESS; }; + int get_nr_capabilities(srsran::byte_buffer_t* nr_cap) override { return SRSRAN_SUCCESS; }; void phy_set_cells_to_meas(uint32_t carrier_freq_r15) override{}; void phy_meas_stop() override{}; bool rrc_reconfiguration(bool endc_release_and_add_r15, diff --git a/srsue/src/stack/rrc/test/ue_rrc_nr_test.cc b/srsue/src/stack/rrc/test/ue_rrc_nr_test.cc index 7539d4369..001589824 100644 --- a/srsue/src/stack/rrc/test/ue_rrc_nr_test.cc +++ b/srsue/src/stack/rrc/test/ue_rrc_nr_test.cc @@ -11,26 +11,201 @@ */ #include "srsran/common/test_common.h" +#include "srsran/interfaces/ue_gw_interfaces.h" +#include "srsran/interfaces/ue_interfaces.h" +#include "srsran/interfaces/ue_pdcp_interfaces.h" +#include "srsran/interfaces/ue_rlc_interfaces.h" +#include "srsran/interfaces/ue_usim_interfaces.h" #include "srsue/hdr/stack/rrc/rrc_nr.h" using namespace srsue; +class dummy_phy : public phy_interface_rrc_nr +{ + bool set_config(const srsran::phy_cfg_nr_t& cfg) { return true; } +}; + +class dummy_mac : public mac_interface_rrc_nr +{ + int setup_lcid(const srsran::logical_channel_config_t& config) { return SRSRAN_SUCCESS; } + int set_config(const srsran::bsr_cfg_nr_t& bsr_cfg) { return SRSRAN_SUCCESS; } + int set_config(const srsran::sr_cfg_nr_t& sr_cfg) { return SRSRAN_SUCCESS; } + int set_config(const srsran::dl_harq_cfg_nr_t& dl_hrq_cfg) { return SRSRAN_SUCCESS; } + void set_config(const srsran::rach_nr_cfg_t& rach_cfg) {} + int add_tag_config(const srsran::tag_cfg_nr_t& tag_cfg) { return SRSRAN_SUCCESS; } + int set_config(const srsran::phr_cfg_nr_t& phr_cfg) { return SRSRAN_SUCCESS; } + int remove_tag_config(const uint32_t tag_id) { return SRSRAN_SUCCESS; } + + void start_ra_procedure() {} + + void set_contention_id(const uint64_t ue_identity){}; + + bool set_crnti(const uint16_t crnti) { return true; }; +}; + +class dummy_rlc : public rlc_interface_rrc +{ + void reset() {} + void reestablish() {} + void reestablish(uint32_t lcid) {} + void add_bearer(uint32_t lcid, const srsran::rlc_config_t& cnfg) {} + void add_bearer_mrb(uint32_t lcid) {} + void del_bearer(uint32_t lcid) {} + void suspend_bearer(uint32_t lcid) {} + void resume_bearer(uint32_t lcid) {} + void change_lcid(uint32_t old_lcid, uint32_t new_lcid) {} + bool has_bearer(uint32_t lcid) { return true; } + bool has_data(const uint32_t lcid) { return true; } + bool is_suspended(const uint32_t lcid) { return true; } + void write_sdu(uint32_t lcid, srsran::unique_byte_buffer_t sdu) {} +}; + +class dummy_pdcp : public pdcp_interface_rrc +{ + void reestablish(){}; + void reestablish(uint32_t lcid){}; + void reset(){}; + void write_sdu(uint32_t lcid, srsran::unique_byte_buffer_t sdu, int sn = -1){}; + void add_bearer(uint32_t lcid, srsran::pdcp_config_t cnfg){}; + void del_bearer(uint32_t lcid){}; + void change_lcid(uint32_t old_lcid, uint32_t new_lcid){}; + void config_security(uint32_t lcid, const srsran::as_security_config_t& sec_cfg){}; + void config_security_all(const srsran::as_security_config_t& sec_cfg){}; + void enable_integrity(uint32_t lcid, srsran::srsran_direction_t direction){}; + void enable_encryption(uint32_t lcid, + srsran::srsran_direction_t direction = srsran::srsran_direction_t::DIRECTION_TXRX){}; + void send_status_report(){}; + void send_status_report(uint32_t lcid){}; +}; + +class dummy_gw : public gw_interface_rrc +{ + void add_mch_port(uint32_t lcid, uint32_t port){}; + int update_lcid(uint32_t eps_bearer_id, uint32_t new_lcid) { return SRSRAN_SUCCESS; }; + bool is_running() { return true; }; +}; + +class dummy_eutra : public rrc_eutra_interface_rrc_nr +{ + void new_cell_meas_nr(const std::vector& meas){}; + void nr_rrc_con_reconfig_complete(bool status){}; + void nr_notify_reconfiguration_failure(){}; + void nr_scg_failure_information(const srsran::scg_failure_cause_t cause){}; +}; + +class dummy_sim : public usim_interface_rrc_nr +{ + bool generate_nr_context(uint16_t sk_counter, srsran::as_security_config_t* sec_cfg) { return true; } + bool update_nr_context(srsran::as_security_config_t* sec_cfg) { return true; } +}; + +class dummy_stack : public stack_interface_rrc +{ + srsran::tti_point get_current_tti() { return srsran::tti_point(); }; +}; + int rrc_nr_cap_request_test() { - srslog::basic_logger& logger = srslog::fetch_basic_logger("RRC"); + srslog::init(); + srslog::basic_logger& logger = srslog::fetch_basic_logger("RRC-NR"); logger.set_level(srslog::basic_levels::debug); logger.set_hex_dump_max_size(-1); srsran::task_scheduler task_sched{512, 100}; srsran::task_sched_handle task_sched_handle(&task_sched); rrc_nr rrc_nr(task_sched_handle); srsran::byte_buffer_t caps; - rrc_nr.get_eutra_nr_capabilities(&caps); - rrc_nr.get_nr_capabilities(&caps); + + dummy_phy dummy_phy; + dummy_mac dummy_mac; + dummy_rlc dummy_rlc; + dummy_pdcp dummy_pdcp; + dummy_gw dummy_gw; + dummy_eutra dummy_eutra; + dummy_sim dummy_sim; + dummy_stack dummy_stack; + rrc_nr_args_t rrc_nr_args; + + rrc_nr_args.supported_bands_eutra.push_back(7); + rrc_nr_args.supported_bands_nr.push_back(78); + + TESTASSERT(rrc_nr.init(&dummy_phy, + &dummy_mac, + &dummy_rlc, + &dummy_pdcp, + &dummy_gw, + &dummy_eutra, + &dummy_sim, + task_sched.get_timer_handler(), + &dummy_stack, + rrc_nr_args) == SRSRAN_SUCCESS); + + TESTASSERT(rrc_nr.get_eutra_nr_capabilities(&caps) == SRSRAN_SUCCESS); + TESTASSERT(rrc_nr.get_nr_capabilities(&caps) == SRSRAN_SUCCESS); + return SRSRAN_SUCCESS; +} + +int rrc_nr_reconfig_test() +{ + srslog::init(); + srslog::basic_logger& logger = srslog::fetch_basic_logger("RRC-NR"); + logger.set_level(srslog::basic_levels::debug); + logger.set_hex_dump_max_size(-1); + srsran::task_scheduler task_sched{512, 100}; + srsran::task_sched_handle task_sched_handle(&task_sched); + rrc_nr rrc_nr(task_sched_handle); + + dummy_phy dummy_phy; + dummy_mac dummy_mac; + dummy_rlc dummy_rlc; + dummy_pdcp dummy_pdcp; + dummy_gw dummy_gw; + dummy_eutra dummy_eutra; + dummy_sim dummy_sim; + dummy_stack dummy_stack; + rrc_nr_args_t rrc_nr_args; + TESTASSERT(rrc_nr.init(&dummy_phy, + &dummy_mac, + &dummy_rlc, + &dummy_pdcp, + &dummy_gw, + &dummy_eutra, + &dummy_sim, + task_sched.get_timer_handler(), + &dummy_stack, + rrc_nr_args) == SRSRAN_SUCCESS); + + uint8_t nr_secondary_cell_group_cfg_r15_bytes[] = { + 0x08, 0x81, 0x19, 0x5c, 0x40, 0xb1, 0x42, 0x7e, 0x08, 0x30, 0xf3, 0x20, 0x3e, 0x00, 0x80, 0x34, 0x1e, 0x00, 0x80, + 0x02, 0xe8, 0x5b, 0x98, 0xc0, 0x06, 0x93, 0x5a, 0x40, 0x04, 0xd2, 0x6b, 0x00, 0x00, 0x00, 0x00, 0xcd, 0x8d, 0xb2, + 0x45, 0xe2, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1b, 0x82, 0x21, 0x00, 0x00, 0x44, 0x04, 0x00, 0xd0, + 0x1a, 0xe2, 0x00, 0x00, 0x01, 0x98, 0x71, 0xb6, 0x48, 0x95, 0x00, 0x20, 0x07, 0xb7, 0x25, 0x58, 0xf0, 0x00, 0x00, + 0x13, 0x8c, 0x21, 0xb8, 0x83, 0x69, 0x92, 0xa0, 0xb8, 0x75, 0x01, 0x08, 0x1c, 0x0c, 0x00, 0x30, 0x78, 0x00, 0x03, + 0x49, 0xa9, 0xe0, 0x07, 0xb7, 0x25, 0x58, 0x00, 0x25, 0x06, 0xa0, 0x00, 0x80, 0xe0, 0x12, 0xd8, 0x0c, 0x88, 0x03, + 0x70, 0x84, 0x20, 0x00, 0x11, 0x11, 0x6d, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00, 0x00, 0x83, 0xa6, 0x02, 0x66, 0xaa, + 0xe9, 0x28, 0x38, 0x00, 0x20, 0x81, 0x84, 0x0a, 0x18, 0x39, 0x38, 0x81, 0x22, 0x85, 0x8c, 0x1a, 0x38, 0x78, 0xfc, + 0x00, 0x00, 0x66, 0x02, 0x18, 0x10, 0x00, 0xcc, 0x04, 0xb0, 0x40, 0x01, 0x98, 0x0a, 0x60, 0xc0, 0x03, 0x30, 0x16, + 0xc2, 0x00, 0x06, 0x60, 0x31, 0x85, 0x00, 0x0c, 0xc0, 0x6b, 0x0c, 0x00, 0x19, 0x80, 0xe6, 0x1c, 0x00, 0x33, 0x21, + 0x40, 0x31, 0x00, 0x01, 0x72, 0x58, 0x62, 0x40, 0x02, 0xe4, 0xb2, 0xc5, 0x00, 0x05, 0xc9, 0x69, 0x8b, 0x00, 0x0b, + 0x92, 0xdb, 0x18, 0x00, 0x17, 0x25, 0xc6, 0x34, 0x00, 0x2e, 0x4b, 0xac, 0x70, 0x00, 0x5c, 0x97, 0x98, 0xf0, 0x00, + 0xcd, 0x85, 0x07, 0x95, 0xe5, 0x79, 0x43, 0x01, 0xe4, 0x07, 0x23, 0x45, 0x67, 0x89, 0x7d, 0x42, 0x10, 0x84, 0x00, + 0x0c, 0xd0, 0x1a, 0x41, 0x07, 0x82, 0xb8, 0x03, 0x04, 0x28, 0x01, 0x63, 0xff, 0x4a, 0x52, 0x63, 0x18, 0xdc, 0xa0, + 0x50, 0x00, 0x08, 0x72, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12, 0x00, 0x00, 0x00, 0x04, 0x8a, 0x80}; + + asn1::dyn_octstring nr_secondary_cell_group_cfg_r15; + nr_secondary_cell_group_cfg_r15.resize(sizeof(nr_secondary_cell_group_cfg_r15_bytes)); + memcpy(nr_secondary_cell_group_cfg_r15.data(), + nr_secondary_cell_group_cfg_r15_bytes, + sizeof(nr_secondary_cell_group_cfg_r15_bytes)); + + asn1::dyn_octstring nr_radio_bearer_cfg1_r15; + rrc_nr.rrc_reconfiguration(true, true, nr_secondary_cell_group_cfg_r15, false, 0, false, nr_radio_bearer_cfg1_r15); + task_sched.run_pending_tasks(); return SRSRAN_SUCCESS; } int main(int argc, char** argv) { TESTASSERT(rrc_nr_cap_request_test() == SRSRAN_SUCCESS); + TESTASSERT(rrc_nr_reconfig_test() == SRSRAN_SUCCESS); return SRSRAN_SUCCESS; }