From 826dd32c8917cb87abfb91cade3fd11d754bce2c Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Wed, 2 Dec 2020 17:57:15 +0100 Subject: [PATCH] Rename meas_cell to meas_cell_eutra Added meas_cell_nr class Make meas_cell list as template class Inheritance rrc_cell to meas_cell_nr Added process_new_cell_meas_nr function --- lib/test/asn1/CMakeLists.txt | 4 + srsue/hdr/stack/rrc/rrc.h | 18 ++- srsue/hdr/stack/rrc/rrc_cell.h | 174 ++++++++++++++++++-------- srsue/hdr/stack/rrc/rrc_meas.h | 7 +- srsue/hdr/stack/rrc/rrc_procedures.h | 6 +- srsue/src/stack/rrc/rrc.cc | 42 +++++-- srsue/src/stack/rrc/rrc_cell.cc | 112 ++++++++++------- srsue/src/stack/rrc/rrc_meas.cc | 10 +- srsue/src/stack/rrc/rrc_procedures.cc | 8 +- srsue/test/ttcn3/src/CMakeLists.txt | 36 +++--- srsue/test/upper/CMakeLists.txt | 12 +- srsue/test/upper/rrc_cell_test.cc | 14 +-- 12 files changed, 298 insertions(+), 145 deletions(-) diff --git a/lib/test/asn1/CMakeLists.txt b/lib/test/asn1/CMakeLists.txt index 9456a08c7..a0d30ca64 100644 --- a/lib/test/asn1/CMakeLists.txt +++ b/lib/test/asn1/CMakeLists.txt @@ -15,7 +15,11 @@ target_link_libraries(srslte_asn1_rrc_mcch_test rrc_asn1 srslte_common) add_test(srslte_asn1_rrc_mcch_test srslte_asn1_rrc_mcch_test) add_executable(srslte_asn1_rrc_meas_test srslte_asn1_rrc_meas_test.cc) +if (ENABLE_5GNR) +target_link_libraries(srslte_asn1_rrc_meas_test rrc_asn1 rrc_nr_asn1 srslte_common) +else() target_link_libraries(srslte_asn1_rrc_meas_test rrc_asn1 srslte_common) +endif(ENABLE_5GNR) add_test(srslte_asn1_rrc_meas_test srslte_asn1_rrc_meas_test) add_executable(srslte_asn1_rrc_ul_dcch_test srslte_asn1_rrc_ul_dcch_test.cc) diff --git a/srsue/hdr/stack/rrc/rrc.h b/srsue/hdr/stack/rrc/rrc.h index e6ff2e24c..1ec94334d 100644 --- a/srsue/hdr/stack/rrc/rrc.h +++ b/srsue/hdr/stack/rrc/rrc.h @@ -62,7 +62,9 @@ class rrc : public rrc_interface_nas, public rrc_interface_phy_lte, public rrc_interface_mac, public rrc_interface_pdcp, +#ifdef HAVE_5GNR public rrc_interface_rrc_nr, +#endif public rrc_interface_rlc, public srslte::timer_callback { @@ -108,10 +110,10 @@ public: bool connection_request(srslte::establishment_cause_t cause, srslte::unique_byte_buffer_t dedicated_info_nas); void set_ue_identity(srslte::s_tmsi_t s_tmsi); void paging_completed(bool outcome) final; - +#ifdef HAVE_5GNR // NR interface void new_cell_meas_nr(const std::vector& meas); - +#endif // PHY interface void in_sync() final; void out_of_sync() final; @@ -238,8 +240,12 @@ private: std::unique_ptr measurements; // List of strongest neighbour cell - using unique_cell_t = std::unique_ptr; - meas_cell_list meas_cells; + using unique_cell_t = std::unique_ptr; + meas_cell_list meas_cells; + +#ifdef HAVE_5GNR + meas_cell_list meas_cells_nr; +#endif bool initiated = false; asn1::rrc::reest_cause_e m_reest_cause = asn1::rrc::reest_cause_e::nulltype; @@ -253,15 +259,17 @@ private: std::set get_cells(const uint32_t earfcn); float get_cell_rsrp(const uint32_t earfcn, const uint32_t pci); float get_cell_rsrq(const uint32_t earfcn, const uint32_t pci); - meas_cell* get_serving_cell(); + meas_cell_eutra* get_serving_cell(); void process_cell_meas(); void process_new_cell_meas(const std::vector& meas); srslte::block_queue > cell_meas_q; +#ifdef HAVE_5GNR void process_cell_meas_nr(); void process_new_cell_meas_nr(const std::vector& meas); srslte::block_queue > cell_meas_nr_q; +#endif // Cell selection/reselection functions/variables typedef struct { diff --git a/srsue/hdr/stack/rrc/rrc_cell.h b/srsue/hdr/stack/rrc/rrc_cell.h index 0ba38c918..0070e4f4b 100644 --- a/srsue/hdr/stack/rrc/rrc_cell.h +++ b/srsue/hdr/stack/rrc/rrc_cell.h @@ -15,6 +15,10 @@ #include "srslte/asn1/rrc.h" #include "srslte/asn1/rrc_utils.h" +#if HAVE_5GNR +#include "srslte/asn1/rrc_nr.h" +#include "srslte/asn1/rrc_nr_utils.h" +#endif #include "srslte/interfaces/ue_interfaces.h" namespace srsue { @@ -43,14 +47,6 @@ public: bool greater(const meas_cell* x) const { return rsrp > x->rsrp || std::isnan(rsrp); } bool greater(const meas_cell& x) const { return rsrp > x.rsrp || std::isnan(rsrp); } - bool has_plmn_id(asn1::rrc::plmn_id_s plmn_id) const; - uint32_t nof_plmns() const { return has_sib1() ? sib1.cell_access_related_info.plmn_id_list.size() : 0; } - srslte::plmn_id_t get_plmn(uint32_t idx) const; - - uint16_t get_tac() const { return has_sib1() ? (uint16_t)sib1.cell_access_related_info.tac.to_number() : 0; } - uint32_t get_earfcn() const { return phy_cell.earfcn; } - uint32_t get_pci() const { return phy_cell.pci; } - void set_rsrp(float rsrp_) { if (!std::isnan(rsrp_)) { @@ -71,10 +67,90 @@ public: } } + bool has_sib1() const { return has_valid_sib1; } + bool has_sib2() const { return has_valid_sib2; } + bool has_sib3() const { return has_valid_sib3; } + bool has_sib13() const { return has_valid_sib13; } + bool has_sib(uint32_t index) const; + bool has_sibs(srslte::span indexes) const; + + bool is_sib_scheduled(uint32_t sib_index) const; + + void reset_sibs() + { + has_valid_sib1 = false; + has_valid_sib2 = false; + has_valid_sib3 = false; + has_valid_sib13 = false; + } + + uint32_t get_earfcn() const { return phy_cell.earfcn; } + uint32_t get_pci() const { return phy_cell.pci; } + float get_rsrp() const { return rsrp; } float get_rsrq() const { return rsrq; } float get_cfo_hz() const { return phy_cell.cfo_hz; } + phy_cell_t phy_cell = {0, 0, 0}; + srslte::unique_timer timer; + +protected: + float rsrp = NAN; + float rsrq = NAN; + + bool has_valid_sib1 = false; + bool has_valid_sib2 = false; + bool has_valid_sib3 = false; + bool has_valid_sib13 = false; + std::map sib_info_map; ///< map of sib_index to index of schedInfoList in SIB1 +}; + +#ifdef HAVE_5GNR +class meas_cell_nr : public meas_cell +{ +public: + explicit meas_cell_nr(srslte::unique_timer timer) : meas_cell(std::move(timer)){}; + meas_cell_nr(const phy_cell_t& phy_cell_, srslte::unique_timer timer) : meas_cell(phy_cell_, std::move(timer)){}; + + bool has_plmn_id(asn1::rrc_nr::plmn_id_s plmn_id) const; + uint32_t nof_plmns() const { return has_sib1() ? sib1.cell_access_related_info.plmn_id_list.size() : 0; } + srslte::plmn_id_t get_plmn(uint32_t idx) const; + + void set_sib1(const asn1::rrc_nr::sib1_s& sib1_); + void set_sib2(const asn1::rrc_nr::sib2_s& sib2_); + void set_sib3(const asn1::rrc_nr::sib3_s& sib3_); + + const asn1::rrc_nr::sib1_s* sib1ptr() const { return has_sib1() ? &sib1 : nullptr; } + const asn1::rrc_nr::sib2_s* sib2ptr() const { return has_sib2() ? &sib2 : nullptr; } + const asn1::rrc_nr::sib3_s* sib3ptr() const { return has_sib3() ? &sib3 : nullptr; } + + uint32_t get_cell_id() const { return (uint32_t)0xFFFF; } // TODO find the correct sib + + uint16_t get_mcc() const; + uint16_t get_mnc() const; + + std::string to_string() const; + + bool has_mcch = false; + asn1::rrc_nr::sib1_s sib1 = {}; + asn1::rrc_nr::sib2_s sib2 = {}; + asn1::rrc_nr::sib3_s sib3 = {}; + asn1::rrc::mcch_msg_s mcch = {}; +}; +#endif + +class meas_cell_eutra : public meas_cell +{ +public: + explicit meas_cell_eutra(srslte::unique_timer timer) : meas_cell(std::move(timer)){}; + meas_cell_eutra(const phy_cell_t& phy_cell_, srslte::unique_timer timer) : meas_cell(phy_cell_, std::move(timer)){}; + + bool has_plmn_id(asn1::rrc::plmn_id_s plmn_id) const; + uint32_t nof_plmns() const { return has_sib1() ? sib1.cell_access_related_info.plmn_id_list.size() : 0; } + srslte::plmn_id_t get_plmn(uint32_t idx) const; + + uint16_t get_tac() const { return has_sib1() ? (uint16_t)sib1.cell_access_related_info.tac.to_number() : 0; } + void set_sib1(const asn1::rrc::sib_type1_s& sib1_); void set_sib2(const asn1::rrc::sib_type2_s& sib2_); void set_sib3(const asn1::rrc::sib_type3_s& sib3_); @@ -87,46 +163,22 @@ public: uint32_t get_cell_id() const { return (uint32_t)sib1.cell_access_related_info.cell_id.to_number(); } - bool has_sibs(srslte::span indexes) const; - bool has_sib(uint32_t index) const; - bool has_sib1() const { return has_valid_sib1; } - bool has_sib2() const { return has_valid_sib2; } - bool has_sib3() const { return has_valid_sib3; } bool has_sib13() const { return has_valid_sib13; } - void reset_sibs() - { - has_valid_sib1 = false; - has_valid_sib2 = false; - has_valid_sib3 = false; - has_valid_sib13 = false; - } - uint16_t get_mcc() const; uint16_t get_mnc() const; std::string to_string() const; - bool is_sib_scheduled(uint32_t sib_index) const; - - phy_cell_t phy_cell = {0, 0, 0}; bool has_mcch = false; asn1::rrc::sib_type1_s sib1 = {}; asn1::rrc::sib_type2_s sib2 = {}; asn1::rrc::sib_type3_s sib3 = {}; asn1::rrc::sib_type13_r9_s sib13 = {}; asn1::rrc::mcch_msg_s mcch = {}; - srslte::unique_timer timer; private: - float rsrp = NAN; - float rsrq = NAN; - - bool has_valid_sib1 = false; - bool has_valid_sib2 = false; - bool has_valid_sib3 = false; bool has_valid_sib13 = false; - std::map sib_info_map; ///< map of sib_index to index of schedInfoList in SIB1 }; //! Universal methods to extract pci/earfcn and compare the two values @@ -136,33 +188,47 @@ uint32_t get_pci(const T& t) return t.pci; } template <> -inline uint32_t get_pci(const meas_cell& t) +inline uint32_t get_pci(const meas_cell_eutra& t) { return t.get_pci(); } +#ifdef HAVE_5GNR +template <> +inline uint32_t get_pci(const meas_cell_nr& t) +{ + return t.get_pci(); +} +#endif template uint32_t get_earfcn(const T& t) { return t.earfcn; } template <> -inline uint32_t get_earfcn(const meas_cell& t) +inline uint32_t get_earfcn(const meas_cell_eutra& t) { return t.get_earfcn(); } +#ifdef HAVE_5GNR +template <> +inline uint32_t get_earfcn(const meas_cell_nr& t) +{ + return t.get_earfcn(); +} +#endif template bool is_same_cell(const T& lhs, const U& rhs) { return get_pci(lhs) == get_pci(rhs) and get_earfcn(lhs) == get_earfcn(rhs); } - +template class meas_cell_list { public: - const static int NEIGHBOUR_TIMEOUT = 5; - const static int MAX_NEIGHBOUR_CELLS = 8; - typedef std::unique_ptr unique_meas_cell; + const static int NEIGHBOUR_TIMEOUT = 5; + const static int MAX_NEIGHBOUR_CELLS = 8; + typedef std::unique_ptr unique_meas_cell; explicit meas_cell_list(srslte::task_sched_handle task_sched_); @@ -173,28 +239,28 @@ public: void clean_neighbours(); void sort_neighbour_cells(); - bool process_new_cell_meas(const std::vector& meas, - const std::function& filter_meas); + bool process_new_cell_meas(const std::vector& meas, + const std::function& filter_meas); - meas_cell* get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci); - const meas_cell* get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci) const; - void log_neighbour_cells() const; - std::string print_neighbour_cells() const; - std::set get_neighbour_pcis(uint32_t earfcn) const; - bool has_neighbour_cell(uint32_t earfcn, uint32_t pci) const; - size_t nof_neighbours() const { return neighbour_cells.size(); } - meas_cell& operator[](size_t idx) { return *neighbour_cells[idx]; } - const meas_cell& operator[](size_t idx) const { return *neighbour_cells[idx]; } - meas_cell& at(size_t idx) { return *neighbour_cells.at(idx); } - meas_cell* find_cell(uint32_t earfcn, uint32_t pci); + T* get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci); + const T* get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci) const; + void log_neighbour_cells() const; + std::string print_neighbour_cells() const; + std::set get_neighbour_pcis(uint32_t earfcn) const; + bool has_neighbour_cell(uint32_t earfcn, uint32_t pci) const; + size_t nof_neighbours() const { return neighbour_cells.size(); } + T& operator[](size_t idx) { return *neighbour_cells[idx]; } + const T& operator[](size_t idx) const { return *neighbour_cells[idx]; } + T& at(size_t idx) { return *neighbour_cells.at(idx); } + T* find_cell(uint32_t earfcn, uint32_t pci); // serving cell handling int set_serving_cell(phy_cell_t phy_cell, bool discard_serving); - meas_cell& serving_cell() { return *serv_cell; } - const meas_cell& serving_cell() const { return *serv_cell; } + T& serving_cell() { return *serv_cell; } + const T& serving_cell() const { return *serv_cell; } - using iterator = std::vector::iterator; + using iterator = typename std::vector::iterator; iterator begin() { return neighbour_cells.begin(); } iterator end() { return neighbour_cells.end(); } diff --git a/srsue/hdr/stack/rrc/rrc_meas.h b/srsue/hdr/stack/rrc/rrc_meas.h index 95343ce6b..f81730ead 100644 --- a/srsue/hdr/stack/rrc/rrc_meas.h +++ b/srsue/hdr/stack/rrc/rrc_meas.h @@ -99,7 +99,12 @@ private: void ho_reest_finish(const uint32_t src_earfcn, const uint32_t dst_earfcn); bool parse_meas_config(const meas_cfg_s* meas_config, bool is_ho_reest, uint32_t src_earfcn); void eval_triggers(); - void eval_triggers_eutra(uint32_t meas_id, report_cfg_eutra_s& report_cfg, meas_obj_eutra_s& meas_obj, meas_cell* serv_cell, float Ofs, float Ocs); + void eval_triggers_eutra(uint32_t meas_id, + report_cfg_eutra_s& report_cfg, + meas_obj_eutra_s& meas_obj, + meas_cell_eutra* serv_cell, + float Ofs, + float Ocs); void report_triggers(); void report_triggers_eutra(uint32_t meas_id, report_cfg_eutra_s& report_cfg, meas_obj_eutra_s& meas_obj); diff --git a/srsue/hdr/stack/rrc/rrc_procedures.h b/srsue/hdr/stack/rrc/rrc_procedures.h index 443f9b109..d23bd66f7 100644 --- a/srsue/hdr/stack/rrc/rrc_procedures.h +++ b/srsue/hdr/stack/rrc/rrc_procedures.h @@ -128,12 +128,12 @@ private: bool is_serv_cell_suitable() const; bool is_sib_acq_required() const; srslte::proc_outcome_t set_proc_complete(); - srslte::proc_outcome_t start_phy_cell_selection(const meas_cell& cell); + srslte::proc_outcome_t start_phy_cell_selection(const meas_cell_eutra& cell); srslte::proc_outcome_t start_sib_acquisition(); // consts - rrc* rrc_ptr; - meas_cell_list* meas_cells; + rrc* rrc_ptr; + meas_cell_list* meas_cells; // state variables enum class search_state_t { cell_selection, serv_cell_camp, cell_config, cell_search }; diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index 565d5525b..7104a28dc 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -61,6 +61,9 @@ rrc::rrc(stack_interface_rrc* stack_, srslte::task_sched_handle task_sched_) : connection_reest(this), ho_handler(this), conn_recfg_proc(this), +#ifdef HAVE_5GNR + meas_cells_nr(task_sched_), +#endif meas_cells(task_sched_) {} @@ -111,7 +114,7 @@ void rrc::init(phy_interface_rrc_lte* phy_, auto on_every_cell_selection = [this](uint32_t earfcn, uint32_t pci, bool csel_result) { if (not csel_result) { - meas_cell* c = meas_cells.find_cell(earfcn, pci); + meas_cell_eutra* c = meas_cells.find_cell(earfcn, pci); if (c != nullptr) { c->set_rsrp(-INFINITY); } @@ -364,6 +367,7 @@ void rrc::set_config_complete(bool status) void rrc::set_scell_complete(bool status) {} +#ifdef HAVE_5GNR /* This function is called from a NR PHY worker thus must return very quickly. * Queue the values of the measurements and process them from the RRC thread */ @@ -385,7 +389,31 @@ void rrc::process_cell_meas_nr() } } -void rrc::process_new_cell_meas_nr(const std::vector& meas) {} +void rrc::process_new_cell_meas_nr(const std::vector& meas) +{ + + // Convert vector + std::vector meas_lte; + for (const auto& m : meas) { + phy_meas_t tmp_meas = {}; + tmp_meas.cfo_hz = m.cfo_hz; + tmp_meas.earfcn = m.arfcn_nr; + tmp_meas.rsrp = m.rsrp; + tmp_meas.rsrq = m.rsrp; + tmp_meas.pci = m.pci_nr; + meas_lte.push_back(tmp_meas); + } + const std::function filter = [this](meas_cell_nr& c, const phy_meas_t& m) { + c.set_rsrp(measurements->rsrp_filter(m.rsrp, c.get_rsrp())); + c.set_rsrq(measurements->rsrq_filter(m.rsrq, c.get_rsrq())); + c.set_cfo(m.cfo_hz); + }; + + rrc_log->debug("MEAS: Processing measurement of %zd cells\n", meas.size()); + + bool neighbour_added = meas_cells_nr.process_new_cell_meas(meas_lte, filter); +} +#endif /* This function is called from a PHY worker thus must return very quickly. * Queue the values of the measurements and process them from the RRC thread @@ -394,7 +422,6 @@ void rrc::new_cell_meas(const std::vector& meas) { cell_meas_q.push(meas); } - /* Processes all pending PHY measurements in queue. */ void rrc::process_cell_meas() @@ -410,7 +437,8 @@ void rrc::process_cell_meas() void rrc::process_new_cell_meas(const std::vector& meas) { - const std::function filter = [this](meas_cell& c, const phy_meas_t& m) { + const std::function filter = [this](meas_cell_eutra& c, + const phy_meas_t& m) { c.set_rsrp(measurements->rsrp_filter(m.rsrp, c.get_rsrp())); c.set_rsrq(measurements->rsrq_filter(m.rsrq, c.get_rsrq())); c.set_cfo(m.cfo_hz); @@ -1080,17 +1108,17 @@ std::set rrc::get_cells(const uint32_t earfcn) float rrc::get_cell_rsrp(const uint32_t earfcn, const uint32_t pci) { - meas_cell* c = meas_cells.get_neighbour_cell_handle(earfcn, pci); + meas_cell_eutra* c = meas_cells.get_neighbour_cell_handle(earfcn, pci); return (c != nullptr) ? c->get_rsrp() : NAN; } float rrc::get_cell_rsrq(const uint32_t earfcn, const uint32_t pci) { - meas_cell* c = meas_cells.get_neighbour_cell_handle(earfcn, pci); + meas_cell_eutra* c = meas_cells.get_neighbour_cell_handle(earfcn, pci); return (c != nullptr) ? c->get_rsrq() : NAN; } -meas_cell* rrc::get_serving_cell() +meas_cell_eutra* rrc::get_serving_cell() { return &meas_cells.serving_cell(); } diff --git a/srsue/src/stack/rrc/rrc_cell.cc b/srsue/src/stack/rrc/rrc_cell.cc index 36574dd6b..4e5651b76 100644 --- a/srsue/src/stack/rrc/rrc_cell.cc +++ b/srsue/src/stack/rrc/rrc_cell.cc @@ -24,7 +24,7 @@ meas_cell::meas_cell(const phy_cell_t& phy_cell_, srslte::unique_timer timer) : phy_cell = phy_cell_; } -srslte::plmn_id_t meas_cell::get_plmn(uint32_t idx) const +srslte::plmn_id_t meas_cell_eutra::get_plmn(uint32_t idx) const { if (idx < sib1.cell_access_related_info.plmn_id_list.size() && has_valid_sib1) { return srslte::make_plmn_id_t(sib1.cell_access_related_info.plmn_id_list[idx].plmn_id); @@ -33,7 +33,7 @@ srslte::plmn_id_t meas_cell::get_plmn(uint32_t idx) const } } -void meas_cell::set_sib1(const asn1::rrc::sib_type1_s& sib1_) +void meas_cell_eutra::set_sib1(const asn1::rrc::sib_type1_s& sib1_) { sib1 = sib1_; has_valid_sib1 = true; @@ -46,17 +46,17 @@ void meas_cell::set_sib1(const asn1::rrc::sib_type1_s& sib1_) } } -void meas_cell::set_sib2(const asn1::rrc::sib_type2_s& sib2_) +void meas_cell_eutra::set_sib2(const asn1::rrc::sib_type2_s& sib2_) { sib2 = sib2_; has_valid_sib2 = true; } -void meas_cell::set_sib3(const asn1::rrc::sib_type3_s& sib3_) +void meas_cell_eutra::set_sib3(const asn1::rrc::sib_type3_s& sib3_) { sib3 = sib3_; has_valid_sib3 = true; } -void meas_cell::set_sib13(const asn1::rrc::sib_type13_r9_s& sib13_) +void meas_cell_eutra::set_sib13(const asn1::rrc::sib_type13_r9_s& sib13_) { sib13 = sib13_; has_valid_sib13 = true; @@ -94,7 +94,23 @@ bool meas_cell::has_sib(uint32_t index) const return false; } -std::string meas_cell::to_string() const +#ifdef HAVE_5GNR +std::string meas_cell_nr::to_string() const +{ + char buf[256]; + snprintf(buf, + 256, + "{cell_id: 0x%x, pci: %d, dl_arfcn_nr: %d, rsrp=%+.1f, cfo=%+.1f}", + get_cell_id(), + get_pci(), + get_earfcn(), + get_rsrp(), + get_cfo_hz()); + return std::string{buf}; +} +#endif + +std::string meas_cell_eutra::to_string() const { char buf[256]; snprintf(buf, @@ -108,7 +124,7 @@ std::string meas_cell::to_string() const return std::string{buf}; } -bool meas_cell::has_plmn_id(asn1::rrc::plmn_id_s plmn_id) const +bool meas_cell_eutra::has_plmn_id(asn1::rrc::plmn_id_s plmn_id) const { if (has_valid_sib1) { for (const auto& e : sib1.cell_access_related_info.plmn_id_list) { @@ -120,7 +136,7 @@ bool meas_cell::has_plmn_id(asn1::rrc::plmn_id_s plmn_id) const return false; } -uint16_t meas_cell::get_mcc() const +uint16_t meas_cell_eutra::get_mcc() const { uint16_t mcc; if (has_valid_sib1) { @@ -133,7 +149,7 @@ uint16_t meas_cell::get_mcc() const return 0; } -uint16_t meas_cell::get_mnc() const +uint16_t meas_cell_eutra::get_mnc() const { uint16_t mnc; if (has_valid_sib1) { @@ -151,21 +167,22 @@ uint16_t meas_cell::get_mnc() const /********************************************* * Neighbour Cell List ********************************************/ - -meas_cell_list::meas_cell_list(srslte::task_sched_handle task_sched_) : - serv_cell(new meas_cell(task_sched_.get_unique_timer())), +template +meas_cell_list::meas_cell_list(srslte::task_sched_handle task_sched_) : + serv_cell(new T(task_sched_.get_unique_timer())), task_sched(task_sched_) {} -meas_cell* meas_cell_list::get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci) +template +T* meas_cell_list::get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci) { auto it = find_if(neighbour_cells.begin(), neighbour_cells.end(), [&](const unique_meas_cell& cell) { return cell->equals(earfcn, pci); }); return it != neighbour_cells.end() ? it->get() : nullptr; } - -const meas_cell* meas_cell_list::get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci) const +template +const T* meas_cell_list::get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci) const { auto it = find_if(neighbour_cells.begin(), neighbour_cells.end(), [&](const unique_meas_cell& cell) { return cell->equals(earfcn, pci); @@ -174,19 +191,20 @@ const meas_cell* meas_cell_list::get_neighbour_cell_handle(uint32_t earfcn, uint } // If only neighbour PCI is provided, copy full cell from serving cell -bool meas_cell_list::add_meas_cell(const phy_meas_t& meas) +template +bool meas_cell_list::add_meas_cell(const phy_meas_t& meas) { phy_cell_t phy_cell = {}; phy_cell.earfcn = meas.earfcn; phy_cell.pci = meas.pci; - unique_meas_cell c = unique_meas_cell(new meas_cell(phy_cell, task_sched.get_unique_timer())); + unique_meas_cell c = unique_meas_cell(new T(phy_cell, task_sched.get_unique_timer())); c.get()->set_rsrp(meas.rsrp); c.get()->set_rsrq(meas.rsrq); c.get()->set_cfo(meas.cfo_hz); return add_meas_cell(std::move(c)); } - -bool meas_cell_list::add_meas_cell(unique_meas_cell cell) +template +bool meas_cell_list::add_meas_cell(unique_meas_cell cell) { bool ret = add_neighbour_cell_unsorted(std::move(cell)); if (ret) { @@ -194,8 +212,8 @@ bool meas_cell_list::add_meas_cell(unique_meas_cell cell) } return ret; } - -bool meas_cell_list::add_neighbour_cell_unsorted(unique_meas_cell new_cell) +template +bool meas_cell_list::add_neighbour_cell_unsorted(unique_meas_cell new_cell) { // Make sure cell is valid if (!new_cell->is_valid()) { @@ -210,7 +228,7 @@ bool meas_cell_list::add_neighbour_cell_unsorted(unique_meas_cell new_cell) } // If cell exists, update RSRP value - meas_cell* existing_cell = get_neighbour_cell_handle(new_cell->get_earfcn(), new_cell->get_pci()); + T* existing_cell = get_neighbour_cell_handle(new_cell->get_earfcn(), new_cell->get_pci()); if (existing_cell != nullptr) { if (std::isnormal(new_cell.get()->get_rsrp())) { existing_cell->set_rsrp(new_cell.get()->get_rsrp()); @@ -234,8 +252,8 @@ bool meas_cell_list::add_neighbour_cell_unsorted(unique_meas_cell new_cell) neighbour_cells.push_back(std::move(new_cell)); return true; } - -void meas_cell_list::rem_last_neighbour() +template +void meas_cell_list::rem_last_neighbour() { if (not neighbour_cells.empty()) { unique_meas_cell& c = neighbour_cells.back(); @@ -243,8 +261,8 @@ void meas_cell_list::rem_last_neighbour() neighbour_cells.pop_back(); } } - -meas_cell_list::unique_meas_cell meas_cell_list::remove_neighbour_cell(uint32_t earfcn, uint32_t pci) +template +typename meas_cell_list::unique_meas_cell meas_cell_list::remove_neighbour_cell(uint32_t earfcn, uint32_t pci) { auto it = find_if(neighbour_cells.begin(), neighbour_cells.end(), [&](const unique_meas_cell& cell) { return cell->equals(earfcn, pci); @@ -258,7 +276,8 @@ meas_cell_list::unique_meas_cell meas_cell_list::remove_neighbour_cell(uint32_t } // Sort neighbour cells by decreasing order of RSRP -void meas_cell_list::sort_neighbour_cells() +template +void meas_cell_list::sort_neighbour_cells() { std::sort(std::begin(neighbour_cells), std::end(neighbour_cells), @@ -266,8 +285,8 @@ void meas_cell_list::sort_neighbour_cells() log_neighbour_cells(); } - -void meas_cell_list::log_neighbour_cells() const +template +void meas_cell_list::log_neighbour_cells() const { if (not neighbour_cells.empty()) { const int32_t MAX_STR_LEN = 512; @@ -289,7 +308,8 @@ void meas_cell_list::log_neighbour_cells() const } //! Called by main RRC thread to remove neighbours from which measurements have not been received in a while -void meas_cell_list::clean_neighbours() +template +void meas_cell_list::clean_neighbours() { for (auto it = neighbour_cells.begin(); it != neighbour_cells.end();) { if (it->get()->timer.is_expired()) { @@ -300,8 +320,8 @@ void meas_cell_list::clean_neighbours() } } } - -std::string meas_cell_list::print_neighbour_cells() const +template +std::string meas_cell_list::print_neighbour_cells() const { if (neighbour_cells.empty()) { return ""; @@ -314,8 +334,8 @@ std::string meas_cell_list::print_neighbour_cells() const s += neighbour_cells.back()->to_string(); return s; } - -std::set meas_cell_list::get_neighbour_pcis(uint32_t earfcn) const +template +std::set meas_cell_list::get_neighbour_pcis(uint32_t earfcn) const { std::set pcis = {}; for (const unique_meas_cell& cell : neighbour_cells) { @@ -325,21 +345,21 @@ std::set meas_cell_list::get_neighbour_pcis(uint32_t earfcn) const } return pcis; } - -bool meas_cell_list::has_neighbour_cell(uint32_t earfcn, uint32_t pci) const +template +bool meas_cell_list::has_neighbour_cell(uint32_t earfcn, uint32_t pci) const { return get_neighbour_cell_handle(earfcn, pci) != nullptr; } - -meas_cell* meas_cell_list::find_cell(uint32_t earfcn, uint32_t pci) +template +T* meas_cell_list::find_cell(uint32_t earfcn, uint32_t pci) { if (serving_cell().phy_cell.pci == pci and serving_cell().phy_cell.earfcn == earfcn) { return &serving_cell(); } return get_neighbour_cell_handle(earfcn, pci); } - -int meas_cell_list::set_serving_cell(phy_cell_t phy_cell, bool discard_serving) +template +int meas_cell_list::set_serving_cell(phy_cell_t phy_cell, bool discard_serving) { // don't update neighbor cell list unless serving cell changes if (phy_cell.pci == serving_cell().get_pci() && phy_cell.earfcn == serving_cell().get_earfcn()) { @@ -367,12 +387,13 @@ int meas_cell_list::set_serving_cell(phy_cell_t phy_cell, bool discard_serving) return SRSLTE_SUCCESS; } -bool meas_cell_list::process_new_cell_meas(const std::vector& meas, - const std::function& filter_meas) +template +bool meas_cell_list::process_new_cell_meas(const std::vector& meas, + const std::function& filter_meas) { bool neighbour_added = false; for (const auto& m : meas) { - meas_cell* c = nullptr; + T* c = nullptr; // Get serving_cell handle if it's the serving cell bool is_serving_cell = m.earfcn == 0 or is_same_cell(m, serving_cell()); @@ -405,4 +426,9 @@ bool meas_cell_list::process_new_cell_meas(const std::vector& return neighbour_added; } +template class meas_cell_list; +#ifdef HAVE_5GNR +template class meas_cell_list; +#endif + } // namespace srsue diff --git a/srsue/src/stack/rrc/rrc_meas.cc b/srsue/src/stack/rrc/rrc_meas.cc index ced9413ac..72bf45fa0 100644 --- a/srsue/src/stack/rrc/rrc_meas.cc +++ b/srsue/src/stack/rrc/rrc_meas.cc @@ -197,7 +197,7 @@ void rrc::rrc_meas::var_meas_report_list::init(rrc* rrc_ptr_) /* Generate report procedure 5.5.5 */ void rrc::rrc_meas::var_meas_report_list::generate_report(const uint32_t measId) { - meas_cell* serv_cell = rrc_ptr->get_serving_cell(); + meas_cell_eutra* serv_cell = rrc_ptr->get_serving_cell(); if (serv_cell == nullptr) { log_h->warning("MEAS: Serving cell not set when evaluating triggers\n"); return; @@ -435,7 +435,7 @@ void rrc::rrc_meas::var_meas_cfg::report_triggers_eutra(uint32_t meas } } { - meas_cell* serv_cell = rrc_ptr->get_serving_cell(); + meas_cell_eutra* serv_cell = rrc_ptr->get_serving_cell(); if (serv_cell == nullptr) { log_h->warning("MEAS: Serving cell not set when reporting triggers\n"); return; @@ -499,7 +499,7 @@ bool rrc::rrc_meas::var_meas_cfg::is_rsrp(report_cfg_eutra_s::trigger_quant_opts void rrc::rrc_meas::var_meas_cfg::eval_triggers_eutra(uint32_t meas_id, report_cfg_eutra_s& report_cfg, meas_obj_eutra_s& meas_obj, - meas_cell* serv_cell, + meas_cell_eutra* serv_cell, float Ofs, float Ocs) { @@ -627,7 +627,7 @@ void rrc::rrc_meas::var_meas_cfg::eval_triggers_eutra(uint32_t meas_i /* Evaluate event trigger conditions for each cell 5.5.4 */ void rrc::rrc_meas::var_meas_cfg::eval_triggers() { - meas_cell* serv_cell = rrc_ptr->get_serving_cell(); + meas_cell_eutra* serv_cell = rrc_ptr->get_serving_cell(); if (serv_cell == nullptr) { log_h->warning("MEAS: Serving cell not set when evaluating triggers\n"); @@ -1226,7 +1226,7 @@ bool rrc::rrc_meas::var_meas_cfg::parse_meas_config(const meas_cfg_s* cfg, bool // According to 5.5.6.1, if the new configuration after a HO/Reest does not configure the target frequency, we need to // swap frequencies with source if (is_ho_reest) { - meas_cell* serv_cell = rrc_ptr->get_serving_cell(); + meas_cell_eutra* serv_cell = rrc_ptr->get_serving_cell(); if (serv_cell) { // Check if the target frequency is configured uint32_t target_earfcn = serv_cell->get_earfcn(); diff --git a/srsue/src/stack/rrc/rrc_procedures.cc b/srsue/src/stack/rrc/rrc_procedures.cc index e5320d8e1..f8996ead8 100644 --- a/srsue/src/stack/rrc/rrc_procedures.cc +++ b/srsue/src/stack/rrc/rrc_procedures.cc @@ -82,7 +82,7 @@ proc_outcome_t rrc::cell_search_proc::handle_cell_found(const phy_cell_t& new_ce // Create a cell with NaN RSRP. Will be updated by new_phy_meas() during SIB search. if (not rrc_ptr->meas_cells.add_meas_cell( - unique_cell_t(new meas_cell(new_cell, rrc_ptr->task_sched.get_unique_timer())))) { + unique_cell_t(new meas_cell_eutra(new_cell, rrc_ptr->task_sched.get_unique_timer())))) { Error("Could not add new found cell\n"); return proc_outcome_t::error; } @@ -552,7 +552,7 @@ proc_outcome_t rrc::cell_selection_proc::start_next_cell_selection() // If serving is not available, use the stored information (known neighbours) to find the strongest // cell that meets the selection criteria. for (; neigh_index < meas_cells->nof_neighbours(); ++neigh_index) { - const meas_cell& neigh_cell = meas_cells->at(neigh_index); + const meas_cell_eutra& neigh_cell = meas_cells->at(neigh_index); /*TODO: CHECK that PLMN matches. Currently we don't receive SIB1 of neighbour cells * meas_cells[i]->plmn_equals(selected_plmn_id) && */ @@ -598,7 +598,7 @@ proc_outcome_t rrc::cell_selection_proc::react(const bool& cell_selection_result return start_next_cell_selection(); } -srslte::proc_outcome_t rrc::cell_selection_proc::start_phy_cell_selection(const meas_cell& cell) +srslte::proc_outcome_t rrc::cell_selection_proc::start_phy_cell_selection(const meas_cell_eutra& cell) { if (not is_same_cell(cell, meas_cells->serving_cell())) { rrc_ptr->set_serving_cell(cell.phy_cell, discard_serving); @@ -1547,7 +1547,7 @@ srslte::proc_outcome_t rrc::ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& rrc : rrc_ptr->meas_cells.serving_cell().get_earfcn(); // Target cell shall be either serving cell (intra-cell HO) or neighbour cell - meas_cell* cell_to_ho = rrc_ptr->meas_cells.find_cell(target_earfcn, mob_ctrl_info->target_pci); + meas_cell_eutra* cell_to_ho = rrc_ptr->meas_cells.find_cell(target_earfcn, mob_ctrl_info->target_pci); if (cell_to_ho != nullptr) { target_cell = cell_to_ho->phy_cell; } else { diff --git a/srsue/test/ttcn3/src/CMakeLists.txt b/srsue/test/ttcn3/src/CMakeLists.txt index 00b3f49ed..1a4d0303c 100644 --- a/srsue/test/ttcn3/src/CMakeLists.txt +++ b/srsue/test/ttcn3/src/CMakeLists.txt @@ -8,18 +8,26 @@ set(SOURCES ttcn3_ue.cc ttcn3_syssim.cc) add_executable(ttcn3_dut ttcn3_dut.cc lte_ttcn3_phy.cc ${SOURCES}) -target_link_libraries(ttcn3_dut srsue_stack - srsue_upper - srsue_rrc - srslte_upper - srslte_common - srslte_mac - srslte_phy - srslte_radio - srslte_upper - srsue_phy - srsue_mac - rrc_asn1 - sctp - ${Boost_LIBRARIES}) + +set(LINK_LIBRARIES srsue_stack + srsue_upper + srsue_rrc + srslte_upper + srslte_common + srslte_mac + srslte_phy + srslte_radio + srslte_upper + srsue_phy + srsue_mac + rrc_asn1 + sctp +${Boost_LIBRARIES}) + +if (ENABLE_5GNR) + set(LINK_LIBRARIES ${LINK_LIBRARIES} rrc_nr_asn1) +endif (ENABLE_5GNR) + +target_link_libraries(ttcn3_dut ${LINK_LIBRARIES}) + include_directories(${PROJECT_SOURCE_DIR}/srsue/test/ttcn3/hdr) diff --git a/srsue/test/upper/CMakeLists.txt b/srsue/test/upper/CMakeLists.txt index f8c452430..aba74d0fa 100644 --- a/srsue/test/upper/CMakeLists.txt +++ b/srsue/test/upper/CMakeLists.txt @@ -20,7 +20,11 @@ target_link_libraries(rrc_reconfig_test srsue_upper srslte_upper srslte_phy rrc_ add_test(rrc_reconfig_test rrc_reconfig_test) add_executable(rrc_meas_test rrc_meas_test.cc) -target_link_libraries(rrc_meas_test srsue_rrc srsue_upper srslte_upper srslte_phy rrc_asn1) +if (ENABLE_5GNR) + target_link_libraries(rrc_meas_test srsue_rrc srsue_upper srslte_upper srslte_phy rrc_asn1 rrc_nr_asn1) +else (ENABLE_5GNR) + target_link_libraries(rrc_meas_test srsue_rrc srsue_upper srslte_upper srslte_phy rrc_asn1) +endif(ENABLE_5GNR) add_test(rrc_meas_test rrc_meas_test) add_executable(nas_test nas_test.cc) @@ -36,7 +40,11 @@ target_link_libraries(rrc_phy_ctrl_test srslte_common srsue_rrc) add_test(rrc_phy_ctrl_test rrc_phy_ctrl_test) add_executable(rrc_cell_test rrc_cell_test.cc) -target_link_libraries(rrc_cell_test srsue_rrc srsue_upper srslte_upper srslte_phy rrc_asn1) +if (ENABLE_5GNR) + target_link_libraries(rrc_cell_test srsue_rrc srsue_upper srslte_upper srslte_phy rrc_asn1 rrc_nr_asn1) +else (ENABLE_5GNR) + target_link_libraries(rrc_cell_test srsue_rrc srsue_upper srslte_upper srslte_phy rrc_asn1) +endif(ENABLE_5GNR) add_test(rrc_cell_test rrc_cell_test) ######################################################################## diff --git a/srsue/test/upper/rrc_cell_test.cc b/srsue/test/upper/rrc_cell_test.cc index 95a4203f3..55de8181b 100644 --- a/srsue/test/upper/rrc_cell_test.cc +++ b/srsue/test/upper/rrc_cell_test.cc @@ -18,7 +18,7 @@ using namespace srsue; int test_meas_cell() { srslte::task_scheduler task_sched; - meas_cell invalid_cell{task_sched.get_unique_timer()}, cell{phy_cell_t{1, 3400}, task_sched.get_unique_timer()}; + meas_cell_eutra invalid_cell{task_sched.get_unique_timer()}, cell{phy_cell_t{1, 3400}, task_sched.get_unique_timer()}; TESTASSERT(not invalid_cell.is_valid()); TESTASSERT(cell.is_valid()); @@ -33,13 +33,13 @@ int test_meas_cell() TESTASSERT(cell.get_rsrp() == -50); // Test meas timer expiry - for (size_t i = 0; i < meas_cell::neighbour_timeout_ms; ++i) { + for (size_t i = 0; i < meas_cell_eutra::neighbour_timeout_ms; ++i) { TESTASSERT(not cell.timer.is_expired()); task_sched.tic(); } TESTASSERT(cell.timer.is_expired()); cell.set_rsrp(-20); - for (size_t i = 0; i < meas_cell::neighbour_timeout_ms; ++i) { + for (size_t i = 0; i < meas_cell_eutra::neighbour_timeout_ms; ++i) { TESTASSERT(not cell.timer.is_expired()); task_sched.tic(); } @@ -50,8 +50,8 @@ int test_meas_cell() int test_add_neighbours() { - srslte::task_scheduler task_sched; - meas_cell_list list{&task_sched}; + srslte::task_scheduler task_sched; + meas_cell_list list{&task_sched}; TESTASSERT(list.nof_neighbours() == 0); TESTASSERT(not list.serving_cell().is_valid()); TESTASSERT(list.get_neighbour_cell_handle(0, 0) == nullptr); @@ -65,7 +65,7 @@ int test_add_neighbours() TESTASSERT(list.add_meas_cell(pmeas)); TESTASSERT(not list.serving_cell().is_valid()); TESTASSERT(list.nof_neighbours() == 1); - meas_cell* c = list.get_neighbour_cell_handle(3400, 1); + meas_cell_eutra* c = list.get_neighbour_cell_handle(3400, 1); TESTASSERT(c != nullptr and c->is_valid() and c->equals(3400, 1)); TESTASSERT(c->get_rsrp() == pmeas.rsrp and c->get_rsrq() == pmeas.rsrq); @@ -91,7 +91,7 @@ int test_add_neighbours() task_sched.tic(); task_sched.tic(); list.get_neighbour_cell_handle(3400, 1)->set_rsrp(-20); - for (size_t i = 0; i < meas_cell::neighbour_timeout_ms; ++i) { + for (size_t i = 0; i < meas_cell_eutra::neighbour_timeout_ms; ++i) { TESTASSERT(list.nof_neighbours() == 1); list.clean_neighbours(); task_sched.tic();