From fc5d0697439fb23e210a89fc69ac31f84cb94c5e Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 10 Jun 2021 19:31:09 +0200 Subject: [PATCH] SRSUE: Default PHY measurements to NAN --- srsue/hdr/phy/phy_common.h | 44 +++++++------- srsue/src/phy/lte/cc_worker.cc | 5 ++ srsue/src/phy/phy.cc | 4 ++ srsue/src/phy/phy_common.cc | 101 ++++++++++++++++----------------- 4 files changed, 81 insertions(+), 73 deletions(-) diff --git a/srsue/hdr/phy/phy_common.h b/srsue/hdr/phy/phy_common.h index 3acbd80df..d283ddf7d 100644 --- a/srsue/hdr/phy/phy_common.h +++ b/srsue/hdr/phy/phy_common.h @@ -168,6 +168,12 @@ public: */ uint32_t get_ul_earfcn(uint32_t dl_earfcn); + /** + * @brief Resets measurements from a given CC + * @param cc_idx CC index + */ + void reset_measurements(uint32_t cc_idx); + void update_measurements(uint32_t cc_idx, const srsran_chest_dl_res_t& chest_res, srsran_dl_sf_cfg_t sf_cfg_dl, @@ -218,32 +224,26 @@ public: } } } - void reset_neighbour_cells() - { - for (uint32_t i = 0; i < SRSRAN_MAX_CARRIERS; i++) { - avg_rsrp_neigh[i] = NAN; - } - } private: std::mutex meas_mutex; - float pathloss[SRSRAN_MAX_CARRIERS] = {}; - float cur_pathloss = 0.0f; - float cur_pusch_power = 0.0f; - float avg_rsrp[SRSRAN_MAX_CARRIERS] = {}; - float avg_rsrp_dbm[SRSRAN_MAX_CARRIERS] = {}; - float avg_rsrq_db[SRSRAN_MAX_CARRIERS] = {}; - float avg_rssi_dbm[SRSRAN_MAX_CARRIERS] = {}; - float avg_cfo_hz[SRSRAN_MAX_CARRIERS] = {}; - float rx_gain_offset = 0.0f; - float avg_sinr_db[SRSRAN_MAX_CARRIERS] = {}; - float avg_snr_db[SRSRAN_MAX_CARRIERS] = {}; - float avg_noise[SRSRAN_MAX_CARRIERS] = {}; - float avg_rsrp_neigh[SRSRAN_MAX_CARRIERS] = {}; - - uint32_t pcell_report_period = 0; - uint32_t rssi_read_cnt = 0; + float cur_pathloss = 0.0f; + float cur_pusch_power = 0.0f; + float rx_gain_offset = 0.0f; + std::array pathloss = {}; + std::array avg_rsrp = {}; + std::array avg_rsrp_dbm = {}; + std::array avg_rsrq_db = {}; + std::array avg_rssi_dbm = {}; + std::array avg_cfo_hz = {}; + std::array avg_sinr_db = {}; + std::array avg_snr_db = {}; + std::array avg_noise = {}; + std::array avg_rsrp_neigh = {}; + + static constexpr uint32_t pcell_report_period = 20; + uint32_t rssi_read_cnt = 0; rsrp_insync_itf* insync_itf = nullptr; diff --git a/srsue/src/phy/lte/cc_worker.cc b/srsue/src/phy/lte/cc_worker.cc index 913e5beae..ddafb7efe 100644 --- a/srsue/src/phy/lte/cc_worker.cc +++ b/srsue/src/phy/lte/cc_worker.cc @@ -549,6 +549,11 @@ void cc_worker::decode_phich() void cc_worker::update_measurements(std::vector& serving_cells, cf_t* rssi_power_buffer) { + // Do not update any measurement if the CC is not configured to prevent false or inaccurate data + if (not phy->cell_state.is_configured(cc_idx)) { + return; + } + 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/phy.cc b/srsue/src/phy/phy.cc index 3c22ade56..12de63ba3 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -529,6 +529,10 @@ bool phy::set_scell(srsran_cell_t cell_info, uint32_t cc_idx, uint32_t earfcn) } } + // Reset measurements for the given CC after all workers finished processing and have been configured to ensure the + // measurements are not overwritten + common.reset_measurements(cc_idx); + // Change frequency only if the earfcn was modified if (earfcn_is_different) { double dl_freq = srsran_band_fd(earfcn) * 1e6; diff --git a/srsue/src/phy/phy_common.cc b/srsue/src/phy/phy_common.cc index 0b70dbddf..4803d5fce 100644 --- a/srsue/src/phy/phy_common.cc +++ b/srsue/src/phy/phy_common.cc @@ -611,8 +611,31 @@ void phy_common::update_cfo_measurement(uint32_t cc_idx, float cfo_hz) { std::unique_lock lock(meas_mutex); - // use SNR EMA coefficient for averaging - avg_cfo_hz[cc_idx] = SRSRAN_VEC_EMA(cfo_hz, avg_cfo_hz[cc_idx], args->snr_ema_coeff); + // Use SNR EMA coefficient for averaging + avg_cfo_hz[cc_idx] = SRSRAN_VEC_SAFE_EMA(cfo_hz, avg_cfo_hz[cc_idx], args->snr_ema_coeff); +} + +void phy_common::reset_measurements(uint32_t cc_idx) +{ + // If the CC index exceeds the maximum number of carriers, reset them all + if (cc_idx >= SRSRAN_MAX_CARRIERS) { + for (uint32_t cc = 0; cc < SRSRAN_MAX_CARRIERS; cc++) { + reset_measurements(cc); + } + } + + // Default all metrics to NAN to prevent providing invalid information on traces and other layers + std::unique_lock lock(meas_mutex); + pathloss[cc_idx] = NAN; + avg_rsrp[cc_idx] = NAN; + avg_rsrp_dbm[cc_idx] = NAN; + avg_rsrq_db[cc_idx] = NAN; + avg_rssi_dbm[cc_idx] = NAN; + avg_cfo_hz[cc_idx] = NAN; + avg_sinr_db[cc_idx] = NAN; + avg_snr_db[cc_idx] = NAN; + avg_noise[cc_idx] = NAN; + avg_rsrp_neigh[cc_idx] = NAN; } void phy_common::update_measurements(uint32_t cc_idx, @@ -644,7 +667,7 @@ void phy_common::update_measurements(uint32_t cc_idx, 30) : 0; if (std::isnormal(rssi_dbm)) { - avg_rssi_dbm[0] = SRSRAN_VEC_EMA(rssi_dbm, avg_rssi_dbm[0], args->snr_ema_coeff); + avg_rssi_dbm[0] = SRSRAN_VEC_SAFE_EMA(rssi_dbm, avg_rssi_dbm[0], args->snr_ema_coeff); } rx_gain_offset = get_radio()->get_rx_gain() + args->rx_gain_offset; @@ -658,21 +681,17 @@ void phy_common::update_measurements(uint32_t cc_idx, // Average RSRQ over DEFAULT_MEAS_PERIOD_MS then sent to RRC float rsrq_db = chest_res.rsrq_db; if (std::isnormal(rsrq_db)) { - if (!(sf_cfg_dl.tti % pcell_report_period) || !std::isnormal(avg_rsrq_db[cc_idx])) { - avg_rsrq_db[cc_idx] = rsrq_db; - } else { - avg_rsrq_db[cc_idx] = SRSRAN_VEC_CMA(rsrq_db, avg_rsrq_db[cc_idx], sf_cfg_dl.tti % pcell_report_period); + // Reset average RSRQ measurement + if (sf_cfg_dl.tti % pcell_report_period == 0) { + avg_rsrq_db[cc_idx] = NAN; } + avg_rsrq_db[cc_idx] = SRSRAN_VEC_SAFE_CMA(rsrq_db, avg_rsrq_db[cc_idx], sf_cfg_dl.tti % pcell_report_period); } // Average RSRP taken from CRS float rsrp_lin = chest_res.rsrp; if (std::isnormal(rsrp_lin)) { - if (!std::isnormal(avg_rsrp[cc_idx])) { - avg_rsrp[cc_idx] = rsrp_lin; - } else { - avg_rsrp[cc_idx] = SRSRAN_VEC_EMA(rsrp_lin, avg_rsrp[cc_idx], snr_ema_coeff); - } + avg_rsrp[cc_idx] = SRSRAN_VEC_SAFE_EMA(rsrp_lin, avg_rsrp[cc_idx], snr_ema_coeff); } /* Correct absolute power measurements by RX gain offset */ @@ -680,11 +699,11 @@ void phy_common::update_measurements(uint32_t cc_idx, // Serving cell RSRP measurements are averaged over DEFAULT_MEAS_PERIOD_MS then sent to RRC if (std::isnormal(rsrp_dbm)) { - if (!(sf_cfg_dl.tti % pcell_report_period) || !std::isnormal(avg_rsrp_dbm[cc_idx])) { - avg_rsrp_dbm[cc_idx] = rsrp_dbm; - } else { - avg_rsrp_dbm[cc_idx] = SRSRAN_VEC_CMA(rsrp_dbm, avg_rsrp_dbm[cc_idx], sf_cfg_dl.tti % pcell_report_period); + // Reset average RSRP measurement + if (sf_cfg_dl.tti % pcell_report_period == 0) { + avg_rsrp_dbm[cc_idx] = NAN; } + avg_rsrp_dbm[cc_idx] = SRSRAN_VEC_SAFE_CMA(rsrp_dbm, avg_rsrp_dbm[cc_idx], sf_cfg_dl.tti % pcell_report_period); } // Compute PL @@ -693,11 +712,7 @@ void phy_common::update_measurements(uint32_t cc_idx, // Average noise float cur_noise = chest_res.noise_estimate; if (std::isnormal(cur_noise)) { - if (!std::isnormal(avg_noise[cc_idx])) { - avg_noise[cc_idx] = cur_noise; - } else { - avg_noise[cc_idx] = SRSRAN_VEC_EMA(cur_noise, avg_noise[cc_idx], snr_ema_coeff); - } + avg_noise[cc_idx] = SRSRAN_VEC_SAFE_EMA(cur_noise, avg_noise[cc_idx], snr_ema_coeff); } // Calculate SINR using CRS from neighbours if are detected @@ -714,20 +729,12 @@ void phy_common::update_measurements(uint32_t cc_idx, // Average sinr in the log domain if (std::isnormal(sinr_db)) { - if (!std::isnormal(avg_sinr_db[cc_idx])) { - avg_sinr_db[cc_idx] = sinr_db; - } else { - avg_sinr_db[cc_idx] = SRSRAN_VEC_EMA(sinr_db, avg_sinr_db[cc_idx], snr_ema_coeff); - } + avg_sinr_db[cc_idx] = SRSRAN_VEC_SAFE_EMA(sinr_db, avg_sinr_db[cc_idx], snr_ema_coeff); } // Average snr in the log domain if (std::isnormal(chest_res.snr_db)) { - if (!std::isnormal(avg_snr_db[cc_idx])) { - avg_snr_db[cc_idx] = chest_res.snr_db; - } else { - avg_snr_db[cc_idx] = SRSRAN_VEC_EMA(chest_res.snr_db, avg_snr_db[cc_idx], snr_ema_coeff); - } + avg_snr_db[cc_idx] = SRSRAN_VEC_SAFE_EMA(chest_res.snr_db, avg_snr_db[cc_idx], snr_ema_coeff); } // Store metrics @@ -742,9 +749,9 @@ void phy_common::update_measurements(uint32_t cc_idx, set_ch_metrics(cc_idx, ch); - // 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)) { + // Prepare measurements for serving cells - skip if any measurement is invalid assuming pure zeros are not possible + if (std::isnormal(avg_rsrp_dbm[cc_idx]) and + std::isnormal(avg_cfo_hz[cc_idx] and ((sf_cfg_dl.tti % pcell_report_period) == pcell_report_period - 1))) { phy_meas_t meas = {}; meas.rsrp = avg_rsrp_dbm[cc_idx]; meas.rsrq = avg_rsrq_db[cc_idx]; @@ -866,25 +873,17 @@ void phy_common::reset() { reset_radio(); - sr_enabled = false; - cur_pathloss = 0; - cur_pusch_power = 0; - sr_last_tx_tti = -1; - pcell_report_period = 20; - last_ri = 0; + sr_enabled = false; + cur_pathloss = 0; + cur_pusch_power = 0; + sr_last_tx_tti = -1; + last_ri = 0; - { - std::unique_lock lock(meas_mutex); - ZERO_OBJECT(pathloss); - ZERO_OBJECT(avg_sinr_db); - ZERO_OBJECT(avg_snr_db); - ZERO_OBJECT(avg_rsrp); - ZERO_OBJECT(avg_rsrp_dbm); - ZERO_OBJECT(avg_rsrq_db); - } - cell_state.reset(); + // Reset all measurements + reset_measurements(SRSRAN_MAX_CARRIERS); - reset_neighbour_cells(); + // Reset all SCell states + cell_state.reset(); // Note: Using memset to reset these members is forbidden because they are real objects, not plain arrays. {