diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index e576445e45..b047cdd4ee 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -3441,26 +3441,8 @@ void nr_measgap_scheduling(gNB_MAC_INST *nr_mac, frame_t frame, sub_frame_t slot } } -void nr_mac_clean_cellgroup(NR_CellGroupConfig_t *cell_group) +void clean_bwp_structures(NR_SpCellConfig_t *spCellConfig) { - DevAssert(cell_group != NULL); - NR_SpCellConfig_t *spCellConfig = cell_group->spCellConfig; - /* remove a reconfigurationWithSync, we don't need it anymore */ - if (spCellConfig && spCellConfig->reconfigurationWithSync != NULL) { - ASN_STRUCT_FREE(asn_DEF_NR_ReconfigurationWithSync, spCellConfig->reconfigurationWithSync); - spCellConfig->reconfigurationWithSync = NULL; - } - /* remove the rlc_BearerToReleaseList, we don't need it anymore */ - if (cell_group->rlc_BearerToReleaseList != NULL) { - struct NR_CellGroupConfig__rlc_BearerToReleaseList *l = cell_group->rlc_BearerToReleaseList; - asn_sequence_del(&l->list, l->list.count, /* free */ 1); - free(cell_group->rlc_BearerToReleaseList); - cell_group->rlc_BearerToReleaseList = NULL; - } - /* remove reestablishRLC, we don't need it anymore */ - for (int i = 0; i < cell_group->rlc_BearerToAddModList->list.count; ++i) - free_and_zero(cell_group->rlc_BearerToAddModList->list.array[i]->reestablishRLC); - /* clean BWP structures */ NR_ServingCellConfig_t *spCellConfigDedicated = spCellConfig->spCellConfigDedicated; if (spCellConfigDedicated->downlinkBWP_ToReleaseList) { struct NR_ServingCellConfig__downlinkBWP_ToReleaseList *rel_dl = spCellConfigDedicated->downlinkBWP_ToReleaseList; @@ -3504,6 +3486,29 @@ void nr_mac_clean_cellgroup(NR_CellGroupConfig_t *cell_group) } } +void nr_mac_clean_cellgroup(NR_CellGroupConfig_t *cell_group) +{ + DevAssert(cell_group != NULL); + NR_SpCellConfig_t *spCellConfig = cell_group->spCellConfig; + /* remove a reconfigurationWithSync, we don't need it anymore */ + if (spCellConfig && spCellConfig->reconfigurationWithSync != NULL) { + ASN_STRUCT_FREE(asn_DEF_NR_ReconfigurationWithSync, spCellConfig->reconfigurationWithSync); + spCellConfig->reconfigurationWithSync = NULL; + } + /* remove the rlc_BearerToReleaseList, we don't need it anymore */ + if (cell_group->rlc_BearerToReleaseList != NULL) { + struct NR_CellGroupConfig__rlc_BearerToReleaseList *l = cell_group->rlc_BearerToReleaseList; + asn_sequence_del(&l->list, l->list.count, /* free */ 1); + free(cell_group->rlc_BearerToReleaseList); + cell_group->rlc_BearerToReleaseList = NULL; + } + /* remove reestablishRLC, we don't need it anymore */ + for (int i = 0; i < cell_group->rlc_BearerToAddModList->list.count; ++i) + free_and_zero(cell_group->rlc_BearerToAddModList->list.array[i]->reestablishRLC); + /* clean BWP structures */ + clean_bwp_structures(spCellConfig); +} + int nr_mac_get_reconfig_delay_slots(NR_SubcarrierSpacing_t scs) { /* we previously assumed a specific "slot ahead" value for the PHY processing @@ -3886,21 +3891,26 @@ bool nr_mac_check_ul_failure(gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ctrl_t * void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_t *UE, int new_bwp_id) { 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 (new_bwp_id == UE->current_DL_BWP.bwp_id) LOG_E(NR_MAC, "Source BWP ID and target BWP ID are the same, can't perform switch\n"); else - 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); + 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); } uint8_t buf[2048]; - asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, NULL, UE->CellGroup, buf, sizeof(buf)); + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, + NULL, + cellGroup_for_UE ? cellGroup_for_UE : UE->CellGroup, + buf, + sizeof(buf)); AssertFatal(enc_rval.encoded > 0, "ASN1 encoding of CellGroupConfig failed, failed type %s\n", enc_rval.failed_type->name); du_to_cu_rrc_information_t du2cu = { .cellGroupConfig = buf, @@ -3915,6 +3925,8 @@ void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_ .cause_value = F1AP_CauseRadioNetwork_action_desirable_for_radio_reasons, }; nrmac->mac_rrc.ue_context_modification_required(&required); + if (cellGroup_for_UE) + free_cellGroupConfig(cellGroup_for_UE); } /* \brief add bearers from CellGroupConfig. diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 7ea9a831f9..bed6b8a1ad 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -476,7 +476,7 @@ bool nr_mac_check_release(NR_UE_sched_ctrl_t *sched_ctrl, int rnti); void nr_mac_trigger_release_complete(gNB_MAC_INST *mac, int rnti); void nr_mac_release_ue(gNB_MAC_INST *mac, int rnti); bool nr_mac_request_release_ue(const gNB_MAC_INST *nrmac, int rnti); - +void clean_bwp_structures(NR_SpCellConfig_t *spCellConfig); void nr_mac_trigger_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing); 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); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index a48171aff8..c3e9225b4e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -3683,13 +3683,13 @@ static long set_ul_max_layers(const nr_mac_config_t *configuration, const NR_UE_ return ul_max_layers; } -void update_cellGroupConfig_for_BWP_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 old_bwp, - int new_bwp) +NR_CellGroupConfig_t * update_cellGroupConfig_for_BWP_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 old_bwp, + int new_bwp) { NR_SpCellConfig_t *spCellConfig = cellGroupConfig->spCellConfig; NR_ServingCellConfig_t *configDedicated = spCellConfig->spCellConfigDedicated; @@ -3751,6 +3751,17 @@ void update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t *cellGroupConfig NR_BWP_Uplink_t *ul_bwp = config_uplinkBWP(new_bwp - 1, true, uid, ul_maxMIMO_Layers, configuration, scc, uecap); asn1cSeqAdd(&uplinkConfig->uplinkBWP_ToAddModList->list, ul_bwp); } + + // 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 + if (old_bwp > 0) { + 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"); + clean_bwp_structures(clone_cg->spCellConfig); + return clone_cg; + } + return NULL; } void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h index 44715dc66d..d5df69b3c6 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h @@ -121,13 +121,13 @@ NR_RLC_BearerConfig_t *get_DRB_RLC_BearerConfig(long lcChannelId, NR_RLC_Config_PR rlc_conf, long priority, const nr_rlc_configuration_t *default_rlc_config); -void update_cellGroupConfig_for_BWP_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 old_bwp, - int new_bwp); +NR_CellGroupConfig_t * update_cellGroupConfig_for_BWP_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 old_bwp, + int new_bwp); 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);