From 15370e7192f2259fb7ed0389ec9d117261431526 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 6 Jun 2025 07:50:14 +0200 Subject: [PATCH] Implement RB suspend at gNB MAC Add a flag for each RB that tracks suspension state. Mark all RBs (except SRB1) as suspended on reestablishment, and de-suspend on reconfiguration. Only check RLC status for non-suspended RBs. For UL data traffic, check that DRB/SRB2 exist (SRB1 should be there as soon as the UE context exists). --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 3 ++ .../NR_MAC_gNB/gNB_scheduler_primitives.c | 10 ++++++ .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 32 ++++++++++++------- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 1 + .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 8 ++++- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 2 ++ 6 files changed, 44 insertions(+), 12 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 3303bb7362..cb3c1bf801 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -335,6 +335,9 @@ static void nr_store_dlsch_buffer(module_id_t module_id, frame_t frame, slot_t s const int lcid = c->lcid; const uint16_t rnti = UE->rnti; LOG_D(NR_MAC, "In %s: UE %x: LCID %d\n", __FUNCTION__, rnti, lcid); + memset(&sched_ctrl->rlc_status[lcid], 0, sizeof(sched_ctrl->rlc_status[lcid])); + if (c->suspended) + continue; if (lcid == DL_SCH_LCID_DTCH && nr_timer_is_active(&sched_ctrl->transm_interrupt)) continue; start_meas(&RC.nrmac[module_id]->rlc_status_ind); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 5ceff85296..79c266bce7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -3477,6 +3477,16 @@ static int cmp_lc_config(const void *va, const void *vb) return 1; } +nr_lc_config_t *nr_mac_get_lc_config(NR_UE_sched_ctrl_t* sched_ctrl, int lcid) +{ + nr_lc_config_t c = {.lcid = lcid}; + elm_arr_t elm = find_if(&sched_ctrl->lc_config, &c, eq_lcid_config); + if (elm.found) + return elm.it; + else + return NULL; +} + bool nr_mac_add_lcid(NR_UE_sched_ctrl_t* sched_ctrl, const nr_lc_config_t *c) { elm_arr_t elm = find_if(&sched_ctrl->lc_config, (void *) c, eq_lcid_config); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 3626599fe5..b4297c230f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -390,10 +390,15 @@ static int nr_process_mac_pdu(instance_t module_idP, slot, lcid); - nr_mac_rlc_data_ind(module_idP, UE->rnti, true, lcid, (char *)(pduP + mac_subheader_len), mac_len); + const nr_lc_config_t *srbc = nr_mac_get_lc_config(sched_ctrl, lcid); + if (!srbc || srbc->suspended) { + LOG_I(NR_MAC, "RNTI %04x LCID %d: ignoring %d bytes\n", UE->rnti, lcid, mac_len); + } else { + nr_mac_rlc_data_ind(module_idP, UE->rnti, true, lcid, (char *)(pduP + mac_subheader_len), mac_len); - UE->mac_stats.ul.total_sdu_bytes += mac_len; - UE->mac_stats.ul.lc_bytes[lcid] += mac_len; + UE->mac_stats.ul.total_sdu_bytes += mac_len; + UE->mac_stats.ul.lc_bytes[lcid] += mac_len; + } break; case UL_SCH_LCID_DTCH ...(UL_SCH_LCID_DTCH + 28): @@ -406,16 +411,21 @@ static int nr_process_mac_pdu(instance_t module_idP, lcid, module_idP, mac_len); - UE->mac_stats.ul.lc_bytes[lcid] += mac_len; + const nr_lc_config_t *c = nr_mac_get_lc_config(sched_ctrl, lcid); + if (!c || c->suspended) { + LOG_I(NR_MAC, "RNTI %04x LCID %d: ignoring %d bytes\n", UE->rnti, lcid, mac_len); + } else { + UE->mac_stats.ul.lc_bytes[lcid] += mac_len; - nr_mac_rlc_data_ind(module_idP, UE->rnti, true, lcid, (char *)(pduP + mac_subheader_len), mac_len); + nr_mac_rlc_data_ind(module_idP, UE->rnti, true, lcid, (char *)(pduP + mac_subheader_len), mac_len); - sdus += 1; - /* Updated estimated buffer when receiving data */ - if (sched_ctrl->estimated_ul_buffer >= mac_len) - sched_ctrl->estimated_ul_buffer -= mac_len; - else - sched_ctrl->estimated_ul_buffer = 0; + sdus += 1; + /* Updated estimated buffer when receiving data */ + if (sched_ctrl->estimated_ul_buffer >= mac_len) + sched_ctrl->estimated_ul_buffer -= mac_len; + else + sched_ctrl->estimated_ul_buffer = 0; + } break; case UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY: diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index f0b59c73de..c24baad097 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -451,6 +451,7 @@ void process_addmod_bearers_cellGroupConfig(NR_UE_sched_ctrl_t *sched_ctrl, const struct NR_CellGroupConfig__rlc_BearerToAddModList *addmod); bool nr_mac_add_lcid(NR_UE_sched_ctrl_t *sched_ctrl, const nr_lc_config_t *c); +nr_lc_config_t *nr_mac_get_lc_config(NR_UE_sched_ctrl_t* sched_ctrl, int lcid); bool nr_mac_remove_lcid(NR_UE_sched_ctrl_t *sched_ctrl, long lcid); bool nr_mac_get_new_rnti(NR_UEs_t *UEs, rnti_t *rnti); 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 99a8439dc9..90dc604471 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -777,6 +777,10 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) // 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); + 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; + } } if (ue_cap != NULL) { @@ -965,7 +969,9 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) oldUE->uid = temp_uid; 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_lc_config_t new = *c; + new.suspended = true; + nr_mac_add_lcid(&UE->UE_sched_ctrl, &new); } ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); UE->CellGroup = oldUE->CellGroup; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index d97783604f..f7f034cd97 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -564,6 +564,8 @@ typedef struct NR_QoS_config_s { typedef struct nr_lc_config { uint8_t lcid; + /// flag if corresponding RB is suspended + bool suspended; /// priority as specified in 38.321 int priority; /// associated NSSAI for DRB