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
|
* `do_CSIRS` (default 0): flag whether to use channel-state information
|
||||||
reference signal (CSI-RS)
|
reference signal (CSI-RS)
|
||||||
* `do_SRS` (default 0): flag whether to use sounding reference signal (SRS)
|
* `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
|
* `min_rxtxtime` (default 2): minimum feedback time for UE to respond to
|
||||||
transmissions (k1 and k2 in 3GPP spec)
|
transmissions (k1 and k2 in 3GPP spec)
|
||||||
* `ul_prbblacklist`: PRBs that should not be used for UL scheduling. Cf with
|
* `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,
|
- `du_sibs` (default `[]`): list of SIBs to transmit in the cell. Currently,
|
||||||
SIB19 (for NTN) is supported.
|
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
|
## ServingCellConfigCommon parameters
|
||||||
|
|
||||||
The `gNBs` configuration section has a big structure `servingCellConfigCommon`
|
The `gNBs` configuration section has a big structure `servingCellConfigCommon`
|
||||||
|
|||||||
@@ -129,6 +129,8 @@ typedef struct {
|
|||||||
short rsrp_dBm;
|
short rsrp_dBm;
|
||||||
long arfcn;
|
long arfcn;
|
||||||
rlm_t radiolink_monitoring; // -1 no monitoring, 0 out_of_sync, 1 in_sync
|
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;
|
} fapi_nr_ssb_pdu_t;
|
||||||
|
|
||||||
typedef struct {
|
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" );
|
AssertFatal( nb_connected_gNB <= NUMBER_OF_CONNECTED_gNB_MAX, "n_connected_gNB is too large" );
|
||||||
// init phy_vars_ue
|
// 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_rsrp_dBm[i] = INT_MIN;
|
||||||
|
ue->measurements.ssb_sinr_dB[i] = INT_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
ue->rx_gain_max[i] = 135;
|
ue->rx_gain_max[i] = 135;
|
||||||
|
|||||||
@@ -111,11 +111,11 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
|
|||||||
uint32_t pdsch_est_size,
|
uint32_t pdsch_est_size,
|
||||||
int32_t dl_ch_estimates[][pdsch_est_size]);
|
int32_t dl_ch_estimates[][pdsch_est_size]);
|
||||||
|
|
||||||
int nr_ue_calculate_ssb_rsrp(const NR_DL_FRAME_PARMS *fp,
|
uint32_t nr_ue_calculate_ssb_rsrp(const NR_DL_FRAME_PARMS *fp,
|
||||||
const UE_nr_rxtx_proc_t *proc,
|
const UE_nr_rxtx_proc_t *proc,
|
||||||
const c16_t rxdataF[][fp->samples_per_slot_wCP],
|
const c16_t rxdataF[][fp->samples_per_slot_wCP],
|
||||||
int symbol_offset,
|
int symbol_offset,
|
||||||
int ssb_start_subcarrier);
|
int ssb_start_subcarrier);
|
||||||
|
|
||||||
void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
|
void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
|
||||||
uint8_t gNB_index,
|
uint8_t gNB_index,
|
||||||
|
|||||||
@@ -172,11 +172,11 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
|
|||||||
|
|
||||||
// This function calculates:
|
// This function calculates:
|
||||||
// - SS reference signal received digital power in dB/RE
|
// - SS reference signal received digital power in dB/RE
|
||||||
int nr_ue_calculate_ssb_rsrp(const NR_DL_FRAME_PARMS *fp,
|
uint32_t nr_ue_calculate_ssb_rsrp(const NR_DL_FRAME_PARMS *fp,
|
||||||
const UE_nr_rxtx_proc_t *proc,
|
const UE_nr_rxtx_proc_t *proc,
|
||||||
const c16_t rxdataF[][fp->samples_per_slot_wCP],
|
const c16_t rxdataF[][fp->samples_per_slot_wCP],
|
||||||
int symbol_offset,
|
int symbol_offset,
|
||||||
int ssb_start_subcarrier)
|
int ssb_start_subcarrier)
|
||||||
{
|
{
|
||||||
int k_start = 56;
|
int k_start = 56;
|
||||||
int k_end = 183;
|
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);
|
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;
|
||||||
|
|
||||||
return rsrp_db_per_re;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function implements:
|
// This function implements:
|
||||||
@@ -234,7 +232,8 @@ void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
|
|||||||
if (fp->half_frame_bit)
|
if (fp->half_frame_bit)
|
||||||
symbol_offset += (fp->slots_per_frame >> 1) * fp->symbols_per_slot;
|
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];
|
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])
|
- ((int)cfg0->rx_gain[0] - (int)cfg0->rx_gain_offset[0])
|
||||||
- dB_fixed(fp->ofdm_symbol_size);
|
- 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,
|
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,
|
ue->Mod_id,
|
||||||
ssb_index,
|
ssb_index,
|
||||||
ue->measurements.ssb_rsrp_dBm[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
|
// This function computes the received noise power
|
||||||
|
|||||||
@@ -285,7 +285,8 @@ void nr_scan_ssb(void *arg)
|
|||||||
&ssbInfo->pbchResult,
|
&ssbInfo->pbchResult,
|
||||||
rxdataF); // start pbch detection at first symbol after pss
|
rxdataF); // start pbch detection at first symbol after pss
|
||||||
if (ssbInfo->syncRes.cell_detected) {
|
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;
|
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);
|
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];
|
uint32_t rsrp[7];
|
||||||
short rsrp_dBm[7];
|
short rsrp_dBm[7];
|
||||||
int ssb_rsrp_dBm[64];
|
int ssb_rsrp_dBm[64];
|
||||||
|
float ssb_sinr_dB[64];
|
||||||
// common measurements
|
// common measurements
|
||||||
//! estimated noise power (linear)
|
//! estimated noise power (linear)
|
||||||
unsigned int n0_power[NB_ANTENNAS_RX];
|
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.cell_id = frame_parms->Nid_cell;
|
||||||
rx->ssb_pdu.ssb_start_subcarrier = frame_parms->ssb_start_subcarrier;
|
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.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.arfcn = get_ssb_arfcn(frame_parms);
|
||||||
rx->ssb_pdu.radiolink_monitoring = RLM_in_sync; // TODO to be removed from here
|
rx->ssb_pdu.radiolink_monitoring = RLM_in_sync; // TODO to be removed from here
|
||||||
rx->ssb_pdu.decoded_pdu = true;
|
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_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_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_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
|
// check for some general sections
|
||||||
verify_section_notset(cfg, NULL, CONFIG_STRING_L1_LIST);
|
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);
|
LOG_I(GNB_APP, "SIB1 TDA %d\n", config.sib1_tda);
|
||||||
config.do_CSIRS = *GNBParamList.paramarray[0][GNB_DO_CSIRS_IDX].iptr;
|
config.do_CSIRS = *GNBParamList.paramarray[0][GNB_DO_CSIRS_IDX].iptr;
|
||||||
config.do_SRS = *GNBParamList.paramarray[0][GNB_DO_SRS_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_256qam_off = *GNBParamList.paramarray[0][GNB_FORCE256QAMOFF_IDX].iptr;
|
||||||
config.force_UL256qam_off = *GNBParamList.paramarray[0][GNB_FORCEUL256QAMOFF_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;
|
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)
|
if (config.disable_harq)
|
||||||
LOG_W(GNB_APP, "\"disable_harq\" is a REL17 feature and is incompatible with REL15 and REL16 UEs!\n");
|
LOG_W(GNB_APP, "\"disable_harq\" is a REL17 feature and is incompatible with REL15 and REL16 UEs!\n");
|
||||||
LOG_I(GNB_APP,
|
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_CSIRS,
|
||||||
config.do_SRS,
|
config.do_SRS,
|
||||||
|
config.do_SINR,
|
||||||
config.force_256qam_off ? "force off" : "may be on",
|
config.force_256qam_off ? "force off" : "may be on",
|
||||||
config.use_deltaMCS ? "on" : "off",
|
config.use_deltaMCS ? "on" : "off",
|
||||||
config.maxMIMO_layers,
|
config.maxMIMO_layers,
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ typedef enum {
|
|||||||
#define GNB_CONFIG_STRING_UESS_AGG_LEVEL_LIST "uess_agg_levels"
|
#define GNB_CONFIG_STRING_UESS_AGG_LEVEL_LIST "uess_agg_levels"
|
||||||
#define GNB_CONFIG_STRING_CU_SIB_LIST "cu_sibs"
|
#define GNB_CONFIG_STRING_CU_SIB_LIST "cu_sibs"
|
||||||
#define GNB_CONFIG_STRING_DU_SIB_LIST "du_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_STRING_ENABLE_SDAP "enable the SDAP layer\n"
|
||||||
#define GNB_CONFIG_HLP_FORCE256QAMOFF "suppress activation of 256 QAM despite UE support"
|
#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_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_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_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 */
|
/* 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_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_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_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
|
// clang-format on
|
||||||
|
|
||||||
@@ -244,6 +247,7 @@ typedef enum {
|
|||||||
#define GNB_UESS_AGG_LEVEL_LIST_IDX 36
|
#define GNB_UESS_AGG_LEVEL_LIST_IDX 36
|
||||||
#define GNB_CU_SIBS_IDX 37
|
#define GNB_CU_SIBS_IDX 37
|
||||||
#define GNB_DU_SIBS_IDX 38
|
#define GNB_DU_SIBS_IDX 38
|
||||||
|
#define GNB_DO_SINR_IDX 39
|
||||||
|
|
||||||
#define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
|
#define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
|
||||||
#define NUM_DL_HARQ_OKVALUES {2,4,6,8,10,12,16,32}
|
#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 } }, \
|
||||||
{ .s5 = { NULL } }, \
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|||||||
@@ -517,7 +517,9 @@ typedef struct {
|
|||||||
uint8_t cri_ssbri_bitlen;
|
uint8_t cri_ssbri_bitlen;
|
||||||
uint8_t rsrp_bitlen;
|
uint8_t rsrp_bitlen;
|
||||||
uint8_t diff_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{
|
typedef struct{
|
||||||
uint8_t ri_restriction;
|
uint8_t ri_restriction;
|
||||||
@@ -535,13 +537,14 @@ typedef struct{
|
|||||||
typedef struct nr_csi_report {
|
typedef struct nr_csi_report {
|
||||||
NR_CSI_ReportConfigId_t reportConfigId;
|
NR_CSI_ReportConfigId_t reportConfigId;
|
||||||
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type;
|
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type;
|
||||||
|
NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR reportQuantity_type_r16;
|
||||||
long periodicity;
|
long periodicity;
|
||||||
uint16_t offset;
|
uint16_t offset;
|
||||||
long **SSB_Index_list;
|
long **SSB_Index_list;
|
||||||
long **CSI_Index_list;
|
long **CSI_Index_list;
|
||||||
// uint8_t nb_of_nzp_csi_report;
|
// uint8_t nb_of_nzp_csi_report;
|
||||||
uint8_t nb_of_csi_ssb_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;
|
CSI_Meas_bitlen_t csi_meas_bitlen;
|
||||||
int codebook_mode;
|
int codebook_mode;
|
||||||
int N1;
|
int N1;
|
||||||
|
|||||||
@@ -4427,7 +4427,10 @@ static uint8_t number_of_bits_set(uint8_t buf)
|
|||||||
return nb_of_bits_set;
|
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 (NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled == csi_reportconfig->groupBasedBeamReporting.present) {
|
||||||
if (csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS)
|
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;
|
csi_report->CSI_report_bitlen.nb_ssbri_cri = 2;
|
||||||
|
|
||||||
if (nb_resources) {
|
if (nb_resources) {
|
||||||
csi_report->CSI_report_bitlen.cri_ssbri_bitlen =ceil(log2 (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
|
if (is_RSRP_configured) {
|
||||||
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.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 {
|
} else {
|
||||||
csi_report->CSI_report_bitlen.cri_ssbri_bitlen = 0;
|
csi_report->CSI_report_bitlen.cri_ssbri_bitlen = 0;
|
||||||
csi_report->CSI_report_bitlen.rsrp_bitlen = 0;
|
csi_report->CSI_report_bitlen.rsrp_bitlen = 0;
|
||||||
csi_report->CSI_report_bitlen.diff_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;
|
reportQuantity_type = csi_reportconfig->reportQuantity.present;
|
||||||
csi_report->reportQuantity_type = reportQuantity_type;
|
csi_report->reportQuantity_type = reportQuantity_type;
|
||||||
csi_report->reportConfigId = csi_reportconfig->reportConfigId;
|
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
|
// 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++) {
|
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 ==
|
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])){
|
*(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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (resourceType == NR_CSI_ResourceConfig__resourceType_periodic) {
|
if (resourceType == NR_CSI_ResourceConfig__resourceType_periodic) {
|
||||||
AssertFatal(csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList != NULL,
|
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");
|
"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);
|
LOG_D(NR_MAC,"nb_resources %d\n",nb_resources);
|
||||||
// computation of bit length depending on the report type
|
// computation of bit length depending on the report type
|
||||||
switch(reportQuantity_type){
|
if (csi_report->reportQuantity_type_r16 != NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_NOTHING) {
|
||||||
case (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP):
|
switch (csi_report->reportQuantity_type_r16) {
|
||||||
compute_rsrp_bitlen(csi_reportconfig, nb_resources, csi_report);
|
case NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_ssb_Index_SINR_r16:
|
||||||
break;
|
compute_rsrp_or_sinr_bitlen(csi_reportconfig, nb_resources, csi_report, false);
|
||||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP):
|
break;
|
||||||
compute_rsrp_bitlen(csi_reportconfig, nb_resources, csi_report);
|
case NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_cri_SINR_r16:
|
||||||
break;
|
compute_rsrp_or_sinr_bitlen(csi_reportconfig, nb_resources, csi_report, false);
|
||||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI):
|
break;
|
||||||
csi_report->csi_meas_bitlen.cri_bitlen = ceil(log2(nb_resources));
|
default:
|
||||||
csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report);
|
AssertFatal(1 == 0, "Not yet supported CSI report quantity type");
|
||||||
compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
}
|
||||||
break;
|
} else {
|
||||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI):
|
switch (reportQuantity_type) {
|
||||||
csi_report->csi_meas_bitlen.cri_bitlen = ceil(log2(nb_resources));
|
case (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP):
|
||||||
csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report);
|
compute_rsrp_or_sinr_bitlen(csi_reportconfig, nb_resources, csi_report, true);
|
||||||
compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
break;
|
||||||
compute_pmi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP):
|
||||||
break;
|
compute_rsrp_or_sinr_bitlen(csi_reportconfig, nb_resources, csi_report, true);
|
||||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI):
|
break;
|
||||||
csi_report->csi_meas_bitlen.cri_bitlen = ceil(log2(nb_resources));
|
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI):
|
||||||
csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report);
|
csi_report->csi_meas_bitlen.cri_bitlen = ceil(log2(nb_resources));
|
||||||
compute_li_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
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_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;
|
||||||
break;
|
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI):
|
||||||
default:
|
csi_report->csi_meas_bitlen.cri_bitlen = ceil(log2(nb_resources));
|
||||||
AssertFatal(1==0,"Not yet supported CSI report quantity type");
|
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 csi_bitlen = 0;
|
||||||
uint16_t max_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;
|
CSI_Meas_bitlen_t *csi_meas_bitlen = NULL;
|
||||||
|
|
||||||
if (csi_report->reportQuantity_type == NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP ||
|
if (csi_report->reportQuantity_type_r16 == NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_ssb_Index_SINR_r16
|
||||||
csi_report->reportQuantity_type == NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP) {
|
|| 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_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_bitlen += ((CSI_report_bitlen->cri_ssbri_bitlen * CSI_report_bitlen->nb_ssbri_cri) +
|
||||||
CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen *
|
CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen *
|
||||||
|
|||||||
@@ -417,6 +417,7 @@ typedef struct {
|
|||||||
uint32_t ssb_index;
|
uint32_t ssb_index;
|
||||||
/// SSB RSRP in dBm
|
/// SSB RSRP in dBm
|
||||||
short ssb_rsrp_dBm;
|
short ssb_rsrp_dBm;
|
||||||
|
float_t ssb_sinr_dB;
|
||||||
} NR_SSB_meas_t;
|
} NR_SSB_meas_t;
|
||||||
|
|
||||||
typedef enum ta_type {
|
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;
|
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,
|
csi_payload_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac,
|
||||||
int csi_report_id,
|
int csi_report_id,
|
||||||
CSI_mapping_t mapping_type,
|
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};
|
csi_payload_t csi = {0};
|
||||||
struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
|
struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
|
||||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement;
|
NR_CSI_ResourceConfigId_t csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement;
|
||||||
switch(csi_reportconfig->reportQuantity.present) {
|
if (csi_reportconfig->ext2 && csi_reportconfig->ext2->reportQuantity_r16) {
|
||||||
case NR_CSI_ReportConfig__reportQuantity_PR_none:
|
switch (csi_reportconfig->ext2->reportQuantity_r16->present) {
|
||||||
break;
|
case NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_ssb_Index_SINR_r16:
|
||||||
case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP:
|
csi = get_ssb_sinr_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig);
|
||||||
csi = get_ssb_rsrp_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig);
|
break;
|
||||||
break;
|
case NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_cri_SINR_r16:
|
||||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI:
|
LOG_E(NR_MAC, "CSI Reporting of CSI-RS based SINR not yet available\n");
|
||||||
csi = get_csirs_RI_PMI_CQI_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig, mapping_type);
|
break;
|
||||||
break;
|
default:
|
||||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP:
|
AssertFatal(1 == 0, "Invalid CSI report quantity r16 type %d\n", csi_reportconfig->ext2->reportQuantity_r16->present);
|
||||||
csi = get_csirs_RSRP_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig);
|
}
|
||||||
break;
|
} else {
|
||||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1:
|
switch (csi_reportconfig->reportQuantity.present) {
|
||||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI:
|
case NR_CSI_ReportConfig__reportQuantity_PR_none:
|
||||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI:
|
break;
|
||||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI:
|
case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP:
|
||||||
LOG_E(NR_MAC,"Measurement report %d based on CSI-RS is not available\n", csi_reportconfig->reportQuantity.present);
|
csi = get_ssb_rsrp_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig);
|
||||||
break;
|
break;
|
||||||
default:
|
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI:
|
||||||
AssertFatal(1==0,"Invalid CSI report quantity type %d\n",csi_reportconfig->reportQuantity.present);
|
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;
|
return csi;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -429,6 +429,78 @@ static uint8_t pickandreverse_bits(uint8_t *payload, uint16_t bitlen, uint8_t st
|
|||||||
return rev_bits;
|
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,
|
static void evaluate_rsrp_report(gNB_MAC_INST *nrmac,
|
||||||
NR_UE_info_t *UE,
|
NR_UE_info_t *UE,
|
||||||
NR_UE_sched_ctrl_t *sched_ctrl,
|
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;
|
uint8_t *payload = uci_pdu->csi_part1.csi_part1_payload;
|
||||||
uint16_t bitlen = uci_pdu->csi_part1.csi_part1_bit_len;
|
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__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_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||||
NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
|
NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
|
||||||
NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_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
|
// verify if report with current id has been scheduled for this frame and slot
|
||||||
if ((n_slots_frame*frame + slot - offset)%period == 0) {
|
if ((n_slots_frame*frame + slot - offset)%period == 0) {
|
||||||
reportQuantity_type = csi_report->reportQuantity_type;
|
reportQuantity_type = csi_report->reportQuantity_type;
|
||||||
// phy-test has hardcoded allocation, so no use to handle CSI reports except RSRP
|
reportQuantity_type_r16 = csi_report->reportQuantity_type_r16;
|
||||||
if (get_softmodem_params()->phy_test
|
LOG_D(MAC, "SFN/SF:%d/%d reportQuantity type = %d, type_r16 = %d\n", frame, slot, reportQuantity_type, reportQuantity_type_r16);
|
||||||
&& reportQuantity_type != NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP
|
if (reportQuantity_type_r16 == NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_cri_SINR_r16
|
||||||
&& reportQuantity_type != NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP)
|
|| reportQuantity_type_r16 == NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_ssb_Index_SINR_r16) {
|
||||||
continue;
|
evaluate_sinr_report(nrmac, UE, sched_ctrl, csi_report_id, payload, &cumul_bits, reportQuantity_type_r16);
|
||||||
LOG_D(MAC,"SFN/SF:%d/%d reportQuantity type = %d\n",frame,slot,reportQuantity_type);
|
} else {
|
||||||
switch(reportQuantity_type) {
|
// phy-test has hardcoded allocation, so no use to handle CSI reports except RSRP
|
||||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP:
|
if (get_softmodem_params()->phy_test
|
||||||
evaluate_rsrp_report(nrmac, UE, sched_ctrl, csi_report_id, payload, &cumul_bits, reportQuantity_type);
|
&& reportQuantity_type != NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP
|
||||||
break;
|
&& reportQuantity_type != NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP)
|
||||||
case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP:
|
continue;
|
||||||
evaluate_rsrp_report(nrmac, UE, sched_ctrl, csi_report_id, payload, &cumul_bits, reportQuantity_type);
|
switch (reportQuantity_type) {
|
||||||
beam_selection_procedures(nrmac, UE);
|
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP:
|
||||||
break;
|
evaluate_rsrp_report(nrmac, UE, sched_ctrl, csi_report_id, payload, &cumul_bits, reportQuantity_type);
|
||||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI:
|
break;
|
||||||
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.print_report = true;
|
case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP:
|
||||||
cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen;
|
evaluate_rsrp_report(nrmac, UE, sched_ctrl, csi_report_id, payload, &cumul_bits, reportQuantity_type);
|
||||||
if(cri_bitlen)
|
beam_selection_procedures(nrmac, UE);
|
||||||
evaluate_cri_report(payload,cri_bitlen,cumul_bits,sched_ctrl);
|
break;
|
||||||
cumul_bits += cri_bitlen;
|
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI:
|
||||||
ri_bitlen = csi_report->csi_meas_bitlen.ri_bitlen;
|
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.print_report = true;
|
||||||
if(ri_bitlen)
|
cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen;
|
||||||
r_index = evaluate_ri_report(payload,ri_bitlen,csi_report->csi_meas_bitlen.ri_restriction,cumul_bits,sched_ctrl);
|
if (cri_bitlen)
|
||||||
cumul_bits += ri_bitlen;
|
evaluate_cri_report(payload, cri_bitlen, cumul_bits, sched_ctrl);
|
||||||
if (r_index != -1)
|
cumul_bits += cri_bitlen;
|
||||||
skip_zero_padding(&cumul_bits,csi_report,r_index,bitlen);
|
ri_bitlen = csi_report->csi_meas_bitlen.ri_bitlen;
|
||||||
evaluate_cqi_report(payload,csi_report,cumul_bits,r_index,UE,cqi_table);
|
if (ri_bitlen)
|
||||||
break;
|
r_index = evaluate_ri_report(payload, ri_bitlen, csi_report->csi_meas_bitlen.ri_restriction, cumul_bits, sched_ctrl);
|
||||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI:
|
cumul_bits += ri_bitlen;
|
||||||
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.print_report = true;
|
if (r_index != -1)
|
||||||
cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen;
|
skip_zero_padding(&cumul_bits, csi_report, r_index, bitlen);
|
||||||
if(cri_bitlen)
|
evaluate_cqi_report(payload, csi_report, cumul_bits, r_index, UE, cqi_table);
|
||||||
evaluate_cri_report(payload,cri_bitlen,cumul_bits,sched_ctrl);
|
break;
|
||||||
cumul_bits += cri_bitlen;
|
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI:
|
||||||
ri_bitlen = csi_report->csi_meas_bitlen.ri_bitlen;
|
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.print_report = true;
|
||||||
if(ri_bitlen)
|
cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen;
|
||||||
r_index = evaluate_ri_report(payload,ri_bitlen,csi_report->csi_meas_bitlen.ri_restriction,cumul_bits,sched_ctrl);
|
if (cri_bitlen)
|
||||||
cumul_bits += ri_bitlen;
|
evaluate_cri_report(payload, cri_bitlen, cumul_bits, sched_ctrl);
|
||||||
if (r_index != -1)
|
cumul_bits += cri_bitlen;
|
||||||
skip_zero_padding(&cumul_bits,csi_report,r_index,bitlen);
|
ri_bitlen = csi_report->csi_meas_bitlen.ri_bitlen;
|
||||||
pmi_bitlen = evaluate_pmi_report(payload,csi_report,cumul_bits,r_index,sched_ctrl);
|
if (ri_bitlen)
|
||||||
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.csi_report_id = csi_report_id;
|
r_index = evaluate_ri_report(payload, ri_bitlen, csi_report->csi_meas_bitlen.ri_restriction, cumul_bits, sched_ctrl);
|
||||||
cumul_bits += pmi_bitlen;
|
cumul_bits += ri_bitlen;
|
||||||
evaluate_cqi_report(payload,csi_report,cumul_bits,r_index,UE,cqi_table);
|
if (r_index != -1)
|
||||||
break;
|
skip_zero_padding(&cumul_bits, csi_report, r_index, bitlen);
|
||||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI:
|
pmi_bitlen = evaluate_pmi_report(payload, csi_report, cumul_bits, r_index, sched_ctrl);
|
||||||
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.print_report = true;
|
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.csi_report_id = csi_report_id;
|
||||||
cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen;
|
cumul_bits += pmi_bitlen;
|
||||||
if(cri_bitlen)
|
evaluate_cqi_report(payload, csi_report, cumul_bits, r_index, UE, cqi_table);
|
||||||
evaluate_cri_report(payload,cri_bitlen,cumul_bits,sched_ctrl);
|
break;
|
||||||
cumul_bits += cri_bitlen;
|
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI:
|
||||||
ri_bitlen = csi_report->csi_meas_bitlen.ri_bitlen;
|
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.print_report = true;
|
||||||
if(ri_bitlen)
|
cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen;
|
||||||
r_index = evaluate_ri_report(payload,ri_bitlen,csi_report->csi_meas_bitlen.ri_restriction,cumul_bits,sched_ctrl);
|
if (cri_bitlen)
|
||||||
cumul_bits += ri_bitlen;
|
evaluate_cri_report(payload, cri_bitlen, cumul_bits, sched_ctrl);
|
||||||
li_bitlen = evaluate_li_report(payload,csi_report,cumul_bits,r_index,sched_ctrl);
|
cumul_bits += cri_bitlen;
|
||||||
cumul_bits += li_bitlen;
|
ri_bitlen = csi_report->csi_meas_bitlen.ri_bitlen;
|
||||||
if (r_index != -1)
|
if (ri_bitlen)
|
||||||
skip_zero_padding(&cumul_bits,csi_report,r_index,bitlen);
|
r_index = evaluate_ri_report(payload, ri_bitlen, csi_report->csi_meas_bitlen.ri_restriction, cumul_bits, sched_ctrl);
|
||||||
pmi_bitlen = evaluate_pmi_report(payload,csi_report,cumul_bits,r_index,sched_ctrl);
|
cumul_bits += ri_bitlen;
|
||||||
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.csi_report_id = csi_report_id;
|
li_bitlen = evaluate_li_report(payload, csi_report, cumul_bits, r_index, sched_ctrl);
|
||||||
cumul_bits += pmi_bitlen;
|
cumul_bits += li_bitlen;
|
||||||
evaluate_cqi_report(payload,csi_report,cumul_bits,r_index,UE,cqi_table);
|
if (r_index != -1)
|
||||||
break;
|
skip_zero_padding(&cumul_bits, csi_report, r_index, bitlen);
|
||||||
default:
|
pmi_bitlen = evaluate_pmi_report(payload, csi_report, cumul_bits, r_index, sched_ctrl);
|
||||||
AssertFatal(1==0, "Invalid or not supported CSI measurement report\n");
|
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;
|
int32_t *bw_list;
|
||||||
int num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS];
|
int num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS];
|
||||||
nr_redcap_config_t *redcap;
|
nr_redcap_config_t *redcap;
|
||||||
|
bool do_SINR;
|
||||||
} nr_mac_config_t;
|
} nr_mac_config_t;
|
||||||
|
|
||||||
typedef struct NR_preamble_ue {
|
typedef struct NR_preamble_ue {
|
||||||
@@ -537,6 +538,8 @@ typedef struct RSRP_report {
|
|||||||
uint8_t nr_reports;
|
uint8_t nr_reports;
|
||||||
uint8_t resource_id[MAX_NR_OF_REPORTED_RS];
|
uint8_t resource_id[MAX_NR_OF_REPORTED_RS];
|
||||||
int RSRP[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;
|
} RSRP_report_t;
|
||||||
|
|
||||||
struct CSI_Report {
|
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);
|
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_index = ssb_index;
|
||||||
mac->ssb_measurements.ssb_rsrp_dBm = rsrp_dbm;
|
mac->ssb_measurements.ssb_rsrp_dBm = rsrp_dbm;
|
||||||
|
mac->ssb_measurements.ssb_sinr_dB = sinr_dB;
|
||||||
}
|
}
|
||||||
|
|
||||||
// L2 Abstraction Layer
|
// 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) {
|
if(rx_indication_body.ssb_pdu.decoded_pdu) {
|
||||||
handle_ssb_meas(mac,
|
handle_ssb_meas(mac,
|
||||||
rx_indication_body.ssb_pdu.ssb_index,
|
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,
|
ret_mask |= (handle_bcch_bch(mac,
|
||||||
dl_info->cc_id,
|
dl_info->cc_id,
|
||||||
dl_info->gNB_index,
|
dl_info->gNB_index,
|
||||||
|
|||||||
@@ -1934,7 +1934,8 @@ static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
|
|||||||
int rep_id,
|
int rep_id,
|
||||||
int uid,
|
int uid,
|
||||||
int curr_bwp,
|
int curr_bwp,
|
||||||
int num_antenna_ports)
|
int num_antenna_ports,
|
||||||
|
bool do_sinr)
|
||||||
{
|
{
|
||||||
int resource_id = -1;
|
int resource_id = -1;
|
||||||
for (int csi_list = 0; csi_list < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_list++) {
|
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 {
|
} else {
|
||||||
csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP;
|
csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP;
|
||||||
csirep->reportQuantity.choice.ssb_Index_RSRP = (NULL_t)0;
|
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.present = NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled;
|
||||||
csirep->groupBasedBeamReporting.choice.disabled = calloc(1, sizeof(*csirep->groupBasedBeamReporting.choice.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));
|
NR_PUCCH_CSI_Resource_t *pucchrsrp = calloc(1, sizeof(*pucchrsrp));
|
||||||
pucchrsrp->uplinkBandwidthPartId = bwp_id;
|
pucchrsrp->uplinkBandwidthPartId = bwp_id;
|
||||||
pucchrsrp->pucch_Resource = pucch_Resource;
|
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);
|
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,
|
bwp->bwp_Id + 10,
|
||||||
uid,
|
uid,
|
||||||
curr_bwp,
|
curr_bwp,
|
||||||
dl_antenna_ports);
|
dl_antenna_ports,
|
||||||
|
configuration->do_SINR);
|
||||||
}
|
}
|
||||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->sCellDeactivationTimer = NULL;
|
secondaryCellGroup->spCellConfig->spCellConfigDedicated->sCellDeactivationTimer = NULL;
|
||||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig = NULL;
|
secondaryCellGroup->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig = NULL;
|
||||||
|
|||||||
Reference in New Issue
Block a user