diff --git a/lib/include/srslte/common/common.h b/lib/include/srslte/common/common.h index f9ea6e333..cc1dabfa6 100644 --- a/lib/include/srslte/common/common.h +++ b/lib/include/srslte/common/common.h @@ -283,6 +283,25 @@ inline const_byte_span make_span(const unique_byte_buffer_t& b) return const_byte_span{b->msg, b->N_bytes}; } +// helper functions +inline const char* enum_to_text(const char* const array[], uint32_t nof_types, uint32_t enum_val) +{ + return enum_val >= nof_types ? "" : array[enum_val]; +} + +template +ItemType enum_to_number(ItemType* array, uint32_t nof_types, uint32_t enum_val) +{ + return enum_val >= nof_types ? -1 : array[enum_val]; +} + +enum class srslte_rat_t { lte, nr, nulltype }; +inline std::string to_string(const srslte_rat_t& type) +{ + constexpr static const char* options[] = {"LTE", "NR"}; + return enum_to_text(options, (uint32_t)srslte_rat_t::nulltype, (uint32_t)type); +} + } // namespace srslte #endif // SRSLTE_COMMON_H diff --git a/lib/include/srslte/interfaces/rlc_interface_types.h b/lib/include/srslte/interfaces/rlc_interface_types.h index ad5f8c744..cc2e0b2e7 100644 --- a/lib/include/srslte/interfaces/rlc_interface_types.h +++ b/lib/include/srslte/interfaces/rlc_interface_types.h @@ -117,13 +117,6 @@ struct rlc_um_nr_config_t { #define RLC_TX_QUEUE_LEN (256) -enum class srslte_rat_t { lte, nr, nulltype }; -inline std::string to_string(const srslte_rat_t& type) -{ - constexpr static const char* options[] = {"LTE", "NR"}; - return enum_to_text(options, (uint32_t)srslte_rat_t::nulltype, (uint32_t)type); -} - class rlc_config_t { public: diff --git a/lib/include/srslte/interfaces/rrc_interface_types.h b/lib/include/srslte/interfaces/rrc_interface_types.h index 71fb59c47..1b0baf6ee 100644 --- a/lib/include/srslte/interfaces/rrc_interface_types.h +++ b/lib/include/srslte/interfaces/rrc_interface_types.h @@ -13,6 +13,7 @@ #ifndef SRSLTE_RRC_INTERFACE_TYPES_H #define SRSLTE_RRC_INTERFACE_TYPES_H +#include "srslte/common/common.h" #include "srslte/common/bcd_helpers.h" #include "srslte/config.h" #include "srslte/srslte.h" @@ -20,18 +21,6 @@ namespace srslte { -// helper functions -inline const char* enum_to_text(const char* const array[], uint32_t nof_types, uint32_t enum_val) -{ - return enum_val >= nof_types ? "" : array[enum_val]; -} - -template -ItemType enum_to_number(ItemType* array, uint32_t nof_types, uint32_t enum_val) -{ - return enum_val >= nof_types ? -1 : array[enum_val]; -} - /*************************** * PLMN ID **************************/ diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 6e1bf4190..545df8810 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -132,19 +132,35 @@ struct phy_cell_t { float cfo_hz; }; +// Measurement object from phy +typedef struct { + float rsrp; + float rsrq; + float cfo_hz; + uint32_t earfcn; + uint32_t pci; +} phy_meas_t; + +typedef struct { + float rsrp; + float rsrq; + float sinr; + float cfo_hz; + uint32_t arfcn_nr; + uint32_t pci_nr; +} phy_meas_nr_t; + +// RRC interface for RRC NR +class rrc_interface_rrc_nr +{ +public: + virtual void new_cell_meas_nr(const std::vector& meas) = 0; +}; + // RRC interface for PHY class rrc_interface_phy_lte { public: - // Measurement object from phy - typedef struct { - float rsrp; - float rsrq; - float cfo_hz; - uint32_t earfcn; - uint32_t pci; - } phy_meas_t; - virtual void in_sync() = 0; virtual void out_of_sync() = 0; virtual void new_cell_meas(const std::vector& meas) = 0; diff --git a/srsue/hdr/phy/lte/cc_worker.h b/srsue/hdr/phy/lte/cc_worker.h index 6853af9b7..ccefbc3c8 100644 --- a/srsue/hdr/phy/lte/cc_worker.h +++ b/srsue/hdr/phy/lte/cc_worker.h @@ -54,8 +54,7 @@ public: int read_ce_abs(float* ce_abs, uint32_t tx_antenna, uint32_t rx_antenna); int read_pdsch_d(cf_t* pdsch_d); - void update_measurements(std::vector& serving_cells, - cf_t* rssi_power_buffer = nullptr); + void update_measurements(std::vector& serving_cells, cf_t* rssi_power_buffer = nullptr); private: void reset(); diff --git a/srsue/hdr/phy/phy_common.h b/srsue/hdr/phy/phy_common.h index 3a8602a3d..afe3ec09e 100644 --- a/srsue/hdr/phy/phy_common.h +++ b/srsue/hdr/phy/phy_common.h @@ -162,12 +162,12 @@ public: */ uint32_t get_ul_earfcn(uint32_t dl_earfcn); - void update_measurements(uint32_t cc_idx, - srslte_chest_dl_res_t chest_res, - srslte_dl_sf_cfg_t sf_cfg_dl, - float tx_crs_power, - std::vector& serving_cells, - cf_t* rssi_power_buffer = nullptr); + void update_measurements(uint32_t cc_idx, + srslte_chest_dl_res_t chest_res, + srslte_dl_sf_cfg_t sf_cfg_dl, + float tx_crs_power, + std::vector& serving_cells, + cf_t* rssi_power_buffer = nullptr); void update_cfo_measurement(uint32_t cc_idx, float cfo_hz); @@ -197,7 +197,7 @@ public: void neighbour_cells_reset(uint32_t cc_idx) { avg_rsrp_neigh[cc_idx] = NAN; } - void set_neighbour_cells(uint32_t cc_idx, const std::vector& meas) + void set_neighbour_cells(uint32_t cc_idx, const std::vector& meas) { // Add RSRP in the linear domain and average float total_rsrp = 0; diff --git a/srsue/hdr/phy/scell/intra_measure.h b/srsue/hdr/phy/scell/intra_measure.h index 5db4b3c58..0e1de9b75 100644 --- a/srsue/hdr/phy/scell/intra_measure.h +++ b/srsue/hdr/phy/scell/intra_measure.h @@ -51,8 +51,8 @@ public: class meas_itf { public: - virtual void cell_meas_reset(uint32_t cc_idx) = 0; - virtual void new_cell_meas(uint32_t cc_idx, const std::vector& meas) = 0; + virtual void cell_meas_reset(uint32_t cc_idx) = 0; + virtual void new_cell_meas(uint32_t cc_idx, const std::vector& meas) = 0; }; /** diff --git a/srsue/hdr/phy/sync.h b/srsue/hdr/phy/sync.h index ed27bab4f..2d973f236 100644 --- a/srsue/hdr/phy/sync.h +++ b/srsue/hdr/phy/sync.h @@ -114,7 +114,7 @@ public: // Interface from scell::intra_measure for providing neighbour cell measurements void cell_meas_reset(uint32_t cc_idx) override; - void new_cell_meas(uint32_t cc_idx, const std::vector& meas) override; + void new_cell_meas(uint32_t cc_idx, const std::vector& meas) override; private: void reset(); diff --git a/srsue/hdr/stack/rrc/rrc.h b/srsue/hdr/stack/rrc/rrc.h index f00452338..e6ff2e24c 100644 --- a/srsue/hdr/stack/rrc/rrc.h +++ b/srsue/hdr/stack/rrc/rrc.h @@ -62,6 +62,7 @@ class rrc : public rrc_interface_nas, public rrc_interface_phy_lte, public rrc_interface_mac, public rrc_interface_pdcp, + public rrc_interface_rrc_nr, public rrc_interface_rlc, public srslte::timer_callback { @@ -108,6 +109,9 @@ public: void set_ue_identity(srslte::s_tmsi_t s_tmsi); void paging_completed(bool outcome) final; + // NR interface + void new_cell_meas_nr(const std::vector& meas); + // PHY interface void in_sync() final; void out_of_sync() final; @@ -255,6 +259,10 @@ private: void process_new_cell_meas(const std::vector& meas); srslte::block_queue > cell_meas_q; + void process_cell_meas_nr(); + void process_new_cell_meas_nr(const std::vector& meas); + srslte::block_queue > cell_meas_nr_q; + // Cell selection/reselection functions/variables typedef struct { float Qrxlevmin; diff --git a/srsue/hdr/stack/rrc/rrc_cell.h b/srsue/hdr/stack/rrc/rrc_cell.h index df6921313..0ba38c918 100644 --- a/srsue/hdr/stack/rrc/rrc_cell.h +++ b/srsue/hdr/stack/rrc/rrc_cell.h @@ -158,7 +158,6 @@ bool is_same_cell(const T& lhs, const U& rhs) class meas_cell_list { - using phy_meas_t = rrc_interface_phy_lte::phy_meas_t; public: const static int NEIGHBOUR_TIMEOUT = 5; diff --git a/srsue/hdr/stack/rrc/rrc_metrics.h b/srsue/hdr/stack/rrc/rrc_metrics.h index 23d1c7c3d..ad2e453d2 100644 --- a/srsue/hdr/stack/rrc/rrc_metrics.h +++ b/srsue/hdr/stack/rrc/rrc_metrics.h @@ -19,8 +19,8 @@ namespace srsue { struct rrc_metrics_t { - rrc_state_t state; - std::vector neighbour_cells; + rrc_state_t state; + std::vector neighbour_cells; }; } // namespace srsue diff --git a/srsue/src/phy/lte/cc_worker.cc b/srsue/src/phy/lte/cc_worker.cc index 9b9f8aa6d..3a1d66c8b 100644 --- a/srsue/src/phy/lte/cc_worker.cc +++ b/srsue/src/phy/lte/cc_worker.cc @@ -556,8 +556,7 @@ void cc_worker::decode_phich() } } -void cc_worker::update_measurements(std::vector& serving_cells, - cf_t* rssi_power_buffer) +void cc_worker::update_measurements(std::vector& serving_cells, cf_t* rssi_power_buffer) { phy->update_measurements( cc_idx, ue_dl.chest_res, sf_cfg_dl, ue_dl_cfg.cfg.pdsch.rs_power, serving_cells, rssi_power_buffer); diff --git a/srsue/src/phy/lte/sf_worker.cc b/srsue/src/phy/lte/sf_worker.cc index 53c08b923..44ba1a9d2 100644 --- a/srsue/src/phy/lte/sf_worker.cc +++ b/srsue/src/phy/lte/sf_worker.cc @@ -268,7 +268,7 @@ void sf_worker::reset_uci(srslte_uci_data_t* uci_data) void sf_worker::update_measurements() { - std::vector serving_cells = {}; + std::vector serving_cells = {}; for (uint32_t cc_idx = 0; cc_idx < cc_workers.size(); cc_idx++) { cf_t* rssi_power_buffer = nullptr; // Setting rssi_power_buffer to nullptr disables RSSI update. Do it only by worker 0 diff --git a/srsue/src/phy/phy_common.cc b/srsue/src/phy/phy_common.cc index 2582e7d3c..f37311175 100644 --- a/srsue/src/phy/phy_common.cc +++ b/srsue/src/phy/phy_common.cc @@ -600,12 +600,12 @@ void phy_common::update_cfo_measurement(uint32_t cc_idx, float cfo_hz) avg_cfo_hz[cc_idx] = SRSLTE_VEC_EMA(cfo_hz, avg_cfo_hz[cc_idx], args->snr_ema_coeff); } -void phy_common::update_measurements(uint32_t cc_idx, - srslte_chest_dl_res_t chest_res, - srslte_dl_sf_cfg_t sf_cfg_dl, - float tx_crs_power, - std::vector& serving_cells, - cf_t* rssi_power_buffer) +void phy_common::update_measurements(uint32_t cc_idx, + srslte_chest_dl_res_t chest_res, + srslte_dl_sf_cfg_t sf_cfg_dl, + float tx_crs_power, + std::vector& serving_cells, + cf_t* rssi_power_buffer) { bool insync = true; { @@ -731,7 +731,7 @@ void phy_common::update_measurements(uint32_t // Prepare measurements for serving cells bool active = cell_state.is_configured(cc_idx); if (active && ((sf_cfg_dl.tti % pcell_report_period) == pcell_report_period - 1)) { - rrc_interface_phy_lte::phy_meas_t meas = {}; + phy_meas_t meas = {}; meas.rsrp = avg_rsrp_dbm[cc_idx]; meas.rsrq = avg_rsrq_db[cc_idx]; meas.cfo_hz = avg_cfo_hz[cc_idx]; diff --git a/srsue/src/phy/scell/intra_measure.cc b/srsue/src/phy/scell/intra_measure.cc index d8043a2d0..e37f2bbd4 100644 --- a/srsue/src/phy/scell/intra_measure.cc +++ b/srsue/src/phy/scell/intra_measure.cc @@ -169,7 +169,7 @@ void intra_measure::measure_proc() } // Initialise empty neighbour cell list - std::vector neighbour_cells = {}; + std::vector neighbour_cells = {}; new_cell_itf->cell_meas_reset(cc_idx); @@ -186,12 +186,12 @@ void intra_measure::measure_proc() srslte_refsignal_dl_sync_run(&refsignal_dl_sync, search_buffer, intra_freq_meas_len_ms * current_sflen); if (refsignal_dl_sync.found) { - rrc_interface_phy_lte::phy_meas_t m = {}; - m.pci = cell.id; - m.earfcn = current_earfcn; - m.rsrp = refsignal_dl_sync.rsrp_dBfs - rx_gain_offset_db; - m.rsrq = refsignal_dl_sync.rsrq_dB; - m.cfo_hz = refsignal_dl_sync.cfo_Hz; + phy_meas_t m = {}; + m.pci = cell.id; + m.earfcn = current_earfcn; + m.rsrp = refsignal_dl_sync.rsrp_dBfs - rx_gain_offset_db; + m.rsrq = refsignal_dl_sync.rsrq_dB; + m.cfo_hz = refsignal_dl_sync.cfo_Hz; neighbour_cells.push_back(m); Info("INTRA: Found neighbour cell: EARFCN=%d, PCI=%03d, RSRP=%5.1f dBm, RSRQ=%5.1f, peak_idx=%5d, " diff --git a/srsue/src/phy/sync.cc b/srsue/src/phy/sync.cc index 017336a1b..08ba706d1 100644 --- a/srsue/src/phy/sync.cc +++ b/srsue/src/phy/sync.cc @@ -1059,7 +1059,7 @@ void sync::cell_meas_reset(uint32_t cc_idx) worker_com->neighbour_cells_reset(cc_idx); } -void sync::new_cell_meas(uint32_t cc_idx, const std::vector& meas) +void sync::new_cell_meas(uint32_t cc_idx, const std::vector& meas) { // Pass measurements to phy_common for SINR estimation worker_com->set_neighbour_cells(cc_idx, meas); diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index d05198511..565d5525b 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -170,7 +170,7 @@ void rrc::get_metrics(rrc_metrics_t& m) m.state = state; // Save strongest cells metrics for (auto& c : meas_cells) { - rrc_interface_phy_lte::phy_meas_t meas = {}; + phy_meas_t meas = {}; meas.cfo_hz = c->get_cfo_hz(); meas.earfcn = c->get_earfcn(); meas.rsrq = c->get_rsrq(); @@ -364,6 +364,29 @@ void rrc::set_config_complete(bool status) void rrc::set_scell_complete(bool status) {} +/* 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 + */ +void rrc::new_cell_meas_nr(const std::vector& meas) +{ + cell_meas_nr_q.push(meas); +} + +/* Processes all pending PHY measurements in queue. + */ +void rrc::process_cell_meas_nr() +{ + std::vector m; + while (cell_meas_nr_q.try_pop(&m)) { + if (cell_meas_nr_q.size() > 0) { + rrc_log->debug("MEAS: Processing measurement. %zd measurements in queue\n", cell_meas_q.size()); + } + process_new_cell_meas_nr(m); + } +} + +void rrc::process_new_cell_meas_nr(const std::vector& meas) {} + /* 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 */ diff --git a/srsue/src/stack/rrc/rrc_cell.cc b/srsue/src/stack/rrc/rrc_cell.cc index 9770960c3..36574dd6b 100644 --- a/srsue/src/stack/rrc/rrc_cell.cc +++ b/srsue/src/stack/rrc/rrc_cell.cc @@ -174,7 +174,7 @@ 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 rrc_interface_phy_lte::phy_meas_t& meas) +bool meas_cell_list::add_meas_cell(const phy_meas_t& meas) { phy_cell_t phy_cell = {}; phy_cell.earfcn = meas.earfcn; diff --git a/srsue/test/metrics_test.cc b/srsue/test/metrics_test.cc index bff35c660..a53a7c744 100644 --- a/srsue/test/metrics_test.cc +++ b/srsue/test/metrics_test.cc @@ -52,7 +52,7 @@ public: // random neighbour cells if (rand() % 2 == 0) { - rrc_interface_phy_lte::phy_meas_t neighbor = {}; + phy_meas_t neighbor = {}; neighbor.pci = 8; neighbor.rsrp = -33; m->stack.rrc.neighbour_cells.push_back(neighbor); diff --git a/srsue/test/phy/scell_search_test.cc b/srsue/test/phy/scell_search_test.cc index f9c1e0e57..4354e872c 100644 --- a/srsue/test/phy/scell_search_test.cc +++ b/srsue/test/phy/scell_search_test.cc @@ -234,7 +234,7 @@ public: std::map cells; void cell_meas_reset(uint32_t cc_idx) override {} - void new_cell_meas(uint32_t cc_idx, const std::vector& meas) override + void new_cell_meas(uint32_t cc_idx, const std::vector& meas) override { for (auto& m : meas) { uint32_t pci = m.pci; diff --git a/srsue/test/phy/ue_phy_test.cc b/srsue/test/phy/ue_phy_test.cc index 1f09871a7..973c170ce 100644 --- a/srsue/test/phy/ue_phy_test.cc +++ b/srsue/test/phy/ue_phy_test.cc @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -83,7 +84,7 @@ private: void in_sync() override { notify_in_sync(); } void out_of_sync() override { notify_out_of_sync(); } - void new_cell_meas(const std::vector& meas) override + void new_cell_meas(const std::vector& meas) override { for (auto& m : meas) { notify_new_phy_meas(); diff --git a/srsue/test/ttcn3/src/lte_ttcn3_phy.cc b/srsue/test/ttcn3/src/lte_ttcn3_phy.cc index 9a129a2f6..23f21d9a2 100644 --- a/srsue/test/ttcn3/src/lte_ttcn3_phy.cc +++ b/srsue/test/ttcn3/src/lte_ttcn3_phy.cc @@ -339,10 +339,10 @@ void lte_ttcn3_phy::radio_failure() void lte_ttcn3_phy::run_tti() { // send report for all cells stronger than non-suitable cell RS - std::vector phy_meas; + std::vector phy_meas; for (auto& cell : cells) { if (cell.power >= NON_SUITABLE_CELL_RS_EPRE) { - rrc_interface_phy_lte::phy_meas_t m = {}; + phy_meas_t m = {}; m.pci = cell.info.id; m.earfcn = cell.earfcn; m.rsrp = cell.power; diff --git a/srsue/test/upper/rrc_cell_test.cc b/srsue/test/upper/rrc_cell_test.cc index ba6628c14..95a4203f3 100644 --- a/srsue/test/upper/rrc_cell_test.cc +++ b/srsue/test/upper/rrc_cell_test.cc @@ -56,7 +56,7 @@ int test_add_neighbours() TESTASSERT(not list.serving_cell().is_valid()); TESTASSERT(list.get_neighbour_cell_handle(0, 0) == nullptr); - rrc_interface_phy_lte::phy_meas_t pmeas; + phy_meas_t pmeas; pmeas.cfo_hz = 4; pmeas.rsrp = -20; pmeas.pci = 1; diff --git a/srsue/test/upper/rrc_meas_test.cc b/srsue/test/upper/rrc_meas_test.cc index c854fa035..19dce4120 100644 --- a/srsue/test/upper/rrc_meas_test.cc +++ b/srsue/test/upper/rrc_meas_test.cc @@ -307,11 +307,11 @@ public: void add_neighbour_cell(uint32_t pci, uint32_t earfcn, float rsrp = 0) { - std::vector phy_meas = {}; - rrc_interface_phy_lte::phy_meas_t meas = {}; - meas.pci = pci; - meas.earfcn = earfcn; - meas.rsrp = rsrp; + std::vector phy_meas = {}; + phy_meas_t meas = {}; + meas.pci = pci; + meas.earfcn = earfcn; + meas.rsrp = rsrp; phy_meas.push_back(meas); // neighbour cell new_cell_meas(phy_meas); run_tti(1); @@ -637,7 +637,7 @@ int meas_obj_test() TESTASSERT(rrctest.phytest.meas_cell_started(2, 24)); // was added log1->info("Test7: PHY finds new neighbours in frequency 1 and 2, check RRC instructs to search them\n"); - std::vector phy_meas = {}; + std::vector phy_meas = {}; phy_meas.push_back({0, 0, 0.0f, 1, 31}); phy_meas.push_back({-1, 0, 0.0f, 1, 32}); phy_meas.push_back({-2, 0, 0.0f, 1, 33}); @@ -760,7 +760,7 @@ void send_report(rrc_test& rrctest, const std::vector earfcn, const std::vector pci) { - std::vector phy_meas = {}; + std::vector phy_meas = {}; for (uint32_t i = 0; i < pci.size(); i++) { float r = rsrp[0]; if (rsrp.size() == pci.size()) {