diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 5fbfad04d2..0d5755dd71 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2365,9 +2365,8 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG scc, genericParameters, NULL); - sched_ctrl->bwp_switch_info.current_bwp = bwp_id; - sched_ctrl->bwp_switch_info.next_bwp = -1; - sched_ctrl->bwp_switch_info.bwp_switch_state = BWP_SWITCH_INACTIVE; + sched_ctrl->next_dl_bwp_id = -1; + sched_ctrl->next_ul_bwp_id = -1; const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig ? servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList : NULL; if (ubwpList) AssertFatal(ubwpList->list.count <= NR_MAX_NUM_BWP, "uplinkBWP_ToAddModList has %d BWP!\n", @@ -2900,52 +2899,6 @@ void nr_mac_update_timers(module_id_t module_id, } } -void nr_bwp_switch(module_id_t module_id, - frame_t frame, - sub_frame_t slot, - int UE_id, - int bwp_id) { - - NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; - NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; - - switch(sched_ctrl->bwp_switch_info.bwp_switch_state) { - - case BWP_SWITCH_TO_START: - LOG_W(NR_MAC,"(%d.%d) [UE_id %d] Schedule BWP switch from bwp_id %ld to %d\n", - frame, slot, UE_id, UE_info->UE_sched_ctrl[UE_id].active_bwp->bwp_Id, bwp_id); - sched_ctrl->bwp_switch_info.bwp_switch_state = BWP_SWITCH_RUNNING; - sched_ctrl->bwp_switch_info.bwp_switch_slot = slot; - nr_mac_rrc_bwp_switch_req(module_id, frame, slot, UE_info->rnti[UE_id], bwp_id); - break; - - case BWP_SWITCH_RUNNING: - // The BWP switching takes at least 10+6 ms (3GPP TS 38.331 Section 12) - // gNB needs time to schedule and send RRCReconfiguration message - // Therefore, we wait for the same slot in next frame (10 ms) before update bwp_id in the gNB - if (sched_ctrl->bwp_switch_info.bwp_switch_slot == slot) { - const NR_ServingCellConfig_t *servingCellConfig = UE_info->CellGroup[UE_id] ? UE_info->CellGroup[UE_id]->spCellConfig->spCellConfigDedicated : NULL; - const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig ? servingCellConfig->downlinkBWP_ToAddModList : NULL; - const int bwp_id = servingCellConfig && servingCellConfig->firstActiveDownlinkBWP_Id ? - *servingCellConfig->firstActiveDownlinkBWP_Id : 0; - sched_ctrl->active_bwp = bwpList && bwp_id > 0 ? bwpList->list.array[bwp_id - 1] : NULL; - const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig ? servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList : NULL; - const int ubwp_id = servingCellConfig && servingCellConfig->uplinkConfig && servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id ? - *servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id : 0; - sched_ctrl->active_ubwp = ubwpList && ubwp_id > 0 ? ubwpList->list.array[ubwp_id - 1] : NULL; - sched_ctrl->bwp_switch_info.bwp_switch_state = BWP_SWITCH_INACTIVE; - } - break; - - case BWP_SWITCH_INACTIVE: - break; - - default: - AssertFatal(1==0,"Invalid bwp switch state\n"); - break; - } -} - void schedule_nr_bwp_switch(module_id_t module_id, frame_t frame, sub_frame_t slot) { @@ -2954,16 +2907,21 @@ void schedule_nr_bwp_switch(module_id_t module_id, const NR_list_t *UE_list = &UE_info->list; // TODO: Implementation of a algorithm to perform: - // - the BWP switch trigger: sched_ctrl->bwp_switch_info.bwp_switch_state = BWP_SWITCH_TO_START - // - the BWP selection: sched_ctrl->bwp_switch_info.next_bwp = bwp_id + // - DL BWP selection: sched_ctrl->next_dl_bwp_id = dl_bwp_id + // - UL BWP selection: sched_ctrl->next_ul_bwp_id = ul_bwp_id for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; - if(sched_ctrl->bwp_switch_info.bwp_switch_state > BWP_SWITCH_INACTIVE) { - nr_bwp_switch(module_id, frame, slot, UE_id, sched_ctrl->bwp_switch_info.next_bwp); + if (sched_ctrl->rrc_processing_timer == 0 && + UE_info->Msg4_ACKed[UE_id] == true && + ((sched_ctrl->next_dl_bwp_id >= 0 && sched_ctrl->active_bwp && sched_ctrl->active_bwp->bwp_Id != sched_ctrl->next_dl_bwp_id) || + (sched_ctrl->next_ul_bwp_id >= 0 && sched_ctrl->active_ubwp && sched_ctrl->active_ubwp->bwp_Id != sched_ctrl->next_ul_bwp_id))) { + + LOG_W(NR_MAC,"(%d.%d) [UE_id %d] Schedule BWP switch from dl_bwp_id %ld to %ld and from ul_bwp_id %ld to %ld\n", + frame, slot, UE_id, sched_ctrl->active_bwp->bwp_Id, sched_ctrl->next_dl_bwp_id, sched_ctrl->active_ubwp->bwp_Id, sched_ctrl->next_ul_bwp_id); + nr_mac_rrc_bwp_switch_req(module_id, frame, slot, UE_info->rnti[UE_id], sched_ctrl->next_dl_bwp_id, sched_ctrl->next_ul_bwp_id); } } - } /*void fill_nfapi_coresets_and_searchspaces(NR_CellGroupConfig_t *cg, diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index b80b954b8c..4d82f51868 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -558,19 +558,6 @@ typedef struct NR_UE_ul_harq { NR_sched_pusch_t sched_pusch; } NR_UE_ul_harq_t; -typedef enum { - BWP_SWITCH_INACTIVE = 0, - BWP_SWITCH_TO_START, - BWP_SWITCH_RUNNING -} NR_BWP_switch_states_t; - -typedef struct NR_BWP_switch_info { - NR_BWP_Id_t current_bwp; - NR_BWP_Id_t next_bwp; - sub_frame_t bwp_switch_slot; - NR_BWP_switch_states_t bwp_switch_state; -} NR_BWP_switch_info_t; - /*! \brief scheduling control information set through an API */ #define MAX_CSI_REPORTS 48 typedef struct { @@ -579,8 +566,10 @@ typedef struct { /// the currently active BWP in UL NR_BWP_Uplink_t *active_ubwp; - /// the state of bwp switch procedure - NR_BWP_switch_info_t bwp_switch_info; + /// the next active BWP ID in DL + NR_BWP_Id_t next_dl_bwp_id; + /// the next active BWP ID in UL + NR_BWP_Id_t next_ul_bwp_id; /// CCE index and aggregation, should be coherent with cce_list NR_SearchSpace_t *search_space; diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 9c06dfaff4..c8df5d4b5f 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -297,13 +297,14 @@ int8_t nr_mac_rrc_bwp_switch_req(const module_id_t module_idP, const frame_t frameP, const sub_frame_t sub_frameP, const rnti_t rntiP, - const int bwp_id) { + const int dl_bwp_id, + const int ul_bwp_id) { struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[module_idP], rntiP); protocol_ctxt_t ctxt; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, GNB_FLAG_YES, rntiP, frameP, sub_frameP, 0); - nr_rrc_reconfiguration_req(ue_context_p, &ctxt, bwp_id); + nr_rrc_reconfiguration_req(ue_context_p, &ctxt, dl_bwp_id, ul_bwp_id); return 0; } diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index ab5f5fbc65..6a320123de 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -171,7 +171,8 @@ int8_t nr_mac_rrc_bwp_switch_req(const module_id_t module_idP, const frame_t frameP, const sub_frame_t sub_frameP, const rnti_t rntiP, - const int bwp_id); + const int dl_bwp_id, + const int ul_bwp_id); int8_t nr_mac_rrc_data_ind( const module_id_t module_idP, @@ -188,7 +189,8 @@ int8_t nr_mac_rrc_data_ind( int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP, protocol_ctxt_t *const ctxt_pP, - const int bwp_id); + const int dl_bwp_id, + const int ul_bwp_id); int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, const uint8_t *buffer, diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 3f47e41b0d..3d41787a2d 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1942,16 +1942,21 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete( int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP, protocol_ctxt_t *const ctxt_pP, - const int bwp_id) { + const int dl_bwp_id, + const int ul_bwp_id) { uint8_t buffer[RRC_BUF_SIZE]; memset(buffer, 0, sizeof(buffer)); uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); NR_CellGroupConfig_t *masterCellGroup = ue_context_pP->ue_context.masterCellGroup; - *masterCellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id = bwp_id; - *masterCellGroup->spCellConfig->spCellConfigDedicated->defaultDownlinkBWP_Id = bwp_id; - *masterCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id = bwp_id; + if (dl_bwp_id >= 0) { + *masterCellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id = dl_bwp_id; + *masterCellGroup->spCellConfig->spCellConfigDedicated->defaultDownlinkBWP_Id = dl_bwp_id; + } + if (ul_bwp_id >= 0) { + *masterCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id = ul_bwp_id; + } uint16_t size = do_RRCReconfiguration(ctxt_pP, buffer,