From 2f453b43baaedae5b6c9c13a665491dd69107769 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 12 Apr 2021 22:48:25 +0200 Subject: [PATCH] Initial NR PHY interface --- lib/include/srsran/phy/phch/pdsch_nr.h | 1 + lib/include/srsran/phy/phch/sch_cfg_nr.h | 9 +- lib/src/phy/phch/ra_nr.c | 2 + srsue/hdr/phy/nr/state.h | 106 +++++++++++++++++++- srsue/hdr/phy/nr/worker_pool.h | 1 + srsue/hdr/phy/phy_common.h | 20 ++-- srsue/hdr/phy/phy_metrics.h | 121 +++++++++++++++++++++-- srsue/hdr/ue_metrics_interface.h | 1 - srsue/src/metrics_csv.cc | 12 +-- srsue/src/metrics_stdout.cc | 8 +- srsue/src/phy/lte/cc_worker.cc | 4 +- srsue/src/phy/lte/sf_worker.cc | 2 +- srsue/src/phy/nr/cc_worker.cc | 27 +++++ srsue/src/phy/nr/worker_pool.cc | 5 + srsue/src/phy/phy.cc | 5 + srsue/src/phy/phy_common.cc | 59 +++-------- srsue/src/ue.cc | 1 - srsue/test/metrics_test.cc | 10 +- 18 files changed, 304 insertions(+), 90 deletions(-) diff --git a/lib/include/srsran/phy/phch/pdsch_nr.h b/lib/include/srsran/phy/phch/pdsch_nr.h index e581e3359..3e299d931 100644 --- a/lib/include/srsran/phy/phch/pdsch_nr.h +++ b/lib/include/srsran/phy/phch/pdsch_nr.h @@ -70,6 +70,7 @@ typedef struct { uint8_t* payload; bool crc; float evm; + uint32_t fec_iters; } srsran_pdsch_res_nr_t; SRSRAN_API int srsran_pdsch_nr_init_enb(srsran_pdsch_nr_t* q, const srsran_pdsch_nr_args_t* args); diff --git a/lib/include/srsran/phy/phch/sch_cfg_nr.h b/lib/include/srsran/phy/phch/sch_cfg_nr.h index 2c7d548f6..ac39594e2 100644 --- a/lib/include/srsran/phy/phch/sch_cfg_nr.h +++ b/lib/include/srsran/phy/phch/sch_cfg_nr.h @@ -25,10 +25,11 @@ typedef struct SRSRAN_API { typedef struct SRSRAN_API { srsran_mod_t mod; - uint32_t N_L; ///< the number of transmission layers that the transport block is mapped onto - int tbs; ///< Payload size, TS 38.212 refers to it as A - double R; ///< Target LDPC rate - int rv; + uint32_t N_L; ///< the number of transmission layers that the transport block is mapped onto + uint32_t mcs; ///< Modulation Code Scheme (MCS) for debug and trace purpose + int tbs; ///< Payload size, TS 38.212 refers to it as A + double R; ///< Target LDPC rate + int rv; ///< Redundancy version uint32_t nof_re; ///< Number of available resource elements to send, known as N_RE uint32_t nof_bits; ///< Number of available bits to send, known as G uint32_t cw_idx; diff --git a/lib/src/phy/phch/ra_nr.c b/lib/src/phy/phch/ra_nr.c index 325713857..62bf5512b 100644 --- a/lib/src/phy/phch/ra_nr.c +++ b/lib/src/phy/phch/ra_nr.c @@ -676,6 +676,7 @@ int srsran_ra_dl_dci_to_grant_nr(const srsran_carrier_nr_t* carrier, pdsch_grant->rnti = dci_dl->ctx.rnti; pdsch_grant->rnti_type = dci_dl->ctx.rnti_type; pdsch_grant->tb[0].rv = dci_dl->rv; + pdsch_grant->tb[0].mcs = dci_dl->mcs; // 5.1.4 PDSCH resource mapping if (ra_dl_resource_mapping(carrier, slot, pdsch_hl_cfg, pdsch_cfg) < SRSRAN_SUCCESS) { @@ -785,6 +786,7 @@ int srsran_ra_ul_dci_to_grant_nr(const srsran_carrier_nr_t* carrier, pusch_grant->rnti = dci_ul->ctx.rnti; pusch_grant->rnti_type = dci_ul->ctx.rnti_type; pusch_grant->tb[0].rv = dci_ul->rv; + pusch_grant->tb[0].mcs = dci_ul->mcs; // 5.1.6.2 DM-RS reception procedure if (ra_ul_dmrs(pusch_hl_cfg, pusch_grant, pusch_cfg) < SRSRAN_SUCCESS) { diff --git a/srsue/hdr/phy/nr/state.h b/srsue/hdr/phy/nr/state.h index 337b6ee8f..c1298d624 100644 --- a/srsue/hdr/phy/nr/state.h +++ b/srsue/hdr/phy/nr/state.h @@ -13,6 +13,7 @@ #ifndef SRSRAN_STATE_H #define SRSRAN_STATE_H +#include "../phy_metrics.h" #include "srsran/adt/circular_array.h" #include "srsran/common/common.h" #include "srsran/interfaces/ue_nr_interfaces.h" @@ -47,9 +48,27 @@ private: srsran::circular_array pending_ack = {}; mutable std::mutex pending_ack_mutex; + info_metrics_t info_metrics = {}; + sync_metrics_t sync_metrics = {}; + ch_metrics_t ch_metrics = {}; + dl_metrics_t dl_metrics = {}; + ul_metrics_t ul_metrics = {}; + mutable std::mutex metrics_mutex; + /// CSI-RS measurements std::array csi_measurements = {}; + /** + * @brief Resets all metrics (unprotected) + */ + void reset_metrics_() + { + sync_metrics.reset(); + ch_metrics.reset(); + dl_metrics.reset(); + ul_metrics.reset(); + } + public: mac_interface_phy_nr* stack = nullptr; srsran_carrier_nr_t carrier = {}; @@ -71,6 +90,8 @@ public: carrier.nof_prb = 100; carrier.max_mimo_layers = 1; + info_metrics.pci = carrier.id; + // Hard-coded values, this should be set when the measurements take place csi_measurements[0].K_csi_rs = 1; csi_measurements[0].nof_ports = 1; @@ -257,7 +278,11 @@ public: return true; } - void reset() { clear_pending_grants(); } + void reset() + { + clear_pending_grants(); + reset_metrics(); + } bool has_valid_sr_resource(uint32_t sr_id) { @@ -323,6 +348,85 @@ public: uci_data.cfg.pucch.rnti = stack->get_ul_sched_rnti_nr(tti).id; } + + /** + * @brief Sets time and frequency synchronization metrics + * @param m Metrics object + */ + void set_info_metrics(const info_metrics_t& m) + { + std::lock_guard lock(metrics_mutex); + info_metrics = m; + } + + /** + * @brief Sets time and frequency synchronization metrics + * @param m Metrics object + */ + void set_sync_metrics(const sync_metrics_t& m) + { + std::lock_guard lock(metrics_mutex); + sync_metrics.set(m); + } + + /** + * @brief Sets DL channel metrics from received CSI-RS resources + * @param m Metrics object + */ + void set_channel_metrics(const ch_metrics_t& m) + { + std::lock_guard lock(metrics_mutex); + ch_metrics.set(m); + } + + /** + * @brief Sets DL metrics of a given PDSCH transmission + * @param m Metrics object + */ + void set_dl_metrics(const dl_metrics_t& m) + { + std::lock_guard lock(metrics_mutex); + dl_metrics.set(m); + } + + /** + * @brief Sets UL metrics of a given PUSCH transmission + * @param m Metrics object + */ + void set_ul_metrics(const ul_metrics_t& m) + { + std::lock_guard lock(metrics_mutex); + ul_metrics.set(m); + } + + /** + * @brief Resets all metrics (protected) + */ + void reset_metrics() + { + std::lock_guard lock(metrics_mutex); + reset_metrics_(); + } + + /** + * @brief Appends the NR PHY metrics to the general metric hub + * @param m PHY Metrics object + */ + void get_metrics(phy_metrics_t& m) + { + std::lock_guard lock(metrics_mutex); + + uint32_t cc = m.nof_active_cc; + m.info[cc] = info_metrics; + m.sync[cc] = sync_metrics; + m.ch[cc] = ch_metrics; + m.dl[cc] = dl_metrics; + m.ul[cc] = ul_metrics; + m.nof_active_cc++; + + // Reset all metrics + reset_metrics_(); + } }; } // namespace nr } // namespace srsue diff --git a/srsue/hdr/phy/nr/worker_pool.h b/srsue/hdr/phy/nr/worker_pool.h index 7f435ceba..adc42609d 100644 --- a/srsue/hdr/phy/nr/worker_pool.h +++ b/srsue/hdr/phy/nr/worker_pool.h @@ -42,6 +42,7 @@ public: bool set_config(const srsran::phy_cfg_nr_t& cfg); bool has_valid_sr_resource(uint32_t sr_id); void clear_pending_grants(); + void get_metrics(phy_metrics_t& m); }; } // namespace nr diff --git a/srsue/hdr/phy/phy_common.h b/srsue/hdr/phy/phy_common.h index f319c82ed..ef210afa3 100644 --- a/srsue/hdr/phy/phy_common.h +++ b/srsue/hdr/phy/phy_common.h @@ -136,16 +136,16 @@ public: srsran::radio_interface_phy* get_radio(); void set_dl_metrics(uint32_t cc_idx, const dl_metrics_t& m); - void get_dl_metrics(dl_metrics_t m[SRSRAN_MAX_CARRIERS]); + void get_dl_metrics(dl_metrics_t::array_t& m); void set_ch_metrics(uint32_t cc_idx, const ch_metrics_t& m); - void get_ch_metrics(ch_metrics_t m[SRSRAN_MAX_CARRIERS]); + void get_ch_metrics(ch_metrics_t::array_t& m); void set_ul_metrics(uint32_t cc_idx, const ul_metrics_t& m); - void get_ul_metrics(ul_metrics_t m[SRSRAN_MAX_CARRIERS]); + void get_ul_metrics(ul_metrics_t::array_t& m); void set_sync_metrics(const uint32_t& cc_idx, const sync_metrics_t& m); - void get_sync_metrics(sync_metrics_t m[SRSRAN_MAX_CARRIERS]); + void get_sync_metrics(sync_metrics_t::array_t& m); void reset(); void reset_radio(); @@ -302,14 +302,10 @@ private: std::mutex metrics_mutex; - ch_metrics_t ch_metrics[SRSRAN_MAX_CARRIERS] = {}; - uint32_t ch_metrics_count[SRSRAN_MAX_CARRIERS] = {}; - dl_metrics_t dl_metrics[SRSRAN_MAX_CARRIERS] = {}; - uint32_t dl_metrics_count[SRSRAN_MAX_CARRIERS] = {}; - ul_metrics_t ul_metrics[SRSRAN_MAX_CARRIERS] = {}; - uint32_t ul_metrics_count[SRSRAN_MAX_CARRIERS] = {}; - sync_metrics_t sync_metrics[SRSRAN_MAX_CARRIERS] = {}; - uint32_t sync_metrics_count[SRSRAN_MAX_CARRIERS] = {}; + ch_metrics_t::array_t ch_metrics = {}; + dl_metrics_t::array_t dl_metrics = {}; + ul_metrics_t::array_t ul_metrics = {}; + sync_metrics_t::array_t sync_metrics = {}; // MBSFN bool sib13_configured = false; diff --git a/srsue/hdr/phy/phy_metrics.h b/srsue/hdr/phy/phy_metrics.h index 152af9bcf..c1334d4c2 100644 --- a/srsue/hdr/phy/phy_metrics.h +++ b/srsue/hdr/phy/phy_metrics.h @@ -14,23 +14,58 @@ #define SRSUE_PHY_METRICS_H #include "srsran/srsran.h" +#include namespace srsue { struct info_metrics_t { + typedef srsran::circular_array array_t; + uint32_t pci; uint32_t dl_earfcn; }; +#define PHY_METRICS_SET(PARAM) \ + do { \ + PARAM = PARAM + (other.PARAM - PARAM) / count; \ + } while (false) + struct sync_metrics_t { + typedef srsran::circular_array array_t; + float ta_us; float distance_km; float speed_kmph; float cfo; float sfo; + + void set(const sync_metrics_t& other) + { + count++; + ta_us = other.ta_us; + distance_km = other.distance_km; + speed_kmph = other.speed_kmph; + PHY_METRICS_SET(cfo); + PHY_METRICS_SET(sfo); + } + + void reset() + { + count = 0; + ta_us = 0.0f; + distance_km = 0.0f; + speed_kmph = 0.0f; + cfo = 0.0f; + sfo = 0.0f; + } + +private: + uint32_t count = 0; }; struct ch_metrics_t { + typedef srsran::circular_array array_t; + float n; float sinr; float rsrp; @@ -39,25 +74,97 @@ struct ch_metrics_t { float ri; float pathloss; float sync_err; + + void set(const ch_metrics_t& other) + { + count++; + PHY_METRICS_SET(n); + PHY_METRICS_SET(sinr); + PHY_METRICS_SET(rsrp); + PHY_METRICS_SET(rsrq); + PHY_METRICS_SET(rssi); + PHY_METRICS_SET(ri); + PHY_METRICS_SET(pathloss); + PHY_METRICS_SET(sync_err); + } + + void reset() + { + count = 0; + n = 0.0; + sinr = 0.0; + rsrp = 0.0; + rsrq = 0.0; + rssi = 0.0; + ri = 0.0; + pathloss = 0.0; + sync_err = 0.0; + } + +private: + uint32_t count = 0; }; struct dl_metrics_t { - float turbo_iters; + typedef srsran::circular_array array_t; + + float fec_iters; float mcs; + float evm; + + void set(const dl_metrics_t& other) + { + count++; + PHY_METRICS_SET(fec_iters); + PHY_METRICS_SET(mcs); + PHY_METRICS_SET(evm); + } + + void reset() + { + count = 0; + fec_iters = 0.0f; + mcs = 0.0f; + evm = 0.0f; + } + +private: + uint32_t count = 0; }; struct ul_metrics_t { + typedef srsran::circular_array array_t; + float mcs; float power; + + void set(const ul_metrics_t& other) + { + count++; + PHY_METRICS_SET(mcs); + PHY_METRICS_SET(power); + } + + void reset() + { + count = 0; + mcs = 0.0f; + power = 0.0f; + } + +private: + uint32_t count = 0; }; +#undef PHY_METRICS_SET + struct phy_metrics_t { - info_metrics_t info[SRSRAN_MAX_CARRIERS]; - sync_metrics_t sync[SRSRAN_MAX_CARRIERS]; - ch_metrics_t ch[SRSRAN_MAX_CARRIERS]; - dl_metrics_t dl[SRSRAN_MAX_CARRIERS]; - ul_metrics_t ul[SRSRAN_MAX_CARRIERS]; - uint32_t nof_active_cc; + info_metrics_t::array_t info = {}; + sync_metrics_t::array_t sync = {}; + ch_metrics_t::array_t ch = {}; + dl_metrics_t::array_t dl = {}; + ul_metrics_t::array_t ul = {}; + uint32_t nof_active_cc = 0; }; } // namespace srsue diff --git a/srsue/hdr/ue_metrics_interface.h b/srsue/hdr/ue_metrics_interface.h index 43bca5f5f..1ee671569 100644 --- a/srsue/hdr/ue_metrics_interface.h +++ b/srsue/hdr/ue_metrics_interface.h @@ -40,7 +40,6 @@ typedef struct { typedef struct { srsran::rf_metrics_t rf; phy_metrics_t phy; - phy_metrics_t phy_nr; gw_metrics_t gw; stack_metrics_t stack; srsran::sys_metrics_t sys; diff --git a/srsue/src/metrics_csv.cc b/srsue/src/metrics_csv.cc index 3ef637369..50eee86bd 100644 --- a/srsue/src/metrics_csv.cc +++ b/srsue/src/metrics_csv.cc @@ -70,7 +70,7 @@ void metrics_csv::set_metrics_helper(const srsran::rf_metrics_t rf, const phy_metrics_t phy, const mac_metrics_t mac[SRSRAN_MAX_CARRIERS], const rrc_metrics_t rrc, - const uint32_t cc, + const uint32_t cc, const uint32_t r) { if (not file.is_open()) { @@ -108,7 +108,7 @@ void metrics_csv::set_metrics_helper(const srsran::rf_metrics_t rf, file << float_to_string(phy.dl[r].mcs, 2); file << float_to_string(phy.ch[r].sinr, 2); - file << float_to_string(phy.dl[r].turbo_iters, 2); + file << float_to_string(phy.dl[r].fec_iters, 2); if (mac[r].rx_brate > 0) { file << float_to_string(mac[r].rx_brate / (mac[r].nof_tti * 1e-3), 2); @@ -191,16 +191,16 @@ void metrics_csv::set_metrics(const ue_metrics_t& metrics, const uint32_t period file << "\n"; } - // Metrics for LTE carrier + // Metrics for LTE carrier for (uint32_t r = 0; r < metrics.phy.nof_active_cc; r++) { set_metrics_helper(metrics.rf, metrics.sys, metrics.phy, metrics.stack.mac, metrics.stack.rrc, r, r); } - // Metrics for NR carrier - for (uint32_t r = 0; r < metrics.phy_nr.nof_active_cc; r++) { + // Metrics for NR carrier + for (uint32_t r = 0; r < metrics.phy.nof_active_cc; r++) { set_metrics_helper(metrics.rf, metrics.sys, - metrics.phy_nr, + metrics.phy, metrics.stack.mac_nr, metrics.stack.rrc, metrics.phy.nof_active_cc + r, // NR carrier offset diff --git a/srsue/src/metrics_stdout.cc b/srsue/src/metrics_stdout.cc index f504be62b..062087c70 100644 --- a/srsue/src/metrics_stdout.cc +++ b/srsue/src/metrics_stdout.cc @@ -110,7 +110,7 @@ void metrics_stdout::set_metrics_helper(const phy_metrics_t phy, cout << float_to_string(phy.dl[r].mcs, 2); cout << float_to_string(phy.ch[r].sinr, 2); - cout << float_to_string(phy.dl[r].turbo_iters, 2); + cout << float_to_string(phy.dl[r].fec_iters, 2); cout << float_to_eng_string((float)mac[r].rx_brate / (mac[r].nof_tti * 1e-3), 2); if (mac[r].rx_pkts > 0) { @@ -174,12 +174,6 @@ void metrics_stdout::set_metrics(const ue_metrics_t& metrics, const uint32_t per set_metrics_helper(metrics.phy, metrics.stack.mac, metrics.stack.rrc, display_neighbours, r); } - for (uint32_t r = 0; r < metrics.phy_nr.nof_active_cc; r++) { - // Assumption LTE is followed by the NR carriers. - cout << std::setw(2) << metrics.phy.nof_active_cc + r; - set_metrics_helper(metrics.phy_nr, metrics.stack.mac_nr, metrics.stack.rrc, display_neighbours, r); - } - if (metrics.rf.rf_error) { printf("RF status: O=%d, U=%d, L=%d\n", metrics.rf.rf_o, metrics.rf.rf_u, metrics.rf.rf_l); } diff --git a/srsue/src/phy/lte/cc_worker.cc b/srsue/src/phy/lte/cc_worker.cc index 8f22b0ea9..122af973c 100644 --- a/srsue/src/phy/lte/cc_worker.cc +++ b/srsue/src/phy/lte/cc_worker.cc @@ -473,7 +473,7 @@ int cc_worker::decode_pdsch(srsran_pdsch_ack_resource_t ack_resource, } else { dl_metrics.mcs = (ue_dl_cfg.cfg.pdsch.grant.tb[0].mcs_idx + ue_dl_cfg.cfg.pdsch.grant.tb[1].mcs_idx) / 2; } - dl_metrics.turbo_iters = pdsch_dec->avg_iterations_block / 2; + dl_metrics.fec_iters = pdsch_dec->avg_iterations_block / 2; phy->set_dl_metrics(cc_idx, dl_metrics); // Logging @@ -507,7 +507,7 @@ int cc_worker::decode_pmch(mac_interface_phy_lte::tb_action_dl_t* action, srsran // Metrics dl_metrics_t dl_metrics = {}; dl_metrics.mcs = ue_dl_cfg.cfg.pdsch.grant.tb[0].mcs_idx; - dl_metrics.turbo_iters = pmch_dec.avg_iterations_block / 2; + dl_metrics.fec_iters = pmch_dec.avg_iterations_block / 2; phy->set_dl_metrics(cc_idx, dl_metrics); Info("PMCH: l_crb=%2d, tbs=%d, mcs=%d, crc=%s, snr=%.1f dB, n_iter=%.1f", diff --git a/srsue/src/phy/lte/sf_worker.cc b/srsue/src/phy/lte/sf_worker.cc index f4d1406c8..ea1c4ab3f 100644 --- a/srsue/src/phy/lte/sf_worker.cc +++ b/srsue/src/phy/lte/sf_worker.cc @@ -307,7 +307,7 @@ int sf_worker::read_pdsch_d(cf_t* pdsch_d) float sf_worker::get_cfo() { - sync_metrics_t sync_metrics[SRSRAN_MAX_CARRIERS] = {}; + sync_metrics_t::array_t sync_metrics = {}; phy->get_sync_metrics(sync_metrics); return sync_metrics[0].cfo; } diff --git a/srsue/src/phy/nr/cc_worker.cc b/srsue/src/phy/nr/cc_worker.cc index 186fad1a0..a9eb775ea 100644 --- a/srsue/src/phy/nr/cc_worker.cc +++ b/srsue/src/phy/nr/cc_worker.cc @@ -290,6 +290,26 @@ bool cc_worker::work_dl() // Send data to MAC phy->stack->tb_decoded(cc_idx, mac_nr_grant); + + // Generate DL metrics + dl_metrics_t dl_m = {}; + dl_m.mcs = pdsch_cfg.grant.tb[0].mcs; + dl_m.fec_iters = pdsch_res[0].fec_iters; + dl_m.evm = pdsch_res[0].evm; + phy->set_dl_metrics(dl_m); + + // Generate Synch metrics + sync_metrics_t sync_m = {}; + sync_m.cfo = ue_dl.chest.cfo; + phy->set_sync_metrics(sync_m); + + // Generate channel metrics + ch_metrics_t ch_m = {}; + ch_m.n = ue_dl.chest.noise_estimate; + ch_m.sinr = ue_dl.chest.snr_db; + ch_m.rsrp = ue_dl.chest.rsrp_dbm; + ch_m.sync_err = ue_dl.chest.sync_error; + phy->set_channel_metrics(ch_m); } } @@ -377,6 +397,13 @@ bool cc_worker::work_ul() str.data(), ul_slot_cfg.idx); } + + // Set metrics + ul_metrics_t ul_m = {}; + ul_m.mcs = pusch_cfg.grant.tb[0].mcs; + ul_m.power = srsran_convert_power_to_dB(srsran_vec_avg_power_cf(tx_buffer[0], ue_ul.ifft.sf_sz)); + phy->set_ul_metrics(ul_m); + } else if (srsran_uci_nr_total_bits(&uci_data.cfg) > 0) { // Get PUCCH resource srsran_pucch_nr_resource_t resource = {}; diff --git a/srsue/src/phy/nr/worker_pool.cc b/srsue/src/phy/nr/worker_pool.cc index 0da8f85d8..a429e5438 100644 --- a/srsue/src/phy/nr/worker_pool.cc +++ b/srsue/src/phy/nr/worker_pool.cc @@ -155,5 +155,10 @@ void worker_pool::clear_pending_grants() phy_state.clear_pending_grants(); } +void worker_pool::get_metrics(phy_metrics_t& m) +{ + phy_state.get_metrics(m); +} + } // namespace nr } // namespace srsue diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index e7c5454f5..d251fa4a8 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -202,6 +202,11 @@ void phy::get_metrics(phy_metrics_t* m) common.get_ul_metrics(m->ul); common.get_sync_metrics(m->sync); m->nof_active_cc = args.nof_lte_carriers; + + // Get NR metrics + if (args.nof_nr_carriers > 0) { + nr_workers.get_metrics(*m); + } } void phy::set_timeadv_rar(uint32_t tti, uint32_t ta_cmd) diff --git a/srsue/src/phy/phy_common.cc b/srsue/src/phy/phy_common.cc index f6a03c1f7..6c79fb1ff 100644 --- a/srsue/src/phy/phy_common.cc +++ b/srsue/src/phy/phy_common.cc @@ -792,91 +792,64 @@ void phy_common::update_measurements(uint32_t cc_idx, void phy_common::set_dl_metrics(uint32_t cc_idx, const dl_metrics_t& m) { std::unique_lock lock(metrics_mutex); - - dl_metrics_count[cc_idx]++; - dl_metrics[cc_idx].mcs = dl_metrics[cc_idx].mcs + (m.mcs - dl_metrics[cc_idx].mcs) / dl_metrics_count[cc_idx]; - dl_metrics[cc_idx].turbo_iters = - dl_metrics[cc_idx].turbo_iters + (m.turbo_iters - dl_metrics[cc_idx].turbo_iters) / dl_metrics_count[cc_idx]; + dl_metrics[cc_idx].set(m); } -void phy_common::get_dl_metrics(dl_metrics_t m[SRSRAN_MAX_CARRIERS]) +void phy_common::get_dl_metrics(dl_metrics_t::array_t& m) { std::unique_lock lock(metrics_mutex); for (uint32_t i = 0; i < args->nof_lte_carriers; i++) { - m[i] = dl_metrics[i]; - dl_metrics[i] = {}; - dl_metrics_count[i] = 0; + m[i] = dl_metrics[i]; + dl_metrics[i].reset(); } } void phy_common::set_ch_metrics(uint32_t cc_idx, const ch_metrics_t& m) { std::unique_lock lock(metrics_mutex); - - ch_metrics_count[cc_idx]++; - ch_metrics[cc_idx].n = ch_metrics[cc_idx].n + (m.n - ch_metrics[cc_idx].n) / ch_metrics_count[cc_idx]; - ch_metrics[cc_idx].rsrq = ch_metrics[cc_idx].rsrq + (m.rsrq - ch_metrics[cc_idx].rsrq) / ch_metrics_count[cc_idx]; - ch_metrics[cc_idx].rssi = ch_metrics[cc_idx].rssi + (m.rssi - ch_metrics[cc_idx].rssi) / ch_metrics_count[cc_idx]; - ch_metrics[cc_idx].rsrp = ch_metrics[cc_idx].rsrp + (m.rsrp - ch_metrics[cc_idx].rsrp) / ch_metrics_count[cc_idx]; - ch_metrics[cc_idx].sinr = ch_metrics[cc_idx].sinr + (m.sinr - ch_metrics[cc_idx].sinr) / ch_metrics_count[cc_idx]; - ch_metrics[cc_idx].sync_err = - ch_metrics[cc_idx].sync_err + (m.sync_err - ch_metrics[cc_idx].sync_err) / ch_metrics_count[cc_idx]; - ch_metrics[cc_idx].pathloss = - ch_metrics[cc_idx].pathloss + (m.pathloss - ch_metrics[cc_idx].pathloss) / ch_metrics_count[cc_idx]; + ch_metrics[cc_idx].set(m); } -void phy_common::get_ch_metrics(ch_metrics_t m[SRSRAN_MAX_CARRIERS]) +void phy_common::get_ch_metrics(ch_metrics_t::array_t& m) { std::unique_lock lock(metrics_mutex); for (uint32_t i = 0; i < args->nof_lte_carriers; i++) { - m[i] = ch_metrics[i]; - ch_metrics[i] = {}; - ch_metrics_count[i] = 0; + m[i] = ch_metrics[i]; + ch_metrics[i].reset(); } } void phy_common::set_ul_metrics(uint32_t cc_idx, const ul_metrics_t& m) { std::unique_lock lock(metrics_mutex); - - ul_metrics_count[cc_idx]++; - ul_metrics[cc_idx].mcs = ul_metrics[cc_idx].mcs + (m.mcs - ul_metrics[cc_idx].mcs) / ul_metrics_count[cc_idx]; - ul_metrics[cc_idx].power = ul_metrics[cc_idx].power + (m.power - ul_metrics[cc_idx].power) / ul_metrics_count[cc_idx]; + ul_metrics[cc_idx].set(m); } -void phy_common::get_ul_metrics(ul_metrics_t m[SRSRAN_MAX_CARRIERS]) +void phy_common::get_ul_metrics(ul_metrics_t::array_t& m) { std::unique_lock lock(metrics_mutex); for (uint32_t i = 0; i < args->nof_lte_carriers; i++) { - m[i] = ul_metrics[i]; - ul_metrics[i] = {}; - ul_metrics_count[i] = 0; + m[i] = ul_metrics[i]; + ul_metrics[i].reset(); } } void phy_common::set_sync_metrics(const uint32_t& cc_idx, const sync_metrics_t& m) { std::unique_lock lock(metrics_mutex); - - sync_metrics_count[cc_idx]++; - sync_metrics[cc_idx].cfo = sync_metrics[cc_idx].cfo + (m.cfo - sync_metrics[cc_idx].cfo) / sync_metrics_count[cc_idx]; - sync_metrics[cc_idx].sfo = sync_metrics[cc_idx].sfo + (m.sfo - sync_metrics[cc_idx].sfo) / sync_metrics_count[cc_idx]; - sync_metrics[cc_idx].ta_us = m.ta_us; - sync_metrics[cc_idx].distance_km = m.distance_km; - sync_metrics[cc_idx].speed_kmph = m.speed_kmph; + sync_metrics[cc_idx].set(m); } -void phy_common::get_sync_metrics(sync_metrics_t m[SRSRAN_MAX_CARRIERS]) +void phy_common::get_sync_metrics(sync_metrics_t::array_t& m) { std::unique_lock lock(metrics_mutex); for (uint32_t i = 0; i < args->nof_lte_carriers; i++) { - m[i] = sync_metrics[i]; - sync_metrics[i] = {}; - sync_metrics_count[i] = 0; + m[i] = sync_metrics[i]; + sync_metrics[i].reset(); } } diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 3de79e8a2..380b1bba9 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -335,7 +335,6 @@ bool ue::get_metrics(ue_metrics_t* m) stack->get_metrics(&m->stack); gw_inst->get_metrics(m->gw, m->stack.mac[0].nof_tti); m->sys = sys_proc.get_metrics(); - m->phy_nr.nof_active_cc = args.phy.nof_nr_carriers; // FIXME: temporary until PHY metrics are complete return true; } diff --git a/srsue/test/metrics_test.cc b/srsue/test/metrics_test.cc index f1308b047..d1d9bc1be 100644 --- a/srsue/test/metrics_test.cc +++ b/srsue/test/metrics_test.cc @@ -54,15 +54,15 @@ public: // random neighbour cells if (rand() % 2 == 0) { phy_meas_t neighbor = {}; - neighbor.pci = 8; - neighbor.rsrp = -33; + neighbor.pci = 8; + neighbor.rsrp = -33; m->stack.rrc.neighbour_cells.push_back(neighbor); m->stack.rrc.neighbour_cells.push_back(neighbor); // need to add twice since we use CA } - m->phy_nr.nof_active_cc = 1; - m->phy_nr.ch[0].rsrp = -10.0f; - m->phy_nr.ch[0].pathloss = 32; + m->phy.nof_active_cc = 1; + m->phy.ch[0].rsrp = -10.0f; + m->phy.ch[0].pathloss = 32; m->stack.mac_nr[0].rx_pkts = 100; m->stack.mac_nr[0].rx_errors = 2; m->stack.mac_nr[0].rx_brate = 223;