From 25cd85fa68081b803896776eec4e58db336ab1a7 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 4 Dec 2025 16:44:19 +0100 Subject: [PATCH] gNB: apply new NR_CellGroupConfig when reconfiguration is complete --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 14 ++++----- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 18 +++++++++-- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 2 +- .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 30 ++++++++++--------- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 7 ++--- 5 files changed, 43 insertions(+), 28 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index d5c1048ad6..9832f0332b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -595,17 +595,17 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac, static void ack_reconfig(gNB_MAC_INST *mac, NR_UE_info_t *UE) { - if (UE->reconfigSpCellConfig) { - // in case of reestablishment, the spCellConfig had to be released - // temporarily. Reapply now before doing the reconfiguration. - UE->CellGroup->spCellConfig = UE->reconfigSpCellConfig; - // UE->reconfigSpCellConfig to be NULLed after receiving reconfiguration complete + if (!UE->reconfigCellGroup) { + LOG_W(NR_MAC, "Received ACK for RRCReconfiguration, but nothing to apply!\n"); + return; } + ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); + UE->CellGroup = UE->reconfigCellGroup; + UE->reconfigCellGroup = NULL; NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon; /* clean BWP structures */ clean_bwp_structures(UE->CellGroup->spCellConfig); configure_UE_BWP(mac, scc, UE, false, NR_SearchSpace__searchSpaceType_PR_common, -1, -1); - UE->await_reconfig = false; } typedef struct UEsched_s { @@ -885,7 +885,7 @@ static void pf_dl(gNB_MAC_INST *mac, sched_pdsch.action = NULL; int srb1 = 1; /* everything that's only 3 bytes is an ack. To be safe, use a bit more. */ - if (iterator->UE->await_reconfig && sched_ctrl->rlc_status[srb1].bytes_in_buffer > 10) + if (iterator->UE->reconfigCellGroup && sched_ctrl->rlc_status[srb1].bytes_in_buffer > 10) sched_pdsch.action = ack_reconfig; // Fix me: currently, the RLC does not give us the total number of PDUs diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 14dedb1de9..5e611e4150 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2488,7 +2488,7 @@ 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_SpCellConfig, UE->reconfigSpCellConfig); + 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); @@ -2852,6 +2852,20 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, sc_info->nrofHARQ_ProcessesForPUSCH_r17 = pusch_servingcellconfig->ext3->nrofHARQ_ProcessesForPUSCH_r17; } } + } else { + sc_info->csi_MeasConfig = NULL; + sc_info->nrofHARQ_ProcessesForPDSCH = NULL; + sc_info->maxMIMO_Layers_PDSCH = NULL; + sc_info->downlinkHARQ_FeedbackDisabled_r17 = NULL; + sc_info->pdsch_CGB_Transmission = NULL; + sc_info->nrofHARQ_ProcessesForPDSCH_v1700 = NULL; + sc_info->crossCarrierSchedulingConfig = NULL; + sc_info->supplementaryUplink = NULL; + sc_info->carrierSwitching = NULL; + sc_info->maxMIMO_Layers_PUSCH = NULL; + sc_info->rateMatching_PUSCH = NULL; + sc_info->pusch_CGB_Transmission = NULL; + sc_info->nrofHARQ_ProcessesForPUSCH_r17 = NULL; } if (CellGroup && CellGroup->physicalCellGroupConfig) @@ -3919,7 +3933,7 @@ void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, NR_UE_info_t *UE, buf, sizeof(buf)); AssertFatal(enc_rval.encoded > 0, "ASN1 encoding of CellGroupConfig failed, failed type %s\n", enc_rval.failed_type->name); - UE->await_reconfig = true; + UE->reestablish_rlc = true; du_to_cu_rrc_information_t du2cu = { .cellGroupConfig = buf, .cellGroupConfig_length = (enc_rval.encoded + 7) >> 3, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index abe5cd8361..0e97ea7a6c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -882,7 +882,7 @@ static void nr_rx_ra_sdu(const module_id_t mod_id, // Only trigger RRCReconfiguration if UE is not performing RRCReestablishment // The RRCReconfiguration will be triggered by the RRCReestablishmentComplete - if (!old_UE->reconfigSpCellConfig) { + 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); 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 6d105078b7..4fbc637355 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -695,8 +695,8 @@ void ue_context_setup_request(const f1ap_ue_context_setup_req_t *req) cgc.len = (enc_rval.encoded + 7) >> 3; resp.du_to_cu_rrc_info.cell_group_config = cgc; - ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); - UE->CellGroup = new_CellGroup; + ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->reconfigCellGroup); + UE->reconfigCellGroup = new_CellGroup; int ss_type = cg_configinfo ? NR_SearchSpace__searchSpaceType_PR_ue_Specific: NR_SearchSpace__searchSpaceType_PR_common; configure_UE_BWP(mac, scc, UE, false, ss_type, -1, -1); @@ -770,19 +770,19 @@ void ue_context_modification_request(const f1ap_ue_context_mod_req_t *req) "RRC reconfiguration outcome unsuccessful, but no rollback mechanism implemented to come back to old configuration\n"); } else if (req->reconfig_compl) { LOG_I(NR_MAC, "DU received confirmation of successful RRC Reconfiguration\n"); - if (UE->reconfigSpCellConfig) { - if (UE->await_reconfig) { - // in case of reestablishment, the spCellConfig had to be released - // temporarily. Reapply now before doing the reconfiguration. - UE->CellGroup->spCellConfig = UE->reconfigSpCellConfig; - UE->await_reconfig = false; - } - UE->reconfigSpCellConfig = NULL; + if (UE->reconfigCellGroup) { + LOG_W(NR_MAC, "reconfigCellGroup still present, did we miss ACK for RRCReconfiguration?\n"); + ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); + UE->CellGroup = UE->reconfigCellGroup; + UE->reconfigCellGroup = NULL; + } + if (UE->reestablish_rlc) { for (int i = 1; i < seq_arr_size(&UE->UE_sched_ctrl.lc_config); ++i) { nr_lc_config_t *c = seq_arr_at(&UE->UE_sched_ctrl.lc_config, i); c->suspended = false; nr_rlc_reestablish_entity(req->gNB_DU_ue_id, c->lcid); } + UE->reestablish_rlc = false; } // we re-configure the BWP to apply the CellGroup and to use UE specific Search Space with DCIX1 configure_UE_BWP(mac, scc, UE, false, NR_SearchSpace__searchSpaceType_PR_ue_Specific, -1, -1); @@ -809,8 +809,8 @@ void ue_context_modification_request(const f1ap_ue_context_mod_req_t *req) cgc.len = (enc_rval.encoded + 7) >> 3; resp.du_to_cu_rrc_info->cell_group_config = cgc; - ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); - UE->CellGroup = new_CellGroup; + ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->reconfigCellGroup); + UE->reconfigCellGroup = 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 @@ -966,6 +966,7 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); UE->CellGroup = oldUE->CellGroup; oldUE->CellGroup = NULL; + ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->capability); UE->capability = oldUE->capability; oldUE->capability = NULL; UE->mac_stats = oldUE->mac_stats; @@ -973,9 +974,10 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) /* 38.331 5.3.7.2 says that the UE releases the spCellConfig, so we drop it * from the current configuration. It will be reapplied when the * reconfiguration has succeeded (indicated by the CU) */ - UE->reconfigSpCellConfig = UE->CellGroup->spCellConfig; + asn_copy(&asn_DEF_NR_CellGroupConfig, (void **)&UE->reconfigCellGroup, UE->CellGroup); + ASN_STRUCT_FREE(asn_DEF_NR_SpCellConfig, UE->CellGroup->spCellConfig); UE->CellGroup->spCellConfig = NULL; - UE->await_reconfig = true; + UE->reestablish_rlc = true; 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); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 9035901456..133606e6e9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -788,9 +788,8 @@ typedef struct NR_UE_info { NR_mac_stats_t mac_stats; /// currently active CellGroupConfig NR_CellGroupConfig_t *CellGroup; - /// in case of reestablishment, old spCellConfig to apply after - /// reconfiguration - NR_SpCellConfig_t *reconfigSpCellConfig; + /// in case of reconfiguration, new CellConfig to apply + NR_CellGroupConfig_t *reconfigCellGroup; NR_UE_NR_Capability_t *capability; measgap_config_t measgap_config; // UE selected beam index @@ -799,7 +798,7 @@ typedef struct NR_UE_info { float dl_thr_ue; long pdsch_HARQ_ACK_Codebook; bool is_redcap; - bool await_reconfig; + bool reestablish_rlc; NR_RA_t *ra; // 3GPP mandates that BWPs are enumerated consecutively, but we only send one (dedicated) // BWP to the UE (and modify that BWP on reconfiguration); consequently, the BWP ID for a