diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 9b9b5b54ce..6f41db3764 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -1013,24 +1013,3 @@ void nr_mac_prepare_ra_ue(gNB_MAC_INST *nrmac, NR_UE_info_t *UE) } LOG_I(NR_MAC, "Added new %s process for UE RNTI %04x with initial CellGroup\n", ra->cfra ? "CFRA" : "CBRA", UE->rnti); } - -/* Prepare a new CellGroupConfig to be applied for this UE. We cannot - * immediatly apply it, as we have to wait for the reconfiguration through RRC. - * This function sets up everything to apply the reconfiguration. Later, we - * will trigger the UE inactivity with nr_mac_interrupt_ue_transmission(); upon - * expiry, nr_mac_apply_cellgroup() will apply the CellGroupConfig (radio - * config etc). */ -bool nr_mac_prepare_cellgroup_update(gNB_MAC_INST *nrmac, NR_UE_info_t *UE, NR_CellGroupConfig_t *CellGroup) -{ - DevAssert(nrmac != NULL); - DevAssert(UE != NULL); - DevAssert(CellGroup != NULL); - - /* we assume that this function is mutex-protected from outside */ - NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock); - - UE->reconfigCellGroup = CellGroup; - UE->expect_reconfiguration = true; - - return true; -} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 595d849cc4..0c5a2c759c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1738,12 +1738,6 @@ static void nr_generate_Msg2(module_id_t module_idP, *ul_bwp->tdaList_Common->list.array[ra->Msg3_tda_id]->k2 + get_NTN_Koffset(scc), ul_bwp->scs); - if (ra->cfra) { - int delay = nr_mac_get_reconfig_delay_slots(dl_bwp->scs); - interrupt_followup_action_t action = UE->reconfigCellGroup ? FOLLOW_INSYNC_RECONFIG : FOLLOW_INSYNC; - nr_mac_interrupt_ue_transmission(RC.nrmac[module_idP], UE, action, delay); - } - LOG_D(NR_MAC, "UE %04x: %d.%d: Setting RA-Msg3 reception (%s) for SFN.Slot %d.%d\n", UE->rnti, @@ -2091,25 +2085,17 @@ void nr_check_Msg4_MsgB_Ack(module_id_t module_id, frame_t frame, slot_t slot, N if (harq->round == 0) { if (success) { + gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; + NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels[0].ServingCellConfigCommon; + // we configure the UE using common search space with DCIX0 while waiting for a reconfiguration + configure_UE_BWP(nr_mac, scc, UE, false, NR_SearchSpace__searchSpaceType_PR_common, -1, -1); + transition_ra_connected_nr_ue(nr_mac, UE); LOG_A(NR_MAC, "%4d.%2d UE %04x: Received Ack of %s. CBRA procedure succeeded!\n", frame, slot, UE->rnti, ra_type_str); } else { LOG_I(NR_MAC, "%4d.%2d UE %04x: RA Procedure failed at %s!\n", frame, slot, UE->rnti, ra_type_str); nr_mac_trigger_ul_failure(sched_ctrl, UE->current_DL_BWP.scs); } - // Pause scheduling according to: - // 3GPP TS 38.331 Section 12 Table 12.1-1: UE performance requirements for RRC procedures for UEs - // Msg4 may transmit a RRCReconfiguration, for example when UE sends RRCReestablishmentComplete and MAC CE for C-RNTI in Msg3. - // In that case, gNB will generate a RRCReconfiguration that will be transmitted in Msg4, so we need to apply CellGroup after the Ack, - // UE->reconfigCellGroup already set when processing RRCReestablishment message - int delay = nr_mac_get_reconfig_delay_slots(UE->current_UL_BWP.scs); - gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; - nr_mac_interrupt_ue_transmission(nr_mac, UE, UE->interrupt_action, delay); - if (!transition_ra_connected_nr_ue(nr_mac, UE)) { - LOG_E(NR_MAC, "cannot add UE %04x: list is full\n", UE->rnti); - delete_nr_ue_data(UE, NULL, &nr_mac->UE_info.uid_allocator); - return; - } if (sched_ctrl->retrans_dl_harq.head >= 0) { remove_nr_list(&sched_ctrl->retrans_dl_harq, current_harq_pid); } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 727cf63cd6..17a6ae53bd 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2083,7 +2083,6 @@ NR_UE_info_t *find_ra_UE(NR_UEs_t *UEs, rnti_t rntiP) void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_allocator_t *uia) { ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); - ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->reconfigCellGroup); ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->capability); NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; seq_arr_free(&sched_ctrl->lc_config, NULL); @@ -2098,7 +2097,7 @@ void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_alloca free_sched_pucch_list(sched_ctrl); uid_linear_allocator_free(uia, UE->uid); LOG_I(NR_MAC, "Remove NR rnti 0x%04x\n", UE->rnti); - free(UE->ra); + free_and_zero(UE->ra); free(UE); } @@ -2392,6 +2391,8 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, sc_info->nrofHARQ_ProcessesForPUSCH_r17 = pusch_servingcellconfig->ext3->nrofHARQ_ProcessesForPUSCH_r17; } } + create_dl_harq_list(sched_ctrl, sc_info); + create_ul_harq_list(sched_ctrl, sc_info); } if (CellGroup && CellGroup->physicalCellGroupConfig) @@ -3025,7 +3026,7 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, slot_t slot, nfapi_nr_dl_tt } } -static void nr_mac_clean_cellgroup(NR_CellGroupConfig_t *cell_group) +void nr_mac_clean_cellgroup(NR_CellGroupConfig_t *cell_group) { DevAssert(cell_group != NULL); /* remove a reconfigurationWithSync, we don't need it anymore */ @@ -3045,43 +3046,6 @@ static void nr_mac_clean_cellgroup(NR_CellGroupConfig_t *cell_group) free_and_zero(cell_group->rlc_BearerToAddModList->list.array[i]->reestablishRLC); } -static void nr_mac_apply_cellgroup(gNB_MAC_INST *mac, NR_UE_info_t *UE, frame_t frame, slot_t slot) -{ - LOG_D(NR_MAC, "%4d.%2d RNTI %04x: UE inactivity timer expired\n", frame, slot, UE->rnti); - - /* check if there is a new CellGroupConfig to be applied */ - if (UE->interrupt_action == FOLLOW_INSYNC_RECONFIG && UE->reconfigCellGroup != NULL) { - LOG_D(NR_MAC, "%4d.%2d RNTI %04x: Apply CellGroupConfig after UE inactivity\n", frame, slot, UE->rnti); - ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); - UE->CellGroup = UE->reconfigCellGroup; - UE->reconfigCellGroup = NULL; - UE->interrupt_action = FOLLOW_INSYNC; - - if (LOG_DEBUGFLAG(DEBUG_ASN1)) - xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *)UE->CellGroup); - - nr_mac_clean_cellgroup(UE->CellGroup); - } - - NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon; - - NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - int ss_type; - if (UE->CellGroup && UE->CellGroup->spCellConfig) - ss_type = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - else - ss_type = NR_SearchSpace__searchSpaceType_PR_common; - configure_UE_BWP(mac, scc, UE, false, ss_type, -1, -1); - - reset_srs_stats(UE); - - if (IS_SA_MODE(get_softmodem_params())) { - // add all available DL,UL HARQ processes for this UE in SA - create_dl_harq_list(sched_ctrl, &UE->sc_info); - create_ul_harq_list(sched_ctrl, &UE->sc_info); - } -} - int nr_mac_get_reconfig_delay_slots(NR_SubcarrierSpacing_t scs) { /* we previously assumed a specific "slot ahead" value for the PHY processing @@ -3109,7 +3073,7 @@ int nr_mac_interrupt_ue_transmission(gNB_MAC_INST *mac, NR_UE_info_t *UE, interr // frames, after the inactivity of the UE. UE->UE_sched_ctrl.ta_frame = (mac->frame - 1 + 1024) % 1024; - LOG_D(NR_MAC, "UE %04x: Interrupt UE transmission (%d slots) action %d reconfigCellGroup %p\n", UE->rnti, slots, UE->interrupt_action, UE->reconfigCellGroup); + LOG_D(NR_MAC, "UE %04x: Interrupt UE transmission (%d slots) action %d\n", UE->rnti, slots, UE->interrupt_action); return 0; } @@ -3182,8 +3146,6 @@ void nr_mac_update_timers(module_id_t module_id, frame_t frame, slot_t slot) nr_timer_stop(&sched_ctrl->transm_interrupt); if (UE->interrupt_action == FOLLOW_OUTOFSYNC) nr_mac_trigger_ul_failure(sched_ctrl, UE->current_DL_BWP.scs); - else - nr_mac_apply_cellgroup(mac, UE, frame, slot); } } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 9fcf8a8e9c..49fe0fca5e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -622,36 +622,6 @@ static void handle_msg3_failed_rx(gNB_MAC_INST *mac, NR_RA_t *ra, rnti_t rnti, i ra->ra_state = nrRA_Msg3_retransmission; } -static NR_UE_info_t *configure_UE_crnti_msg3(gNB_MAC_INST *mac, NR_UE_info_t *old_UE, NR_UE_info_t *new_UE) -{ - // in case UE beam has changed - old_UE->UE_beam_index = new_UE->UE_beam_index; - // Reset UL failure for old UE - nr_mac_reset_ul_failure(&old_UE->UE_sched_ctrl); - // Reset HARQ processes - reset_dl_harq_list(&old_UE->UE_sched_ctrl); - reset_ul_harq_list(&old_UE->UE_sched_ctrl); - // old UE need to complete RA by sending DL - free_and_zero(old_UE->ra); - old_UE->ra = new_UE->ra; - new_UE->ra = NULL; - NR_UE_sched_ctrl_t *sched_ctrl = &old_UE->UE_sched_ctrl; - sched_ctrl->search_space = new_UE->UE_sched_ctrl.search_space; - sched_ctrl->coreset = new_UE->UE_sched_ctrl.coreset; - memcpy(&sched_ctrl->sched_pdcch, &new_UE->UE_sched_ctrl.sched_pdcch, sizeof(NR_sched_pdcch_t)); - old_UE->current_DL_BWP.dci_format = NR_DL_DCI_FORMAT_1_0; - // replace new UE with old UE in the access list - for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { - if (mac->UE_info.access_ue_list[i] && mac->UE_info.access_ue_list[i]->rnti == new_UE->rnti) { - mac->UE_info.access_ue_list[i] = old_UE; - break; - } - } - // remove new UE - delete_nr_ue_data(new_UE, mac->common_channels, &mac->UE_info.uid_allocator); - return old_UE; -} - static void nr_rx_ra_sdu(const module_id_t mod_id, const int CC_id, const frame_t frame, @@ -732,12 +702,21 @@ static void nr_rx_ra_sdu(const module_id_t mod_id, UE_scheduling_control->ta_update = timing_advance; UE_scheduling_control->raw_rssi = rssi; LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n", UE->rnti, UE_scheduling_control->tpc0, UE_scheduling_control->ta_update); + NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon; if (ra->cfra) { LOG_A(NR_MAC, "(rnti 0x%04x) CFRA procedure succeeded!\n", UE->rnti); nr_mac_reset_ul_failure(UE_scheduling_control); reset_dl_harq_list(UE_scheduling_control); reset_ul_harq_list(UE_scheduling_control); process_addmod_bearers_cellGroupConfig(&UE->UE_sched_ctrl, UE->CellGroup->rlc_BearerToAddModList); + int ss_type; + // we configure the UE using common search space with DCIX0 while waiting for a reconfiguration in SA + // in NSA (or do-ra) there is no reconfiguration in NR + if (IS_SA_MODE(get_softmodem_params())) + ss_type = NR_SearchSpace__searchSpaceType_PR_common; + else + ss_type = NR_SearchSpace__searchSpaceType_PR_ue_Specific; + configure_UE_BWP(mac, scc, UE, false, ss_type, -1, -1); if (!transition_ra_connected_nr_ue(mac, UE)) { LOG_E(NR_MAC, "cannot add UE %04x: list is full\n", UE->rnti); delete_nr_ue_data(UE, NULL, &mac->UE_info.uid_allocator); @@ -766,19 +745,23 @@ static void nr_rx_ra_sdu(const module_id_t mod_id, nr_release_ra_UE(mac, rnti); return; } - // remove old UE from connected UEs - remove_UE_from_list(MAX_MOBILES_PER_GNB + 1, mac->UE_info.connected_ue_list, crnti); - UE = configure_UE_crnti_msg3(mac, old_UE, UE); - ra = UE->ra; - if (UE->reconfigCellGroup) { - // Nothing to do - // A RRCReconfiguration message should be already pending (for example, an ongoing RRCReestablishment), and it will be - // transmitted in Msg4 - } else { - // Trigger RRC Reconfiguration - LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x, triggering RRC Reconfiguration\n", UE->rnti); - nr_mac_trigger_reconfiguration(mac, UE); - } + // in case UE beam has changed + old_UE->UE_beam_index = UE->UE_beam_index; + // Reset UL failure for old UE + nr_mac_reset_ul_failure(&old_UE->UE_sched_ctrl); + // Reset HARQ processes + reset_dl_harq_list(&old_UE->UE_sched_ctrl); + reset_ul_harq_list(&old_UE->UE_sched_ctrl); + // Trigger RRC Reconfiguration + LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x, triggering RRC Reconfiguration\n", crnti); + nr_mac_trigger_reconfiguration(mac, old_UE); + nr_release_ra_UE(mac, rnti); + LOG_A(NR_MAC, "%4d.%2d UE %04x: RA with C-RNTI complete\n", frame, slot, crnti); + // 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); + // TODO do we actually need to still process the PDU? + nr_process_mac_pdu(mod_id, old_UE, CC_id, frame, slot, sdu, sdu_len, -1); + return; } else { // UE Contention Resolution Identity // Store the first 48 bits belonging to the uplink CCCH SDU within Msg3 to fill in Msg4 diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 66baea3427..563cfd19b2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -64,7 +64,6 @@ void nr_mac_prepare_ra_ue(gNB_MAC_INST *nrmac, NR_UE_info_t *UE); bool add_new_UE_RA(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE); int nr_mac_get_reconfig_delay_slots(NR_SubcarrierSpacing_t scs); -bool nr_mac_prepare_cellgroup_update(gNB_MAC_INST *nrmac, NR_UE_info_t *UE, NR_CellGroupConfig_t *CellGroup); int nr_mac_interrupt_ue_transmission(gNB_MAC_INST *mac, NR_UE_info_t *UE, interrupt_followup_action_t action, int slots); int nr_transmission_action_indicator_stop(gNB_MAC_INST *mac, NR_UE_info_t *UE_info); @@ -463,4 +462,6 @@ void prepare_du_configuration_update(gNB_MAC_INST *mac, f1ap_served_cell_info_t *info, NR_BCCH_BCH_Message_t *mib, const NR_BCCH_DL_SCH_Message_t *sib1); + +void nr_mac_clean_cellgroup(NR_CellGroupConfig_t *cell_group); #endif /*__LAYER2_NR_MAC_PROTO_H__*/ 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 d3d63fb0df..8ba63890ca 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -571,10 +571,10 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) nr_rlc_srb_recv_sdu(req->gNB_DU_ue_id, id, req->rrc_container, req->rrc_container_length); } + NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon; UE->capability = ue_cap; if (ue_cap != NULL) { // store the new UE capabilities, and update the cellGroupConfig - NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon; update_cellGroupConfig(new_CellGroup, UE->uid, UE->capability, &mac->radio_config, scc); } @@ -583,6 +583,10 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) struct NR_CellGroupConfig__rlc_BearerToAddModList *addmod = new_CellGroup->rlc_BearerToAddModList; for (int i = 0; i < addmod->list.count; ++i) { asn1cCallocOne(addmod->list.array[i]->reestablishRLC, NR_RLC_BearerConfig__reestablishRLC_true); + for (int i = 1; i < seq_arr_size(&UE->UE_sched_ctrl.lc_config); ++i) { + nr_lc_config_t *lc_config = seq_arr_at(&UE->UE_sched_ctrl.lc_config, i); + nr_rlc_reestablish_entity(UE->rnti, lc_config->lcid); + } } } @@ -595,7 +599,9 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) AssertFatal(enc_rval.encoded > 0, "Could not encode CellGroup, failed element %s\n", enc_rval.failed_type->name); resp.du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded + 7) >> 3; - nr_mac_prepare_cellgroup_update(mac, UE, new_CellGroup); + ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); + UE->CellGroup = new_CellGroup; + configure_UE_BWP(mac, scc, UE, false, NR_SearchSpace__searchSpaceType_PR_common, -1, -1); NR_SCHED_UNLOCK(&mac->sched_lock); @@ -666,9 +672,15 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) nr_rlc_srb_recv_sdu(req->gNB_DU_ue_id, id, req->rrc_container, req->rrc_container_length); } + NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon; if (req->ReconfigComplOutcome != RRCreconf_info_not_present && req->ReconfigComplOutcome != RRCreconf_success) { LOG_E(NR_MAC, "RRC reconfiguration outcome unsuccessful, but no rollback mechanism implemented to come back to old configuration\n"); + } else if (req->ReconfigComplOutcome == RRCreconf_success) { + LOG_I(NR_MAC, "DU received confirmation of successful RRC Reconfiguration\n"); + // we re-configure the BWP to apply the CellGroup and to use UE specific Search Space with DCIX1 + nr_mac_clean_cellgroup(UE->CellGroup); + configure_UE_BWP(mac, scc, UE, false, NR_SearchSpace__searchSpaceType_PR_ue_Specific, -1, -1); } if (ue_cap != NULL) { @@ -676,7 +688,6 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->capability); UE->capability = ue_cap; LOG_I(NR_MAC, "UE %04x: received capabilities, updating CellGroupConfig\n", UE->rnti); - NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon; update_cellGroupConfig(new_CellGroup, UE->uid, UE->capability, &mac->radio_config, scc); } @@ -694,7 +705,9 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) AssertFatal(enc_rval.encoded > 0, "Could not encode CellGroup, failed element %s\n", enc_rval.failed_type->name); resp.du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded + 7) >> 3; - nr_mac_prepare_cellgroup_update(mac, UE, new_CellGroup); + ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); + UE->CellGroup = new_CellGroup; + configure_UE_BWP(mac, scc, UE, false, NR_SearchSpace__searchSpaceType_PR_common, -1, -1); } else { ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, new_CellGroup); // we actually don't need it } @@ -832,24 +845,13 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) DevAssert(success); } - if (UE->expect_reconfiguration && dl_rrc->srb_id == 1) { - /* we expected a reconfiguration, and this is on DCCH. We assume this is - * the reconfiguration: nr_mac_prepare_cellgroup_update() already stored - * the CellGroupConfig. Below, we trigger a timer, and the CellGroupConfig - * will be applied after its expiry in nr_mac_apply_cellgroup().*/ - NR_SCHED_LOCK(&mac->sched_lock); - int delay = nr_mac_get_reconfig_delay_slots(UE->current_UL_BWP.scs); - nr_mac_interrupt_ue_transmission(mac, UE, FOLLOW_INSYNC_RECONFIG, delay); - NR_SCHED_UNLOCK(&mac->sched_lock); - UE->expect_reconfiguration = false; - /* Re-establish RLC for all remaining bearers */ - if (UE->reestablish_rlc) { - for (int i = 1; i < seq_arr_size(&UE->UE_sched_ctrl.lc_config); ++i) { - nr_lc_config_t *lc_config = seq_arr_at(&UE->UE_sched_ctrl.lc_config, i); - nr_rlc_reestablish_entity(dl_rrc->gNB_DU_ue_id, lc_config->lcid); - } - UE->reestablish_rlc = false; + if (UE->reestablish_rlc && dl_rrc->srb_id == 1) { + // we expected a reconfiguration to re-establish RLC, and this is on DCCH. We assume this is the reconfiguration. + for (int i = 1; i < seq_arr_size(&UE->UE_sched_ctrl.lc_config); ++i) { + nr_lc_config_t *lc_config = seq_arr_at(&UE->UE_sched_ctrl.lc_config, i); + nr_rlc_reestablish_entity(dl_rrc->gNB_DU_ue_id, lc_config->lcid); } + UE->reestablish_rlc = false; } if (dl_rrc->old_gNB_DU_ue_id != NULL) { @@ -866,27 +868,25 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) * from the current configuration. Also, expect the reconfiguration from * the CU, so save the old UE's CellGroup for the new UE */ UE->CellGroup->spCellConfig = NULL; - NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon; uid_t temp_uid = UE->uid; UE->uid = oldUE->uid; oldUE->uid = temp_uid; - configure_UE_BWP(mac, scc, UE, false, NR_SearchSpace__searchSpaceType_PR_common, -1, -1); for (int i = 1; i < seq_arr_size(&oldUE->UE_sched_ctrl.lc_config); ++i) { const nr_lc_config_t *c = seq_arr_at(&oldUE->UE_sched_ctrl.lc_config, i); nr_mac_add_lcid(&UE->UE_sched_ctrl, c); } - - nr_mac_prepare_cellgroup_update(mac, UE, oldUE->CellGroup); + ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); + UE->CellGroup = oldUE->CellGroup; oldUE->CellGroup = NULL; mac_remove_nr_ue(mac, *dl_rrc->old_gNB_DU_ue_id); pthread_mutex_unlock(&mac->sched_lock); nr_rlc_remove_ue(dl_rrc->gNB_DU_ue_id); nr_rlc_update_id(*dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id); + /* 38.331 clause 5.3.7.4: apply the specified configuration defined in 9.2.1 for SRB1 */ + nr_rlc_reconfigure_entity(dl_rrc->gNB_DU_ue_id, 1, NULL); /* Set flag to trigger RLC re-establishment * for remaining RBs in next RRCReconfiguration */ UE->reestablish_rlc = true; - /* 38.331 clause 5.3.7.4: apply the specified configuration defined in 9.2.1 for SRB1 */ - nr_rlc_reconfigure_entity(dl_rrc->gNB_DU_ue_id, 1, NULL); instance_t f1inst = get_f1_gtp_instance(); if (f1inst >= 0) // we actually use F1-U gtpv1u_update_ue_id(f1inst, *dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 6002c5756f..43dcbab20d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -743,11 +743,8 @@ typedef struct { NR_mac_stats_t mac_stats; /// currently active CellGroupConfig NR_CellGroupConfig_t *CellGroup; - /// CellGroupConfig that is to be activated after the next reconfiguration - bool expect_reconfiguration; /// reestablishRLC has to be signaled in RRCreconfiguration bool reestablish_rlc; - NR_CellGroupConfig_t *reconfigCellGroup; interrupt_followup_action_t interrupt_action; NR_UE_NR_Capability_t *capability; // UE selected beam index diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index df7cabf804..4c95b435c6 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -3135,7 +3135,7 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid, css_num_agg_level_candidates[PDCCH_AGG_LEVEL8] = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0; css_num_agg_level_candidates[PDCCH_AGG_LEVEL16] = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0; int searchspaceid = 4; - NR_SearchSpace_t *ss = rrc_searchspace_config(true, searchspaceid, coreset->controlResourceSetId, css_num_agg_level_candidates); + NR_SearchSpace_t *ss = rrc_searchspace_config(true, searchspaceid, 0, css_num_agg_level_candidates); searchspaceid = 5; int rrc_num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS]; int num_cces = get_coreset_num_cces(coreset->frequencyDomainResources.buf, coreset->duration); diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 79d102f9e3..a3029cefd2 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -238,7 +238,7 @@ typedef struct gNB_RRC_UE_s { uint32_t ue_rrc_inactivity_timer; uint32_t ue_reestablishment_counter; uint32_t ue_reconfiguration_counter; - + bool ongoing_reconfiguration; bool an_release; // flag if core requested UE release /* NGUEContextSetup might come with PDU sessions, but setup needs to be diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index a110e4af53..c8cec12375 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1145,6 +1145,7 @@ int nr_rrc_reconfiguration_req(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p, const int { uint8_t xid = rrc_gNB_get_next_transaction_identifier(rrc->module_id); ue_p->xids[xid] = RRC_DEDICATED_RECONF; + ue_p->ongoing_reconfiguration = true; NR_CellGroupConfig_t *masterCellGroup = ue_p->masterCellGroup; if (dl_bwp_id > 0) { @@ -1237,6 +1238,7 @@ static void rrc_handle_RRCSetupRequest(gNB_RRC_INST *rrc, UE->establishment_cause = rrcSetupRequest->establishmentCause; UE->nr_cellid = msg->nr_cellid; UE->masterCellGroup = cellGroupConfig; + UE->ongoing_reconfiguration = false; activate_srb(UE, 1); rrc_gNB_generate_RRCSetup(0, msg->crnti, ue_context_p, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length); } @@ -1804,6 +1806,7 @@ static void handle_rrcReconfigurationComplete(gNB_RRC_INST *rrc, gNB_RRC_UE_t *U { uint8_t xid = reconfig_complete->rrc_TransactionIdentifier; UE->ue_reconfiguration_counter++; + UE->ongoing_reconfiguration = false; switch (UE->xids[xid]) { case RRC_PDUSESSION_RELEASE: { @@ -1854,6 +1857,15 @@ static void handle_rrcReconfigurationComplete(gNB_RRC_INST *rrc, gNB_RRC_UE_t *U UE->ho_context->target->ho_success(rrc, UE); nr_rrc_finalize_ho(UE); } + + f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id); + RETURN_IF_INVALID_ASSOC_ID(ue_data.du_assoc_id); + f1ap_ue_context_modif_req_t ue_context_modif_req = { + .gNB_CU_ue_id = UE->rrc_ue_id, + .gNB_DU_ue_id = ue_data.secondary_ue, + .ReconfigComplOutcome = RRCreconf_success, + }; + rrc->mac_rrc.ue_context_modification_request(ue_data.du_assoc_id, &ue_context_modif_req); } static void rrc_gNB_generate_UECapabilityEnquiry(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue) @@ -2417,7 +2429,8 @@ static void rrc_CU_process_ue_modification_required(MessageDef *msg_p, instance_ xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, UE->masterCellGroup); /* trigger reconfiguration */ - nr_rrc_reconfiguration_req(rrc, UE, 0, 0); + if (!UE->ongoing_reconfiguration) + nr_rrc_reconfiguration_req(rrc, UE, 0, 0); return; } LOG_W(RRC, diff --git a/openair2/RRC/NR/rrc_gNB_mobility.c b/openair2/RRC/NR/rrc_gNB_mobility.c index 477be84800..e6e50ffbf1 100644 --- a/openair2/RRC/NR/rrc_gNB_mobility.c +++ b/openair2/RRC/NR/rrc_gNB_mobility.c @@ -231,7 +231,6 @@ static void rrc_gNB_trigger_reconfiguration_for_handover(gNB_RRC_INST *rrc, gNB_ .plmn = rrc->configuration.plmn[0], .nr_cellid = rrc->nr_cellid, // TODO target cell ID .servCellId = 0, // TODO: correct value? - .ReconfigComplOutcome = RRCreconf_success, .transm_action_ind = &transmission_action_indicator, }; deliver_ue_ctxt_modification_data_t data = {.rrc = rrc,