mirror of https://github.com/PentHertz/srsLTE.git
srsenb,metrics: add PUSCH/PUCCH RSSI metrics. Add bearer DL total data metric for RLC UM
This commit is contained in:
parent
9a0d7113bc
commit
cf647b1fd5
|
@ -75,6 +75,7 @@ typedef struct SRSRAN_API {
|
|||
srsran_uci_value_t uci_data;
|
||||
float dmrs_correlation;
|
||||
float snr_db;
|
||||
float rsrp_db;
|
||||
float correlation;
|
||||
bool detected;
|
||||
|
||||
|
|
|
@ -61,6 +61,15 @@ extern "C" {
|
|||
// Proportional moving average
|
||||
#define SRSRAN_VEC_PMA(average1, n1, average2, n2) (((average1) * (n1) + (average2) * (n2)) / ((n1) + (n2)))
|
||||
|
||||
// Safe Proportional moving average
|
||||
#ifdef __cplusplus
|
||||
#define SRSRAN_VEC_SAFE_PMA(average1, n1, average2, n2) \
|
||||
(std::isnormal((n1) + (n2)) ? SRSRAN_VEC_PMA(average1, n1, average2, n2) : (0))
|
||||
#else
|
||||
#define SRSRAN_VEC_SAFE_PMA(average1, n1, average2, n2) \
|
||||
(isnormal((n1) + (n2)) ? SRSRAN_VEC_PMA(average1, n1, average2, n2) : (0))
|
||||
#endif
|
||||
|
||||
// Exponential moving average
|
||||
#define SRSRAN_VEC_EMA(data, average, alpha) ((alpha) * (data) + (1 - alpha) * (average))
|
||||
|
||||
|
|
|
@ -221,6 +221,10 @@ void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu, int upper_sn)
|
|||
// Pass PDU to lower layers
|
||||
metrics.num_tx_pdus++;
|
||||
metrics.num_tx_pdu_bytes += sdu->N_bytes;
|
||||
// Count TX'd bytes as if they were ACK'd if RLC is UM
|
||||
if (rlc->rb_is_um(lcid)) {
|
||||
metrics.num_tx_acked_bytes = metrics.num_tx_pdu_bytes;
|
||||
}
|
||||
rlc->write_sdu(lcid, std::move(sdu));
|
||||
}
|
||||
|
||||
|
|
|
@ -347,13 +347,16 @@ static void chest_ul_estimate(srsran_chest_ul_t* q,
|
|||
}
|
||||
|
||||
// Estimate received pilot power
|
||||
float signal_power = srsran_vec_avg_power_cf(q->pilot_recv_signal, nslots * nrefs_sym);
|
||||
if (isnormal(res->noise_estimate)) {
|
||||
res->snr = srsran_vec_avg_power_cf(q->pilot_recv_signal, nslots * nrefs_sym) / res->noise_estimate;
|
||||
res->snr = signal_power / res->noise_estimate;
|
||||
} else {
|
||||
res->snr = NAN;
|
||||
}
|
||||
|
||||
// Convert measurements in logarithm scale
|
||||
res->rsrp = signal_power;
|
||||
res->rsrp_dBfs = srsran_convert_power_to_dB(signal_power);
|
||||
res->snr_db = srsran_convert_power_to_dB(res->snr);
|
||||
res->noise_estimate_dbm = srsran_convert_power_to_dBm(res->noise_estimate);
|
||||
}
|
||||
|
|
|
@ -185,6 +185,7 @@ static int get_pucch(srsran_enb_ul_t* q, srsran_ul_sf_cfg_t* ul_sf, srsran_pucch
|
|||
return SRSRAN_ERROR;
|
||||
}
|
||||
pucch_res.snr_db = q->chest_res.snr_db;
|
||||
pucch_res.rsrp_db = q->chest_res.rsrp_dBfs;
|
||||
|
||||
ret = srsran_pucch_decode(&q->pucch, ul_sf, cfg, &q->chest_res, q->sf_symbols, &pucch_res);
|
||||
if (ret < SRSRAN_SUCCESS) {
|
||||
|
|
|
@ -387,7 +387,7 @@ nr_pdsch_mcs=28
|
|||
# rlf_release_timer_ms: Time taken by eNB to release UE context after it detects a RLF
|
||||
# rlf_min_ul_snr_estim: SNR threshold in dB below which the enb is notified with RLF ko
|
||||
# s1_setup_max_retries: Maximum amount of retries to setup the S1AP connection. If this value is exceeded, an alarm is written to the log. -1 means infinity.
|
||||
#
|
||||
# rx_gain_offset: RX Gain offset to add to rx_gain to calibrate RSRP readings
|
||||
#####################################################################
|
||||
[expert]
|
||||
#pusch_max_its = 8 # These are half iterations
|
||||
|
@ -423,3 +423,4 @@ nr_pdsch_mcs=28
|
|||
#rlf_release_timer_ms = 4000
|
||||
#rlf_min_ul_snr_estim = -2
|
||||
#s1_setup_max_retries = -1
|
||||
#rx_gain_offset = 62
|
||||
|
|
|
@ -100,7 +100,7 @@ private:
|
|||
void metrics_read(phy_metrics_t* metrics);
|
||||
void metrics_dl(uint32_t mcs);
|
||||
void metrics_ul(uint32_t mcs, float rssi, float sinr, float turbo_iters);
|
||||
void metrics_ul_pucch(float sinr);
|
||||
void metrics_ul_pucch(float rssi, float sinr);
|
||||
uint32_t get_rnti() const { return rnti; }
|
||||
|
||||
private:
|
||||
|
|
|
@ -50,6 +50,7 @@ struct phy_args_t {
|
|||
std::string type;
|
||||
srsran::phy_log_args_t log;
|
||||
|
||||
float rx_gain_offset = 62;
|
||||
float max_prach_offset_us = 10;
|
||||
uint32_t pusch_max_its = 10;
|
||||
uint32_t nr_pusch_max_its = 10;
|
||||
|
|
|
@ -22,16 +22,11 @@ namespace srsenb {
|
|||
struct ul_metrics_t {
|
||||
float n;
|
||||
float pusch_sinr;
|
||||
// Initialize this member with an invalid value as this field is optional.
|
||||
float pusch_rssi = std::numeric_limits<float>::quiet_NaN();
|
||||
// Initialize this member with an invalid value as this field is optional.
|
||||
int64_t pusch_tpc = 0;
|
||||
float pusch_rssi;
|
||||
int64_t pusch_tpc;
|
||||
float pucch_sinr;
|
||||
// Initialize this member with an invalid value as this field is optional.
|
||||
float pucch_rssi = std::numeric_limits<float>::quiet_NaN();
|
||||
// Initialize this member with an invalid value as this field is optional.
|
||||
float pucch_ni = std::numeric_limits<float>::quiet_NaN();
|
||||
float rssi;
|
||||
float pucch_rssi;
|
||||
float pucch_ni;
|
||||
float turbo_iters;
|
||||
float mcs;
|
||||
int n_samples;
|
||||
|
@ -40,8 +35,7 @@ struct ul_metrics_t {
|
|||
|
||||
struct dl_metrics_t {
|
||||
float mcs;
|
||||
// Initialize this member with an invalid value as this field is optional.
|
||||
int64_t pucch_tpc = 0;
|
||||
int64_t pucch_tpc;
|
||||
int n_samples;
|
||||
};
|
||||
|
||||
|
|
|
@ -259,6 +259,7 @@ void parse_args(all_args_t* args, int argc, char* argv[])
|
|||
("expert.ts1_reloc_overall_timeout", bpo::value<uint32_t>(&args->stack.s1ap.ts1_reloc_overall_timeout)->default_value(10000), "S1AP TS 36.413 TS1RelocOverall Expiry Timeout value in milliseconds.")
|
||||
("expert.rlf_min_ul_snr_estim", bpo::value<int>(&args->stack.mac.rlf_min_ul_snr_estim)->default_value(-2), "SNR threshold in dB below which the eNB is notified with rlf ko.")
|
||||
("expert.max_s1_setup_retries", bpo::value<int32_t>(&args->stack.s1ap.max_s1_setup_retries)->default_value(-1), "Max S1 setup retries")
|
||||
("expert.rx_gain_offset", bpo::value<float>(&args->phy.rx_gain_offset)->default_value(62), "RX Gain offset to add to rx_gain to calibrate RSRP readings")
|
||||
|
||||
// eMBMS section
|
||||
("embms.enable", bpo::value<bool>(&args->stack.embms.enable)->default_value(false), "Enables MBMS in the eNB")
|
||||
|
|
|
@ -363,7 +363,10 @@ bool cc_worker::decode_pusch_rnti(stack_interface_phy_lte::ul_sched_grant_t& ul_
|
|||
// Save statistics only if data was provided
|
||||
if (ul_grant.data != nullptr) {
|
||||
// Save metrics stats
|
||||
ue_db[rnti]->metrics_ul(ul_grant.dci.tb.mcs_idx, 0, enb_ul.chest_res.snr_db, pusch_res.avg_iterations_block);
|
||||
ue_db[rnti]->metrics_ul(ul_grant.dci.tb.mcs_idx,
|
||||
enb_ul.chest_res.rsrp_dBfs - phy->params.rx_gain_offset,
|
||||
enb_ul.chest_res.snr_db,
|
||||
pusch_res.avg_iterations_block);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -451,7 +454,9 @@ int cc_worker::decode_pucch()
|
|||
}
|
||||
|
||||
// Save metrics
|
||||
ue_db[rnti]->metrics_ul_pucch(pucch_res.snr_db);
|
||||
if (pucch_res.detected) {
|
||||
ue_db[rnti]->metrics_ul_pucch(pucch_res.rsrp_db - phy->params.rx_gain_offset, pucch_res.snr_db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -666,15 +671,22 @@ void cc_worker::ue::metrics_dl(uint32_t mcs)
|
|||
|
||||
void cc_worker::ue::metrics_ul(uint32_t mcs, float rssi, float sinr, float turbo_iters)
|
||||
{
|
||||
if (isnan(rssi)) {
|
||||
rssi = 0;
|
||||
}
|
||||
metrics.ul.mcs = SRSRAN_VEC_CMA((float)mcs, metrics.ul.mcs, metrics.ul.n_samples);
|
||||
metrics.ul.pusch_sinr = SRSRAN_VEC_CMA((float)sinr, metrics.ul.pusch_sinr, metrics.ul.n_samples);
|
||||
metrics.ul.rssi = SRSRAN_VEC_CMA((float)rssi, metrics.ul.rssi, metrics.ul.n_samples);
|
||||
metrics.ul.pusch_rssi = SRSRAN_VEC_CMA((float)rssi, metrics.ul.pusch_rssi, metrics.ul.n_samples);
|
||||
metrics.ul.turbo_iters = SRSRAN_VEC_CMA((float)turbo_iters, metrics.ul.turbo_iters, metrics.ul.n_samples);
|
||||
metrics.ul.n_samples++;
|
||||
}
|
||||
|
||||
void cc_worker::ue::metrics_ul_pucch(float sinr)
|
||||
void cc_worker::ue::metrics_ul_pucch(float rssi, float sinr)
|
||||
{
|
||||
if (isnan(rssi)) {
|
||||
rssi = 0;
|
||||
}
|
||||
metrics.ul.pucch_rssi = SRSRAN_VEC_CMA((float)rssi, metrics.ul.pucch_rssi, metrics.ul.n_samples_pucch);
|
||||
metrics.ul.pucch_sinr = SRSRAN_VEC_CMA((float)sinr, metrics.ul.pucch_sinr, metrics.ul.n_samples_pucch);
|
||||
metrics.ul.n_samples_pucch++;
|
||||
}
|
||||
|
|
|
@ -268,15 +268,17 @@ uint32_t sf_worker::get_metrics(std::vector<phy_metrics_t>& metrics)
|
|||
for (uint32_t r = 0; r < cnt; r++) {
|
||||
phy_metrics_t* m = &metrics[r];
|
||||
phy_metrics_t* m_ = &metrics_[r];
|
||||
m->dl.mcs = SRSRAN_VEC_PMA(m->dl.mcs, m->dl.n_samples, m_->dl.mcs, m_->dl.n_samples);
|
||||
m->dl.mcs = SRSRAN_VEC_SAFE_PMA(m->dl.mcs, m->dl.n_samples, m_->dl.mcs, m_->dl.n_samples);
|
||||
m->dl.n_samples += m_->dl.n_samples;
|
||||
m->ul.n = SRSRAN_VEC_PMA(m->ul.n, m->ul.n_samples, m_->ul.n, m_->ul.n_samples);
|
||||
m->ul.pusch_sinr = SRSRAN_VEC_PMA(m->ul.pusch_sinr, m->ul.n_samples, m_->ul.pusch_sinr, m_->ul.n_samples);
|
||||
m->ul.n = SRSRAN_VEC_SAFE_PMA(m->ul.n, m->ul.n_samples, m_->ul.n, m_->ul.n_samples);
|
||||
m->ul.pusch_sinr = SRSRAN_VEC_SAFE_PMA(m->ul.pusch_sinr, m->ul.n_samples, m_->ul.pusch_sinr, m_->ul.n_samples);
|
||||
m->ul.pucch_sinr =
|
||||
SRSRAN_VEC_PMA(m->ul.pucch_sinr, m->ul.n_samples_pucch, m_->ul.pucch_sinr, m_->ul.n_samples_pucch);
|
||||
m->ul.mcs = SRSRAN_VEC_PMA(m->ul.mcs, m->ul.n_samples, m_->ul.mcs, m_->ul.n_samples);
|
||||
m->ul.rssi = SRSRAN_VEC_PMA(m->ul.rssi, m->ul.n_samples, m_->ul.rssi, m_->ul.n_samples);
|
||||
m->ul.turbo_iters = SRSRAN_VEC_PMA(m->ul.turbo_iters, m->ul.n_samples, m_->ul.turbo_iters, m_->ul.n_samples);
|
||||
SRSRAN_VEC_SAFE_PMA(m->ul.pucch_sinr, m->ul.n_samples_pucch, m_->ul.pucch_sinr, m_->ul.n_samples_pucch);
|
||||
m->ul.mcs = SRSRAN_VEC_SAFE_PMA(m->ul.mcs, m->ul.n_samples, m_->ul.mcs, m_->ul.n_samples);
|
||||
m->ul.pusch_rssi = SRSRAN_VEC_SAFE_PMA(m->ul.pusch_rssi, m->ul.n_samples, m_->ul.pusch_rssi, m_->ul.n_samples);
|
||||
m->ul.pucch_rssi =
|
||||
SRSRAN_VEC_SAFE_PMA(m->ul.pucch_rssi, m->ul.n_samples_pucch, m_->ul.pucch_rssi, m_->ul.n_samples_pucch);
|
||||
m->ul.turbo_iters = SRSRAN_VEC_SAFE_PMA(m->ul.turbo_iters, m->ul.n_samples, m_->ul.turbo_iters, m_->ul.n_samples);
|
||||
m->ul.n_samples += m_->ul.n_samples;
|
||||
m->ul.n_samples_pucch += m_->ul.n_samples_pucch;
|
||||
}
|
||||
|
|
|
@ -252,22 +252,28 @@ void phy::get_metrics(std::vector<phy_metrics_t>& metrics)
|
|||
metrics[j].ul.n_samples_pucch += metrics_tmp[j].ul.n_samples_pucch;
|
||||
metrics[j].ul.mcs += metrics_tmp[j].ul.n_samples * metrics_tmp[j].ul.mcs;
|
||||
metrics[j].ul.n += metrics_tmp[j].ul.n_samples * metrics_tmp[j].ul.n;
|
||||
metrics[j].ul.rssi += metrics_tmp[j].ul.n_samples * metrics_tmp[j].ul.rssi;
|
||||
metrics[j].ul.pusch_rssi += metrics_tmp[j].ul.n_samples * metrics_tmp[j].ul.pusch_rssi;
|
||||
metrics[j].ul.pusch_sinr += metrics_tmp[j].ul.n_samples * metrics_tmp[j].ul.pusch_sinr;
|
||||
metrics[j].ul.pucch_rssi += metrics_tmp[j].ul.n_samples_pucch * metrics_tmp[j].ul.pucch_rssi;
|
||||
metrics[j].ul.pucch_sinr += metrics_tmp[j].ul.n_samples_pucch * metrics_tmp[j].ul.pucch_sinr;
|
||||
metrics[j].ul.turbo_iters += metrics_tmp[j].ul.n_samples * metrics_tmp[j].ul.turbo_iters;
|
||||
}
|
||||
}
|
||||
for (uint32_t j = 0; j < metrics.size(); j++) {
|
||||
if (metrics[j].dl.n_samples > 0) {
|
||||
metrics[j].dl.mcs /= metrics[j].dl.n_samples;
|
||||
}
|
||||
if (metrics[j].ul.n_samples > 0) {
|
||||
metrics[j].ul.mcs /= metrics[j].ul.n_samples;
|
||||
metrics[j].ul.n /= metrics[j].ul.n_samples;
|
||||
metrics[j].ul.rssi /= metrics[j].ul.n_samples;
|
||||
metrics[j].ul.pusch_rssi /= metrics[j].ul.n_samples;
|
||||
metrics[j].ul.pusch_sinr /= metrics[j].ul.n_samples;
|
||||
metrics[j].ul.pucch_rssi /= metrics[j].ul.n_samples_pucch;
|
||||
metrics[j].ul.pucch_sinr /= metrics[j].ul.n_samples_pucch;
|
||||
metrics[j].ul.turbo_iters /= metrics[j].ul.n_samples;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void phy::cmd_cell_gain(uint32_t cell_id, float gain_db)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue