Merge remote-tracking branch 'origin/NR_SSB_SINR' into integration_2025_w16 (!3326)
Enable SSB-SINR based CSI reporting 3GPP 38.331 release 16 specifies that If the field reportQuantity-r16 is present, UE shall ignore reportQuantity (without suffix). reportQuantity-r16 configures SSB based SINR as the reporting quantity. set do_SINR = 1; in gNB params part of the config file to enable SSB based SINR reporting.
This commit is contained in:
@@ -250,6 +250,8 @@ configuration](../RRC/rrc-usage.md) as well for SIB configuration.
|
||||
* `do_CSIRS` (default 0): flag whether to use channel-state information
|
||||
reference signal (CSI-RS)
|
||||
* `do_SRS` (default 0): flag whether to use sounding reference signal (SRS)
|
||||
* `do_SINR` (default 0): flag whether to enable CSI reporting of SSB-SINR (introduced in rel16)
|
||||
Default setting of CSI reporting quantity is SSB-RSRP.
|
||||
* `min_rxtxtime` (default 2): minimum feedback time for UE to respond to
|
||||
transmissions (k1 and k2 in 3GPP spec)
|
||||
* `ul_prbblacklist`: PRBs that should not be used for UL scheduling. Cf with
|
||||
@@ -272,6 +274,18 @@ configuration](../RRC/rrc-usage.md) as well for SIB configuration.
|
||||
- `du_sibs` (default `[]`): list of SIBs to transmit in the cell. Currently,
|
||||
SIB19 (for NTN) is supported.
|
||||
|
||||
| DL MIMO |`do_CSIRS`|`do_SINR`| CSI report Quantity |
|
||||
| ---------------------------- | -------- | ------- | --------------------------------------------------|
|
||||
| OFF (pdsch_AntennaPorts = 1) | 0 | 0 | SSB-RSRP |
|
||||
| OFF (pdsch_AntennaPorts = 1) | 0 | 1 | SSB-SINR |
|
||||
| OFF (pdsch_AntennaPorts = 1) | 1 | 0 | CSI-Reference signal RSRP |
|
||||
| OFF (pdsch_AntennaPorts = 1) | 1 | 1 | CSI-Reference signal SINR (not supported yet) |
|
||||
| ON (pdsch_AntennaPorts > 1) | 1 | 0 | cri-RI-PMI-CQI |
|
||||
|
||||
DL-MIMO is configured using following parameters:
|
||||
`pdsch_AntennaPorts_XP` , `pdsch_AntennaPorts_N1` , `pdsch_AntennaPorts_N2`, `maxMIMO_layers`
|
||||
(see also [`RUNMODEM.md`](../RUNMODEM.md))
|
||||
|
||||
## ServingCellConfigCommon parameters
|
||||
|
||||
The `gNBs` configuration section has a big structure `servingCellConfigCommon`
|
||||
|
||||
@@ -129,6 +129,8 @@ typedef struct {
|
||||
short rsrp_dBm;
|
||||
long arfcn;
|
||||
rlm_t radiolink_monitoring; // -1 no monitoring, 0 out_of_sync, 1 in_sync
|
||||
// SINR value times 10 as reporting granularity is 0.5
|
||||
float sinr_dB;
|
||||
} fapi_nr_ssb_pdu_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -180,8 +180,10 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
||||
AssertFatal( nb_connected_gNB <= NUMBER_OF_CONNECTED_gNB_MAX, "n_connected_gNB is too large" );
|
||||
// init phy_vars_ue
|
||||
|
||||
for (int i = 0; i < fp->Lmax; i++)
|
||||
for (int i = 0; i < fp->Lmax; i++) {
|
||||
ue->measurements.ssb_rsrp_dBm[i] = INT_MIN;
|
||||
ue->measurements.ssb_sinr_dB[i] = INT_MIN;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
ue->rx_gain_max[i] = 135;
|
||||
|
||||
@@ -111,11 +111,11 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
|
||||
uint32_t pdsch_est_size,
|
||||
int32_t dl_ch_estimates[][pdsch_est_size]);
|
||||
|
||||
int nr_ue_calculate_ssb_rsrp(const NR_DL_FRAME_PARMS *fp,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
const c16_t rxdataF[][fp->samples_per_slot_wCP],
|
||||
int symbol_offset,
|
||||
int ssb_start_subcarrier);
|
||||
uint32_t nr_ue_calculate_ssb_rsrp(const NR_DL_FRAME_PARMS *fp,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
const c16_t rxdataF[][fp->samples_per_slot_wCP],
|
||||
int symbol_offset,
|
||||
int ssb_start_subcarrier);
|
||||
|
||||
void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
|
||||
uint8_t gNB_index,
|
||||
|
||||
@@ -172,11 +172,11 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
|
||||
|
||||
// This function calculates:
|
||||
// - SS reference signal received digital power in dB/RE
|
||||
int nr_ue_calculate_ssb_rsrp(const NR_DL_FRAME_PARMS *fp,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
const c16_t rxdataF[][fp->samples_per_slot_wCP],
|
||||
int symbol_offset,
|
||||
int ssb_start_subcarrier)
|
||||
uint32_t nr_ue_calculate_ssb_rsrp(const NR_DL_FRAME_PARMS *fp,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
const c16_t rxdataF[][fp->samples_per_slot_wCP],
|
||||
int symbol_offset,
|
||||
int ssb_start_subcarrier)
|
||||
{
|
||||
int k_start = 56;
|
||||
int k_end = 183;
|
||||
@@ -209,9 +209,7 @@ int nr_ue_calculate_ssb_rsrp(const NR_DL_FRAME_PARMS *fp,
|
||||
|
||||
LOG_D(PHY, "In %s: RSRP/nb_re: %d nb_re :%d\n", __FUNCTION__, rsrp, nb_re);
|
||||
|
||||
int rsrp_db_per_re = 10 * log10(rsrp);
|
||||
|
||||
return rsrp_db_per_re;
|
||||
return rsrp;
|
||||
}
|
||||
|
||||
// This function implements:
|
||||
@@ -234,7 +232,8 @@ void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
|
||||
if (fp->half_frame_bit)
|
||||
symbol_offset += (fp->slots_per_frame >> 1) * fp->symbols_per_slot;
|
||||
|
||||
int rsrp_db_per_re = nr_ue_calculate_ssb_rsrp(fp, proc, rxdataF, symbol_offset, fp->ssb_start_subcarrier);
|
||||
uint32_t rsrp_avg = nr_ue_calculate_ssb_rsrp(fp, proc, rxdataF, symbol_offset, fp->ssb_start_subcarrier);
|
||||
float rsrp_db_per_re = 10 * log10(rsrp_avg);
|
||||
|
||||
openair0_config_t *cfg0 = &openair0_cfg[0];
|
||||
|
||||
@@ -242,12 +241,18 @@ void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
|
||||
- ((int)cfg0->rx_gain[0] - (int)cfg0->rx_gain_offset[0])
|
||||
- dB_fixed(fp->ofdm_symbol_size);
|
||||
|
||||
// to obtain non-integer dB value with a resoluion of 0.5dB
|
||||
uint32_t signal_pwr = rsrp_avg > ue->measurements.n0_power_avg ? rsrp_avg - ue->measurements.n0_power_avg : 0;
|
||||
int SNRtimes10 = dB_fixed_x10(signal_pwr) - dB_fixed_x10(ue->measurements.n0_power_avg);
|
||||
ue->measurements.ssb_sinr_dB[ssb_index] = SNRtimes10 / 10.0;
|
||||
|
||||
LOG_D(PHY,
|
||||
"[UE %d] ssb %d SS-RSRP: %d dBm/RE (%d dB/RE)\n",
|
||||
"[UE %d] ssb %d SS-RSRP: %d dBm/RE (%f dB/RE), SS-SINR: %f dB\n",
|
||||
ue->Mod_id,
|
||||
ssb_index,
|
||||
ue->measurements.ssb_rsrp_dBm[ssb_index],
|
||||
rsrp_db_per_re);
|
||||
rsrp_db_per_re,
|
||||
ue->measurements.ssb_sinr_dB[ssb_index]);
|
||||
}
|
||||
|
||||
// This function computes the received noise power
|
||||
|
||||
@@ -285,7 +285,8 @@ void nr_scan_ssb(void *arg)
|
||||
&ssbInfo->pbchResult,
|
||||
rxdataF); // start pbch detection at first symbol after pss
|
||||
if (ssbInfo->syncRes.cell_detected) {
|
||||
int rsrp_db_per_re = nr_ue_calculate_ssb_rsrp(ssbInfo->fp, ssbInfo->proc, rxdataF, 0, ssbInfo->gscnInfo.ssbFirstSC);
|
||||
uint32_t rsrp_avg = nr_ue_calculate_ssb_rsrp(ssbInfo->fp, ssbInfo->proc, rxdataF, 0, ssbInfo->gscnInfo.ssbFirstSC);
|
||||
int rsrp_db_per_re = 10 * log10(rsrp_avg);
|
||||
ssbInfo->adjust_rxgain = TARGET_RX_POWER - rsrp_db_per_re;
|
||||
LOG_I(PHY, "pbch rx ok. rsrp:%d dB/RE, adjust_rxgain:%d dB\n", rsrp_db_per_re, ssbInfo->adjust_rxgain);
|
||||
}
|
||||
|
||||
@@ -140,6 +140,7 @@ typedef struct {
|
||||
uint32_t rsrp[7];
|
||||
short rsrp_dBm[7];
|
||||
int ssb_rsrp_dBm[64];
|
||||
float ssb_sinr_dB[64];
|
||||
// common measurements
|
||||
//! estimated noise power (linear)
|
||||
unsigned int n0_power[NB_ANTENNAS_RX];
|
||||
|
||||
@@ -175,6 +175,7 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
|
||||
rx->ssb_pdu.cell_id = frame_parms->Nid_cell;
|
||||
rx->ssb_pdu.ssb_start_subcarrier = frame_parms->ssb_start_subcarrier;
|
||||
rx->ssb_pdu.rsrp_dBm = ue->measurements.ssb_rsrp_dBm[frame_parms->ssb_index];
|
||||
rx->ssb_pdu.sinr_dB = ue->measurements.ssb_sinr_dB[frame_parms->ssb_index];
|
||||
rx->ssb_pdu.arfcn = get_ssb_arfcn(frame_parms);
|
||||
rx->ssb_pdu.radiolink_monitoring = RLM_in_sync; // TODO to be removed from here
|
||||
rx->ssb_pdu.decoded_pdu = true;
|
||||
|
||||
@@ -858,6 +858,7 @@ void RCconfig_verify(configmodule_interface_t *cfg, ngran_node_t node_type)
|
||||
verify_gnb_param_notset(gnbp, GNB_DISABLE_HARQ_IDX, GNB_CONFIG_STRING_DISABLE_HARQ);
|
||||
verify_gnb_param_notset(gnbp, GNB_NUM_DL_HARQ_IDX, GNB_CONFIG_STRING_NUM_DL_HARQPROCESSES);
|
||||
verify_gnb_param_notset(gnbp, GNB_NUM_UL_HARQ_IDX, GNB_CONFIG_STRING_NUM_UL_HARQPROCESSES);
|
||||
verify_gnb_param_notset(gnbp, GNB_DO_SINR_IDX, GNB_CONFIG_STRING_DOSINR);
|
||||
|
||||
// check for some general sections
|
||||
verify_section_notset(cfg, NULL, CONFIG_STRING_L1_LIST);
|
||||
@@ -1500,6 +1501,7 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
|
||||
LOG_I(GNB_APP, "SIB1 TDA %d\n", config.sib1_tda);
|
||||
config.do_CSIRS = *GNBParamList.paramarray[0][GNB_DO_CSIRS_IDX].iptr;
|
||||
config.do_SRS = *GNBParamList.paramarray[0][GNB_DO_SRS_IDX].iptr;
|
||||
config.do_SINR = *GNBParamList.paramarray[0][GNB_DO_SINR_IDX].iptr;
|
||||
config.force_256qam_off = *GNBParamList.paramarray[0][GNB_FORCE256QAMOFF_IDX].iptr;
|
||||
config.force_UL256qam_off = *GNBParamList.paramarray[0][GNB_FORCEUL256QAMOFF_IDX].iptr;
|
||||
config.use_deltaMCS = *GNBParamList.paramarray[0][GNB_USE_DELTA_MCS_IDX].iptr != 0;
|
||||
@@ -1510,9 +1512,10 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
|
||||
if (config.disable_harq)
|
||||
LOG_W(GNB_APP, "\"disable_harq\" is a REL17 feature and is incompatible with REL15 and REL16 UEs!\n");
|
||||
LOG_I(GNB_APP,
|
||||
"CSI-RS %d, SRS %d, 256 QAM %s, delta_MCS %s, maxMIMO_Layers %d, HARQ feedback %s, num DLHARQ:%d, num ULHARQ:%d\n",
|
||||
"CSI-RS %d, SRS %d, SINR:%d, 256 QAM %s, delta_MCS %s, maxMIMO_Layers %d, HARQ feedback %s, num DLHARQ:%d, num ULHARQ:%d\n",
|
||||
config.do_CSIRS,
|
||||
config.do_SRS,
|
||||
config.do_SINR,
|
||||
config.force_256qam_off ? "force off" : "may be on",
|
||||
config.use_deltaMCS ? "on" : "off",
|
||||
config.maxMIMO_layers,
|
||||
|
||||
@@ -141,6 +141,7 @@ typedef enum {
|
||||
#define GNB_CONFIG_STRING_UESS_AGG_LEVEL_LIST "uess_agg_levels"
|
||||
#define GNB_CONFIG_STRING_CU_SIB_LIST "cu_sibs"
|
||||
#define GNB_CONFIG_STRING_DU_SIB_LIST "du_sibs"
|
||||
#define GNB_CONFIG_STRING_DOSINR "do_SINR"
|
||||
|
||||
#define GNB_CONFIG_HLP_STRING_ENABLE_SDAP "enable the SDAP layer\n"
|
||||
#define GNB_CONFIG_HLP_FORCE256QAMOFF "suppress activation of 256 QAM despite UE support"
|
||||
@@ -154,6 +155,7 @@ typedef enum {
|
||||
#define GNB_CONFIG_HLP_UESS_AGG_LEVEL_LIST "List of aggregation levels with number of candidates per level. Element 0 - aggregation level 1"
|
||||
#define GNB_CONFIG_HLP_CU_SIBS "List of CU generated SIBs to be transmitted"
|
||||
#define GNB_CONFIG_HLP_DU_SIBS "List of DU generated SIBs to be transmitted"
|
||||
#define GNB_CONFIG_HLP_DOSINR "Enable CSI feedback using SINR measurements on SSB"
|
||||
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* cell configuration parameters */
|
||||
@@ -201,6 +203,7 @@ typedef enum {
|
||||
GNB_CONFIG_HLP_UESS_AGG_LEVEL_LIST, 0, .iptr=NULL, .defintarrayval=NULL, TYPE_INTARRAY, 0}, \
|
||||
{GNB_CONFIG_STRING_CU_SIB_LIST, GNB_CONFIG_HLP_CU_SIBS, 0, .iptr=NULL, .defintarrayval=0, TYPE_INTARRAY, 0}, \
|
||||
{GNB_CONFIG_STRING_DU_SIB_LIST, GNB_CONFIG_HLP_DU_SIBS, 0, .iptr=NULL, .defintarrayval=0, TYPE_INTARRAY, 0}, \
|
||||
{GNB_CONFIG_STRING_DOSINR, GNB_CONFIG_HLP_DOSINR, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
@@ -244,6 +247,7 @@ typedef enum {
|
||||
#define GNB_UESS_AGG_LEVEL_LIST_IDX 36
|
||||
#define GNB_CU_SIBS_IDX 37
|
||||
#define GNB_DU_SIBS_IDX 38
|
||||
#define GNB_DO_SINR_IDX 39
|
||||
|
||||
#define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
|
||||
#define NUM_DL_HARQ_OKVALUES {2,4,6,8,10,12,16,32}
|
||||
@@ -289,6 +293,7 @@ typedef enum {
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
@@ -517,7 +517,9 @@ typedef struct {
|
||||
uint8_t cri_ssbri_bitlen;
|
||||
uint8_t rsrp_bitlen;
|
||||
uint8_t diff_rsrp_bitlen;
|
||||
} L1_RSRP_bitlen_t;
|
||||
uint8_t sinr_bitlen;
|
||||
uint8_t diff_sinr_bitlen;
|
||||
} L1_Meas_bitlen_t;
|
||||
|
||||
typedef struct{
|
||||
uint8_t ri_restriction;
|
||||
@@ -535,13 +537,14 @@ typedef struct{
|
||||
typedef struct nr_csi_report {
|
||||
NR_CSI_ReportConfigId_t reportConfigId;
|
||||
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type;
|
||||
NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR reportQuantity_type_r16;
|
||||
long periodicity;
|
||||
uint16_t offset;
|
||||
long **SSB_Index_list;
|
||||
long **CSI_Index_list;
|
||||
// uint8_t nb_of_nzp_csi_report;
|
||||
uint8_t nb_of_csi_ssb_report;
|
||||
L1_RSRP_bitlen_t CSI_report_bitlen;
|
||||
L1_Meas_bitlen_t CSI_report_bitlen;
|
||||
CSI_Meas_bitlen_t csi_meas_bitlen;
|
||||
int codebook_mode;
|
||||
int N1;
|
||||
|
||||
@@ -4427,7 +4427,10 @@ static uint8_t number_of_bits_set(uint8_t buf)
|
||||
return nb_of_bits_set;
|
||||
}
|
||||
|
||||
static void compute_rsrp_bitlen(const NR_CSI_ReportConfig_t *csi_reportconfig, uint8_t nb_resources, nr_csi_report_t *csi_report)
|
||||
static void compute_rsrp_or_sinr_bitlen(const NR_CSI_ReportConfig_t *csi_reportconfig,
|
||||
uint8_t nb_resources,
|
||||
nr_csi_report_t *csi_report,
|
||||
bool is_RSRP_configured)
|
||||
{
|
||||
if (NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled == csi_reportconfig->groupBasedBeamReporting.present) {
|
||||
if (csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS)
|
||||
@@ -4445,13 +4448,20 @@ static void compute_rsrp_bitlen(const NR_CSI_ReportConfig_t *csi_reportconfig, u
|
||||
csi_report->CSI_report_bitlen.nb_ssbri_cri = 2;
|
||||
|
||||
if (nb_resources) {
|
||||
csi_report->CSI_report_bitlen.cri_ssbri_bitlen =ceil(log2 (nb_resources));
|
||||
csi_report->CSI_report_bitlen.rsrp_bitlen = 7; // From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP
|
||||
csi_report->CSI_report_bitlen.diff_rsrp_bitlen = 4; // From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP
|
||||
csi_report->CSI_report_bitlen.cri_ssbri_bitlen = ceil(log2 (nb_resources));
|
||||
if (is_RSRP_configured) {
|
||||
csi_report->CSI_report_bitlen.rsrp_bitlen = 7; // From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP
|
||||
csi_report->CSI_report_bitlen.diff_rsrp_bitlen = 4; // From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP
|
||||
} else {
|
||||
csi_report->CSI_report_bitlen.sinr_bitlen = 7; // From spec 38.212 Table 6.3.1.1.2-6A: CRI, SSBRI, and SINR
|
||||
csi_report->CSI_report_bitlen.diff_sinr_bitlen = 4; // From spec 38.212 Table 6.3.1.1.2-6A: CRI, SSBRI, and SINR
|
||||
}
|
||||
} else {
|
||||
csi_report->CSI_report_bitlen.cri_ssbri_bitlen = 0;
|
||||
csi_report->CSI_report_bitlen.rsrp_bitlen = 0;
|
||||
csi_report->CSI_report_bitlen.diff_rsrp_bitlen = 0;
|
||||
csi_report->CSI_report_bitlen.sinr_bitlen = 0;
|
||||
csi_report->CSI_report_bitlen.diff_sinr_bitlen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4878,9 +4888,13 @@ void compute_csi_bitlen(const NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report
|
||||
reportQuantity_type = csi_reportconfig->reportQuantity.present;
|
||||
csi_report->reportQuantity_type = reportQuantity_type;
|
||||
csi_report->reportConfigId = csi_reportconfig->reportConfigId;
|
||||
csi_report->reportQuantity_type_r16 = NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_NOTHING;
|
||||
if (csi_reportconfig->ext2 != NULL && csi_reportconfig->ext2->reportQuantity_r16)
|
||||
csi_report->reportQuantity_type_r16 = csi_reportconfig->ext2->reportQuantity_r16->present;
|
||||
|
||||
// setting the CSI or SSB index list
|
||||
if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == csi_report->reportQuantity_type) {
|
||||
if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == csi_report->reportQuantity_type
|
||||
|| NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_ssb_Index_SINR_r16 == csi_report->reportQuantity_type_r16) {
|
||||
for (int csi_idx = 0; csi_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_idx++) {
|
||||
if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceSetId ==
|
||||
*(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])){
|
||||
@@ -4891,8 +4905,7 @@ void compute_csi_bitlen(const NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (resourceType == NR_CSI_ResourceConfig__resourceType_periodic) {
|
||||
AssertFatal(csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList != NULL,
|
||||
"Wrong settings! Report quantity requires CSI-RS but csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList is NULL\n");
|
||||
@@ -4911,33 +4924,46 @@ void compute_csi_bitlen(const NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report
|
||||
}
|
||||
LOG_D(NR_MAC,"nb_resources %d\n",nb_resources);
|
||||
// computation of bit length depending on the report type
|
||||
switch(reportQuantity_type){
|
||||
case (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP):
|
||||
compute_rsrp_bitlen(csi_reportconfig, nb_resources, csi_report);
|
||||
break;
|
||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP):
|
||||
compute_rsrp_bitlen(csi_reportconfig, nb_resources, csi_report);
|
||||
break;
|
||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI):
|
||||
csi_report->csi_meas_bitlen.cri_bitlen = ceil(log2(nb_resources));
|
||||
csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report);
|
||||
compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
break;
|
||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI):
|
||||
csi_report->csi_meas_bitlen.cri_bitlen = ceil(log2(nb_resources));
|
||||
csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report);
|
||||
compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
compute_pmi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
break;
|
||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI):
|
||||
csi_report->csi_meas_bitlen.cri_bitlen = ceil(log2(nb_resources));
|
||||
csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report);
|
||||
compute_li_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
compute_pmi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"Not yet supported CSI report quantity type");
|
||||
if (csi_report->reportQuantity_type_r16 != NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_NOTHING) {
|
||||
switch (csi_report->reportQuantity_type_r16) {
|
||||
case NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_ssb_Index_SINR_r16:
|
||||
compute_rsrp_or_sinr_bitlen(csi_reportconfig, nb_resources, csi_report, false);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_cri_SINR_r16:
|
||||
compute_rsrp_or_sinr_bitlen(csi_reportconfig, nb_resources, csi_report, false);
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1 == 0, "Not yet supported CSI report quantity type");
|
||||
}
|
||||
} else {
|
||||
switch (reportQuantity_type) {
|
||||
case (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP):
|
||||
compute_rsrp_or_sinr_bitlen(csi_reportconfig, nb_resources, csi_report, true);
|
||||
break;
|
||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP):
|
||||
compute_rsrp_or_sinr_bitlen(csi_reportconfig, nb_resources, csi_report, true);
|
||||
break;
|
||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI):
|
||||
csi_report->csi_meas_bitlen.cri_bitlen = ceil(log2(nb_resources));
|
||||
csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report);
|
||||
compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
break;
|
||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI):
|
||||
csi_report->csi_meas_bitlen.cri_bitlen = ceil(log2(nb_resources));
|
||||
csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report);
|
||||
compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
compute_pmi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
break;
|
||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI):
|
||||
csi_report->csi_meas_bitlen.cri_bitlen = ceil(log2(nb_resources));
|
||||
csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report);
|
||||
compute_li_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
compute_pmi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1 == 0, "Not yet supported CSI report quantity type");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4946,11 +4972,16 @@ uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report)
|
||||
{
|
||||
uint16_t csi_bitlen = 0;
|
||||
uint16_t max_bitlen = 0;
|
||||
L1_RSRP_bitlen_t *CSI_report_bitlen = NULL;
|
||||
L1_Meas_bitlen_t *CSI_report_bitlen = NULL;
|
||||
CSI_Meas_bitlen_t *csi_meas_bitlen = NULL;
|
||||
|
||||
if (csi_report->reportQuantity_type == NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP ||
|
||||
csi_report->reportQuantity_type == NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP) {
|
||||
if (csi_report->reportQuantity_type_r16 == NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_ssb_Index_SINR_r16
|
||||
|| csi_report->reportQuantity_type_r16 == NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_cri_SINR_r16) {
|
||||
CSI_report_bitlen = &(csi_report->CSI_report_bitlen); // This might need to be moodif for Aperiodic CSI-RS measurements
|
||||
csi_bitlen += ((CSI_report_bitlen->cri_ssbri_bitlen * CSI_report_bitlen->nb_ssbri_cri) + CSI_report_bitlen->sinr_bitlen
|
||||
+ (CSI_report_bitlen->diff_sinr_bitlen * (CSI_report_bitlen->nb_ssbri_cri - 1)));
|
||||
} else if (csi_report->reportQuantity_type == NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP
|
||||
|| csi_report->reportQuantity_type == NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP) {
|
||||
CSI_report_bitlen = &(csi_report->CSI_report_bitlen); // This might need to be moodif for Aperiodic CSI-RS measurements
|
||||
csi_bitlen += ((CSI_report_bitlen->cri_ssbri_bitlen * CSI_report_bitlen->nb_ssbri_cri) +
|
||||
CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen *
|
||||
|
||||
@@ -417,6 +417,7 @@ typedef struct {
|
||||
uint32_t ssb_index;
|
||||
/// SSB RSRP in dBm
|
||||
short ssb_rsrp_dBm;
|
||||
float_t ssb_sinr_dB;
|
||||
} NR_SSB_meas_t;
|
||||
|
||||
typedef enum ta_type {
|
||||
|
||||
@@ -2643,6 +2643,111 @@ int nr_get_csi_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCC
|
||||
return num_csi;
|
||||
}
|
||||
|
||||
// Referred - Table 10.1.16.1-1 in 38.133 V16.7.0.
|
||||
static uint8_t get_sinr_index(float sinr)
|
||||
{
|
||||
int index = sinr * 2 + 47;
|
||||
if (sinr >= 40)
|
||||
index = 127;
|
||||
if (sinr < -23)
|
||||
index = 0;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
// Reffered Table 10.1.16.1-2 in 38.133 V16.7.0. Differential value is reported.
|
||||
static uint8_t get_sinr_diff_index(float best_sinr, float current_sinr)
|
||||
{
|
||||
int diff = best_sinr - current_sinr;
|
||||
if (diff >= 15)
|
||||
return 15;
|
||||
else if (diff <= 0)
|
||||
return 0;
|
||||
else
|
||||
return diff;
|
||||
}
|
||||
|
||||
static csi_payload_t get_ssb_sinr_payload(NR_UE_MAC_INST_t *mac,
|
||||
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig)
|
||||
{
|
||||
int nb_ssb = 0; // nb of ssb in the resource
|
||||
int nb_meas = 0; // nb of ssb to report measurements on
|
||||
int bits = 0;
|
||||
uint32_t temp_payload = 0;
|
||||
|
||||
for (int csi_resourceidx = 0; csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_resourceidx++) {
|
||||
struct NR_CSI_ResourceConfig *csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx];
|
||||
if (csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId) {
|
||||
if (csi_reportconfig->groupBasedBeamReporting.present == NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled) {
|
||||
if (csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS != NULL)
|
||||
nb_meas = *(csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS) + 1;
|
||||
else
|
||||
nb_meas = 1;
|
||||
} else
|
||||
nb_meas = 2;
|
||||
|
||||
struct NR_CSI_SSB_ResourceSet__csi_SSB_ResourceList SSB_resource;
|
||||
for (int csi_ssb_idx = 0; csi_ssb_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_ssb_idx++) {
|
||||
if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceSetId
|
||||
== *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])) {
|
||||
SSB_resource = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceList;
|
||||
/// only one SSB resource set from spec 38.331 IE CSI-ResourceConfig
|
||||
nb_ssb = SSB_resource.list.count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
AssertFatal(nb_ssb > 0, "No SSB found in the resource set\n");
|
||||
AssertFatal(nb_meas == 1, "PHY currently reports only the strongest SSB to MAC. Can't report more than 1 RSRP\n");
|
||||
int ssbri_bits = ceil(log2(nb_ssb));
|
||||
|
||||
int ssb_index[nb_meas]; // the array contains index and RSRP of each SSB to be reported (nb_meas highest RSRPs)
|
||||
float ssb_sinr[nb_meas];
|
||||
|
||||
// TODO replace the following 2 lines with a function to order the nb_meas highest SSB RSRPs
|
||||
for (int i = 0; i < nb_ssb; i++) {
|
||||
ssb_index[i] = -1;//Invalid index
|
||||
if (*SSB_resource.list.array[i] == mac->mib_ssb) {
|
||||
ssb_index[0] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
AssertFatal(ssb_index[0] >= 0, "Couldn't find corresponding SSB in csi_SSB_ResourceList\n");
|
||||
ssb_sinr[0] = mac->ssb_measurements.ssb_sinr_dB;
|
||||
|
||||
uint8_t ssbi;
|
||||
|
||||
// TS38.212 v16.5.0: Table 6.3.1.1.2-8A
|
||||
if (ssbri_bits > 0) {
|
||||
ssbi = ssb_index[0];
|
||||
temp_payload = reverse_bits(ssbi, ssbri_bits);
|
||||
bits += ssbri_bits;
|
||||
}
|
||||
|
||||
uint8_t sinr_idx = get_sinr_index(ssb_sinr[0]);
|
||||
temp_payload |= (reverse_bits(sinr_idx, 7) << bits);
|
||||
bits += 7; // 7 bits for highest SINR
|
||||
|
||||
// from the second SSB, differential report
|
||||
for (int i = 1; i < nb_meas; i++) {
|
||||
ssbi = ssb_index[i];
|
||||
temp_payload = reverse_bits(ssbi, ssbri_bits);
|
||||
bits += ssbri_bits;
|
||||
|
||||
sinr_idx = get_sinr_diff_index(ssb_sinr[0], ssb_sinr[i]);
|
||||
temp_payload |= (reverse_bits(sinr_idx, 4) << bits);
|
||||
bits += 4; // 7 bits for highest SINR
|
||||
}
|
||||
break; // resource found
|
||||
}
|
||||
}
|
||||
AssertFatal(bits <= 32, "Not supporting CSI report with more than 32 bits\n");
|
||||
csi_payload_t csi = {.part1_payload = temp_payload, .p1_bits = bits, csi.p2_bits = 0};
|
||||
return csi;
|
||||
}
|
||||
|
||||
csi_payload_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac,
|
||||
int csi_report_id,
|
||||
CSI_mapping_t mapping_type,
|
||||
@@ -2652,26 +2757,39 @@ csi_payload_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac,
|
||||
csi_payload_t csi = {0};
|
||||
struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
|
||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement;
|
||||
switch(csi_reportconfig->reportQuantity.present) {
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_none:
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP:
|
||||
csi = get_ssb_rsrp_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI:
|
||||
csi = get_csirs_RI_PMI_CQI_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig, mapping_type);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP:
|
||||
csi = get_csirs_RSRP_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1:
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI:
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI:
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI:
|
||||
LOG_E(NR_MAC,"Measurement report %d based on CSI-RS is not available\n", csi_reportconfig->reportQuantity.present);
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"Invalid CSI report quantity type %d\n",csi_reportconfig->reportQuantity.present);
|
||||
if (csi_reportconfig->ext2 && csi_reportconfig->ext2->reportQuantity_r16) {
|
||||
switch (csi_reportconfig->ext2->reportQuantity_r16->present) {
|
||||
case NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_ssb_Index_SINR_r16:
|
||||
csi = get_ssb_sinr_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_cri_SINR_r16:
|
||||
LOG_E(NR_MAC, "CSI Reporting of CSI-RS based SINR not yet available\n");
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1 == 0, "Invalid CSI report quantity r16 type %d\n", csi_reportconfig->ext2->reportQuantity_r16->present);
|
||||
}
|
||||
} else {
|
||||
switch (csi_reportconfig->reportQuantity.present) {
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_none:
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP:
|
||||
csi = get_ssb_rsrp_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI:
|
||||
csi = get_csirs_RI_PMI_CQI_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig, mapping_type);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP:
|
||||
csi = get_csirs_RSRP_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1:
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI:
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI:
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI:
|
||||
LOG_E(NR_MAC, "Measurement report %d based on CSI-RS is not available\n", csi_reportconfig->reportQuantity.present);
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1 == 0, "Invalid CSI report quantity type %d\n", csi_reportconfig->reportQuantity.present);
|
||||
}
|
||||
}
|
||||
return csi;
|
||||
}
|
||||
|
||||
@@ -429,6 +429,78 @@ static uint8_t pickandreverse_bits(uint8_t *payload, uint16_t bitlen, uint8_t st
|
||||
return rev_bits;
|
||||
}
|
||||
|
||||
static void evaluate_sinr_report(gNB_MAC_INST *nrmac,
|
||||
NR_UE_info_t *UE,
|
||||
NR_UE_sched_ctrl_t *sched_ctrl,
|
||||
uint8_t csi_report_id,
|
||||
uint8_t *payload,
|
||||
int *cumul_bits,
|
||||
NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR reportQuantity_type_r16)
|
||||
{
|
||||
/*! As per the spec 38.212 and table: 6.3.1.1.2-12 in a single UCI sequence we can have multiple CSI_report
|
||||
* the number of CSI_report will depend on number of CSI resource sets that are configured in CSI-ResourceConfig RRC IE
|
||||
* From spec 38.331 from the IE CSI-ResourceConfig for SSB RSRP reporting we can configure only one resource set
|
||||
* From spec 38.214 section 5.2.1.2 For periodic and semi-persistent CSI Resource Settings, the number of CSI-RS Resource Sets
|
||||
* configured is limited to S=1
|
||||
*/
|
||||
|
||||
/** from 38.214 sec 5.2.1.4.2
|
||||
- if the UE is configured with the higher layer parameter groupBasedBeamReporting set to 'disabled', the UE is
|
||||
not required to update measurements for more than 64 CSI-RS and/or SSB resources, and the UE shall report in
|
||||
a single report nrofReportedRS (higher layer configured) different CRI or SSBRI for each report setting
|
||||
|
||||
- if the UE is configured with the higher layer parameter groupBasedBeamReporting set to 'enabled', the UE is not
|
||||
required to update measurements for more than 64 CSI-RS and/or SSB resources, and the UE shall report in a
|
||||
single reporting instance two different CRI or SSBRI for each report setting, where CSI-RS and/or SSB
|
||||
resources can be received simultaneously by the UE either with a single spatial domain receive filter, or with
|
||||
multiple simultaneous spatial domain receive filter
|
||||
*/
|
||||
|
||||
nr_csi_report_t *csi_report = &UE->csi_report_template[csi_report_id];
|
||||
RSRP_report_t *sinr_report;
|
||||
long **index_list;
|
||||
switch (reportQuantity_type_r16) {
|
||||
case NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_ssb_Index_SINR_r16:
|
||||
sinr_report = &sched_ctrl->CSI_report.ssb_rsrp_report;
|
||||
index_list = csi_report->SSB_Index_list;
|
||||
break;
|
||||
case NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_cri_SINR_r16:
|
||||
sinr_report = &sched_ctrl->CSI_report.csirs_rsrp_report;
|
||||
index_list = csi_report->CSI_Index_list;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(false, "Invalid RSRP report type\n");
|
||||
}
|
||||
|
||||
sinr_report->nr_reports = csi_report->CSI_report_bitlen.nb_ssbri_cri;
|
||||
uint16_t curr_payload;
|
||||
for (int i = 0; i < sinr_report->nr_reports; i++) {
|
||||
int bitlen = csi_report->CSI_report_bitlen.cri_ssbri_bitlen;
|
||||
curr_payload = pickandreverse_bits(payload, bitlen, *cumul_bits);
|
||||
sinr_report->resource_id[i] = *(index_list[bitlen > 0 ? ((curr_payload) & ~(~1U << (bitlen - 1))) : bitlen]);
|
||||
LOG_D(MAC, "SSB/CSI-RS index = %d\n", sinr_report->resource_id[i]);
|
||||
*cumul_bits += bitlen;
|
||||
}
|
||||
|
||||
curr_payload = pickandreverse_bits(payload, 7, *cumul_bits);
|
||||
sinr_report->SINR_index[0] = curr_payload & 0x7f;
|
||||
*cumul_bits += 7;
|
||||
|
||||
csi_report->nb_of_csi_ssb_report++;
|
||||
if (sinr_report->SINR_index[0] < 0 || sinr_report->SINR_index[0] > 127) {
|
||||
LOG_E(NR_MAC, "UE %04x: reported SINR index %d invalid\n", UE->rnti, sinr_report->SINR_index[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 1; i < sinr_report->nr_reports; i++) {
|
||||
curr_payload = pickandreverse_bits(payload, 4, *cumul_bits);
|
||||
sinr_report->SINR_index[i] = curr_payload & 0x0f;
|
||||
*cumul_bits += 4;
|
||||
}
|
||||
|
||||
LOG_D(MAC, "Reported SSB-SINR index = %d\n", sinr_report->SINR_index[0]);
|
||||
}
|
||||
|
||||
static void evaluate_rsrp_report(gNB_MAC_INST *nrmac,
|
||||
NR_UE_info_t *UE,
|
||||
NR_UE_sched_ctrl_t *sched_ctrl,
|
||||
@@ -627,6 +699,8 @@ static void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
|
||||
uint8_t *payload = uci_pdu->csi_part1.csi_part1_payload;
|
||||
uint16_t bitlen = uci_pdu->csi_part1.csi_part1_bit_len;
|
||||
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type = NR_CSI_ReportConfig__reportQuantity_PR_NOTHING;
|
||||
NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR reportQuantity_type_r16 =
|
||||
NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_NOTHING;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
|
||||
NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP;
|
||||
@@ -650,72 +724,78 @@ static void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
|
||||
// verify if report with current id has been scheduled for this frame and slot
|
||||
if ((n_slots_frame*frame + slot - offset)%period == 0) {
|
||||
reportQuantity_type = csi_report->reportQuantity_type;
|
||||
// phy-test has hardcoded allocation, so no use to handle CSI reports except RSRP
|
||||
if (get_softmodem_params()->phy_test
|
||||
&& reportQuantity_type != NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP
|
||||
&& reportQuantity_type != NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP)
|
||||
continue;
|
||||
LOG_D(MAC,"SFN/SF:%d/%d reportQuantity type = %d\n",frame,slot,reportQuantity_type);
|
||||
switch(reportQuantity_type) {
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP:
|
||||
evaluate_rsrp_report(nrmac, UE, sched_ctrl, csi_report_id, payload, &cumul_bits, reportQuantity_type);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP:
|
||||
evaluate_rsrp_report(nrmac, UE, sched_ctrl, csi_report_id, payload, &cumul_bits, reportQuantity_type);
|
||||
beam_selection_procedures(nrmac, UE);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI:
|
||||
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.print_report = true;
|
||||
cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen;
|
||||
if(cri_bitlen)
|
||||
evaluate_cri_report(payload,cri_bitlen,cumul_bits,sched_ctrl);
|
||||
cumul_bits += cri_bitlen;
|
||||
ri_bitlen = csi_report->csi_meas_bitlen.ri_bitlen;
|
||||
if(ri_bitlen)
|
||||
r_index = evaluate_ri_report(payload,ri_bitlen,csi_report->csi_meas_bitlen.ri_restriction,cumul_bits,sched_ctrl);
|
||||
cumul_bits += ri_bitlen;
|
||||
if (r_index != -1)
|
||||
skip_zero_padding(&cumul_bits,csi_report,r_index,bitlen);
|
||||
evaluate_cqi_report(payload,csi_report,cumul_bits,r_index,UE,cqi_table);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI:
|
||||
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.print_report = true;
|
||||
cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen;
|
||||
if(cri_bitlen)
|
||||
evaluate_cri_report(payload,cri_bitlen,cumul_bits,sched_ctrl);
|
||||
cumul_bits += cri_bitlen;
|
||||
ri_bitlen = csi_report->csi_meas_bitlen.ri_bitlen;
|
||||
if(ri_bitlen)
|
||||
r_index = evaluate_ri_report(payload,ri_bitlen,csi_report->csi_meas_bitlen.ri_restriction,cumul_bits,sched_ctrl);
|
||||
cumul_bits += ri_bitlen;
|
||||
if (r_index != -1)
|
||||
skip_zero_padding(&cumul_bits,csi_report,r_index,bitlen);
|
||||
pmi_bitlen = evaluate_pmi_report(payload,csi_report,cumul_bits,r_index,sched_ctrl);
|
||||
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.csi_report_id = csi_report_id;
|
||||
cumul_bits += pmi_bitlen;
|
||||
evaluate_cqi_report(payload,csi_report,cumul_bits,r_index,UE,cqi_table);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI:
|
||||
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.print_report = true;
|
||||
cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen;
|
||||
if(cri_bitlen)
|
||||
evaluate_cri_report(payload,cri_bitlen,cumul_bits,sched_ctrl);
|
||||
cumul_bits += cri_bitlen;
|
||||
ri_bitlen = csi_report->csi_meas_bitlen.ri_bitlen;
|
||||
if(ri_bitlen)
|
||||
r_index = evaluate_ri_report(payload,ri_bitlen,csi_report->csi_meas_bitlen.ri_restriction,cumul_bits,sched_ctrl);
|
||||
cumul_bits += ri_bitlen;
|
||||
li_bitlen = evaluate_li_report(payload,csi_report,cumul_bits,r_index,sched_ctrl);
|
||||
cumul_bits += li_bitlen;
|
||||
if (r_index != -1)
|
||||
skip_zero_padding(&cumul_bits,csi_report,r_index,bitlen);
|
||||
pmi_bitlen = evaluate_pmi_report(payload,csi_report,cumul_bits,r_index,sched_ctrl);
|
||||
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.csi_report_id = csi_report_id;
|
||||
cumul_bits += pmi_bitlen;
|
||||
evaluate_cqi_report(payload,csi_report,cumul_bits,r_index,UE,cqi_table);
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0, "Invalid or not supported CSI measurement report\n");
|
||||
reportQuantity_type_r16 = csi_report->reportQuantity_type_r16;
|
||||
LOG_D(MAC, "SFN/SF:%d/%d reportQuantity type = %d, type_r16 = %d\n", frame, slot, reportQuantity_type, reportQuantity_type_r16);
|
||||
if (reportQuantity_type_r16 == NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_cri_SINR_r16
|
||||
|| reportQuantity_type_r16 == NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_ssb_Index_SINR_r16) {
|
||||
evaluate_sinr_report(nrmac, UE, sched_ctrl, csi_report_id, payload, &cumul_bits, reportQuantity_type_r16);
|
||||
} else {
|
||||
// phy-test has hardcoded allocation, so no use to handle CSI reports except RSRP
|
||||
if (get_softmodem_params()->phy_test
|
||||
&& reportQuantity_type != NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP
|
||||
&& reportQuantity_type != NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP)
|
||||
continue;
|
||||
switch (reportQuantity_type) {
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP:
|
||||
evaluate_rsrp_report(nrmac, UE, sched_ctrl, csi_report_id, payload, &cumul_bits, reportQuantity_type);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP:
|
||||
evaluate_rsrp_report(nrmac, UE, sched_ctrl, csi_report_id, payload, &cumul_bits, reportQuantity_type);
|
||||
beam_selection_procedures(nrmac, UE);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI:
|
||||
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.print_report = true;
|
||||
cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen;
|
||||
if (cri_bitlen)
|
||||
evaluate_cri_report(payload, cri_bitlen, cumul_bits, sched_ctrl);
|
||||
cumul_bits += cri_bitlen;
|
||||
ri_bitlen = csi_report->csi_meas_bitlen.ri_bitlen;
|
||||
if (ri_bitlen)
|
||||
r_index = evaluate_ri_report(payload, ri_bitlen, csi_report->csi_meas_bitlen.ri_restriction, cumul_bits, sched_ctrl);
|
||||
cumul_bits += ri_bitlen;
|
||||
if (r_index != -1)
|
||||
skip_zero_padding(&cumul_bits, csi_report, r_index, bitlen);
|
||||
evaluate_cqi_report(payload, csi_report, cumul_bits, r_index, UE, cqi_table);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI:
|
||||
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.print_report = true;
|
||||
cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen;
|
||||
if (cri_bitlen)
|
||||
evaluate_cri_report(payload, cri_bitlen, cumul_bits, sched_ctrl);
|
||||
cumul_bits += cri_bitlen;
|
||||
ri_bitlen = csi_report->csi_meas_bitlen.ri_bitlen;
|
||||
if (ri_bitlen)
|
||||
r_index = evaluate_ri_report(payload, ri_bitlen, csi_report->csi_meas_bitlen.ri_restriction, cumul_bits, sched_ctrl);
|
||||
cumul_bits += ri_bitlen;
|
||||
if (r_index != -1)
|
||||
skip_zero_padding(&cumul_bits, csi_report, r_index, bitlen);
|
||||
pmi_bitlen = evaluate_pmi_report(payload, csi_report, cumul_bits, r_index, sched_ctrl);
|
||||
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.csi_report_id = csi_report_id;
|
||||
cumul_bits += pmi_bitlen;
|
||||
evaluate_cqi_report(payload, csi_report, cumul_bits, r_index, UE, cqi_table);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI:
|
||||
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.print_report = true;
|
||||
cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen;
|
||||
if (cri_bitlen)
|
||||
evaluate_cri_report(payload, cri_bitlen, cumul_bits, sched_ctrl);
|
||||
cumul_bits += cri_bitlen;
|
||||
ri_bitlen = csi_report->csi_meas_bitlen.ri_bitlen;
|
||||
if (ri_bitlen)
|
||||
r_index = evaluate_ri_report(payload, ri_bitlen, csi_report->csi_meas_bitlen.ri_restriction, cumul_bits, sched_ctrl);
|
||||
cumul_bits += ri_bitlen;
|
||||
li_bitlen = evaluate_li_report(payload, csi_report, cumul_bits, r_index, sched_ctrl);
|
||||
cumul_bits += li_bitlen;
|
||||
if (r_index != -1)
|
||||
skip_zero_padding(&cumul_bits, csi_report, r_index, bitlen);
|
||||
pmi_bitlen = evaluate_pmi_report(payload, csi_report, cumul_bits, r_index, sched_ctrl);
|
||||
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.csi_report_id = csi_report_id;
|
||||
cumul_bits += pmi_bitlen;
|
||||
evaluate_cqi_report(payload, csi_report, cumul_bits, r_index, UE, cqi_table);
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1 == 0, "Invalid or not supported CSI measurement report\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,6 +179,7 @@ typedef struct nr_mac_config_t {
|
||||
int32_t *bw_list;
|
||||
int num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS];
|
||||
nr_redcap_config_t *redcap;
|
||||
bool do_SINR;
|
||||
} nr_mac_config_t;
|
||||
|
||||
typedef struct NR_preamble_ue {
|
||||
@@ -537,6 +538,8 @@ typedef struct RSRP_report {
|
||||
uint8_t nr_reports;
|
||||
uint8_t resource_id[MAX_NR_OF_REPORTED_RS];
|
||||
int RSRP[MAX_NR_OF_REPORTED_RS];
|
||||
// SINR index according to tables 10.1.16.1-1, 10.1.16.1-2
|
||||
int SINR_index[MAX_NR_OF_REPORTED_RS];
|
||||
} RSRP_report_t;
|
||||
|
||||
struct CSI_Report {
|
||||
|
||||
@@ -1133,10 +1133,11 @@ static nr_dci_format_t handle_dci(NR_UE_MAC_INST_t *mac,
|
||||
return nr_ue_process_dci_indication_pdu(mac, frame, slot, dci);
|
||||
}
|
||||
|
||||
static void handle_ssb_meas(NR_UE_MAC_INST_t *mac, uint8_t ssb_index, int16_t rsrp_dbm)
|
||||
static void handle_ssb_meas(NR_UE_MAC_INST_t *mac, uint8_t ssb_index, int16_t rsrp_dbm, float_t sinr_dB)
|
||||
{
|
||||
mac->ssb_measurements.ssb_index = ssb_index;
|
||||
mac->ssb_measurements.ssb_rsrp_dBm = rsrp_dbm;
|
||||
mac->ssb_measurements.ssb_sinr_dB = sinr_dB;
|
||||
}
|
||||
|
||||
// L2 Abstraction Layer
|
||||
@@ -1272,7 +1273,8 @@ static uint32_t nr_ue_dl_processing(NR_UE_MAC_INST_t *mac, nr_downlink_indicatio
|
||||
if(rx_indication_body.ssb_pdu.decoded_pdu) {
|
||||
handle_ssb_meas(mac,
|
||||
rx_indication_body.ssb_pdu.ssb_index,
|
||||
rx_indication_body.ssb_pdu.rsrp_dBm);
|
||||
rx_indication_body.ssb_pdu.rsrp_dBm,
|
||||
rx_indication_body.ssb_pdu.sinr_dB);
|
||||
ret_mask |= (handle_bcch_bch(mac,
|
||||
dl_info->cc_id,
|
||||
dl_info->gNB_index,
|
||||
|
||||
@@ -1934,7 +1934,8 @@ static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
|
||||
int rep_id,
|
||||
int uid,
|
||||
int curr_bwp,
|
||||
int num_antenna_ports)
|
||||
int num_antenna_ports,
|
||||
bool do_sinr)
|
||||
{
|
||||
int resource_id = -1;
|
||||
for (int csi_list = 0; csi_list < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_list++) {
|
||||
@@ -1968,6 +1969,14 @@ static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
|
||||
} else {
|
||||
csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP;
|
||||
csirep->reportQuantity.choice.ssb_Index_RSRP = (NULL_t)0;
|
||||
if (do_sinr) {
|
||||
csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_none;
|
||||
csirep->reportQuantity.choice.none = (NULL_t)0;
|
||||
csirep->ext2 = calloc(1, sizeof(*csirep->ext2));
|
||||
csirep->ext2->reportQuantity_r16 = calloc(1, sizeof(*csirep->ext2->reportQuantity_r16));
|
||||
csirep->ext2->reportQuantity_r16->present = NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_ssb_Index_SINR_r16;
|
||||
csirep->ext2->reportQuantity_r16->choice.ssb_Index_SINR_r16 = (NULL_t)0;
|
||||
}
|
||||
}
|
||||
csirep->groupBasedBeamReporting.present = NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled;
|
||||
csirep->groupBasedBeamReporting.choice.disabled = calloc(1, sizeof(*csirep->groupBasedBeamReporting.choice.disabled));
|
||||
@@ -3298,7 +3307,15 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid,
|
||||
NR_PUCCH_CSI_Resource_t *pucchrsrp = calloc(1, sizeof(*pucchrsrp));
|
||||
pucchrsrp->uplinkBandwidthPartId = bwp_id;
|
||||
pucchrsrp->pucch_Resource = pucch_Resource;
|
||||
config_rsrp_meas_report(csi_MeasConfig, scc, pucchrsrp, configuration->do_CSIRS, bwp_id + 10, uid, curr_bwp, pdsch_AntennaPorts);
|
||||
config_rsrp_meas_report(csi_MeasConfig,
|
||||
scc,
|
||||
pucchrsrp,
|
||||
configuration->do_CSIRS,
|
||||
bwp_id + 10,
|
||||
uid,
|
||||
curr_bwp,
|
||||
pdsch_AntennaPorts,
|
||||
configuration->do_SINR);
|
||||
}
|
||||
|
||||
fill_harq_IEs(SpCellConfig->spCellConfigDedicated, configuration->num_dlharq, configuration->num_ulharq);
|
||||
@@ -3811,7 +3828,8 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC
|
||||
bwp->bwp_Id + 10,
|
||||
uid,
|
||||
curr_bwp,
|
||||
dl_antenna_ports);
|
||||
dl_antenna_ports,
|
||||
configuration->do_SINR);
|
||||
}
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->sCellDeactivationTimer = NULL;
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig = NULL;
|
||||
|
||||
Reference in New Issue
Block a user