From cad681e626081e24d9f7cae69e55414b9ca67e36 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 12 Jun 2025 18:43:24 +0200 Subject: [PATCH 1/5] renaming structure for LCID to RB mapping --- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 28 +++++++++++----------- openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h | 12 +++++----- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 8dfa57f92b..88c8d5d377 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -77,10 +77,10 @@ static uint64_t get_nr_rlc_current_time(void) static void release_rlc_entity_from_lcid(nr_rlc_ue_t *ue, logical_chan_id_t channel_id) { AssertFatal(channel_id != 0, "LCID = 0 shouldn't be handled here\n"); - nr_rlc_rb_t *rb = &ue->lcid2rb[channel_id - 1]; - if (rb->type == NR_RLC_NONE) + nr_lcid_rb_t *rb = &ue->lcid2rb[channel_id - 1]; + if (rb->type == NR_LCID_NONE) return; - if (rb->type == NR_RLC_SRB) { + if (rb->type == NR_LCID_SRB) { int id = rb->choice.srb_id - 1; AssertFatal(id >= 0, "logic bug: impossible to have srb0 here\n"); if (ue->srb[id]) { @@ -91,7 +91,7 @@ static void release_rlc_entity_from_lcid(nr_rlc_ue_t *ue, logical_chan_id_t chan LOG_E(RLC, "Trying to release a non-established enity with LCID %d\n", channel_id); } else { - AssertFatal(rb->type == NR_RLC_DRB, + AssertFatal(rb->type == NR_LCID_DRB, "Invalid RB type\n"); int id = rb->choice.drb_id - 1; if (ue->drb[id]) { @@ -108,14 +108,14 @@ logical_chan_id_t nr_rlc_get_lcid_from_rb(int ue_id, bool is_srb, int rb_id) nr_rlc_manager_lock(nr_rlc_ue_manager); nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); for (logical_chan_id_t id = 1; id <= 32; id++) { - nr_rlc_rb_t *rb = &ue->lcid2rb[id - 1]; + nr_lcid_rb_t *rb = &ue->lcid2rb[id - 1]; if (is_srb) { - if (rb->type == NR_RLC_SRB && rb->choice.srb_id == rb_id) { + if (rb->type == NR_LCID_SRB && rb->choice.srb_id == rb_id) { nr_rlc_manager_unlock(nr_rlc_ue_manager); return id; } } else { - if (rb->type == NR_RLC_DRB && rb->choice.drb_id == rb_id) { + if (rb->type == NR_LCID_DRB && rb->choice.drb_id == rb_id) { nr_rlc_manager_unlock(nr_rlc_ue_manager); return id; } @@ -130,14 +130,14 @@ static nr_rlc_entity_t *get_rlc_entity_from_lcid(nr_rlc_ue_t *ue, logical_chan_i { if (channel_id == 0) return ue->srb0; - nr_rlc_rb_t *rb = &ue->lcid2rb[channel_id - 1]; - if (rb->type == NR_RLC_NONE) + nr_lcid_rb_t *rb = &ue->lcid2rb[channel_id - 1]; + if (rb->type == NR_LCID_NONE) return NULL; - if (rb->type == NR_RLC_SRB) { + if (rb->type == NR_LCID_SRB) { AssertFatal(rb->choice.srb_id > 0, "logic bug: impossible to have srb0 here\n"); return ue->srb[rb->choice.srb_id - 1]; } else { - AssertFatal(rb->type == NR_RLC_DRB, + AssertFatal(rb->type == NR_LCID_DRB, "Invalid RB type\n"); return ue->drb[rb->choice.drb_id - 1]; } @@ -698,7 +698,7 @@ void nr_rlc_add_srb(int ue_id, int srb_id, const NR_RLC_BearerConfig_t *rlc_Bear NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity), "servedRadioBearer for SRB mandatory present when setting up an SRB RLC entity\n"); int local_id = rlc_BearerConfig->logicalChannelIdentity - 1; // LCID 0 for SRB 0 not mapped - ue->lcid2rb[local_id].type = NR_RLC_SRB; + ue->lcid2rb[local_id].type = NR_LCID_SRB; ue->lcid2rb[local_id].choice.srb_id = rlc_BearerConfig->servedRadioBearer->choice.srb_Identity; if (ue->srb[srb_id-1] != NULL) { LOG_E(RLC, "SRB %d already exists for UE %d, do nothing\n", srb_id, ue_id); @@ -763,7 +763,7 @@ static void add_drb_am(int ue_id, int drb_id, const NR_RLC_BearerConfig_t *rlc_B NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity), "servedRadioBearer for DRB mandatory present when setting up an SRB RLC entity\n"); int local_id = rlc_BearerConfig->logicalChannelIdentity - 1; // LCID 0 for SRB 0 not mapped - ue->lcid2rb[local_id].type = NR_RLC_DRB; + ue->lcid2rb[local_id].type = NR_LCID_DRB; ue->lcid2rb[local_id].choice.drb_id = rlc_BearerConfig->servedRadioBearer->choice.drb_Identity; if (ue->drb[drb_id-1] != NULL) { LOG_E(RLC, "DRB %d already exists for UE %d, do nothing\n", drb_id, ue_id); @@ -818,7 +818,7 @@ static void add_drb_um(int ue_id, int drb_id, const NR_RLC_BearerConfig_t *rlc_B NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity), "servedRadioBearer for DRB mandatory present when setting up an SRB RLC entity\n"); int local_id = rlc_BearerConfig->logicalChannelIdentity - 1; // LCID 0 for SRB 0 not mapped - ue->lcid2rb[local_id].type = NR_RLC_DRB; + ue->lcid2rb[local_id].type = NR_LCID_DRB; ue->lcid2rb[local_id].choice.drb_id = rlc_BearerConfig->servedRadioBearer->choice.drb_Identity; if (ue->drb[drb_id-1] != NULL) { LOG_E(RLC, "DEBUG add_drb_um: warning DRB %d already exist for ue %d, do nothing\n", drb_id, ue_id); diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h index 3dec237958..9a4288f192 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h @@ -28,21 +28,21 @@ typedef void nr_rlc_ue_manager_t; -typedef enum nr_rlc_rb_type { NR_RLC_NONE = 0, NR_RLC_SRB = 1, NR_RLC_DRB = 2 } nr_rlc_rb_type; - typedef enum { NR_RLC_OP_MODE_SPLIT_GNB, NR_RLC_OP_MODE_MONO_GNB, NR_RLC_OP_MODE_UE, } nr_rlc_op_mode_t; -typedef struct nr_rlc_rb_t { - nr_rlc_rb_type type; +typedef enum nr_lcid_rb_type { NR_LCID_NONE = 0, NR_LCID_SRB = 1, NR_LCID_DRB = 2 } nr_lcid_rb_type; + +typedef struct nr_lcid_rb_t { + nr_lcid_rb_type type; union { int srb_id; int drb_id; } choice; -} nr_rlc_rb_t; +} nr_lcid_rb_t; typedef void (*rlf_handler_t)(int rnti); @@ -51,7 +51,7 @@ typedef struct nr_rlc_ue_t { nr_rlc_entity_t *srb0; nr_rlc_entity_t *srb[3]; nr_rlc_entity_t *drb[MAX_DRBS_PER_UE]; - nr_rlc_rb_t lcid2rb[32]; + nr_lcid_rb_t lcid2rb[32]; rlf_handler_t rlf_handler; } nr_rlc_ue_t; From f2e06a8b12f93eeb69a1f1fef2a41d4d0ec9e7dd Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 12 Jun 2025 19:30:09 +0200 Subject: [PATCH 2/5] store RB information in LCID structure at UE --- common/platform_types.h | 10 +++++ openair2/LAYER2/NR_MAC_UE/config_ue.c | 46 +++++++++++++++------- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 1 + openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h | 10 ----- 4 files changed, 43 insertions(+), 24 deletions(-) diff --git a/common/platform_types.h b/common/platform_types.h index 8cbd502fda..e345288061 100644 --- a/common/platform_types.h +++ b/common/platform_types.h @@ -207,6 +207,16 @@ typedef struct nsa_msg_t { uint8_t msg_buffer[MAX_MESSAGE_SIZE]; } nsa_msg_t; +typedef enum nr_lcid_rb_type { NR_LCID_NONE = 0, NR_LCID_SRB = 1, NR_LCID_DRB = 2 } nr_lcid_rb_type; + +typedef struct nr_lcid_rb_t { + nr_lcid_rb_type type; + union { + int srb_id; + int drb_id; + } choice; +} nr_lcid_rb_t; + typedef struct transport_layer_addr_s { /** * Transport Layer Address as a bitstring: diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 3a5d5e5640..626b772e8b 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -811,7 +811,7 @@ static uint32_t get_lc_bucket_size(long prioritisedBitRate, long bucketSizeDurat } // default configuration as per 38.331 section 9.2.1 -static void set_default_logicalchannelconfig(nr_lcordered_info_t *lc_info, NR_SRB_Identity_t srb_id) +static void set_default_logicalchannelconfig(nr_lcordered_info_t *lc_info, int srb_id) { lc_info->lcid = srb_id; lc_info->priority = srb_id == 2 ? 3 : 1; @@ -822,12 +822,13 @@ static void set_default_logicalchannelconfig(nr_lcordered_info_t *lc_info, NR_SR static void nr_configure_lc_config(NR_UE_MAC_INST_t *mac, nr_lcordered_info_t *lc_info, NR_LogicalChannelConfig_t *mac_lc_config, - NR_SRB_Identity_t srb_id) + nr_lcid_rb_t rb) { NR_LC_SCHEDULING_INFO *lc_sched_info = get_scheduling_info_from_lcid(mac, lc_info->lcid); - if (srb_id > 0 && !mac_lc_config->ul_SpecificParameters) { + lc_info->rb = rb; + if (rb.type == NR_LCID_SRB && !mac_lc_config->ul_SpecificParameters) { // release configuration and reset to default - set_default_logicalchannelconfig(lc_info, srb_id); + set_default_logicalchannelconfig(lc_info, rb.choice.srb_id); // invalid LCGID to signal it is absent in the configuration lc_sched_info->LCGID = NR_INVALID_LCGID; return; @@ -848,6 +849,25 @@ static void nr_configure_lc_config(NR_UE_MAC_INST_t *mac, nr_timer_start(bjt); } +static nr_lcid_rb_t configure_lcid_rb(NR_RLC_BearerConfig_t *rlc_bearer) +{ + nr_lcid_rb_t rb; + if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) { + rb.type = NR_LCID_SRB; + rb.choice.srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity; + return rb; + } + + if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity) { + rb.type = NR_LCID_DRB; + rb.choice.drb_id = rlc_bearer->servedRadioBearer->choice.drb_Identity; + return rb; + } + LOG_E(NR_MAC, "Error. RLC should be linked to either DRB or SRB.\n"); + rb.type = NR_LCID_NONE; + return rb; +} + static void configure_logicalChannelBearer(NR_UE_MAC_INST_t *mac, struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_toadd_list, struct NR_CellGroupConfig__rlc_BearerToReleaseList *rlc_torelease_list) @@ -870,6 +890,9 @@ static void configure_logicalChannelBearer(NR_UE_MAC_INST_t *mac, if (rlc_toadd_list) { for (int i = 0; i < rlc_toadd_list->list.count; i++) { NR_RLC_BearerConfig_t *rlc_bearer = rlc_toadd_list->list.array[i]; + nr_lcid_rb_t rb = configure_lcid_rb(rlc_bearer); + if (rb.type == NR_LCID_NONE) + continue; int lc_identity = rlc_bearer->logicalChannelIdentity; NR_LogicalChannelConfig_t *mac_lc_config = rlc_bearer->mac_LogicalChannelConfig; int j; @@ -879,14 +902,9 @@ static void configure_logicalChannelBearer(NR_UE_MAC_INST_t *mac, } if (j < mac->lc_ordered_list.count) { LOG_D(NR_MAC, "Logical channel %d is already established, Reconfiguring now\n", lc_identity); - if (mac_lc_config != NULL) { - NR_SRB_Identity_t srb_id = 0; - if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) - srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity; - nr_configure_lc_config(mac, mac->lc_ordered_list.array[j], mac_lc_config, srb_id); - } - } - else { + if (mac_lc_config != NULL) + nr_configure_lc_config(mac, mac->lc_ordered_list.array[j], mac_lc_config, rb); + } else { /* setup of new LCID*/ nr_lcordered_info_t *lc_info = calloc(1, sizeof(*lc_info)); lc_info->lcid = lc_identity; @@ -895,12 +913,12 @@ static void configure_logicalChannelBearer(NR_UE_MAC_INST_t *mac, if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) { /* SRB */ NR_SRB_Identity_t srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity; if (mac_lc_config != NULL) - nr_configure_lc_config(mac, lc_info, mac_lc_config, srb_id); + nr_configure_lc_config(mac, lc_info, mac_lc_config, rb); else set_default_logicalchannelconfig(lc_info, srb_id); } else { /* DRB */ AssertFatal(mac_lc_config, "When establishing a DRB, LogicalChannelConfig should be mandatorily present\n"); - nr_configure_lc_config(mac, lc_info, mac_lc_config, 0); + nr_configure_lc_config(mac, lc_info, mac_lc_config, rb); } ASN_SEQUENCE_ADD(&mac->lc_ordered_list, lc_info); } diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index b3ca280f86..24b82ecf51 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -450,6 +450,7 @@ typedef struct nr_lcordered_info_s { uint32_t bucket_size; bool sr_DelayTimerApplied; bool lc_SRMask; + nr_lcid_rb_t rb; } nr_lcordered_info_t; typedef struct { diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h index 9a4288f192..67484e7108 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h @@ -34,16 +34,6 @@ typedef enum { NR_RLC_OP_MODE_UE, } nr_rlc_op_mode_t; -typedef enum nr_lcid_rb_type { NR_LCID_NONE = 0, NR_LCID_SRB = 1, NR_LCID_DRB = 2 } nr_lcid_rb_type; - -typedef struct nr_lcid_rb_t { - nr_lcid_rb_type type; - union { - int srb_id; - int drb_id; - } choice; -} nr_lcid_rb_t; - typedef void (*rlf_handler_t)(int rnti); typedef struct nr_rlc_ue_t { From 3331a43b95c02800c83b47d2e2d4fcb89ac0a5b6 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 13 Jun 2025 10:49:22 +0200 Subject: [PATCH 3/5] add option to suspend/resume RBs at MAC upon signaling from RRC --- openair2/COMMON/rrc_messages_def.h | 1 + openair2/COMMON/rrc_messages_types.h | 6 ++++++ openair2/LAYER2/NR_MAC_UE/config_ue.c | 20 ++++++++++++++++++++ openair2/LAYER2/NR_MAC_UE/mac_defs.h | 1 + openair2/LAYER2/NR_MAC_UE/mac_proto.h | 2 +- openair2/RRC/NR_UE/L2_interface_ue.c | 3 +++ openair2/RRC/NR_UE/rrc_UE.c | 18 ++++++++++++++++-- 7 files changed, 48 insertions(+), 3 deletions(-) diff --git a/openair2/COMMON/rrc_messages_def.h b/openair2/COMMON/rrc_messages_def.h index 67aadb2869..df295e2011 100644 --- a/openair2/COMMON/rrc_messages_def.h +++ b/openair2/COMMON/rrc_messages_def.h @@ -88,6 +88,7 @@ MESSAGE_DEF(NRRRC_FRAME_PROCESS, MESSAGE_PRIORITY_MED, NRRrcFramePr // UE: RRC -> MAC messages MESSAGE_DEF(NR_MAC_RRC_CONFIG_RESET, MESSAGE_PRIORITY_MED, nr_mac_rrc_config_reset_t, nr_mac_rrc_config_reset) MESSAGE_DEF(NR_MAC_RRC_CONFIG_CG, MESSAGE_PRIORITY_MED, nr_mac_rrc_config_cg_t, nr_mac_rrc_config_cg) +MESSAGE_DEF(NR_MAC_RRC_RESUME_RB, MESSAGE_PRIORITY_MED, nr_mac_rrc_resume_rb_t, nr_mac_rrc_resume_rb) MESSAGE_DEF(NR_MAC_RRC_CONFIG_MIB, MESSAGE_PRIORITY_MED, nr_mac_rrc_config_mib_t, nr_mac_rrc_config_mib) MESSAGE_DEF(NR_MAC_RRC_CONFIG_SIB1, MESSAGE_PRIORITY_MED, nr_mac_rrc_config_sib1_t, nr_mac_rrc_config_sib1) MESSAGE_DEF(NR_MAC_RRC_CONFIG_OTHER_SIB, MESSAGE_PRIORITY_MED, nr_mac_rrc_config_other_sib_t, nr_mac_rrc_config_other_sib) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index a3db7ebba6..094fd0fa40 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -107,6 +107,7 @@ #define NAS_PDU_SESSION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_pdu_session_req #define NR_MAC_RRC_CONFIG_RESET(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_config_reset #define NR_MAC_RRC_CONFIG_CG(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_config_cg +#define NR_MAC_RRC_RESUME_RB(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_resume_rb #define NR_MAC_RRC_CONFIG_MIB(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_config_mib #define NR_MAC_RRC_CONFIG_SIB1(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_config_sib1 #define NR_MAC_RRC_CONFIG_OTHER_SIB(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_config_other_sib @@ -470,6 +471,11 @@ typedef struct { int ue_id; } RlcMaxRtxIndication; +typedef struct { + bool is_srb; + int rb_id; +} nr_mac_rrc_resume_rb_t; + typedef struct { NR_ReestablishmentCause_t cause; } nr_mac_rrc_config_reset_t; diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 626b772e8b..7583ee3eb7 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -826,6 +826,7 @@ static void nr_configure_lc_config(NR_UE_MAC_INST_t *mac, { NR_LC_SCHEDULING_INFO *lc_sched_info = get_scheduling_info_from_lcid(mac, lc_info->lcid); lc_info->rb = rb; + lc_info->rb_suspended = false; if (rb.type == NR_LCID_SRB && !mac_lc_config->ul_SpecificParameters) { // release configuration and reset to default set_default_logicalchannelconfig(lc_info, rb.choice.srb_id); @@ -1729,6 +1730,13 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t nr_ue_mac_default_configs(mac); nr_ue_reset_sync_state(mac); release_mac_configuration(mac, cause); + // suspend all RBs except SRB0 + for (int j = 0; j < mac->lc_ordered_list.count; j++) { + nr_lcordered_info_t *lc = mac->lc_ordered_list.array[j]; + if (lc->rb.type == NR_LCID_SRB && lc->rb.choice.srb_id == 0) + continue; + lc->rb_suspended = true; + } // apply the timeAlignmentTimerCommon included in SIB1 configure_timeAlignmentTimer(&mac->time_alignment_timer, mac->timeAlignmentTimerCommon, mac->current_UL_BWP->scs); // new sync with old cell ID (re-establishment on the same cell) @@ -1743,6 +1751,18 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t AssertFatal(!ret, "mutex failed %d\n", ret); } +void nr_rrc_mac_resume_rb(module_id_t module_id, bool is_srb, int rb_id) +{ + NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); + for (int j = 0; j < mac->lc_ordered_list.count; j++) { + nr_lcordered_info_t *lc = mac->lc_ordered_list.array[j]; + if (is_srb && lc->rb.type == NR_LCID_SRB && lc->rb.choice.srb_id == rb_id) + lc->rb_suspended = false; + if (!is_srb && lc->rb.type == NR_LCID_DRB && lc->rb.choice.drb_id == rb_id) + lc->rb_suspended = false; + } +} + static void configure_si_schedulingInfo(NR_UE_MAC_INST_t *mac, NR_SI_SchedulingInfo_t *si_SchedulingInfo, NR_SI_SchedulingInfo_v1700_t *si_SchedulingInfo_v1700) diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 24b82ecf51..bd6cab17be 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -451,6 +451,7 @@ typedef struct nr_lcordered_info_s { bool sr_DelayTimerApplied; bool lc_SRMask; nr_lcid_rb_t rb; + bool rb_suspended; } nr_lcordered_info_t; typedef struct { diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index b058f6e681..cdc07c2ca2 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -93,7 +93,7 @@ void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SIB1_t *si struct position; /* forward declaration */ void nr_rrc_mac_config_other_sib(module_id_t module_id, NR_SIB19_r17_t *sib19_r17, bool can_start_ra); - +void nr_rrc_mac_resume_rb(module_id_t module_id, bool is_srb, int rb_id); void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t cause); /**\brief initialization NR UE MAC instance(s)*/ diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index 09bce459f2..fe2eb2cfed 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -146,6 +146,9 @@ void process_msg_rcc_to_mac(MessageDef *msg) bool can_start_ra = NR_MAC_RRC_CONFIG_OTHER_SIB(msg).can_start_ra; nr_rrc_mac_config_other_sib(ue_id, NR_MAC_RRC_CONFIG_OTHER_SIB(msg).sib19, can_start_ra); } break; + case NR_MAC_RRC_RESUME_RB: + nr_rrc_mac_resume_rb(ue_id, NR_MAC_RRC_RESUME_RB(msg).is_srb, NR_MAC_RRC_RESUME_RB(msg).rb_id); + break; default: LOG_E(NR_MAC, "Unexpected msg from RRC: %d\n", ITTI_MSG_ID(msg)); } diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index bb58191e24..4fa5d58cf9 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -894,6 +894,10 @@ static void nr_rrc_handle_msg3_indication(NR_UE_RRC_INST_t *rrc, rnti_t rnti) nr_rlc_reconfigure_entity(rrc->ue_id, lc_id, NULL); // resume SRB1 rrc->Srb[srb_id] = RB_ESTABLISHED; + MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_RESUME_RB); + NR_MAC_RRC_RESUME_RB(msg).is_srb = true; + NR_MAC_RRC_RESUME_RB(msg).rb_id = 1; + itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg); break; case DURING_HANDOVER: AssertFatal(1==0, "ra_trigger not implemented yet!\n"); @@ -1868,11 +1872,21 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc, if (rrc->reconfig_after_reestab) { // if this is the first RRCReconfiguration message after successful completion of the RRC re-establishment procedure // resume SRB2 and DRBs that are suspended - if (rrc->Srb[2] == RB_SUSPENDED) + if (rrc->Srb[2] == RB_SUSPENDED) { rrc->Srb[2] = RB_ESTABLISHED; + MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_RESUME_RB); + NR_MAC_RRC_RESUME_RB(msg).is_srb = true; + NR_MAC_RRC_RESUME_RB(msg).rb_id = 2; + itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg); + } for (int i = 1; i <= MAX_DRBS_PER_UE; i++) { - if (get_DRB_status(rrc, i) == RB_SUSPENDED) + if (get_DRB_status(rrc, i) == RB_SUSPENDED) { set_DRB_status(rrc, i, RB_ESTABLISHED); + MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_RESUME_RB); + NR_MAC_RRC_RESUME_RB(msg).is_srb = false; + NR_MAC_RRC_RESUME_RB(msg).rb_id = i; + itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg); + } } rrc->reconfig_after_reestab = false; } From 2b4b3fcd00237e4dd073462016b11c99fcb4ac85 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 13 Jun 2025 11:40:28 +0200 Subject: [PATCH 4/5] discard rx PDU if RB is suspended --- openair2/LAYER2/NR_MAC_UE/config_ue.c | 11 +++++++++++ openair2/LAYER2/NR_MAC_UE/mac_proto.h | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 11 ++++++++--- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 7583ee3eb7..e74b1a1dc3 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -1751,6 +1751,17 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t AssertFatal(!ret, "mutex failed %d\n", ret); } +bool is_lcid_suspended(NR_UE_MAC_INST_t *mac, int lcid) +{ + for (int j = 0; j < mac->lc_ordered_list.count; j++) { + nr_lcordered_info_t *lc = mac->lc_ordered_list.array[j]; + if (lc->lcid == lcid) + return lc->rb_suspended; + } + LOG_E(NR_MAC, "LCID %d not found in the MAC list\n", lcid); + return false; +} + void nr_rrc_mac_resume_rb(module_id_t module_id, bool is_srb, int rb_id) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index cdc07c2ca2..76e178ea6a 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -293,7 +293,7 @@ void configure_csi_resource_mapping(fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_c uint32_t bwp_size, uint32_t bwp_start); - +bool is_lcid_suspended(NR_UE_MAC_INST_t *mac, int lcid); void nr_ra_contention_resolution_failed(NR_UE_MAC_INST_t *mac); void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame_t frame, const int slot); void nr_ra_backoff_setting(RA_config_t *ra); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 5d3102c07d..f88f574fe0 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -3734,7 +3734,7 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", rx_lcid, pdu_len); bool ret; - switch(rx_lcid){ + switch (rx_lcid) { // MAC CE case DL_SCH_LCID_CCCH: // MSG4 RRC Setup 38.331 @@ -3871,6 +3871,11 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i case 1 ... 32: if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len)) return; + // discard the received subPDU if RB is suspended + if (is_lcid_suspended(mac, rx_lcid)) { + LOG_W(NR_MAC, "Received PDU for a suspended RB, corresponding to LCID %d. Dropping it.\n", rx_lcid); + break; + } LOG_D(NR_MAC, "%4d.%2d : DLSCH -> LCID %d %d bytes\n", frameP, slot, rx_lcid, mac_len); nr_mac_rlc_data_ind(mac->ue_id, mac->ue_id, false, rx_lcid, (char *)(pduP + mac_subheader_len), mac_len); break; @@ -3878,8 +3883,8 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i LOG_W(MAC, "unknown lcid %02x\n", rx_lcid); break; } - pduP += ( mac_subheader_len + mac_len ); - pdu_len -= ( mac_subheader_len + mac_len ); + pduP += (mac_subheader_len + mac_len); + pdu_len -= (mac_subheader_len + mac_len); if (pdu_len < 0) LOG_E(MAC, "[UE %d][%d.%d] nr_ue_process_mac_pdu, residual mac pdu length %d < 0!\n", mac->ue_id, frameP, slot, pdu_len); } From 499cdc62d9893f18d6a3dcefad4e0c2604382c9b Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 16 Jun 2025 16:42:05 +0200 Subject: [PATCH 5/5] do not transmit data for a logical channel corresponding to a radio bearer that is suspended --- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index b810bf8de6..87ea607c84 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1266,10 +1266,11 @@ static void nr_update_rlc_buffers_status(NR_UE_MAC_INST_t *mac, frame_t frameP, { for (int i = 0; i < mac->lc_ordered_list.count; i++) { nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i]; + if (lc_info->rb_suspended) + continue; int lcid = lc_info->lcid; NR_LC_SCHEDULING_INFO *lc_sched_info = get_scheduling_info_from_lcid(mac, lcid); mac_rlc_status_resp_t rlc_status = nr_mac_rlc_status_ind(mac->ue_id, frameP, lcid); - if (rlc_status.bytes_in_buffer > 0) { LOG_D(NR_MAC, "[UE %d] LCID %d has %d bytes to transmit at sfn %d.%d\n", @@ -2553,6 +2554,8 @@ static bool fill_mac_sdu(NR_UE_MAC_INST_t *mac, lcid_remain_buffer, lcid); + if (is_lcid_suspended(mac, lcid)) + return false; if (mac_ce_p->end_for_tailer - mac_ce_p->cur_ptr < sizeof(NR_MAC_SUBHEADER_LONG)) // We can't add one byte after the header return false;