diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index a9e83758f6..6bea8f55cc 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -59,7 +59,9 @@ typedef struct { uint16_t Nid_cell; nfapi_nr_meas_type_e meas_type; bool is_neighboring_cell; - uint8_t rsrp_dBm; + int ssb_index; + int rsrp_dBm; + float sinr_dB; uint8_t rank_indicator; uint16_t i1; uint8_t i2; @@ -133,11 +135,8 @@ typedef struct { uint8_t ssb_length; uint16_t cell_id; uint16_t ssb_start_subcarrier; - 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 { diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c index 825e025308..747a000c4d 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -264,6 +264,7 @@ void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue, .gNB_index = proc->gNB_id, .meas_type = NFAPI_NR_SS_MEAS, .Nid_cell = ue->frame_parms.Nid_cell, + .ssb_index = ssb_index, .is_neighboring_cell = false, }; int ssb_rsrp_dBm = ue->measurements.ssb_rsrp_dBm[ssb_index]; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 25447e4bb4..afb71ed164 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -176,8 +176,6 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, rx->ssb_pdu.ssb_length = frame_parms->Lmax; 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; @@ -967,31 +965,38 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ nr_ue_ssb_rsrp_measurements(ue, ssb_index, proc, rxdataF); // resetting ssb index for PBCH detection if there is a stronger SSB index - if(ue->measurements.ssb_rsrp_dBm[ssb_index] > ue->measurements.ssb_rsrp_dBm[fp->ssb_index]) + if(ue->measurements.ssb_rsrp_dBm[ssb_index] > ue->measurements.ssb_rsrp_dBm[fp->ssb_index]) { fp->ssb_index = ssb_index; - - if(ssb_index == fp->ssb_index) { - - LOG_D(PHY," ------ Decode MIB: frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx); - const int pbchSuccess = nr_ue_pbch_procedures(ue, proc, estimateSz, dl_ch_estimates, rxdataF); - - if (ue->no_timing_correction==0 && pbchSuccess == 0) { - LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction); - sampleShift = - nr_adjust_synch_ue(fp, ue, gNB_id, fp->ofdm_symbol_size, dl_ch_estimates_time, frame_rx, nr_slot_rx, 16384); - } - - if (get_nrUE_params()->cont_fo_comp && pbchSuccess == 0) { - double freq_offset = nr_ue_pbch_freq_offset(fp, estimateSz, dl_ch_estimates); - LOG_D(PHY,"compensated frequency offset = %.3f Hz, detected residual frequency offset = %.3f Hz, accumulated frequency offset = %.3f Hz\n", ue->freq_offset, freq_offset, ue->freq_off_acc); - - // PI controller - const double PID_P = get_nrUE_params()->freq_sync_P; - const double PID_I = get_nrUE_params()->freq_sync_I; - ue->freq_offset += freq_offset * PID_P + ue->freq_off_acc * PID_I; - ue->freq_off_acc += freq_offset; - } + LOG_D(PHY, "New best SSB: index %d RSRP %d\n", ssb_index, ue->measurements.ssb_rsrp_dBm[ssb_index]); } + + if(ssb_index != fp->ssb_index) + continue; + + LOG_D(PHY, " ------ Decode MIB: frame.slot %d.%d ------ \n", frame_rx % 1024, nr_slot_rx); + const int pbchSuccess = nr_ue_pbch_procedures(ue, proc, estimateSz, dl_ch_estimates, rxdataF); + + if (ue->no_timing_correction == 0 && pbchSuccess == 0) { + LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction); + sampleShift = + nr_adjust_synch_ue(fp, ue, gNB_id, fp->ofdm_symbol_size, dl_ch_estimates_time, frame_rx, nr_slot_rx, 16384); + } + + if (get_nrUE_params()->cont_fo_comp && pbchSuccess == 0) { + double freq_offset = nr_ue_pbch_freq_offset(fp, estimateSz, dl_ch_estimates); + LOG_D(PHY, + "compensated freq offset = %.3f Hz, detected residual freq offset = %.3f Hz, accumulated freq offset = %.3f Hz\n", + ue->freq_offset, + freq_offset, + ue->freq_off_acc); + + // PI controller + const double PID_P = get_nrUE_params()->freq_sync_P; + const double PID_I = get_nrUE_params()->freq_sync_I; + ue->freq_offset += freq_offset * PID_P + ue->freq_off_acc * PID_I; + ue->freq_off_acc += freq_offset; + } + LOG_D(PHY, "Doing N0 measurements in %s\n", __FUNCTION__); nr_ue_rrc_measurements(ue, proc, rxdataF); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PBCH, VCD_FUNCTION_OUT); diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 55110fc449..6f33946d93 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -1431,6 +1431,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.max_num_rsrp = *GNBParamList.paramarray[0][GNB_LIMIT_RSRP_REPORT_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; diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index 373958b1e8..e4e4bc3d2a 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -139,6 +139,7 @@ typedef enum { #define GNB_CONFIG_STRING_DU_SIB_LIST "du_sibs" #define GNB_CONFIG_STRING_DOSINR "do_SINR" #define GNB_CONFIG_STRING_1ST_ACTIVE_BWP "first_active_bwp" +#define GNB_CONFIG_STRING_LIMIT_RSRP_REPORT "max_num_RSRP_reported" #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" @@ -202,6 +203,7 @@ typedef enum { {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}, \ {GNB_CONFIG_STRING_1ST_ACTIVE_BWP, NULL, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ +{GNB_CONFIG_STRING_LIMIT_RSRP_REPORT, NULL, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ } // clang-format on @@ -246,6 +248,7 @@ typedef enum { #define GNB_DU_SIBS_IDX 37 #define GNB_DO_SINR_IDX 38 #define GNB_1ST_ACTIVE_BWP_IDX 39 +#define GNB_LIMIT_RSRP_REPORT_IDX 40 #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD} #define NUM_DL_HARQ_OKVALUES {2,4,6,8,10,12,16,32} @@ -292,6 +295,7 @@ typedef enum { { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ } /*-------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 680b5138df..1db7d33afc 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -407,8 +407,8 @@ typedef struct { NR_PUCCH_Resource_t *pucch_resource; uint32_t ack_payload; uint8_t sr_payload; - uint32_t csi_part1_payload; - uint32_t csi_part2_payload; + uint64_t csi_part1_payload; + uint64_t csi_part2_payload; int n_sr; int n_csi; int n_harq; @@ -418,9 +418,8 @@ typedef struct { } PUCCH_sched_t; typedef struct { - uint32_t ssb_index; /// SSB RSRP in dBm - short ssb_rsrp_dBm; + int ssb_rsrp_dBm; float_t ssb_sinr_dB; } NR_SSB_meas_t; @@ -473,8 +472,8 @@ typedef struct { } NR_BWP_PDCCH_t; typedef struct csi_payload { - uint32_t part1_payload; - uint32_t part2_payload; + uint64_t part1_payload; + uint64_t part2_payload; int p1_bits; int p2_bits; } csi_payload_t; @@ -625,7 +624,7 @@ typedef struct NR_UE_MAC_INST_s { uint8_t ssb_subcarrier_offset; int ssb_start_subcarrier; - NR_SSB_meas_t ssb_measurements; + NR_SSB_meas_t ssb_measurements[MAX_NB_SSB]; dci_pdu_rel15_t def_dci_pdu_rel15[NR_MAX_SLOTS_PER_FRAME][8]; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 035e59c09c..4897a8fab8 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -289,7 +289,7 @@ void remove_ul_config_last_item(fapi_nr_ul_config_request_pdu_t *pdu); fapi_nr_ul_config_request_pdu_t *fapiLockIterator(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx); void release_ul_config(fapi_nr_ul_config_request_pdu_t *pdu, bool clearIt); -int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm); +int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac); // PUSCH scheduler: // - Calculate the slot in which ULSCH should be scheduled. This is current slot + K2, diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 78bfb1021c..1f35df5c4b 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -77,6 +77,11 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac) nr_timer_stop(&mac->scheduling_info.sr_DelayTimer); memset(&mac->ssb_measurements, 0, sizeof(mac->ssb_measurements)); + for (int i = 0; i < MAX_NB_SSB; i++) { + mac->ssb_measurements[i].ssb_rsrp_dBm = INT_MIN; + mac->ssb_measurements[i].ssb_sinr_dB = INT_MIN; + } + memset(&mac->ul_time_alignment, 0, sizeof(mac->ul_time_alignment)); memset(&mac->ssb_list, 0, sizeof(mac->ssb_list)); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index bc29f7a9b9..9f962efc6e 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -42,7 +42,7 @@ int16_t get_prach_tx_power(NR_UE_MAC_INST_t *mac) { RA_config_t *ra = &mac->ra; - int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm); + int16_t pathloss = compute_nr_SSB_PL(mac); int16_t ra_preamble_rx_power = (int16_t)(ra->prach_resources.ra_preamble_rx_target_power + pathloss); return min(ra->prach_resources.Pc_max, ra_preamble_rx_power); } @@ -177,7 +177,7 @@ static void select_preamble_group(NR_UE_MAC_INST_t *mac) // – preambleReceivedTargetPower – msg3-DeltaPreamble – messagePowerOffsetGroupB int groupB_pow_offset = get_messagePowerOffsetGroupB(groupB->messagePowerOffsetGroupB); int PLThreshold = ra->prach_resources.Pc_max - ra->preambleRxTargetPower - ra->msg3_deltaPreamble - groupB_pow_offset; - int pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm); + int pathloss = compute_nr_SSB_PL(mac); // TODO if the Random Access procedure was initiated for the CCCH logical channel and the CCCH SDU size // plus MAC subheader is greater than ra-Msg3SizeGroupA if (ra->Msg3_size > get_Msg3SizeGroupA(groupB->ra_Msg3SizeGroupA) && pathloss < PLThreshold) @@ -971,7 +971,7 @@ bool init_RA(NR_UE_MAC_INST_t *mac, int frame) "msgA_RSRP_Threshold_r16 is mandatory present if both 2-step and 4-step random access types are configured\n"); // For thresholds the RSRP value is (IE value – 156) dBm except for the IE 127 in which case the actual value is infinity int rsrp_msga_thr = *twostep_conf->msgA_RSRP_Threshold_r16 - 156; - if (*twostep_conf->msgA_RSRP_Threshold_r16 != 127 && mac->ssb_measurements.ssb_rsrp_dBm > rsrp_msga_thr) + if (*twostep_conf->msgA_RSRP_Threshold_r16 != 127 && mac->ssb_measurements[mac->mib_ssb].ssb_rsrp_dBm > rsrp_msga_thr) twostep = true; } else { // if the BWP selected for Random Access procedure is only configured with 2-step RA type Random Access diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c index 1efa0f1f12..860089165f 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c @@ -358,7 +358,7 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, 1, start_prb); float P_CMIN = current_UL_BWP->P_CMIN; - int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm); + int16_t pathloss = compute_nr_SSB_PL(mac); if (power_config->twoPUCCH_PC_AdjustmentStates && *power_config->twoPUCCH_PC_AdjustmentStates > 1) { LOG_E(MAC,"PUCCH power control adjustment states with 2 states not yet implemented\n"); @@ -427,20 +427,23 @@ static int get_deltatf(uint16_t nb_of_prbs, // - PRACH transmission from a UE is not in response to a detection of a PDCCH order by the UE // Measurement units: // - referenceSignalPower: dBm/RE (average EPRE of the resources elements that carry secondary synchronization signals in dBm) -int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm) +int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac) { + // getting the maximum SSB RSRP from the SSB measurements + int max_ssb_rsrp_dBm = mac->ssb_measurements[mac->mib_ssb].ssb_rsrp_dBm; fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; int referenceSignalPower = cfg->ssb_config.ss_pbch_power; + //TODO improve PL measurements. Probably not correct as it is. - int16_t pathloss = (int16_t)(referenceSignalPower - ssb_rsrp_dBm); + int16_t pathloss = (int16_t)(referenceSignalPower - max_ssb_rsrp_dBm); LOG_D(NR_MAC, "pathloss %d dB, referenceSignalPower %d dBm/RE (%f mW), RSRP %d dBm (%f mW)\n", pathloss, referenceSignalPower, pow(10, referenceSignalPower/10), - ssb_rsrp_dBm, - pow(10, ssb_rsrp_dBm/10)); + max_ssb_rsrp_dBm, + pow(10, max_ssb_rsrp_dBm/10)); return pathloss; } @@ -557,8 +560,8 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac, DELTA_TF = 10 * log10(pow(2, BPRE * 1.25f) * beta_offset); } - // TODO: compute pathoss using correct reference - int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm); + // TODO: compute pathloss using correct reference + int16_t pathloss = compute_nr_SSB_PL(mac); int P_CMIN = mac->current_UL_BWP->P_CMIN; float pusch_power_without_f_b_f_c = P_O_PUSCH + M_pusch_component + alpha * pathloss + DELTA_TF; @@ -626,7 +629,7 @@ int get_srs_tx_power_ue(NR_UE_MAC_INST_t *mac, get_m_srs(srs_resource->freqHopping.c_SRS, srs_resource->freqHopping.b_SRS), 0); // TODO: Determine SRS start RB - int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm); + int16_t pathloss = compute_nr_SSB_PL(mac); int srs_power_without_h_b_f_c = P_0_SRS + alpha * pathloss + m_srs_component; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index ab13c9dd07..f2f783869c 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -78,6 +78,12 @@ const uint16_t table_7_2_1[16] = { 1920, // row index 13 }; +typedef struct { + uint32_t ssb_index; + short ssb_rsrp_dBm; + float_t ssb_sinr_dB; +} NR_RSRP_meas_t; + /* TS 36.213 Table 9.2.3-3: Mapping of values for one HARQ-ACK bit to sequences */ static const int sequence_cyclic_shift_1_harq_ack_bit[2] /* HARQ-ACK Value 0 1 */ @@ -1509,6 +1515,11 @@ void nr_ue_process_l1_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slo LOG_D(NR_MAC, "(%d.%d) Received CSI-RS measurements\n", frame, slot); memcpy(&mac->l1_measurements, l1_measurements, sizeof(*l1_measurements)); bool csi_meas = l1_measurements->meas_type == NFAPI_NR_CSI_MEAS; + if (!csi_meas && !l1_measurements->is_neighboring_cell) { + int ssb_index = l1_measurements->ssb_index; + mac->ssb_measurements[ssb_index].ssb_rsrp_dBm = l1_measurements->rsrp_dBm; + mac->ssb_measurements[ssb_index].ssb_sinr_dB = l1_measurements->sinr_dB; + } nr_mac_rrc_meas_ind_ue(mac->ue_id, l1_measurements->gNB_index, l1_measurements->Nid_cell, @@ -2759,6 +2770,14 @@ static uint8_t get_sinr_diff_index(float best_sinr, float current_sinr) return diff; } +// Comparison function for sorting SSB SINR measurements in descending order +static int compare_ssb_sinr(const void *a, const void *b) +{ + const NR_RSRP_meas_t *ma = (const NR_RSRP_meas_t *)a; + const NR_RSRP_meas_t *mb = (const NR_RSRP_meas_t *)b; + return mb->ssb_sinr_dB - ma->ssb_sinr_dB; +} + 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, @@ -2767,7 +2786,7 @@ static csi_payload_t get_ssb_sinr_payload(NR_UE_MAC_INST_t *mac, 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; + uint64_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]; @@ -2792,51 +2811,55 @@ static csi_payload_t get_ssb_sinr_payload(NR_UE_MAC_INST_t *mac, } 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"); + AssertFatal(nb_meas <= 4,"Can't report more than 4 RSRPs\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; + // map SSB index to SSB resource table index, copy measurements, sort in descending order + NR_RSRP_meas_t sorted_sinr_measurements[nb_ssb]; + int sorted_idx = 0; + for (int measured_ssb_idx = 0; measured_ssb_idx < MAX_NB_SSB; measured_ssb_idx++) { + // searching for the SSB index in the SSB resource table + for (int ssb_resource = 0; ssb_resource < nb_ssb; ssb_resource++) { + if (*SSB_resource.list.array[ssb_resource] == measured_ssb_idx) { + sorted_sinr_measurements[sorted_idx].ssb_index = ssb_resource; + sorted_sinr_measurements[sorted_idx].ssb_rsrp_dBm = mac->ssb_measurements[measured_ssb_idx].ssb_rsrp_dBm; + sorted_sinr_measurements[sorted_idx].ssb_sinr_dB = mac->ssb_measurements[measured_ssb_idx].ssb_sinr_dB; + sorted_idx++; + 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; + qsort(sorted_sinr_measurements, nb_ssb, sizeof(NR_RSRP_meas_t), compare_ssb_sinr); uint8_t ssbi; // TS38.212 v16.5.0: Table 6.3.1.1.2-8A if (ssbri_bits > 0) { - ssbi = ssb_index[0]; + ssbi = sorted_sinr_measurements[0].ssb_index; temp_payload = reverse_bits(ssbi, ssbri_bits); bits += ssbri_bits; } - uint8_t sinr_idx = get_sinr_index(ssb_sinr[0]); + uint8_t sinr_idx = get_sinr_index(sorted_sinr_measurements[0].ssb_sinr_dB); 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); + ssbi = sorted_sinr_measurements[i].ssb_index; + temp_payload |= (reverse_bits(ssbi, ssbri_bits) << bits); bits += ssbri_bits; - sinr_idx = get_sinr_diff_index(ssb_sinr[0], ssb_sinr[i]); + sinr_idx = get_sinr_diff_index(sorted_sinr_measurements[0].ssb_sinr_dB, sorted_sinr_measurements[i].ssb_sinr_dB); temp_payload |= (reverse_bits(sinr_idx, 4) << bits); - bits += 4; // 7 bits for highest SINR + bits += 4; // 4 bits for differential 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}; + int max_bits = sizeof(((csi_payload_t *)0)->part1_payload) * 8; + AssertFatal(bits <= max_bits, "Not supporting CSI report with more than %d bits (payload: %d bits)\n", max_bits, bits); + csi_payload_t csi = {.part1_payload = temp_payload, .part2_payload = 0, .p1_bits = bits, csi.p2_bits = 0}; return csi; } @@ -2886,6 +2909,14 @@ csi_payload_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac, return csi; } +// Comparison function for sorting SSB RSRP measurements in descending order +static int compare_ssb_rsrp(const void *a, const void *b) +{ + const NR_RSRP_meas_t *ma = (const NR_RSRP_meas_t *)a; + const NR_RSRP_meas_t *mb = (const NR_RSRP_meas_t *)b; + return mb->ssb_rsrp_dBm - ma->ssb_rsrp_dBm; +} + static csi_payload_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, struct NR_CSI_ReportConfig *csi_reportconfig, NR_CSI_ResourceConfigId_t csi_ResourceConfigId, @@ -2894,7 +2925,7 @@ static csi_payload_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, 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; + uint64_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]; @@ -2902,7 +2933,7 @@ static csi_payload_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, 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; + nb_meas = *(csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS) + 1; else nb_meas = 1; } else @@ -2919,50 +2950,56 @@ static csi_payload_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, } } - 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"); + AssertFatal(nb_ssb > 0,"No SSB found in the resource set\n"); + AssertFatal(nb_meas <= 4,"Can't report more than 4 RSRPs\n"); int ssbri_bits = ceil(log2(nb_ssb)); - int ssb_rsrp[2][nb_meas]; // the array contains index and RSRP of each SSB to be reported (nb_meas highest RSRPs) - memset(ssb_rsrp, 0, sizeof(ssb_rsrp)); - - //TODO replace the following 2 lines with a function to order the nb_meas highest SSB RSRPs - for (int i=0; imib_ssb) { - ssb_rsrp[0][0] = i; - break; + // map SSB index to SSB resource table index, copy measurements, sort in descending order + NR_RSRP_meas_t sorted_rsrp_measurements[nb_ssb]; + int sorted_idx = 0; + for (int measured_ssb_idx = 0; measured_ssb_idx < MAX_NB_SSB; measured_ssb_idx++) { + // searching for the SSB index in the SSB resource table + for (int ssb_resource = 0; ssb_resource < nb_ssb; ssb_resource++) { + if (*SSB_resource.list.array[ssb_resource] == measured_ssb_idx) { + sorted_rsrp_measurements[sorted_idx].ssb_index = ssb_resource; + sorted_rsrp_measurements[sorted_idx].ssb_rsrp_dBm = mac->ssb_measurements[measured_ssb_idx].ssb_rsrp_dBm; + sorted_rsrp_measurements[sorted_idx].ssb_sinr_dB = mac->ssb_measurements[measured_ssb_idx].ssb_sinr_dB; + sorted_idx++; + break; + } } } - AssertFatal(*SSB_resource.list.array[ssb_rsrp[0][0]] == mac->mib_ssb, "Couldn't find corresponding SSB in csi_SSB_ResourceList\n"); - ssb_rsrp[1][0] = mac->ssb_measurements.ssb_rsrp_dBm; + qsort(sorted_rsrp_measurements, nb_ssb, sizeof(NR_RSRP_meas_t), compare_ssb_rsrp); - uint8_t ssbi; + uint32_t ssbi; if (ssbri_bits > 0) { - ssbi = ssb_rsrp[0][0]; + ssbi = sorted_rsrp_measurements[0].ssb_index; temp_payload = reverse_bits(ssbi, ssbri_bits); bits += ssbri_bits; } - uint8_t rsrp_idx = get_rsrp_index(ssb_rsrp[1][0]); + uint8_t rsrp_idx = get_rsrp_index(sorted_rsrp_measurements[0].ssb_rsrp_dBm); temp_payload |= (reverse_bits(rsrp_idx, 7) << bits); bits += 7; // 7 bits for highest RSRP // from the second SSB, differential report - for (int i=1; ipart1_payload) * 8; + AssertFatal(bits <= max_bits, "Not supporting CSI report with more than %d bits (payload: %d bits)\n", max_bits, bits); + + csi_payload_t csi = {.part1_payload = temp_payload, .part2_payload = 0, .p1_bits = bits, .p2_bits = 0}; return csi; } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index cf7fda5ccf..fed19223f3 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -260,7 +260,7 @@ void update_mac_ul_timers(NR_UE_MAC_INST_t *mac) if (phr_info->is_configured) { bool prohibit_expired = nr_timer_tick(&phr_info->prohibitPHR_Timer); if (prohibit_expired) { - int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm); + int16_t pathloss = compute_nr_SSB_PL(mac); if (abs(pathloss - phr_info->PathlossLastValue) > phr_info->PathlossChange_db) { phr_info->phr_reporting |= (1 << phr_cause_prohibit_timer); } @@ -2905,7 +2905,7 @@ static void nr_ue_fill_phr(NR_UE_MAC_INST_t *mac, headroom, tx_power); - phr_info->PathlossLastValue = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm); + phr_info->PathlossLastValue = compute_nr_SSB_PL(mac); // Restart both timers according to 38.321 nr_timer_start(&phr_info->periodicPHR_Timer); nr_timer_start(&phr_info->prohibitPHR_Timer); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 682ea765ac..f3de970683 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -588,29 +588,31 @@ static void evaluate_rsrp_report(gNB_MAC_INST *nrmac, } rsrp_report->nr_reports = csi_report->CSI_report_bitlen.nb_ssbri_cri; - uint16_t curr_payload; - for (int i = 0; i < rsrp_report->nr_reports; i++) { - int bitlen = csi_report->CSI_report_bitlen.cri_ssbri_bitlen; - curr_payload = pickandreverse_bits(payload, bitlen, *cumul_bits); - rsrp_report->resource_id[i] = *(index_list[bitlen > 0 ? ((curr_payload) & ~(~1U << (bitlen - 1))) : bitlen]); - LOG_D(MAC,"SSB/CSI-RS index = %d\n", rsrp_report->resource_id[i]); - *cumul_bits += bitlen; - } + int bitlen = csi_report->CSI_report_bitlen.cri_ssbri_bitlen; + uint8_t curr_payload = pickandreverse_bits(payload, bitlen, *cumul_bits); + rsrp_report->resource_id[0] = *(index_list[bitlen > 0 ? ((curr_payload) & ~(~1U << (bitlen - 1))) : bitlen]); + *cumul_bits += bitlen; curr_payload = pickandreverse_bits(payload, 7, *cumul_bits); - int rsrp_index = curr_payload & 0x7f; + int rsrp = curr_payload & 0x7f; *cumul_bits += 7; - csi_report->nb_of_csi_ssb_report++; - bool valid = get_measured_rsrp(rsrp_index, &rsrp_report->RSRP[0]); + bool valid = get_measured_rsrp(rsrp, &rsrp_report->RSRP[0]); + LOG_D(NR_MAC, "SSB/CSI-RS index %d RSRP %d\n", rsrp_report->resource_id[0], rsrp_report->RSRP[0]); if (!valid) { - LOG_E(NR_MAC, "UE %04x: reported RSRP index %d invalid\n", UE->rnti, rsrp_index); + LOG_E(NR_MAC, "UE %04x: reported RSRP index %d invalid\n", UE->rnti, rsrp); return; } for (int i = 1; i < rsrp_report->nr_reports; i++) { + curr_payload = pickandreverse_bits(payload, bitlen, *cumul_bits); + rsrp_report->resource_id[i] = *(index_list[bitlen > 0 ? ((curr_payload) & ~(~1U << (bitlen - 1))) : bitlen]); + *cumul_bits += bitlen; + curr_payload = pickandreverse_bits(payload, 4, *cumul_bits); + csi_report->nb_of_csi_ssb_report++; rsrp_report->RSRP[i] = get_diff_rsrp(curr_payload & 0x0f, rsrp_report->RSRP[0]); + LOG_D(NR_MAC, "SSB/CSI-RS index %d RSRP %d\n", rsrp_report->resource_id[i], rsrp_report->RSRP[i]); *cumul_bits += 4; } diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 50f77b681c..026d8d563e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -186,6 +186,7 @@ typedef struct nr_mac_config_t { int minRXTXTIME; int do_CSIRS; int do_SRS; + int max_num_rsrp; bool force_256qam_off; bool force_UL256qam_off; bool use_deltaMCS; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index bb108d4004..f8919a3fa8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -2094,21 +2094,52 @@ static void config_csi_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig, asn1cSeqAdd(&csi_MeasConfig->csi_ReportConfigToAddModList->list, csirep); } +static long config_nrofReportedRS(const NR_UE_NR_Capability_t *uecap, + uint64_t ssb_bitmap, + const NR_ServingCellConfigCommon_t *scc, + int max_num_reported_rs) +{ + long nb_band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; + int num_supported_rs = 0; + if (uecap) { + for (int i = 0; i < uecap->rf_Parameters.supportedBandListNR.list.count; i++) { + NR_BandNR_t *band = uecap->rf_Parameters.supportedBandListNR.list.array[i]; + if (band->bandNR == nb_band) { + if (band->mimo_ParametersPerBand && band->mimo_ParametersPerBand->maxNumberNonGroupBeamReporting) { + int maxNumberNonGroupBeamReporting = 1 << *band->mimo_ParametersPerBand->maxNumberNonGroupBeamReporting; + if (num_supported_rs == 0 || num_supported_rs > maxNumberNonGroupBeamReporting) + num_supported_rs = maxNumberNonGroupBeamReporting; + } + } + } + } + int configured_rs = max_num_reported_rs > 0 ? min(num_supported_rs, max_num_reported_rs) : num_supported_rs; + uint32_t num_ssb = count_bits64(ssb_bitmap); + if (num_ssb == 1 || configured_rs < 2) + return NR_CSI_ReportConfig__groupBasedBeamReporting__disabled__nrofReportedRS_n1; + if (num_ssb == 2 || configured_rs == 2) + return NR_CSI_ReportConfig__groupBasedBeamReporting__disabled__nrofReportedRS_n2; + if (num_ssb == 3 || configured_rs == 3) + return NR_CSI_ReportConfig__groupBasedBeamReporting__disabled__nrofReportedRS_n3; + return NR_CSI_ReportConfig__groupBasedBeamReporting__disabled__nrofReportedRS_n4; +} + static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig, + const NR_UE_NR_Capability_t *uecap, const NR_ServingCellConfigCommon_t *servingcellconfigcommon, NR_PUCCH_CSI_Resource_t *pucchcsires, - int do_csi, // if rsrp is based on CSI or SSB + const nr_mac_config_t *configuration, int rep_id, int uid, int curr_bwp, int num_antenna_ports, - bool do_sinr) + uint64_t ssb_bitmap) { int resource_id = -1; for (int csi_list = 0; csi_list < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_list++) { NR_CSI_ResourceConfig_t *csires = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_list]; if (csires->csi_RS_ResourceSetList.present == NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB) { - if (do_csi && num_antenna_ports < 4) { + if (configuration->do_CSIRS && num_antenna_ports < 4) { if (csires->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList) resource_id = csires->csi_ResourceConfigId; } else { @@ -2130,13 +2161,13 @@ static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig, csirep->reportConfigType.choice.periodic = calloc(1, sizeof(*csirep->reportConfigType.choice.periodic)); set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, curr_bwp, true); asn1cSeqAdd(&csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list, pucchcsires); - if (do_csi && num_antenna_ports < 4) { + if (configuration->do_CSIRS && num_antenna_ports < 4) { csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP; csirep->reportQuantity.choice.cri_RSRP = (NULL_t)0; } else { csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP; csirep->reportQuantity.choice.ssb_Index_RSRP = (NULL_t)0; - if (do_sinr) { + if (configuration->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)); @@ -2148,7 +2179,10 @@ static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig, csirep->groupBasedBeamReporting.present = NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled; csirep->groupBasedBeamReporting.choice.disabled = calloc(1, sizeof(*csirep->groupBasedBeamReporting.choice.disabled)); csirep->groupBasedBeamReporting.choice.disabled->nrofReportedRS = calloc(1, sizeof(*csirep->groupBasedBeamReporting.choice.disabled->nrofReportedRS)); - *csirep->groupBasedBeamReporting.choice.disabled->nrofReportedRS = NR_CSI_ReportConfig__groupBasedBeamReporting__disabled__nrofReportedRS_n1; + *csirep->groupBasedBeamReporting.choice.disabled->nrofReportedRS = config_nrofReportedRS(uecap, + ssb_bitmap, + servingcellconfigcommon, + configuration->max_num_rsrp); asn1cSeqAdd(&csi_MeasConfig->csi_ReportConfigToAddModList->list, csirep); } @@ -3292,6 +3326,7 @@ static NR_BWP_DownlinkDedicated_t *configure_initial_dl_bwp(const NR_ServingCell } static NR_CSI_MeasConfig_t *get_csiMeasConfig(const NR_ServingCellConfig_t *configDedicated, + const NR_UE_NR_Capability_t *uecap, const NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *configuration, int uid, @@ -3396,14 +3431,15 @@ static NR_CSI_MeasConfig_t *get_csiMeasConfig(const NR_ServingCellConfig_t *conf pucchrsrp->uplinkBandwidthPartId = bwp_id; pucchrsrp->pucch_Resource = pucch_Resource; config_rsrp_meas_report(csi_MeasConfig, + uecap, scc, pucchrsrp, - configuration->do_CSIRS, + configuration, bwp_id + 10, uid, curr_bwp, pdsch_AntennaPorts, - configuration->do_SINR); + bitmap); return csi_MeasConfig; } @@ -3482,6 +3518,7 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid, configDedicated->csi_MeasConfig = calloc(1, sizeof(*configDedicated->csi_MeasConfig)); configDedicated->csi_MeasConfig->present = NR_SetupRelease_CSI_MeasConfig_PR_setup; configDedicated->csi_MeasConfig->choice.setup = get_csiMeasConfig(configDedicated, + NULL, scc, configuration, uid, @@ -3786,6 +3823,7 @@ NR_CellGroupConfig_t * update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_ ASN_STRUCT_FREE(asn_DEF_NR_CSI_MeasConfig, configDedicated->csi_MeasConfig->choice.setup); configDedicated->csi_MeasConfig->choice.setup = get_csiMeasConfig(configDedicated, + uecap, scc, configuration, uid, @@ -4101,6 +4139,7 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC configDedicated->csi_MeasConfig = calloc(1, sizeof(*configDedicated->csi_MeasConfig)); configDedicated->csi_MeasConfig->present = NR_SetupRelease_CSI_MeasConfig_PR_setup; configDedicated->csi_MeasConfig->choice.setup = get_csiMeasConfig(configDedicated, + uecap, servingcellconfigcommon, configuration, uid, diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 3f765bf6c9..1f86c61be5 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -374,7 +374,6 @@ static void fill_mib_in_rx_ind(nfapi_nr_dl_tti_request_pdu_t *pdu_list, fapi_nr_ rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu[0] = (ssb_pdu->bchPayload) & 0xff; rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu[1] = (ssb_pdu->bchPayload >> 8) & 0xff; rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu[2] = (ssb_pdu->bchPayload >> 16) & 0xff; - rx_ind->rx_indication_body[pdu_idx].ssb_pdu.rsrp_dBm = ssb_pdu->ssbRsrp; rx_ind->rx_indication_body[pdu_idx].ssb_pdu.ssb_index = ssb_pdu->SsbBlockIndex; rx_ind->rx_indication_body[pdu_idx].ssb_pdu.ssb_length = pdu_list->PDUSize; rx_ind->rx_indication_body[pdu_idx].ssb_pdu.ssb_start_subcarrier = ssb_pdu->SsbSubcarrierOffset; @@ -1138,13 +1137,6 @@ 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, 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 // Note: sdu should always be processed because data and timing advance updates are transmitted by the UE static int8_t handle_dlsch(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info, int pdu_id) @@ -1268,16 +1260,12 @@ static uint32_t nr_ue_dl_processing(NR_UE_MAC_INST_t *mac, nr_downlink_indicatio rx_indication_body.pdu_type, dl_info->rx_ind->number_pdus); - switch(rx_indication_body.pdu_type){ + switch(rx_indication_body.pdu_type) { case FAPI_NR_RX_PDU_TYPE_SSB: handle_rlm(rx_indication_body.ssb_pdu.radiolink_monitoring, dl_info->frame, mac); 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.sinr_dB); ret_mask |= (handle_bcch_bch(mac, dl_info->cc_id, dl_info->gNB_index,