diff --git a/srsue/hdr/stack/mac_nr/dl_harq_nr.h b/srsue/hdr/stack/mac_nr/dl_harq_nr.h index 308834842..e0834264f 100644 --- a/srsue/hdr/stack/mac_nr/dl_harq_nr.h +++ b/srsue/hdr/stack/mac_nr/dl_harq_nr.h @@ -50,6 +50,14 @@ public: float get_average_retx(); + // DL HARQ metrics combined for all processes + struct dl_harq_metrics_t { + uint32_t rx_ok; + uint32_t rx_ko; + uint32_t rx_brate; + }; + dl_harq_metrics_t get_metrics(); + private: class dl_harq_process_nr { @@ -87,12 +95,9 @@ private: demux_interface_harq_nr* demux_unit = nullptr; srslog::basic_logger& logger; uint16_t last_temporal_crnti = SRSRAN_INVALID_RNTI; - - float average_retx = 0.0; - uint64_t nof_pkts = 0; - uint8_t cc_idx = 0; - - pthread_rwlock_t rwlock; + dl_harq_metrics_t metrics = {}; + uint8_t cc_idx = 0; + pthread_rwlock_t rwlock; }; typedef std::unique_ptr dl_harq_entity_nr_ptr; diff --git a/srsue/hdr/stack/mac_nr/ul_harq_nr.h b/srsue/hdr/stack/mac_nr/ul_harq_nr.h index bdb90f632..918e51eae 100644 --- a/srsue/hdr/stack/mac_nr/ul_harq_nr.h +++ b/srsue/hdr/stack/mac_nr/ul_harq_nr.h @@ -37,8 +37,15 @@ public: /***************** PHY->MAC interface for UL processes **************************/ void new_grant_ul(const mac_interface_phy_nr::mac_nr_grant_ul_t& grant, mac_interface_phy_nr::tb_action_ul_t* action); - int get_current_tbs(uint32_t pid); - float get_average_retx(); + int get_current_tbs(uint32_t pid); + + // HARQ specific metrics interface that is combined for all processees + struct ul_harq_metrics_t { + uint32_t tx_ok; + uint32_t tx_ko; + uint32_t tx_brate; + }; + ul_harq_metrics_t get_metrics(); private: class ul_harq_process_nr @@ -95,9 +102,7 @@ private: srslog::basic_logger& logger; srsran::ul_harq_cfg_t harq_cfg = {}; - - float average_retx = 0.0; - uint64_t nof_pkts = 0; + ul_harq_metrics_t metrics = {}; }; typedef std::unique_ptr ul_harq_entity_nr_ptr; diff --git a/srsue/src/stack/mac_nr/dl_harq_nr.cc b/srsue/src/stack/mac_nr/dl_harq_nr.cc index 14a99b9a6..eca971ad6 100644 --- a/srsue/src/stack/mac_nr/dl_harq_nr.cc +++ b/srsue/src/stack/mac_nr/dl_harq_nr.cc @@ -76,7 +76,7 @@ void dl_harq_entity_nr::new_grant_dl(const mac_nr_grant_dl_t& grant, mac_interfa // Set BCCH PID for SI RNTI proc_ptr = &bcch_proc; } else { - if (grant.pid >= cfg.nof_procs) { + if (harq_procs.at(grant.pid) == nullptr) { logger.error("Grant for invalid HARQ PID=%d", grant.pid); return; } @@ -104,7 +104,7 @@ void dl_harq_entity_nr::tb_decoded(const mac_nr_grant_dl_t& grant, mac_interface if (grant.rnti == SRSRAN_SIRNTI) { bcch_proc.tb_decoded(grant, std::move(result)); } else { - if (grant.pid >= cfg.nof_procs) { + if (harq_procs.at(grant.pid) == nullptr) { logger.error("Decoded TB for invalid HARQ PID=%d", grant.pid); return; } @@ -124,9 +124,11 @@ void dl_harq_entity_nr::reset() bcch_proc.reset(); } -float dl_harq_entity_nr::get_average_retx() +dl_harq_entity_nr::dl_harq_metrics_t dl_harq_entity_nr::get_metrics() { - return average_retx; + dl_harq_metrics_t tmp = metrics; + metrics = {}; + return tmp; } dl_harq_entity_nr::dl_harq_process_nr::dl_harq_process_nr(dl_harq_entity_nr* parent_) : @@ -194,6 +196,8 @@ void dl_harq_entity_nr::dl_harq_process_nr::new_grant_dl(const mac_nr_grant_dl_t is_first_tb = false; } else { // This is a retransmission + n_retx++; + if (not acked) { // If data has not yet been successfully decoded, instruct the PHY to combine the received data action->tb.enabled = true; @@ -203,8 +207,7 @@ void dl_harq_entity_nr::dl_harq_process_nr::new_grant_dl(const mac_nr_grant_dl_t } } - // increment counter and store grant - n_retx++; + // store grant current_grant = grant; } @@ -224,11 +227,13 @@ void dl_harq_entity_nr::dl_harq_process_nr::tb_decoded(const mac_nr_grant_dl_t& } else { logger.debug("Delivering PDU=%d bytes to Dissassemble and Demux unit", grant.tbs); harq_entity->demux_unit->push_pdu(std::move(result.payload), grant.tti); - - // Compute average number of retransmissions per packet - harq_entity->average_retx = SRSRAN_VEC_CMA((float)n_retx, harq_entity->average_retx, harq_entity->nof_pkts++); } } + + harq_entity->metrics.rx_ok++; + harq_entity->metrics.rx_brate += grant.tbs * 8; + } else { + harq_entity->metrics.rx_ko++; } logger.info("DL %d: %s tbs=%d, rv=%d, ack=%s, ndi=%d", diff --git a/srsue/src/stack/mac_nr/mac_nr.cc b/srsue/src/stack/mac_nr/mac_nr.cc index 6ca01ecb3..22c023906 100644 --- a/srsue/src/stack/mac_nr/mac_nr.cc +++ b/srsue/src/stack/mac_nr/mac_nr.cc @@ -307,13 +307,6 @@ void mac_nr::tb_decoded(const uint32_t cc_idx, const mac_nr_grant_dl_t& grant, t dl_harq.at(cc_idx)->tb_decoded(grant, std::move(result)); } - - // do metrics - metrics[cc_idx].rx_brate += grant.tbs * 8; - metrics[cc_idx].rx_pkts++; - if (not result.ack) { - metrics[cc_idx].rx_errors++; - } } void mac_nr::new_grant_ul(const uint32_t cc_idx, const mac_nr_grant_ul_t& grant, tb_action_ul_t* action) @@ -346,8 +339,6 @@ void mac_nr::new_grant_ul(const uint32_t cc_idx, const mac_nr_grant_ul_t& grant, } ul_harq.at(cc_idx)->new_grant_ul(grant, action); - metrics[cc_idx].tx_pkts++; - metrics[cc_idx].tx_brate += grant.tbs * 8; // store PCAP if (action->tb.enabled && pcap) { @@ -472,16 +463,32 @@ void mac_nr::get_metrics(mac_metrics_t m[SRSRAN_MAX_CARRIERS]) float dl_avg_ret = 0; int dl_avg_ret_count = 0; - for (const auto& cc : metrics) { - tx_pkts += cc.tx_pkts; - tx_errors += cc.tx_errors; - tx_brate += cc.tx_brate; - rx_pkts += cc.rx_pkts; - rx_errors += cc.rx_errors; - rx_brate += cc.rx_brate; - ul_buffer += cc.ul_buffer; + // Get metrics from HARQ entities explicitly + for (uint32_t i = 0; i < metrics.size(); ++i) { + if (dl_harq.at(i) != nullptr) { + dl_harq_entity_nr::dl_harq_metrics_t harq_metrics = dl_harq.at(i)->get_metrics(); + rx_pkts += (harq_metrics.rx_ok + harq_metrics.rx_ko); + rx_errors += harq_metrics.rx_ko; + rx_brate += harq_metrics.rx_brate; + } + if (ul_harq.at(i) != nullptr) { + ul_harq_entity_nr::ul_harq_metrics_t harq_metrics = ul_harq.at(i)->get_metrics(); + tx_pkts += (harq_metrics.tx_ok + harq_metrics.tx_ko); + tx_errors += harq_metrics.tx_ko; + tx_brate += harq_metrics.tx_brate; + } } + // assign accumulated metrics for PCELL carrier only + auto& pcell_cc = metrics[PCELL_CC_IDX]; + pcell_cc.tx_pkts = tx_pkts; + pcell_cc.tx_errors = tx_errors; + pcell_cc.tx_brate = tx_brate; + pcell_cc.rx_pkts = rx_pkts; + pcell_cc.rx_errors = rx_errors; + pcell_cc.rx_brate = rx_brate; + pcell_cc.ul_buffer = mac_buffer_states.get_total_buffer_size(); + memcpy(m, metrics.data(), sizeof(mac_metrics_t) * SRSRAN_MAX_CARRIERS); metrics = {}; } diff --git a/srsue/src/stack/mac_nr/ul_harq_nr.cc b/srsue/src/stack/mac_nr/ul_harq_nr.cc index fd3f090bb..1ba09a2f3 100644 --- a/srsue/src/stack/mac_nr/ul_harq_nr.cc +++ b/srsue/src/stack/mac_nr/ul_harq_nr.cc @@ -89,7 +89,6 @@ void ul_harq_entity_nr::new_grant_ul(const mac_interface_phy_nr::mac_nr_grant_ul logger.warning("Ignoring grant for CS-RNTI=0x%x", grant.rnti); } else { logger.warning("Received grant for unknown rnti=0x%x", grant.rnti); - printf("Received grant for unknown rnti=0x%x\n", grant.rnti); } srsran_expect(action->tb.enabled ? action->tb.payload != nullptr : true, @@ -105,9 +104,11 @@ int ul_harq_entity_nr::get_current_tbs(uint32_t pid) return harq_procs.at(pid).get_current_tbs(); } -float ul_harq_entity_nr::get_average_retx() +ul_harq_entity_nr::ul_harq_metrics_t ul_harq_entity_nr::get_metrics() { - return average_retx; + ul_harq_entity_nr::ul_harq_metrics_t tmp = metrics; + metrics = {}; + return tmp; } ul_harq_entity_nr::ul_harq_process_nr::ul_harq_process_nr() : logger(srslog::fetch_basic_logger("MAC")) {} @@ -226,10 +227,8 @@ int ul_harq_entity_nr::ul_harq_process_nr::get_current_tbs() void ul_harq_entity_nr::ul_harq_process_nr::generate_new_tx(const mac_interface_phy_nr::mac_nr_grant_ul_t& grant, mac_interface_phy_nr::tb_action_ul_t* action) { - // Compute average number of retransmissions per packet considering previous packet - harq_entity->average_retx = SRSRAN_VEC_CMA((float)nof_retx, harq_entity->average_retx, harq_entity->nof_pkts++); - current_grant = grant; - nof_retx = 0; + current_grant = grant; + nof_retx = 0; logger.info("UL %d: New TX%s, rv=%d, tbs=%d", pid, @@ -238,6 +237,8 @@ void ul_harq_entity_nr::ul_harq_process_nr::generate_new_tx(const mac_interface_ grant.tbs); generate_tx(action); + + harq_entity->metrics.tx_ok++; } // Retransmission (Section 5.4.2.2) @@ -250,12 +251,16 @@ void ul_harq_entity_nr::ul_harq_process_nr::generate_retx(const mac_interface_ph current_grant = grant; generate_tx(action); + + // increment Tx error count + harq_entity->metrics.tx_ko++; } // Transmission of pending frame (Section 5.4.2.2) void ul_harq_entity_nr::ul_harq_process_nr::generate_tx(mac_interface_phy_nr::tb_action_ul_t* action) { nof_retx++; + harq_entity->metrics.tx_brate += current_grant.tbs * 8; action->tb.rv = current_grant.rv; action->tb.enabled = true;