|
|
@ -48,7 +48,6 @@ static bool csi_report_trigger(const srsran_csi_hl_report_cfg_t* cfg, uint32_t s
|
|
|
|
static void csi_wideband_cri_ri_pmi_cqi_quantify(const srsran_csi_hl_report_cfg_t* cfg,
|
|
|
|
static void csi_wideband_cri_ri_pmi_cqi_quantify(const srsran_csi_hl_report_cfg_t* cfg,
|
|
|
|
const srsran_csi_channel_measurements_t* channel_meas,
|
|
|
|
const srsran_csi_channel_measurements_t* channel_meas,
|
|
|
|
const srsran_csi_channel_measurements_t* interf_meas,
|
|
|
|
const srsran_csi_channel_measurements_t* interf_meas,
|
|
|
|
srsran_csi_report_cfg_t* report_cfg,
|
|
|
|
|
|
|
|
srsran_csi_report_value_t* report_value)
|
|
|
|
srsran_csi_report_value_t* report_value)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Take SNR by default
|
|
|
|
// Take SNR by default
|
|
|
@ -59,18 +58,6 @@ static void csi_wideband_cri_ri_pmi_cqi_quantify(const srsran_csi_hl_report_cfg_
|
|
|
|
wideband_sinr_db = channel_meas->wideband_rsrp_dBm - interf_meas->wideband_epre_dBm;
|
|
|
|
wideband_sinr_db = channel_meas->wideband_rsrp_dBm - interf_meas->wideband_epre_dBm;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Fill report configuration
|
|
|
|
|
|
|
|
report_cfg->type = cfg->type;
|
|
|
|
|
|
|
|
report_cfg->quantity = SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI;
|
|
|
|
|
|
|
|
report_cfg->freq_cfg = SRSRAN_CSI_REPORT_FREQ_WIDEBAND;
|
|
|
|
|
|
|
|
report_cfg->nof_ports = channel_meas->nof_ports;
|
|
|
|
|
|
|
|
report_cfg->K_csi_rs = channel_meas->K_csi_rs;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Save PUCCH resource only if periodic type
|
|
|
|
|
|
|
|
if (cfg->type == SRSRAN_CSI_REPORT_TYPE_PERIODIC) {
|
|
|
|
|
|
|
|
report_cfg->pucch_resource = cfg->periodic.resource;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Fill quantified values
|
|
|
|
// Fill quantified values
|
|
|
|
report_value->wideband_cri_ri_pmi_cqi.cqi = csi_snri_db_to_cqi(cfg->cqi_table, wideband_sinr_db);
|
|
|
|
report_value->wideband_cri_ri_pmi_cqi.cqi = csi_snri_db_to_cqi(cfg->cqi_table, wideband_sinr_db);
|
|
|
|
report_value->wideband_cri_ri_pmi_cqi.ri = 0;
|
|
|
|
report_value->wideband_cri_ri_pmi_cqi.ri = 0;
|
|
|
@ -199,48 +186,79 @@ int srsran_csi_new_nzp_csi_rs_measurement(
|
|
|
|
return SRSRAN_SUCCESS;
|
|
|
|
return SRSRAN_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int srsran_csi_generate_reports(const srsran_csi_hl_cfg_t* cfg,
|
|
|
|
int srsran_csi_reports_generate(const srsran_csi_hl_cfg_t* cfg,
|
|
|
|
uint32_t slot_idx,
|
|
|
|
const srsran_slot_cfg_t* slot_cfg,
|
|
|
|
const srsran_csi_channel_measurements_t measurements[SRSRAN_CSI_MAX_NOF_RESOURCES],
|
|
|
|
srsran_csi_report_cfg_t report_cfg[SRSRAN_CSI_MAX_NOF_REPORT])
|
|
|
|
srsran_csi_report_cfg_t report_cfg[SRSRAN_CSI_MAX_NOF_REPORT],
|
|
|
|
|
|
|
|
srsran_csi_report_value_t report_value[SRSRAN_CSI_MAX_NOF_REPORT])
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint32_t count = 0;
|
|
|
|
uint32_t count = 0;
|
|
|
|
|
|
|
|
|
|
|
|
// Check inputs
|
|
|
|
// Check inputs
|
|
|
|
if (cfg == NULL || measurements == NULL || report_cfg == NULL || report_value == NULL) {
|
|
|
|
if (cfg == NULL || report_cfg == NULL) {
|
|
|
|
return SRSRAN_ERROR_INVALID_INPUTS;
|
|
|
|
return SRSRAN_ERROR_INVALID_INPUTS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Make sure report configuration is initialised to zero
|
|
|
|
|
|
|
|
SRSRAN_MEM_ZERO(report_cfg, srsran_csi_report_cfg_t, SRSRAN_CSI_MAX_NOF_REPORT);
|
|
|
|
|
|
|
|
|
|
|
|
// Iterate every possible configured CSI report
|
|
|
|
// Iterate every possible configured CSI report
|
|
|
|
for (uint32_t i = 0; i < SRSRAN_CSI_MAX_NOF_REPORT; i++) {
|
|
|
|
for (uint32_t i = 0; i < SRSRAN_CSI_MAX_NOF_REPORT; i++) {
|
|
|
|
// Skip if report is not configured or triggered
|
|
|
|
// Skip if report is not configured or triggered
|
|
|
|
if (!csi_report_trigger(&cfg->reports[i], slot_idx)) {
|
|
|
|
if (!csi_report_trigger(&cfg->reports[i], slot_cfg->idx)) {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Configure report
|
|
|
|
|
|
|
|
report_cfg[count].cfg = cfg->reports[i];
|
|
|
|
|
|
|
|
report_cfg[count].nof_ports = 1;
|
|
|
|
|
|
|
|
report_cfg[count].K_csi_rs = 1;
|
|
|
|
|
|
|
|
report_cfg[count].has_part2 = false;
|
|
|
|
|
|
|
|
count++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (int)count;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int srsran_csi_reports_quantify(const srsran_csi_report_cfg_t reports[SRSRAN_CSI_MAX_NOF_REPORT],
|
|
|
|
|
|
|
|
const srsran_csi_channel_measurements_t measurements[SRSRAN_CSI_MAX_NOF_RESOURCES],
|
|
|
|
|
|
|
|
srsran_csi_report_value_t report_value[SRSRAN_CSI_MAX_NOF_REPORT])
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
uint32_t count = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check inputs
|
|
|
|
|
|
|
|
if (reports == NULL || measurements == NULL || report_value == NULL) {
|
|
|
|
|
|
|
|
return SRSRAN_ERROR_INVALID_INPUTS;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Iterate every possible configured CSI report
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < SRSRAN_CSI_MAX_NOF_REPORT; i++) {
|
|
|
|
|
|
|
|
// If the report is the last one, break
|
|
|
|
|
|
|
|
if (reports->cfg.type == SRSRAN_CSI_REPORT_TYPE_NONE) {
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Select channel measurement
|
|
|
|
// Select channel measurement
|
|
|
|
if (cfg->reports->channel_meas_id >= SRSRAN_CSI_MAX_NOF_RESOURCES) {
|
|
|
|
uint32_t channel_meas_id = reports[i].cfg.channel_meas_id;
|
|
|
|
ERROR("Channel measurement ID (%d) is out of range", cfg->reports->channel_meas_id);
|
|
|
|
if (channel_meas_id >= SRSRAN_CSI_MAX_NOF_RESOURCES) {
|
|
|
|
|
|
|
|
ERROR("Channel measurement ID (%d) is out of range", channel_meas_id);
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const srsran_csi_channel_measurements_t* channel_meas = &measurements[cfg->reports->channel_meas_id];
|
|
|
|
const srsran_csi_channel_measurements_t* channel_meas = &measurements[channel_meas_id];
|
|
|
|
|
|
|
|
|
|
|
|
// Select interference measurement
|
|
|
|
// Select interference measurement
|
|
|
|
const srsran_csi_channel_measurements_t* interf_meas = NULL;
|
|
|
|
const srsran_csi_channel_measurements_t* interf_meas = NULL;
|
|
|
|
if (cfg->reports->interf_meas_present) {
|
|
|
|
if (reports[i].cfg.interf_meas_present) {
|
|
|
|
if (cfg->reports->interf_meas_id >= SRSRAN_CSI_MAX_NOF_RESOURCES) {
|
|
|
|
uint32_t interf_meas_id = reports[i].cfg.interf_meas_id;
|
|
|
|
ERROR("Interference measurement ID (%d) is out of range", cfg->reports->interf_meas_id);
|
|
|
|
if (interf_meas_id >= SRSRAN_CSI_MAX_NOF_RESOURCES) {
|
|
|
|
|
|
|
|
ERROR("Interference measurement ID (%d) is out of range", interf_meas_id);
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
interf_meas = &measurements[cfg->reports->interf_meas_id];
|
|
|
|
interf_meas = &measurements[interf_meas_id];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Quantify measurements according to frequency and quantity configuration
|
|
|
|
// Quantify measurements according to frequency and quantity configuration
|
|
|
|
if (cfg->reports->freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND &&
|
|
|
|
if (reports[i].cfg.freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND &&
|
|
|
|
cfg->reports->quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) {
|
|
|
|
reports[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) {
|
|
|
|
csi_wideband_cri_ri_pmi_cqi_quantify(
|
|
|
|
csi_wideband_cri_ri_pmi_cqi_quantify(&reports[i].cfg, channel_meas, interf_meas, &report_value[count]);
|
|
|
|
&cfg->reports[i], channel_meas, interf_meas, &report_cfg[count], &report_value[count]);
|
|
|
|
|
|
|
|
count++;
|
|
|
|
count++;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
; // Ignore other types
|
|
|
|
; // Ignore other types
|
|
|
@ -262,9 +280,9 @@ int srsran_csi_part1_nof_bits(const srsran_csi_report_cfg_t* report_list, uint32
|
|
|
|
// Iterate all report configurations
|
|
|
|
// Iterate all report configurations
|
|
|
|
for (uint32_t i = 0; i < nof_reports; i++) {
|
|
|
|
for (uint32_t i = 0; i < nof_reports; i++) {
|
|
|
|
const srsran_csi_report_cfg_t* report = &report_list[i];
|
|
|
|
const srsran_csi_report_cfg_t* report = &report_list[i];
|
|
|
|
if (report->quantity && report->quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) {
|
|
|
|
if (report->cfg.quantity && report->cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) {
|
|
|
|
count += csi_wideband_cri_ri_pmi_cqi_nof_bits(report);
|
|
|
|
count += csi_wideband_cri_ri_pmi_cqi_nof_bits(report);
|
|
|
|
} else if (report->quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) {
|
|
|
|
} else if (report->cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) {
|
|
|
|
count += csi_none_nof_bits(report);
|
|
|
|
count += csi_none_nof_bits(report);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -317,15 +335,15 @@ int srsran_csi_part1_pack(const srsran_csi_report_cfg_t* report_cfg,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < nof_reports && count < max_o_csi1; i++) {
|
|
|
|
for (uint32_t i = 0; i < nof_reports && count < max_o_csi1; i++) {
|
|
|
|
if (report_cfg[i].freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND &&
|
|
|
|
if (report_cfg[i].cfg.freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND &&
|
|
|
|
report_cfg[i].quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) {
|
|
|
|
report_cfg[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) {
|
|
|
|
count += csi_wideband_cri_ri_pmi_cqi_pack(&report_cfg[i], &report_value[i], &o_csi1[count]);
|
|
|
|
count += csi_wideband_cri_ri_pmi_cqi_pack(&report_cfg[i], &report_value[i], &o_csi1[count]);
|
|
|
|
} else if (report_cfg[i].quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) {
|
|
|
|
} else if (report_cfg[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) {
|
|
|
|
count += csi_none_pack(&report_cfg[i], &report_value[i], &o_csi1[count]);
|
|
|
|
count += csi_none_pack(&report_cfg[i], &report_value[i], &o_csi1[count]);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
ERROR("CSI frequency (%d) and quantity (%d) combination is not implemented",
|
|
|
|
ERROR("CSI frequency (%d) and quantity (%d) combination is not implemented",
|
|
|
|
report_cfg[i].freq_cfg,
|
|
|
|
report_cfg[i].cfg.freq_cfg,
|
|
|
|
report_cfg[i].quantity);
|
|
|
|
report_cfg[i].cfg.quantity);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -351,15 +369,15 @@ int srsran_csi_part1_unpack(const srsran_csi_report_cfg_t* report_cfg,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < nof_reports && count < max_o_csi1; i++) {
|
|
|
|
for (uint32_t i = 0; i < nof_reports && count < max_o_csi1; i++) {
|
|
|
|
if (report_cfg[i].freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND &&
|
|
|
|
if (report_cfg[i].cfg.freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND &&
|
|
|
|
report_cfg[i].quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) {
|
|
|
|
report_cfg[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) {
|
|
|
|
count += csi_wideband_cri_ri_pmi_cqi_unpack(&report_cfg[i], &o_csi1[count], &report_value[i]);
|
|
|
|
count += csi_wideband_cri_ri_pmi_cqi_unpack(&report_cfg[i], &o_csi1[count], &report_value[i]);
|
|
|
|
} else if (report_cfg[i].quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) {
|
|
|
|
} else if (report_cfg[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) {
|
|
|
|
count += csi_none_unpack(&report_cfg[i], &o_csi1[count], &report_value[i]);
|
|
|
|
count += csi_none_unpack(&report_cfg[i], &o_csi1[count], &report_value[i]);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
ERROR("CSI frequency (%d) and quantity (%d) combination is not implemented",
|
|
|
|
ERROR("CSI frequency (%d) and quantity (%d) combination is not implemented",
|
|
|
|
report_cfg[i].freq_cfg,
|
|
|
|
report_cfg[i].cfg.freq_cfg,
|
|
|
|
report_cfg[i].quantity);
|
|
|
|
report_cfg[i].cfg.quantity);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -374,10 +392,10 @@ uint32_t srsran_csi_str(const srsran_csi_report_cfg_t* report_cfg,
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint32_t len = 0;
|
|
|
|
uint32_t len = 0;
|
|
|
|
for (uint32_t i = 0; i < nof_reports; i++) {
|
|
|
|
for (uint32_t i = 0; i < nof_reports; i++) {
|
|
|
|
if (report_cfg[i].freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND &&
|
|
|
|
if (report_cfg[i].cfg.freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND &&
|
|
|
|
report_cfg[i].quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) {
|
|
|
|
report_cfg[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) {
|
|
|
|
len = srsran_print_check(str, str_len, len, "cqi=%d ", report_value[i].wideband_cri_ri_pmi_cqi.cqi);
|
|
|
|
len = srsran_print_check(str, str_len, len, "cqi=%d ", report_value[i].wideband_cri_ri_pmi_cqi.cqi);
|
|
|
|
} else if (report_cfg[i].quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) {
|
|
|
|
} else if (report_cfg[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) {
|
|
|
|
char tmp[20] = {};
|
|
|
|
char tmp[20] = {};
|
|
|
|
srsran_vec_sprint_bin(tmp, sizeof(tmp), report_value[i].none, report_cfg->K_csi_rs);
|
|
|
|
srsran_vec_sprint_bin(tmp, sizeof(tmp), report_value[i].none, report_cfg->K_csi_rs);
|
|
|
|
len = srsran_print_check(str, str_len, len, "csi=%s ", tmp);
|
|
|
|
len = srsran_print_check(str, str_len, len, "csi=%s ", tmp);
|
|
|
|