diff --git a/srsenb/hdr/stack/mac/nr/ue_nr.h b/srsenb/hdr/stack/mac/nr/ue_nr.h index 59ef98a15..4fc6259a8 100644 --- a/srsenb/hdr/stack/mac/nr/ue_nr.h +++ b/srsenb/hdr/stack/mac/nr/ue_nr.h @@ -62,6 +62,8 @@ public: void metrics_dl_cqi(const srsran_uci_cfg_nr_t& cfg_, uint32_t dl_cqi); void metrics_dl_mcs(uint32_t mcs); void metrics_ul_mcs(uint32_t mcs); + void metrics_pucch_sinr(float sinr); + void metrics_pusch_sinr(float sinr); void metrics_cnt(); uint32_t read_pdu(uint32_t lcid, uint8_t* payload, uint32_t requested_bytes) final; @@ -83,10 +85,14 @@ private: std::atomic active_state{true}; + // TO DO: some counters are kept as members of class ue_nr, while some others (i.e., mcs) are kept in the ue_metrics + // We should make these counters more uniform uint32_t phr_counter = 0; uint32_t dl_cqi_valid_counter = 0; uint32_t dl_ri_counter = 0; uint32_t dl_pmi_counter = 0; + uint32_t pucch_sinr_counter = 0; + uint32_t pusch_sinr_counter = 0; mac_ue_metrics_t ue_metrics = {}; // UE-specific buffer for MAC PDU packing, unpacking and handling diff --git a/srsenb/src/metrics_stdout.cc b/srsenb/src/metrics_stdout.cc index 0fe35cc1e..06d6e63c1 100644 --- a/srsenb/src/metrics_stdout.cc +++ b/srsenb/src/metrics_stdout.cc @@ -145,6 +145,12 @@ void metrics_stdout::set_metrics_helper(uint32_t num_ue } else { fmt::print(" {:>2}", 0); } + float ul_mcs = (is_nr) ? mac.ues[i].ul_mcs : phy[i].ul.mcs; + if (not isnan(ul_mcs)) { + fmt::print(" {:>2}", int(ul_mcs)); + } else { + fmt::print(" {:>2}", 0); + } if (mac.ues[i].rx_brate > 0) { fmt::print(" {:>6.6}", float_to_eng_string((float)mac.ues[i].rx_brate / (mac.ues[i].nof_tti * 1e-3), 1)); } else { diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index bd418cf53..5a49f1649 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -81,6 +81,8 @@ void mac_nr::stop() /// However, get_metrics is called infrequently enough to cause major halts in the L1/L2 void mac_nr::get_metrics(srsenb::mac_metrics_t& metrics) { + // TO DO: We should comment on the logic we follow to get the metrics. Some of them are retrieved from MAC, some + // others from the scheduler. get_metrics_nolock(metrics); sched.get_metrics(metrics); } @@ -165,9 +167,9 @@ void mac_nr::rach_detected(const rach_info_t& rach_info) uecfg.carriers[0].cc = 0; uecfg.ue_bearers[0].direction = mac_lc_ch_cfg_t::BOTH; srsran::phy_cfg_nr_default_t::reference_cfg_t ref_args{}; - ref_args.duplex = cell_config[0].duplex.mode == SRSRAN_DUPLEX_MODE_TDD - ? srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_TDD_CUSTOM_6_4 - : srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_FDD; + ref_args.duplex = cell_config[0].duplex.mode == SRSRAN_DUPLEX_MODE_TDD + ? srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_TDD_CUSTOM_6_4 + : srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_FDD; uecfg.phy_cfg = srsran::phy_cfg_nr_default_t{ref_args}; uecfg.phy_cfg.csi = {}; // disable CSI until RA is complete @@ -357,6 +359,14 @@ int mac_nr::pucch_info(const srsran_slot_cfg_t& slot_cfg, const mac_interface_ph logger.error("Error handling UCI data from PUCCH reception"); return SRSRAN_ERROR; } + + // process PUCCH SNR + uint16_t rnti = pucch_info.uci_data.cfg.pucch.rnti; + srsran::rwlock_read_guard rw_lock(rwmutex); + if (ue_db.contains(rnti)) { + ue_db[rnti]->metrics_pucch_sinr(pucch_info.csi.snr_dB); + } + return SRSRAN_SUCCESS; } @@ -419,6 +429,7 @@ int mac_nr::pusch_info(const srsran_slot_cfg_t& slot_cfg, mac_interface_phy_nr:: srsran::rwlock_read_guard rw_lock(rwmutex); if (ue_db.contains(rnti)) { ue_db[rnti]->metrics_rx(pusch_info.pusch_data.tb[0].crc, nof_bytes); + ue_db[rnti]->metrics_pusch_sinr(pusch_info.csi.snr_dB); } return SRSRAN_SUCCESS; } diff --git a/srsenb/src/stack/mac/nr/ue_nr.cc b/srsenb/src/stack/mac/nr/ue_nr.cc index 0e7a3779b..261b49d00 100644 --- a/srsenb/src/stack/mac/nr/ue_nr.cc +++ b/srsenb/src/stack/mac/nr/ue_nr.cc @@ -220,9 +220,12 @@ void ue_nr::metrics_read(mac_ue_metrics_t* metrics_) auto it = std::find(cc_list.begin(), cc_list.end(), 0); ue_metrics.cc_idx = std::distance(cc_list.begin(), it); + // printf("RNTI %u: reading and resetting metrics: \n", rnti); *metrics_ = ue_metrics; phr_counter = 0; dl_cqi_valid_counter = 0; + pucch_sinr_counter = 0; + pusch_sinr_counter = 0; ue_metrics = {}; } @@ -286,6 +289,26 @@ void ue_nr::metrics_cnt() ue_metrics.nof_tti++; } +void ue_nr::metrics_pucch_sinr(float sinr) +{ + std::lock_guard lock(metrics_mutex); + // discard nan or inf values for average SINR + if (!std::isinf(sinr) && !std::isnan(sinr)) { + ue_metrics.pucch_sinr = SRSRAN_VEC_SAFE_CMA((float)sinr, ue_metrics.pucch_sinr, pucch_sinr_counter); + pucch_sinr_counter++; + } +} + +void ue_nr::metrics_pusch_sinr(float sinr) +{ + std::lock_guard lock(metrics_mutex); + // discard nan or inf values for average SINR + if (!std::isinf(sinr) && !std::isnan(sinr)) { + ue_metrics.pusch_sinr = SRSRAN_VEC_SAFE_CMA((float)sinr, ue_metrics.pusch_sinr, pusch_sinr_counter); + pusch_sinr_counter++; + } +} + /** Converts the buffer size field of a BSR (5 or 8-bit Buffer Size field) into Bytes * @param buff_size_field The buffer size field contained in the MAC PDU * @param format The BSR format that determines the buffer size field length diff --git a/srsue/hdr/phy/phy_metrics.h b/srsue/hdr/phy/phy_metrics.h index 11233ceb9..7398117bf 100644 --- a/srsue/hdr/phy/phy_metrics.h +++ b/srsue/hdr/phy/phy_metrics.h @@ -79,7 +79,10 @@ struct ch_metrics_t { { count++; PHY_METRICS_SET(n); - PHY_METRICS_SET(sinr); + // We exclude inf and nan from the average SINR + if (!std::isnan(other.sinr) || !std::isinf(other.sinr)) { + PHY_METRICS_SET(sinr); + } PHY_METRICS_SET(rsrp); PHY_METRICS_SET(rsrq); PHY_METRICS_SET(rssi);