From b547dfe056720a39ea467e2bad1ef75a0166d3a8 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 10 Oct 2025 11:36:17 +0200 Subject: [PATCH] apply new configuration after receiving ACK for RRCreconfiguration message --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 19 +++++++++++++++++++ .../NR_MAC_gNB/gNB_scheduler_primitives.c | 1 + .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 13 ++++++------- .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 10 +++++++--- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 7 ++++++- 5 files changed, 39 insertions(+), 11 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 86eed9d575..34a8519bdb 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -592,6 +592,19 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac, return true; } +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 + } + NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon; + configure_UE_BWP(mac, scc, UE, false, NR_SearchSpace__searchSpaceType_PR_common, -1, -1); + UE->await_reconfig = false; +} + typedef struct UEsched_s { float coef; NR_UE_info_t * UE; @@ -866,6 +879,12 @@ static void pf_dl(gNB_MAC_INST *mac, .tda_info = tda_info, }; + 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) + sched_pdsch.action = ack_reconfig; + // Fix me: currently, the RLC does not give us the total number of PDUs // awaiting. Therefore, for the time being, we put a fixed overhead of 12 // (for 4 PDUs) and optionally + 2 for TA. Once RLC gives the number of diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 48768750e0..00bcdded3b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -3948,6 +3948,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; 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_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 27ecbdcbd0..7d73234350 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -393,16 +393,15 @@ int get_pucch_resourceid(NR_PUCCH_Config_t *pucch_Config, int O_uci, int pucch_r return *resource_id; } -static void handle_dl_harq(NR_UE_info_t * UE, - int8_t harq_pid, - bool success, - int harq_round_max) +static void handle_dl_harq(gNB_MAC_INST *mac, NR_UE_info_t * UE, int8_t harq_pid, bool success, int harq_round_max) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_harq_t *harq = &sched_ctrl->harq_processes[harq_pid]; harq->feedback_slot = -1; harq->is_waiting = false; if (success) { + if (harq->sched_pdsch.action) + harq->sched_pdsch.action(mac, UE); finish_nr_dl_harq(sched_ctrl, harq_pid); } else if (harq->round >= harq_round_max - 1) { abort_nr_dl_harq(UE, harq_pid); @@ -873,7 +872,7 @@ static NR_UE_harq_t *find_harq(frame_t frame, slot_t slot, NR_UE_info_t * UE, in frame, slot); remove_front_nr_list(&sched_ctrl->feedback_dl_harq); - handle_dl_harq(UE, pid, 0, harq_round_max); + handle_dl_harq(NULL, UE, pid, false, harq_round_max); pid = sched_ctrl->feedback_dl_harq.head; if (pid < 0) return NULL; @@ -930,7 +929,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, frame_t frame, slot_t slot, con LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit,pid,harq_value); nr_mac_update_pdcch_closed_loop_adjust(sched_ctrl, harq_confidence != 0); bool success = harq_value == 0 && harq_confidence == 0; - handle_dl_harq(UE, pid, success, nrmac->dl_bler.harq_round_max); + handle_dl_harq(nrmac, UE, pid, success, nrmac->dl_bler.harq_round_max); if (is_ra) { bool ue_rejected = nr_check_Msg4_MsgB_Ack(mod_id, frame, slot, UE, success); if (ue_rejected) { @@ -1009,7 +1008,7 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, frame_t frame, slot_t slot, c const int8_t pid = sched_ctrl->feedback_dl_harq.head; remove_front_nr_list(&sched_ctrl->feedback_dl_harq); LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit, pid, acknack); - handle_dl_harq(UE, pid, uci_234->harq.harq_crc != 1 && acknack, nrmac->dl_bler.harq_round_max); + handle_dl_harq(nrmac, UE, pid, uci_234->harq.harq_crc != 1 && acknack, nrmac->dl_bler.harq_round_max); } free(uci_234->harq.harq_payload); } 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 8f98aabbee..ddec1b648e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -770,9 +770,12 @@ void ue_context_modification_request(const f1ap_ue_context_mod_req_t *req) } else if (req->reconfig_compl) { LOG_I(NR_MAC, "DU received confirmation of successful RRC Reconfiguration\n"); 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; + 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; 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); @@ -971,6 +974,7 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) * reconfiguration has succeeded (indicated by the CU) */ UE->reconfigSpCellConfig = UE->CellGroup->spCellConfig; UE->CellGroup->spCellConfig = NULL; + UE->await_reconfig = 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 aa8b2b8644..745c7165ba 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -475,6 +475,9 @@ typedef struct NR_pdsch_dmrs { NR_PTRS_DownlinkConfig_t *phaseTrackingRS; } NR_pdsch_dmrs_t; +struct NR_UE_info; +struct gNB_MAC_INST_s; +typedef void (*feedback_action_t)(struct gNB_MAC_INST_s *mac, struct NR_UE_info *ue); typedef struct NR_sched_pdsch { /// RB allocation within active BWP uint16_t rbSize; @@ -501,6 +504,7 @@ typedef struct NR_sched_pdsch { // time_domain_allocation is the index of a list of tda int time_domain_allocation; NR_tda_info_t tda_info; + feedback_action_t action; } NR_sched_pdsch_t; typedef struct NR_UE_harq { @@ -772,7 +776,7 @@ typedef struct measgap_config { } measgap_config_t; /*! \brief UE list used by gNB to order UEs/CC for scheduling*/ -typedef struct { +typedef struct NR_UE_info { rnti_t rnti; uid_t uid; // unique ID of this UE /// scheduling control info @@ -795,6 +799,7 @@ typedef struct { float dl_thr_ue; long pdsch_HARQ_ACK_Codebook; bool is_redcap; + bool await_reconfig; NR_RA_t *ra; } NR_UE_info_t;