diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 1a1e08563a..bcce053231 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -818,7 +818,8 @@ int main(int argc, char **argv) prepare_sim_uecap(UE_Capability_nr, scc, mu, N_RB_DL, g_mcsTableIdx, 0); rnti_t rnti = 0x1234; int uid = 0; - NR_CellGroupConfig_t *secondaryCellGroup = get_default_secondaryCellGroup(scc, UE_Capability_nr, 0, 1, &conf, uid); + int ssb_index = 0; + NR_CellGroupConfig_t *secondaryCellGroup = get_default_secondaryCellGroup(scc, UE_Capability_nr, 0, 1, &conf, uid, ssb_index); secondaryCellGroup->spCellConfig->reconfigurationWithSync = get_reconfiguration_with_sync(rnti, uid, scc, frame); /* -U option modify DMRS */ diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index f61cc41963..da6b901a11 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -842,7 +842,8 @@ int main(int argc, char *argv[]) prepare_sim_uecap(UE_Capability_nr, scc, mu, N_RB_UL, 0, mcs_table); rnti_t rnti = 0x1234; int uid = 0; - NR_CellGroupConfig_t *secondaryCellGroup = get_default_secondaryCellGroup(scc, UE_Capability_nr, 0, 1, &conf, uid); + int ssb_index = 0; + NR_CellGroupConfig_t *secondaryCellGroup = get_default_secondaryCellGroup(scc, UE_Capability_nr, 0, 1, &conf, uid, ssb_index); secondaryCellGroup->spCellConfig->reconfigurationWithSync = get_reconfiguration_with_sync(rnti, uid, scc, frame); NR_BCCH_BCH_Message_t *mib = get_new_MIB_NR(scc); diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index eea50555c4..bc402e7125 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -1083,7 +1083,7 @@ bool nr_trigger_bwp_switch(uint16_t rnti, int bwp_id) } else if (UE->current_DL_BWP.bwp_id == bwp_id) { LOG_W(NR_MAC, "UE %04x is already on BWP ID %d, not triggering reconfiguration\n", rnti, bwp_id); } else { // UE != NULL && current_DL_BWP.bwp_id != bwp_id - nr_mac_trigger_reconfiguration(nrmac, UE, bwp_id); + nr_mac_trigger_reconfiguration(nrmac, UE, bwp_id, false); success = true; } NR_SCHED_UNLOCK(&nrmac->sched_lock); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 8d1eda288b..99f0e9bb3c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -756,12 +756,14 @@ void nr_initiate_ra_proc(module_id_t module_idP, LOG_A(NR_MAC, "%d.%d UE RA-RNTI %04x TC-RNTI %04x: initiating RA procedure\n", frame, slot, ra->RA_rnti, UE->rnti); - // Configure RA BWP - configure_UE_BWP(nr_mac, scc, UE, true, NR_SearchSpace__searchSpaceType_PR_common, -1, -1); - // return current SSB order in the list of tranmitted SSBs + // return current SSB order in the list of tranmitted SSBs int n_ssb = ssb_index_from_prach(module_idP, frame, slot, preamble_index, freq_index, symbol); UE->UE_beam_index = get_beam_from_ssbidx(nr_mac, cc->ssb_index[n_ssb]); LOG_I(NR_MAC, "UE %04x: Sync beam index %d\n", UE->rnti, UE->UE_beam_index); + + // Configure RA BWP + configure_UE_BWP(nr_mac, scc, UE, true, NR_SearchSpace__searchSpaceType_PR_common, -1, -1); + NR_SCHED_UNLOCK(&nr_mac->sched_lock); } @@ -1483,8 +1485,8 @@ static void nr_generate_Msg2(module_id_t module_idP, const int coresetid = coreset->controlResourceSetId; // Calculate number of symbols int time_domain_assignment = get_dl_tda(nr_mac, slotP); - - NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[cc->ssb_index[UE->UE_beam_index]]; + int ssb_index = get_ssbidx_from_beam(nr_mac, UE->UE_beam_index); + NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[ssb_index]; int mux_pattern = type0_PDCCH_CSS_config ? type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern : 1; NR_tda_info_t tda_info = get_dl_tda_info(dl_bwp, ss->searchSpaceType->present, @@ -1743,9 +1745,9 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP, reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam); return; } - + int ssb_index = get_ssbidx_from_beam(nr_mac, UE->UE_beam_index); uint8_t time_domain_assignment = get_dl_tda(nr_mac, slotP); - NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[cc->ssb_index[UE->UE_beam_index]]; + NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[ssb_index]; int mux_pattern = type0_PDCCH_CSS_config ? type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern : 1; NR_tda_info_t msg4_tda = get_dl_tda_info(dl_bwp, ss->searchSpaceType->present, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 501543e4be..e511850414 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -671,7 +671,8 @@ static void other_sib_sched_control(module_id_t module_idP, LOG_D(NR_MAC, "(%d.%d) otherSIB payload %d transmission for ssb number %d\n", frame, slot, payload_idx, beam_index); NR_COMMON_channels_t *cc = &gNB_mac->common_channels[0]; - NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &gNB_mac->type0_PDCCH_CSS_config[cc->ssb_index[beam_index]]; + int ssb_index = get_ssbidx_from_beam(gNB_mac, beam_index); + NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &gNB_mac->type0_PDCCH_CSS_config[ssb_index]; NR_PDSCH_ConfigCommon_t *pdsch_ConfigCommon = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup; int time_domain_allocation = 1; NR_tda_info_t tda_info = set_tda_info_from_list(pdsch_ConfigCommon->pdsch_TimeDomainAllocationList, time_domain_allocation); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index c4dfa019aa..7b9a32f547 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -124,6 +124,15 @@ static void determine_aggregation_level_search_order(int agg_level_search_order[ static int nr_mac_interrupt_ue_transmission(gNB_MAC_INST *mac, NR_UE_info_t *UE, int slots, int slots_per_frame); +int get_ssbidx_from_beam(gNB_MAC_INST *mac, int beam_idx) +{ + for (int i = 0; i < MAX_NUM_OF_SSB; i++) + if (beam_idx == mac->beam_index_list[i]) + return i; + AssertFatal(false, "beam_idx %d not found\n", beam_idx); + return 0; +} + uint8_t get_dl_nrOfLayers(const NR_UE_sched_ctrl_t *sched_ctrl, const nr_dci_format_t dci_format) { // TODO check this but it should be enough for now @@ -2913,8 +2922,7 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, AssertFatal(sched_ctrl->search_space != NULL, "SearchSpace cannot be null for RA\n"); sched_ctrl->coreset = get_coreset(nr_mac, scc, bwpd, *sched_ctrl->search_space->controlResourceSetId); - NR_COMMON_channels_t *cc = &nr_mac->common_channels[0]; - int ssb_index = cc->ssb_index[UE->UE_beam_index]; + int ssb_index = get_ssbidx_from_beam(nr_mac, UE->UE_beam_index); sched_ctrl->sched_pdcch = set_pdcch_structure(nr_mac, sched_ctrl->search_space, sched_ctrl->coreset, @@ -3568,10 +3576,11 @@ void nr_mac_release_ue(gNB_MAC_INST *mac, int rnti) mac_remove_nr_ue(mac, rnti); } -static void beam_switching_procedure(NR_UE_info_t *UE, int new_beam_index) +void beam_switching_procedure(gNB_MAC_INST *mac, NR_UE_info_t *UE, int new_beam_index) { LOG_I(NR_MAC, "[UE %x] Switching to beam with ID %d (from %d)\n", UE->rnti, new_beam_index, UE->UE_beam_index); UE->UE_beam_index = new_beam_index; + nr_mac_trigger_reconfiguration(mac, UE, -1, true); } void nr_mac_update_timers(module_id_t module_id, frame_t frame, slot_t slot) @@ -3614,7 +3623,7 @@ void nr_mac_update_timers(module_id_t module_id, frame_t frame, slot_t slot) } if (nr_timer_tick(&sched_ctrl->tci_beam_switch)) { nr_timer_stop(&sched_ctrl->tci_beam_switch); - beam_switching_procedure(UE, sched_ctrl->UE_mac_ce_ctrl.tci_state_ind.tciStateId); + beam_switching_procedure(mac, UE, sched_ctrl->UE_mac_ce_ctrl.tci_state_ind.tciStateId); } } } @@ -3742,20 +3751,20 @@ void reset_beam_status(NR_beam_info_t *beam_info, int frame, int slot, int16_t b } } -void beam_selection_procedures(gNB_MAC_INST *mac, NR_UE_info_t *UE) +int beam_selection_procedures(gNB_MAC_INST *mac, NR_UE_info_t *UE) { // do not perform beam procedures if there is no beam information if (mac->beam_info.beam_mode == NO_BEAM_MODE) - return; + return -1; // simple beam switching algorithm -> we select beam with highest RSRP from CSI report NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; RSRP_report_list_t *rsrp_report = &sched_ctrl->CSI_report.ssb_rsrp_report; int new_bf_index = get_beam_from_ssbidx(mac, rsrp_report->r[0].resource_id); if (!mac->radio_config.do_TCI) { // if not TCI is configure we switch beam directly - if (UE->UE_beam_index != new_bf_index) - beam_switching_procedure(UE, new_bf_index); - return; + if (UE->UE_beam_index == new_bf_index) + return -1; // no beam change needed + return new_bf_index; } tciStateInd_t *tci = &sched_ctrl->UE_mac_ce_ctrl.tci_state_ind; @@ -3764,7 +3773,7 @@ void beam_selection_procedures(gNB_MAC_INST *mac, NR_UE_info_t *UE) LOG_I(NR_MAC, "[UE %x] Stopping procedure to switch beam, old beam reported as best again\n", UE->rnti); tci->is_scheduled = false; } - return; // no beam change needed + return -1; // no beam change needed } LOG_I(NR_MAC, "[UE %x] Starting procedure to switch beam\n", UE->rnti); @@ -3774,6 +3783,7 @@ void beam_selection_procedures(gNB_MAC_INST *mac, NR_UE_info_t *UE) tci->is_scheduled = true; tci->coresetId = sched_ctrl->coreset->controlResourceSetId; tci->tciStateId = new_bf_index; // assumption: this correspond to the TCI index + return new_bf_index; } void send_initial_ul_rrc_message(int rnti, const uint8_t *sdu, sdu_size_t sdu_len, void *data) @@ -3827,7 +3837,8 @@ bool prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) int CC_id = 0; int srb_id = 1; const NR_ServingCellConfigCommon_t *scc = mac->common_channels[CC_id].ServingCellConfigCommon; - NR_CellGroupConfig_t *cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, &mac->radio_config, &mac->rlc_config); + int ssb_index = get_ssbidx_from_beam(mac, UE->UE_beam_index); + NR_CellGroupConfig_t *cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, &mac->radio_config, &mac->rlc_config, ssb_index); ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); UE->CellGroup = cellGroupConfig; UE->local_bwp_id = mac->radio_config.first_active_bwp; @@ -3953,24 +3964,40 @@ static bool verify_bwp_switch(const NR_UE_info_t *UE, const nr_mac_config_t *con return false; } -void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, NR_UE_info_t *UE, int new_bwp_id) +void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, NR_UE_info_t *UE, int new_bwp_id, bool new_beam) { DevAssert(UE->CellGroup != NULL); NR_CellGroupConfig_t *cellGroup_for_UE = NULL; - if (new_bwp_id >= 0) { - AssertFatal(UE->current_DL_BWP.bwp_id == UE->current_UL_BWP.bwp_id, "We only support same BWP for UL and DL\n"); - if (!verify_bwp_switch(UE, &nrmac->radio_config, new_bwp_id)) - return; - else { + if (new_beam) { UE->sc_info.csi_MeasConfig = NULL; // to avoid segfault when freeing csi_MeasConfig in configDedicated - UE->local_bwp_id = new_bwp_id; - cellGroup_for_UE = update_cellGroupConfig_for_BWP_switch(UE->CellGroup, + NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP; + current_BWP->srs_Config = NULL; + int ssb_index = nrmac->common_channels[0].ssb_index[UE->UE_beam_index]; + cellGroup_for_UE = update_cellGroupConfig_for_beam_switch(UE->CellGroup, &nrmac->radio_config, UE->capability, nrmac->common_channels[0].ServingCellConfigCommon, UE->uid, UE->current_DL_BWP.bwp_id, - new_bwp_id); + ssb_index); + } else { + if (new_bwp_id >= 0) { + AssertFatal(UE->current_DL_BWP.bwp_id == UE->current_UL_BWP.bwp_id, "We only support same BWP for UL and DL\n"); + if (!verify_bwp_switch(UE, &nrmac->radio_config, new_bwp_id)) + return; + else { + UE->sc_info.csi_MeasConfig = NULL; // to avoid segfault when freeing csi_MeasConfig in configDedicated + UE->local_bwp_id = new_bwp_id; + int ssb_index = nrmac->common_channels[0].ssb_index[UE->UE_beam_index]; + cellGroup_for_UE = update_cellGroupConfig_for_BWP_switch(UE->CellGroup, + &nrmac->radio_config, + UE->capability, + nrmac->common_channels[0].ServingCellConfigCommon, + UE->uid, + UE->current_DL_BWP.bwp_id, + new_bwp_id, + ssb_index); + } } } uint8_t buf[2048]; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 65de51e0ba..8366026691 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -728,6 +728,7 @@ static void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig, const int n_slots_frame = nrmac->frame_structure.numb_slots_frame; int cumul_bits = 0; int r_index = -1; + int new_bf_index = -1; for (int csi_report_id = 0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++) { nr_csi_report_t *csi_report = &UE->csi_report_template[csi_report_id]; csi_report->nb_of_csi_ssb_report = 0; @@ -764,7 +765,7 @@ static void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig, break; case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP: evaluate_rsrp_report(nrmac, UE, sched_ctrl, csi_report_id, payload, &cumul_bits, reportQuantity_type); - beam_selection_procedures(nrmac, UE); + new_bf_index = beam_selection_procedures(nrmac, UE); break; case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI: sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.print_report = true; @@ -822,6 +823,9 @@ static void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig, } } } + if ((new_bf_index !=-1) && !nrmac->radio_config.do_TCI) + // Trigger RRCReconfiguration. Need to be out of the for loop as it may modify csi_MeasConfig + beam_switching_procedure(nrmac, UE, new_bf_index); } static NR_UE_harq_t *find_harq(frame_t frame, slot_t slot, NR_UE_info_t * UE, int harq_round_max) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 3282c4a483..481c0ea9f8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -879,7 +879,7 @@ static void nr_rx_ra_sdu(const module_id_t mod_id, if (!old_UE->reconfigCellGroup) { LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x, triggering RRC Reconfiguration\n", crnti); // Trigger RRCReconfiguration - nr_mac_trigger_reconfiguration(mac, old_UE, -1); + nr_mac_trigger_reconfiguration(mac, old_UE, -1, false); // we configure the UE using common search space with DCIX0 while waiting for a reconfiguration configure_UE_BWP(mac, scc, old_UE, false, NR_SearchSpace__searchSpaceType_PR_common, -1, -1); } @@ -1994,13 +1994,13 @@ static int pf_ul(gNB_MAC_INST *nrmac, NR_beam_alloc_t dci_beam = beam_allocation_procedure(&nrmac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame); if (dci_beam.idx < 0) { - LOG_D(NR_MAC, "[UE %04x][%4d.%2d] Beam could not be allocated\n", UE->rnti, frame, slot); + LOG_D(NR_MAC, "[UE %04x][%4d.%2d] ULSCH DCI Beam could not be allocated\n", UE->rnti, frame, slot); continue; } NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_per_frame); if (beam.idx < 0) { - LOG_D(NR_MAC, "[UE %04x][%4d.%2d] Beam could not be allocated\n", UE->rnti, frame, slot); + LOG_D(NR_MAC, "[UE %04x][%4d.%2d] ULSCH Beam could not be allocated\n", UE->rnti, frame, slot); reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, dci_beam.new_beam); continue; } @@ -2119,7 +2119,7 @@ static int pf_ul(gNB_MAC_INST *nrmac, NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, slots_per_frame); if (beam.idx < 0) { - LOG_D(NR_MAC, "[UE %04x][%4d.%2d] Beam could not be allocated\n", iterator->UE->rnti, frame, slot); + LOG_D(NR_MAC, "[UE %04x][%4d.%2d] ULSCH Beam could not be allocated\n", iterator->UE->rnti, sched_frame, sched_slot); iterator++; continue; } @@ -2132,7 +2132,7 @@ static int pf_ul(gNB_MAC_INST *nrmac, NR_beam_alloc_t dci_beam = beam_allocation_procedure(&nrmac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame); if (dci_beam.idx < 0) { - LOG_D(NR_MAC, "[UE %04x][%4d.%2d] Beam could not be allocated\n", iterator->UE->rnti, frame, slot); + LOG_D(NR_MAC, "[UE %04x][%4d.%2d] ULSCH DCI Beam could not be allocated\n", iterator->UE->rnti, frame, slot); reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam); iterator++; continue; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index efcabbc98a..5a59ed67af 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -56,7 +56,7 @@ void mac_top_init_gNB(ngran_node_t node_type, const nr_rlc_configuration_t *default_rlc_config); void mac_top_destroy_gNB(gNB_MAC_INST *mac); void nr_mac_send_f1_setup_req(void); - +int get_ssbidx_from_beam(gNB_MAC_INST *mac, int beam_idx); void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *mac_config); void nr_mac_configure_sib1(gNB_MAC_INST *nrmac, const plmn_id_t *plmn, uint64_t cellID, int tac); bool nr_mac_configure_other_sib(gNB_MAC_INST *nrmac, int num_cu_sib, const f1ap_sib_msg_t cu_sib[num_cu_sib]); @@ -455,7 +455,8 @@ int16_t get_allocated_beam(const NR_beam_info_t *beam_info, int frame, int slot, uint16_t convert_to_fapi_beam(const uint16_t beam_idx, const nr_beam_mode_t mode); NR_beam_alloc_t beam_allocation_procedure(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_index, int slots_per_frame); void reset_beam_status(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_index, int slots_per_frame, bool new_beam); -void beam_selection_procedures(gNB_MAC_INST *mac, NR_UE_info_t *UE); +int beam_selection_procedures(gNB_MAC_INST *mac, NR_UE_info_t *UE); +void beam_switching_procedure(gNB_MAC_INST *mac, NR_UE_info_t *UE, int new_beam_index); void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t frameP, slot_t slotP); bwp_info_t get_pdsch_bwp_start_size(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE); bwp_info_t get_pusch_bwp_start_size(NR_UE_info_t *UE); @@ -483,7 +484,7 @@ void nr_mac_trigger_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpac void nr_mac_reset_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl); bool nr_mac_check_ul_failure(gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ctrl_t *sched_ctrl); -void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, NR_UE_info_t *UE, int new_bwp_id); +void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, NR_UE_info_t *UE, int new_bwp_id, bool new_beam); bool nr_mac_add_lcid(NR_UE_sched_ctrl_t *sched_ctrl, const nr_lc_config_t *c); nr_lc_config_t *nr_mac_get_lc_config(NR_UE_sched_ctrl_t* sched_ctrl, int lcid); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 29c6694152..d14696db74 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -567,12 +567,13 @@ static NR_UE_info_t *create_new_UE(gNB_MAC_INST *mac, uint32_t cu_id, const NR_C NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; const NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; const nr_mac_config_t *configuration = &mac->radio_config; + int ssb_index = get_ssbidx_from_beam(mac, UE->UE_beam_index); if (is_SA) { - cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, &mac->radio_config, &mac->rlc_config); + cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, &mac->radio_config, &mac->rlc_config, ssb_index); cellGroupConfig->spCellConfig->reconfigurationWithSync = get_reconfiguration_with_sync(UE->rnti, UE->uid, scc, mac->frame); } else { NR_UE_NR_Capability_t *cap = get_ue_nr_cap_from_cg_config_info(cgci); - cellGroupConfig = get_default_secondaryCellGroup(scc, cap, 1, 1, configuration, UE->uid); + cellGroupConfig = get_default_secondaryCellGroup(scc, cap, 1, 1, configuration, UE->uid, ssb_index); cellGroupConfig->spCellConfig->reconfigurationWithSync = get_reconfiguration_with_sync(UE->rnti, UE->uid, scc, mac->frame); // TODO: in NSA we assign capabilities here, otherwise outside => not logic UE->capability = cap; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index 8f3944ee44..054703c2e2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -387,7 +387,7 @@ static void set_csirs_periodicity(NR_NZP_CSI_RS_Resource_t *nzpcsi0, { nzpcsi0->periodicityAndOffset = calloc(1,sizeof(*nzpcsi0->periodicityAndOffset)); // TODO ideal period to be set according to estimation by the gNB on how fast the channel changes - const int offset = fs->numb_slots_period * id; + const int offset = id; // id = ssb_index/2, offset should be set to ssb_index/2. if (check_periodicity(4, ideal_period, fs)) { nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots4; nzpcsi0->periodicityAndOffset->choice.slots4 = offset; @@ -3424,7 +3424,8 @@ static NR_CSI_MeasConfig_t *get_csiMeasConfig(const NR_ServingCellConfig_t *conf const nr_mac_config_t *configuration, int uid, int bwp_id, - uint64_t bitmap) + uint64_t bitmap, + int ssb_index) { NR_CSI_MeasConfig_t *csi_MeasConfig = calloc(1, sizeof(*csi_MeasConfig)); csi_MeasConfig->csi_SSB_ResourceSetToAddModList = calloc(1, sizeof(*csi_MeasConfig->csi_SSB_ResourceSetToAddModList)); @@ -3464,8 +3465,8 @@ static NR_CSI_MeasConfig_t *get_csiMeasConfig(const NR_ServingCellConfig_t *conf const int pdsch_AntennaPorts = configuration->pdsch_AntennaPorts.N1 * configuration->pdsch_AntennaPorts.N2 * configuration->pdsch_AntennaPorts.XP; - config_csirs(scc, csi_MeasConfig, pdsch_AntennaPorts, curr_bwp, configuration->do_CSIRS, bwp_id); - config_csiim(configuration->do_CSIRS, pdsch_AntennaPorts, curr_bwp, csi_MeasConfig, bwp_id); + config_csirs(scc, csi_MeasConfig, pdsch_AntennaPorts, curr_bwp, configuration->do_CSIRS, ssb_index / 2); + config_csiim(configuration->do_CSIRS, pdsch_AntennaPorts, curr_bwp, csi_MeasConfig, ssb_index / 2); NR_CSI_ResourceConfig_t *csires1 = calloc(1, sizeof(*csires1)); csires1->csi_ResourceConfigId = bwp_id + 20; @@ -3491,7 +3492,7 @@ static NR_CSI_MeasConfig_t *get_csiMeasConfig(const NR_ServingCellConfig_t *conf csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList = calloc(1, sizeof(*csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList)); NR_NZP_CSI_RS_ResourceSetId_t *nzp0 = calloc(1, sizeof(*nzp0)); - *nzp0 = bwp_id; + *nzp0 = ssb_index / 2; asn1cSeqAdd(&csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list, nzp0); csires0->bwp_Id = bwp_id; csires0->resourceType = NR_CSI_ResourceConfig__resourceType_periodic; @@ -3505,7 +3506,7 @@ static NR_CSI_MeasConfig_t *get_csiMeasConfig(const NR_ServingCellConfig_t *conf csires2->csi_RS_ResourceSetList.choice.csi_IM_ResourceSetList = calloc(1, sizeof(*csires2->csi_RS_ResourceSetList.choice.csi_IM_ResourceSetList)); NR_CSI_IM_ResourceSetId_t *csiim00 = calloc(1, sizeof(*csiim00)); - *csiim00 = bwp_id; + *csiim00 = ssb_index / 2; asn1cSeqAdd(&csires2->csi_RS_ResourceSetList.choice.csi_IM_ResourceSetList->list, csiim00); csires2->bwp_Id = bwp_id; csires2->resourceType = NR_CSI_ResourceConfig__resourceType_periodic; @@ -3541,7 +3542,8 @@ static NR_CSI_MeasConfig_t *get_csiMeasConfig(const NR_ServingCellConfig_t *conf static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid, const NR_ServingCellConfigCommon_t *scc, - const nr_mac_config_t *configuration) + const nr_mac_config_t *configuration, + int ssb_index) { const int pdsch_AntennaPorts = configuration->pdsch_AntennaPorts.N1 * configuration->pdsch_AntennaPorts.N2 * configuration->pdsch_AntennaPorts.XP; @@ -3605,7 +3607,8 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid, configuration, uid, first_active_bwp, - bitmap); + bitmap, + ssb_index); fill_harq_IEs(configDedicated, configuration->num_dlharq, configuration->num_ulharq, first_active_bwp); SpCellConfig->spCellConfigDedicated = configDedicated; @@ -3785,12 +3788,13 @@ static bool verify_radio_configuration(int uid, const NR_ServingCellConfigCommon NR_CellGroupConfig_t *get_initial_cellGroupConfig(int uid, const NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *configuration, - const nr_rlc_configuration_t *default_rlc_config) + const nr_rlc_configuration_t *default_rlc_config, + int ssb_index) { if (!verify_radio_configuration(uid, scc, configuration)) return NULL; - NR_SpCellConfig_t *spCellConfig = get_initial_SpCellConfig(uid, scc, configuration); + NR_SpCellConfig_t *spCellConfig = get_initial_SpCellConfig(uid, scc, configuration, ssb_index); NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(*cellGroupConfig)); cellGroupConfig->cellGroupId = 0; @@ -3821,7 +3825,8 @@ NR_CellGroupConfig_t *update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t const NR_ServingCellConfigCommon_t *scc, int uid, int old_bwp, - int new_bwp) + int new_bwp, + int ssb_index) { NR_SpCellConfig_t *spCellConfig = cellGroupConfig->spCellConfig; NR_ServingCellConfig_t *configDedicated = spCellConfig->spCellConfigDedicated; @@ -3866,7 +3871,8 @@ NR_CellGroupConfig_t *update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t &local_config, uid, *uplinkConfig->firstActiveUplinkBWP_Id, - bitmap); + bitmap, + ssb_index); // we temporarily need to keep both the old and the new BWP in the CG used by the gNB // while removing the old from the CG sent to the UE @@ -3878,6 +3884,34 @@ NR_CellGroupConfig_t *update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t return clone_cg; } +NR_CellGroupConfig_t *update_cellGroupConfig_for_beam_switch(NR_CellGroupConfig_t *cellGroupConfig, + const nr_mac_config_t *configuration, + const NR_UE_NR_Capability_t *uecap, + const NR_ServingCellConfigCommon_t *scc, + int uid, + int bwp, + int ssb_index) +{ + NR_SpCellConfig_t *spCellConfig = cellGroupConfig->spCellConfig; + NR_ServingCellConfig_t *configDedicated = spCellConfig->spCellConfigDedicated; + + uint64_t bitmap = get_ssb_bitmap(scc); + 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, + bwp, + bitmap, + ssb_index); + + NR_CellGroupConfig_t *clone_cg = NULL; + const int copy_result = asn_copy(&asn_DEF_NR_CellGroupConfig, (void **)&clone_cg, cellGroupConfig); + AssertFatal(copy_result == 0, "unable to copy NR_CellGroupConfig for cloning\n"); + return clone_cg; +} + void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, const int uid, const NR_UE_NR_Capability_t *uecap, @@ -4017,7 +4051,8 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC int scg_id, int servCellIndex, const nr_mac_config_t *configuration, - int uid) + int uid, + int ssb_index) { const nr_pdsch_AntennaPorts_t *pdschap = &configuration->pdsch_AntennaPorts; const int dl_antenna_ports = pdschap->N1 * pdschap->N2 * pdschap->XP; @@ -4168,7 +4203,8 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC configuration, uid, firstActiveUplinkBWP_Id, - bitmap); + bitmap, + ssb_index); configDedicated->sCellDeactivationTimer = NULL; configDedicated->crossCarrierSchedulingConfig = NULL; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h index e2c04aece9..edf53f24f7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h @@ -95,7 +95,8 @@ NR_SIB19_r17_t *get_SIB19_NR(const NR_ServingCellConfigCommon_t *scc); NR_CellGroupConfig_t *get_initial_cellGroupConfig(int uid, const NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *configuration, - const nr_rlc_configuration_t *default_rlc_config); + const nr_rlc_configuration_t *default_rlc_config, + int ssb_index); void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, const int uid, const NR_UE_NR_Capability_t *uecap, @@ -111,7 +112,8 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC int scg_id, int servCellIndex, const nr_mac_config_t *configuration, - int uid); + int uid, + int ssb_index); NR_ReconfigurationWithSync_t *get_reconfiguration_with_sync(rnti_t rnti, uid_t uid, const NR_ServingCellConfigCommon_t *scc, int frame); @@ -133,7 +135,15 @@ NR_CellGroupConfig_t *update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t const NR_ServingCellConfigCommon_t *scc, int uid, int old_bwp, - int new_bwp); + int new_bwp, + int ssb_index); +NR_CellGroupConfig_t *update_cellGroupConfig_for_beam_switch(NR_CellGroupConfig_t *cellGroupConfig, + const nr_mac_config_t *configuration, + const NR_UE_NR_Capability_t *uecap, + const NR_ServingCellConfigCommon_t *scc, + int uid, + int bwp, + int ssb_index); NR_MeasurementTimingConfiguration_t *get_nr_mtc(uint8_t *buf, uint32_t len); measgap_config_t create_measgap_config(const NR_MeasurementTimingConfiguration_t *mtc, int scs, int min_rxtxtime); int encode_measgap_config(const measgap_config_t *c, uint8_t *buf);