From 72ebce4297d57ba9c350b8d45315bf6f7257acb4 Mon Sep 17 00:00:00 2001 From: Balint Cristian Date: Tue, 4 May 2021 00:18:21 +0300 Subject: [PATCH] Add downlink PAPR measurement to eNB. --- .../srsran/interfaces/enb_command_interface.h | 4 ++ srsenb/hdr/enb.h | 1 + srsenb/hdr/phy/enb_phy_base.h | 2 + srsenb/hdr/phy/phy.h | 2 + srsenb/hdr/phy/phy_common.h | 41 +++++++++++++++++++ srsenb/hdr/phy/phy_interfaces.h | 2 + srsenb/hdr/phy/vnf_phy_nr.h | 5 +++ srsenb/src/enb.cc | 5 +++ srsenb/src/main.cc | 5 +++ srsenb/src/phy/lte/cc_worker.cc | 19 +++++++++ srsenb/src/phy/phy.cc | 5 +++ 11 files changed, 91 insertions(+) diff --git a/lib/include/srsran/interfaces/enb_command_interface.h b/lib/include/srsran/interfaces/enb_command_interface.h index bbc581baa8..ce6ed10f53 100644 --- a/lib/include/srsran/interfaces/enb_command_interface.h +++ b/lib/include/srsran/interfaces/enb_command_interface.h @@ -28,6 +28,10 @@ namespace srsenb { class enb_command_interface { public: + /** + * Trigger downlink singnal measurements. + */ + virtual void cmd_cell_measure() = 0; /** * Sets the relative gain of a cell from it's index (following rr.conf) order. * @param cell_id Provides a cell identifier diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index 802922990e..9c7f8a2631 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -142,6 +142,7 @@ class enb : public enb_metrics_interface, enb_command_interface bool get_metrics(enb_metrics_t* m) override; // eNodeB command interface + void cmd_cell_measure() override; void cmd_cell_gain(uint32_t cell_id, float gain) override; private: diff --git a/srsenb/hdr/phy/enb_phy_base.h b/srsenb/hdr/phy/enb_phy_base.h index 767dfde0bf..e19c4394a0 100644 --- a/srsenb/hdr/phy/enb_phy_base.h +++ b/srsenb/hdr/phy/enb_phy_base.h @@ -46,6 +46,8 @@ class enb_phy_base virtual void get_metrics(std::vector& m) = 0; + virtual void cmd_cell_measure() = 0; + virtual void cmd_cell_gain(uint32_t cell_idx, float gain_db) = 0; }; diff --git a/srsenb/hdr/phy/phy.h b/srsenb/hdr/phy/phy.h index 35d21a45b4..db88bdcfa1 100644 --- a/srsenb/hdr/phy/phy.h +++ b/srsenb/hdr/phy/phy.h @@ -63,6 +63,8 @@ class phy final : public enb_phy_base, public phy_interface_stack_lte, public sr void get_metrics(std::vector& metrics) override; + void cmd_cell_measure() override; + void cmd_cell_gain(uint32_t cell_id, float gain_db) override; void radio_overflow() override{}; diff --git a/srsenb/hdr/phy/phy_common.h b/srsenb/hdr/phy/phy_common.h index 8b0ae1d049..bb384ac2aa 100644 --- a/srsenb/hdr/phy/phy_common.h +++ b/srsenb/hdr/phy/phy_common.h @@ -170,6 +170,19 @@ class phy_common return c; }; + void set_cell_measure_trigger() + { + // Trigger on LTE cell + for (auto it_lte = cell_list_lte.begin(); it_lte != cell_list_lte.end(); ++it_lte) { + it_lte->dl_measure = true; + } + + // Trigger on NR cell + for (auto it_nr = cell_list_nr.begin(); it_nr != cell_list_nr.end(); ++it_nr) { + it_nr->dl_measure = true; + } + } + void set_cell_gain(uint32_t cell_id, float gain_db) { // Find LTE cell @@ -195,6 +208,20 @@ class phy_common srsran::console("cell ID %d not found\n", cell_id); } + bool get_cell_measure_trigger(uint32_t cc_idx) + { + if (cc_idx < cell_list_lte.size()) { + return cell_list_lte.at(cc_idx).dl_measure; + } + + cc_idx -= cell_list_lte.size(); + if (cc_idx < cell_list_nr.size()) { + return cell_list_nr.at(cc_idx).dl_measure; + } + + return false; + } + float get_cell_gain(uint32_t cc_idx) { if (cc_idx < cell_list_lte.size()) { @@ -209,6 +236,20 @@ class phy_common return 0.0f; } + void clear_cell_measure_trigger(uint32_t cc_idx) + { + if (cc_idx < cell_list_lte.size()) { + cell_list_lte.at(cc_idx).dl_measure = false; + } + + cc_idx -= cell_list_lte.size(); + if (cc_idx < cell_list_nr.size()) { + cell_list_nr.at(cc_idx).dl_measure = false; + } + + return; + } + // Common Physical Uplink DMRS configuration srsran_refsignal_dmrs_pusch_cfg_t dmrs_pusch_cfg = {}; diff --git a/srsenb/hdr/phy/phy_interfaces.h b/srsenb/hdr/phy/phy_interfaces.h index 9d7d252281..da192fc772 100644 --- a/srsenb/hdr/phy/phy_interfaces.h +++ b/srsenb/hdr/phy/phy_interfaces.h @@ -40,6 +40,7 @@ struct phy_cell_cfg_t { uint32_t root_seq_idx; uint32_t num_ra_preambles; float gain_db; + bool dl_measure; }; struct phy_cell_cfg_nr_t { @@ -51,6 +52,7 @@ struct phy_cell_cfg_nr_t { uint32_t root_seq_idx; uint32_t num_ra_preambles; float gain_db; + bool dl_measure; }; typedef std::vector phy_cell_cfg_list_t; diff --git a/srsenb/hdr/phy/vnf_phy_nr.h b/srsenb/hdr/phy/vnf_phy_nr.h index a4895fe36d..29cb49aa78 100644 --- a/srsenb/hdr/phy/vnf_phy_nr.h +++ b/srsenb/hdr/phy/vnf_phy_nr.h @@ -54,6 +54,11 @@ class vnf_phy_nr : public srsenb::enb_phy_base, public srsenb::phy_interface_sta int dl_config_request(const dl_config_request_t& request) override; int tx_request(const tx_request_t& request) override; + void cmd_cell_measure() override + { + // Do nothing + } + void cmd_cell_gain(uint32_t cell_idx, float gain_db) override { // Do nothing diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index bff489806f..fb09b62462 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -216,6 +216,11 @@ void enb::cmd_cell_gain(uint32_t cell_id, float gain) phy->cmd_cell_gain(cell_id, gain); } +void enb::cmd_cell_measure() +{ + phy->cmd_cell_measure(); +} + std::string enb::get_build_mode() { return std::string(srsran_get_build_mode()); diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index f2c77a9b23..3e5d6d3bc3 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -439,6 +439,7 @@ static void* input_loop(metrics_stdout* metrics, srsenb::enb_command_interface* { struct pollfd pfd = {STDIN_FILENO, POLLIN, 0}; string input_line; + while (running) { int ret = poll(&pfd, 1, 1000); // query stdin with a timeout of 1000ms if (ret == 1) { @@ -458,6 +459,9 @@ static void* input_loop(metrics_stdout* metrics, srsenb::enb_command_interface* cout << "Enter t to restart trace." << endl; } metrics->toggle_print(do_metrics); + } else if (cmd[0] == "m") { + // Trigger cell measurements + control->cmd_cell_measure(); } else if (cmd[0] == "q") { raise(SIGTERM); } else if (cmd[0] == "cell_gain") { @@ -475,6 +479,7 @@ static void* input_loop(metrics_stdout* metrics, srsenb::enb_command_interface* } else { cout << "Available commands: " << endl; cout << " t: starts console trace" << endl; + cout << " m: downlink signal measurements" << endl; cout << " q: quit srsenb" << endl; cout << " cell_gain: set relative cell gain" << endl; cout << endl; diff --git a/srsenb/src/phy/lte/cc_worker.cc b/srsenb/src/phy/lte/cc_worker.cc index 2f1ef9defa..798dc42d14 100644 --- a/srsenb/src/phy/lte/cc_worker.cc +++ b/srsenb/src/phy/lte/cc_worker.cc @@ -18,6 +18,7 @@ * and at http://www.gnu.org/licenses/. * */ +#include #include "srsran/common/threads.h" #include "srsran/srsran.h" @@ -262,6 +263,24 @@ void cc_worker::work_dl(const srsran_dl_sf_cfg_t& dl_sf_cfg, srsran_vec_sc_prod_cfc(signal_buffer_tx[i], scale, signal_buffer_tx[i], sf_len); } } + + // Measure if flag was triggered + bool cell_meas_flag = phy->get_cell_measure_trigger(cc_idx); + if (cell_meas_flag == true) { + uint32_t sf_len = SRSRAN_SF_LEN_PRB(enb_dl.cell.nof_prb); + for (uint32_t i = 0; i < enb_dl.cell.nof_ports; i++) { + // PAPR measure + std::vector sigSq(sf_len); + srsran_vec_abs_square_cf(signal_buffer_tx[i], sigSq.data(), sf_len); + float sigPMax = sigSq[srsran_vec_max_abs_fi(sigSq.data(), sf_len)]; + float sigPMean = srsran_vec_acc_ff(sigSq.data(), sf_len) / float(sf_len); + float PAPRdB = 10.0f * log10(sigPMax / sigPMean); + std::cout << "Cell #" << cc_idx << " port #" << i << " PAPR = " << std::setprecision(4) << PAPRdB << " dB " + << std::endl; + } + // clear measurement flag on cell + phy->clear_cell_measure_trigger(cc_idx); + } } void cc_worker::decode_pusch_rnti(stack_interface_phy_lte::ul_sched_grant_t& ul_grant, diff --git a/srsenb/src/phy/phy.cc b/srsenb/src/phy/phy.cc index 4a825b554a..42f41050ec 100644 --- a/srsenb/src/phy/phy.cc +++ b/srsenb/src/phy/phy.cc @@ -243,6 +243,11 @@ void phy::cmd_cell_gain(uint32_t cell_id, float gain_db) workers_common.set_cell_gain(cell_id, gain_db); } +void phy::cmd_cell_measure() +{ + workers_common.set_cell_measure_trigger(); +} + /***** RRC->PHY interface **********/ void phy::set_config(uint16_t rnti, const phy_rrc_cfg_list_t& phy_cfg_list)