From 6a1203bb159c5b30cf40e2c364306ab84af11916 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 30 Jun 2025 09:49:05 +0200 Subject: [PATCH 1/8] Set RRC reject waitTime to 10 --- openair2/RRC/NR/MESSAGES/asn1_msg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index ad973bdc5f..0f7ec6db1a 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -248,7 +248,7 @@ int do_RRCReject(uint8_t *const buffer) rrcReject->criticalExtensions.choice.rrcReject = CALLOC(1, sizeof(struct NR_RRCReject_IEs)); rrcReject->criticalExtensions.choice.rrcReject->waitTime = CALLOC(1, sizeof(NR_RejectWaitTime_t)); - *rrcReject->criticalExtensions.choice.rrcReject->waitTime = 1; + *rrcReject->criticalExtensions.choice.rrcReject->waitTime = 10; rrcReject->criticalExtensions.present = NR_RRCReject__criticalExtensions_PR_rrcReject; From 511f2f2487e69d0032e8fef74f161113be03f463 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 2 Jan 2025 17:22:35 +0100 Subject: [PATCH 2/8] generate RRCReject if no DU to CU container in initial UL RRC message slightly refactor rrc_gNB_generate_RRCReject() to take rrc pointer. Remove unused/illegal fields from the DL RRC message. --- openair2/RRC/NR/rrc_gNB.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 2ef11ce605..844cc1a104 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -393,10 +393,9 @@ static void rrc_gNB_generate_RRCSetup(instance_t instance, rrc->mac_rrc.dl_rrc_message_transfer(ue_data.du_assoc_id, &dl_rrc); } -static void rrc_gNB_generate_RRCReject(module_id_t module_id, rrc_gNB_ue_context_t *const ue_context_pP) +static void rrc_gNB_generate_RRCReject(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *const ue_context_pP) //----------------------------------------------------------------------------- { - gNB_RRC_INST *rrc = RC.nrrrc[module_id]; gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; LOG_A(NR_RRC, "Send RRCReject to RNTI %04x\n", ue_p->rnti); @@ -420,10 +419,10 @@ static void rrc_gNB_generate_RRCReject(module_id_t module_id, rrc_gNB_ue_context .rrc_container = buf, .rrc_container_length = size, .srb_id = srbid, - .execute_duplication = 1, - .RAT_frequency_priority_information.en_dc = 0 }; rrc->mac_rrc.dl_rrc_message_transfer(ue_data.du_assoc_id, &dl_rrc); + /* release the created UE context, we rejected the UE */ + rrc_remove_ue(rrc, ue_context_pP); } //----------------------------------------------------------------------------- @@ -1135,10 +1134,17 @@ static void rrc_handle_RRCSetupRequest(gNB_RRC_INST *rrc, ue_context_p = rrc_gNB_create_ue_context(assoc_id, msg->crnti, rrc, random_value, msg->gNB_DU_ue_id); LOG_E(NR_RRC, "RRCSetupRequest without random UE identity or S-TMSI not supported, let's reject the UE %04x\n", msg->crnti); - rrc_gNB_generate_RRCReject(0, ue_context_p); + rrc_gNB_generate_RRCReject(rrc, ue_context_p); return; } + // If the DU to CU RRC Container IE is not included in the INITIAL UL RRC MESSAGE TRANSFER, + // the gNB-CU should reject the UE under the assumption that the gNB-DU is not able to serve such UE + if (msg->du2cu_rrc_container == NULL) { + // this will remove the UE context + rrc_gNB_generate_RRCReject(rrc, ue_context_p); + return; + } NR_CellGroupConfig_t *cellGroupConfig = NULL; asn_dec_rval_t dec_rval = uper_decode_complete(NULL, &asn_DEF_NR_CellGroupConfig, From 69ac704adcc11c5cedc17635ed0e90e32e56b17a Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 2 Jan 2025 18:21:18 +0100 Subject: [PATCH 3/8] do not send DU to CU container to CU if we can't serve the UE --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 26 ++++++++++++++----- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 12 ++++++--- .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 9 +++++-- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 2 +- openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c | 6 ++++- 5 files changed, 41 insertions(+), 14 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index e398da1eaf..cbf414fb31 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -2077,7 +2077,7 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP, } } -void nr_check_Msg4_MsgB_Ack(module_id_t module_id, frame_t frame, slot_t slot, NR_UE_info_t *UE, bool success) +bool nr_check_Msg4_MsgB_Ack(module_id_t module_id, frame_t frame, slot_t slot, NR_UE_info_t *UE, bool success) { NR_RA_t *ra = UE->ra; const char *ra_type_str = ra->ra_type == RA_2_STEP ? "MsgB" : "Msg4"; @@ -2092,10 +2092,21 @@ void nr_check_Msg4_MsgB_Ack(module_id_t module_id, frame_t frame, slot_t slot, N 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); + LOG_A(NR_MAC, + "%4d.%2d UE %04x: Received Ack of %s. CBRA procedure succeeded (%s)\n", + frame, + slot, + UE->rnti, + ra_type_str, + UE->CellGroup ? "UE Connected" : "UE Rejected"); + if (UE->CellGroup) { + // 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); + } else { // in case of UE reject + nr_release_ra_UE(nr_mac, UE->rnti); + return true; + } } 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); @@ -2108,6 +2119,7 @@ void nr_check_Msg4_MsgB_Ack(module_id_t module_id, frame_t frame, slot_t slot, N LOG_I(NR_MAC, "(UE %04x) Received Nack in %s, preparing retransmission!\n", UE->rnti, ra_type_str); ra->ra_state = ra->ra_type == RA_4_STEP ? nrRA_Msg4 : nrRA_MsgB; } + return false; } ///////////////////////////////////// @@ -2269,7 +2281,9 @@ void nr_schedule_RA(module_id_t module_idP, ra->contention_resolution_timer--; if (ra->contention_resolution_timer == 0) { LOG_W(NR_MAC, "(%d.%d) RA Contention Resolution timer expired for UE 0x%04x, RA procedure failed...\n", frameP, slotP, UE->rnti); - bool requested = nr_mac_request_release_ue(mac, UE->rnti); + bool requested = false; + if (UE->CellGroup) // request if we did not reject the UE + requested = nr_mac_request_release_ue(mac, UE->rnti); if (!requested) nr_release_ra_UE(mac, UE->rnti); continue; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index a447d9f91c..82fa6d828b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -3297,7 +3297,9 @@ void send_initial_ul_rrc_message(int rnti, const uint8_t *sdu, sdu_size_t sdu_le NR_SCHED_ENSURE_LOCKED(&mac->sched_lock); uint8_t du2cu[1024]; - int encoded = encode_cellGroupConfig(UE->CellGroup, du2cu, sizeof(du2cu)); + int encoded_len = 0; + if (UE->CellGroup) + encoded_len = encode_cellGroupConfig(UE->CellGroup, du2cu, sizeof(du2cu)); DevAssert(mac->f1_config.setup_req != NULL); AssertFatal(mac->f1_config.setup_req->num_cells_available == 1, "can handle only one cell\n"); @@ -3308,8 +3310,8 @@ void send_initial_ul_rrc_message(int rnti, const uint8_t *sdu, sdu_size_t sdu_le .crnti = rnti, .rrc_container = (uint8_t *) sdu, .rrc_container_length = sdu_len, - .du2cu_rrc_container = (uint8_t *) du2cu, - .du2cu_rrc_container_length = encoded + .du2cu_rrc_container = encoded_len ? (uint8_t *) du2cu : NULL, + .du2cu_rrc_container_length = encoded_len }; mac->mac_rrc.initial_ul_rrc_message_transfer(0, &ul_rrc_msg); } @@ -3331,12 +3333,14 @@ bool prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); UE->CellGroup = cellGroupConfig; + if (!cellGroupConfig) + return true; + /* the cellGroup sent to CU specifies there is SRB1, so create it */ DevAssert(cellGroupConfig->rlc_BearerToAddModList->list.count == 1); const NR_RLC_BearerConfig_t *bearer = cellGroupConfig->rlc_BearerToAddModList->list.array[0]; DevAssert(bearer->servedRadioBearer->choice.srb_Identity == srb_id); nr_rlc_add_srb(UE->rnti, bearer->servedRadioBearer->choice.srb_Identity, bearer); - int priority = bearer->mac_LogicalChannelConfig->ul_SpecificParameters->priority; nr_lc_config_t c = {.lcid = bearer->logicalChannelIdentity, .priority = priority}; nr_mac_add_lcid(&UE->UE_sched_ctrl, &c); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 29ff27d38e..00201cdd8d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -899,8 +899,13 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, frame_t frame, slot_t slot, con 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); - if (is_ra) - nr_check_Msg4_MsgB_Ack(mod_id, frame, slot, UE, success); + if (is_ra) { + bool ue_rejected = nr_check_Msg4_MsgB_Ack(mod_id, frame, slot, UE, success); + if (ue_rejected) { + NR_SCHED_UNLOCK(&nrmac->sched_lock); + return; + } + } if (harq_confidence == 1) UE->mac_stats.pucch0_DTX++; } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 6acf4ae1d8..028cfcb0b2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -319,7 +319,7 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, bool transition_ra_connected_nr_ue(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE); bool add_connected_nr_ue(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE); -void nr_check_Msg4_MsgB_Ack(module_id_t module_id, frame_t frame, slot_t slot, NR_UE_info_t *UE, bool success); +bool nr_check_Msg4_MsgB_Ack(module_id_t module_id, frame_t frame, slot_t slot, NR_UE_info_t *UE, bool success); void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti); NR_UE_info_t *get_new_nr_ue_inst(uid_allocator_t *uia, rnti_t rnti, NR_CellGroupConfig_t *CellGroup); int nr_get_default_pucch_res(int pucch_ResourceCommon); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index 41ace5014b..d0d37bbab5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -3498,6 +3498,10 @@ NR_CellGroupConfig_t *get_initial_cellGroupConfig(int uid, const nr_mac_config_t *configuration, const nr_rlc_configuration_t *default_rlc_config) { + NR_SpCellConfig_t *spCellConfig = get_initial_SpCellConfig(uid, scc, servingcellconfigdedicated, configuration); + if (!spCellConfig) + return NULL; + NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(*cellGroupConfig)); cellGroupConfig->cellGroupId = 0; @@ -3515,7 +3519,7 @@ NR_CellGroupConfig_t *get_initial_cellGroupConfig(int uid, cellGroupConfig->physicalCellGroupConfig = configure_phy_cellgroup(); - cellGroupConfig->spCellConfig = get_initial_SpCellConfig(uid, scc, servingcellconfigdedicated, configuration); + cellGroupConfig->spCellConfig = spCellConfig; cellGroupConfig->sCellToAddModList = NULL; cellGroupConfig->sCellToReleaseList = NULL; From 88af2860a2966b169989835417f4e5268ee84e10 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 9 Jan 2025 19:21:36 +0100 Subject: [PATCH 4/8] handle RRC reject at UE --- openair2/LAYER2/NR_MAC_UE/config_ue.c | 5 ++++ openair2/LAYER2/NR_MAC_UE/mac_defs.h | 2 ++ openair2/LAYER2/NR_MAC_UE/mac_proto.h | 5 +--- openair2/RRC/NR_UE/rrc_UE.c | 41 +++++++++++++++++++++++++-- 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index bfea78d540..9bdbeebe10 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -1725,6 +1725,11 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t reset_mac_inst(mac); mac->state = UE_PERFORMING_RA; // still in sync but need to restart RA break; + case REJECT: + reset_ra(mac, false); + reset_mac_inst(mac); + mac->state = UE_BARRED; + break; case RE_ESTABLISHMENT: reset_mac_inst(mac); nr_ue_mac_default_configs(mac); diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index dee2a30c08..0174e88abc 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -148,6 +148,7 @@ // Define the UE L2 states with X-Macro #define NR_UE_L2_STATES \ UE_STATE(UE_NOT_SYNC) \ + UE_STATE(UE_BARRED) \ UE_STATE(UE_RECEIVING_SIB) \ UE_STATE(UE_PERFORMING_RA) \ UE_STATE(UE_CONNECTED) \ @@ -199,6 +200,7 @@ typedef enum { RE_ESTABLISHMENT, RRC_SETUP_REESTAB_RESUME, UL_SYNC_LOST_T430_EXPIRED, + REJECT, } NR_UE_MAC_reset_cause_t; typedef struct { diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index c8eab85462..0a7365ef5d 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -87,10 +87,7 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id, NR_CellGroupConfig_t *cell_group_config, NR_UE_NR_Capability_t *ue_Capability); -void nr_rrc_mac_config_req_mib(module_id_t module_id, - int cc_idP, - NR_MIB_t *mibP, - int sched_sib1); +void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mibP, int sched_sib1); void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SIB1_t *sib1, bool can_start_ra); diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 90713ff50c..af0c1350c1 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1394,8 +1394,44 @@ static void nr_rrc_process_rrcsetup(NR_UE_RRC_INST_t *rrc, const NR_RRCSetup_t * rrc_ue_generate_RRCSetupComplete(rrc, rrcSetup->rrc_TransactionIdentifier); } -static int8_t nr_rrc_ue_decode_ccch(NR_UE_RRC_INST_t *rrc, - const NRRrcMacCcchDataInd *ind) +static void nr_rrc_process_rrcreject(NR_UE_RRC_INST_t *rrc, const NR_RRCReject_t *rrcReject) +{ + // stop timer T300, T302, T319 if running; + NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants; + nr_timer_stop(&timers->T300); + nr_timer_stop(&timers->T302); + nr_timer_stop(&timers->T319); + + // reset MAC and release the default MAC Cell Group configuration + NR_UE_MAC_reset_cause_t cause = REJECT; + MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_RESET); + NR_MAC_RRC_CONFIG_RESET(msg).cause = cause; + itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg); + + // if waitTime is configured in the RRCReject: start timer T302, with the timer value set to the waitTime + NR_RejectWaitTime_t *waitTime = NULL; + if (rrcReject->criticalExtensions.present == NR_RRCReject__criticalExtensions_PR_rrcReject) { + NR_RRCReject_IEs_t *ies = rrcReject->criticalExtensions.choice.rrcReject; + waitTime = ies->waitTime; // Wait time value in seconds + } + if (waitTime) { + nr_timer_setup(&timers->T302, *waitTime * 1000, 10); + nr_timer_start(&timers->T302); + } else { + LOG_W(RRC, "Error: waitTime should be always included in RRCReject message\n"); + } + + // TODO if RRCReject is received in response to a request from upper layers + // inform the upper layer that access barring is applicable for all access categories except categories '0' and '2' + + // TODO if RRCReject is received in response to an RRCSetupRequest + // inform upper layers about the failure to setup the RRC connection, upon which the procedure ends + + // TODO else if RRCReject is received in response to an RRCResumeRequest or an RRCResumeRequest1 + // Resume not implemented yet +} + +static int8_t nr_rrc_ue_decode_ccch(NR_UE_RRC_INST_t *rrc, const NRRrcMacCcchDataInd *ind) { NR_DL_CCCH_Message_t *dl_ccch_msg = NULL; asn_dec_rval_t dec_rval; @@ -1423,6 +1459,7 @@ static int8_t nr_rrc_ue_decode_ccch(NR_UE_RRC_INST_t *rrc, case NR_DL_CCCH_MessageType__c1_PR_rrcReject: LOG_I(NR_RRC, "[UE%ld] Logical Channel DL-CCCH (SRB0), Received RRCReject \n", rrc->ue_id); + nr_rrc_process_rrcreject(rrc, dl_ccch_msg->message.choice.c1->choice.rrcReject); rval = 0; break; From 8932566d2b60aba067702f381af926d1d48d2d1c Mon Sep 17 00:00:00 2001 From: francescomani Date: Sun, 19 Jan 2025 10:34:42 +0100 Subject: [PATCH 5/8] improvements in T302 handling at RRC UE --- openair1/SIMULATION/NR_PHY/dlsim.c | 2 +- openair2/COMMON/rrc_messages_types.h | 1 + openair2/LAYER2/NR_MAC_UE/config_ue.c | 9 +++++- openair2/LAYER2/NR_MAC_UE/mac_proto.h | 2 +- openair2/RRC/NR_UE/L2_interface_ue.c | 6 +++- openair2/RRC/NR_UE/rrc_UE.c | 30 ++++++++++++++----- openair2/RRC/NR_UE/rrc_defs.h | 2 +- openair2/RRC/NR_UE/rrc_proto.h | 1 + openair2/RRC/NR_UE/rrc_timers_and_constants.c | 8 +++++ 9 files changed, 48 insertions(+), 13 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index b858945018..a327abb2d0 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -953,7 +953,7 @@ printf("%d\n", slot); //Configure UE NR_BCCH_BCH_Message_t *mib = get_new_MIB_NR(scc); - nr_rrc_mac_config_req_mib(0, 0, mib->message.choice.mib, false); + nr_rrc_mac_config_req_mib(0, 0, mib->message.choice.mib, false, false); nr_rrc_mac_config_req_cg(0, 0, UE_CellGroup, UE_Capability_nr); asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, UE_CellGroup); diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 094fd0fa40..1d35619ecc 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -486,6 +486,7 @@ typedef struct { typedef struct { NR_BCCH_BCH_Message_t *bcch; int get_sib; + bool access_barred; } nr_mac_rrc_config_mib_t; typedef struct { NR_SIB1_t *sib1; diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 9bdbeebe10..8624766bd1 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -955,7 +955,7 @@ static void update_mib_conf(NR_MIB_t *target, NR_MIB_t *source) target->intraFreqReselection = source->intraFreqReselection; } -void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mib, int sched_sib) +void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mib, int sched_sib, bool barred) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); int ret = pthread_mutex_lock(&mac->if_mutex); @@ -963,6 +963,13 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mib, AssertFatal(mib, "MIB should not be NULL\n"); if (!mac->mib) mac->mib = calloc(1, sizeof(*mac->mib)); + if (barred) + mac->state = UE_BARRED; + else if (mac->state == UE_BARRED) { + // it is synched as we received MIB + // nr_ue_decode_mib is transitionining to the correct state + mac->state = UE_NOT_SYNC; + } update_mib_conf(mac->mib, mib); mac->phy_config.Mod_id = module_id; mac->phy_config.CC_id = cc_idP; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 0a7365ef5d..aacbbdcab2 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -87,7 +87,7 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id, NR_CellGroupConfig_t *cell_group_config, NR_UE_NR_Capability_t *ue_Capability); -void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mibP, int sched_sib1); +void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mibP, int sched_sib1, bool barred); void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SIB1_t *sib1, bool can_start_ra); diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index fe2eb2cfed..6271957f4f 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -133,7 +133,11 @@ void process_msg_rcc_to_mac(MessageDef *msg) asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, NR_MAC_RRC_CONFIG_CG(msg).cellGroupConfig); break; case NR_MAC_RRC_CONFIG_MIB: - nr_rrc_mac_config_req_mib(ue_id, 0, NR_MAC_RRC_CONFIG_MIB(msg).bcch->message.choice.mib, NR_MAC_RRC_CONFIG_MIB(msg).get_sib); + nr_rrc_mac_config_req_mib(ue_id, + 0, + NR_MAC_RRC_CONFIG_MIB(msg).bcch->message.choice.mib, + NR_MAC_RRC_CONFIG_MIB(msg).get_sib, + NR_MAC_RRC_CONFIG_MIB(msg).access_barred); ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, NR_MAC_RRC_CONFIG_MIB(msg).bcch); break; case NR_MAC_RRC_CONFIG_SIB1: { diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index af0c1350c1..f858a10599 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -749,6 +749,7 @@ NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int nb_inst, int num_ant_tx) rrc->reconfig_after_reestab = false; /* 5G-S-TMSI */ rrc->fiveG_S_TMSI = UINT64_MAX; + rrc->access_barred = false; FILE *f = NULL; if (uecap_file) @@ -959,11 +960,12 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc, } NR_UE_RRC_SI_INFO *SI_info = &rrc->perNB[gNB_index].SInfo; + bool barred = rrc->access_barred || bcch_message->message.choice.mib->cellBarred == NR_MIB__cellBarred_barred; int get_sib = 0; if (IS_SA_MODE(get_softmodem_params()) && !SI_info->sib_pending && bcch_message->message.present == NR_BCCH_BCH_MessageType_PR_mib - && bcch_message->message.choice.mib->cellBarred == NR_MIB__cellBarred_notBarred + && !barred && rrc->nrRrcState != RRC_STATE_DETACH_NR) { // to schedule MAC to get SI if required get_sib = check_si_status(SI_info); @@ -975,6 +977,7 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc, // mac will manage the pointer NR_MAC_RRC_CONFIG_MIB(msg).bcch = bcch_message; NR_MAC_RRC_CONFIG_MIB(msg).get_sib = get_sib; + NR_MAC_RRC_CONFIG_MIB(msg).access_barred = barred; itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg); } else { LOG_E(NR_RRC, "RRC-received BCCH message is not a MIB\n"); @@ -1376,7 +1379,11 @@ static void nr_rrc_process_rrcsetup(NR_UE_RRC_INST_t *rrc, const NR_RRCSetup_t * nr_timer_stop(&timers->T319); nr_timer_stop(&timers->T320); - // TODO if T390 and T302 are running (not implemented) + // if T390 (not implemented) and T302 are running + // stop timer + // perform the actions as specified in 5.3.14.4 + nr_timer_stop(&timers->T302); + handle_302_expired_stopped(rrc); // if the RRCSetup is received in response to an RRCResumeRequest, RRCResumeRequest1 or RRCSetupRequest // enter RRC_CONNECTED @@ -1417,6 +1424,7 @@ static void nr_rrc_process_rrcreject(NR_UE_RRC_INST_t *rrc, const NR_RRCReject_t if (waitTime) { nr_timer_setup(&timers->T302, *waitTime * 1000, 10); nr_timer_start(&timers->T302); + rrc->access_barred = true; } else { LOG_W(RRC, "Error: waitTime should be always included in RRCReject message\n"); } @@ -1458,7 +1466,7 @@ static int8_t nr_rrc_ue_decode_ccch(NR_UE_RRC_INST_t *rrc, const NRRrcMacCcchDat break; case NR_DL_CCCH_MessageType__c1_PR_rrcReject: - LOG_I(NR_RRC, "[UE%ld] Logical Channel DL-CCCH (SRB0), Received RRCReject \n", rrc->ue_id); + LOG_W(NR_RRC, "[UE%ld] Logical Channel DL-CCCH (SRB0), Received RRCReject \n", rrc->ue_id); nr_rrc_process_rrcreject(rrc, dl_ccch_msg->message.choice.c1->choice.rrcReject); rval = 0; break; @@ -2777,17 +2785,16 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, nr_timer_setup(&tac->T302, target, 10); nr_timer_start(&tac->T302); // TODO inform upper layers that access barring is applicable - // for all access categories except categories '0' and '2'. - LOG_E(NR_RRC,"Go to IDLE. Handling RRCRelease message including a waitTime not implemented\n"); + // for all access categories except categories '0' and '2'. + // for now we just set the access barred in RRC + rrc->access_barred = true; } } } if (!waitTime) { if (nr_timer_is_active(&tac->T302)) { nr_timer_stop(&tac->T302); - // TODO barring alleviation as in 5.3.14.4 - // not implemented - LOG_E(NR_RRC,"Go to IDLE. Barring alleviation not implemented\n"); + handle_302_expired_stopped(rrc); } } if (nr_timer_is_active(&tac->T390)) { @@ -2897,6 +2904,13 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, itti_send_msg_to_task(TASK_NAS_NRUE, rrc->ue_id, msg_p); } +void handle_302_expired_stopped(NR_UE_RRC_INST_t *rrc) +{ + // for each Access Category for which T390 (TODO not implemented) is not running + // consider the barring for this Access Category to be alleviated + rrc->access_barred = false; +} + void handle_t300_expiry(NR_UE_RRC_INST_t *rrc) { rrc->ra_trigger = RRC_CONNECTION_SETUP; diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index 960dc1aaa0..c71f7697a2 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -205,7 +205,7 @@ typedef struct rrcPerNB { typedef struct NR_UE_RRC_INST_s { instance_t ue_id; rrcPerNB_t perNB[NB_CNX_UE]; - + bool access_barred; rnti_t rnti; uint32_t phyCellID; long arfcn_ssb; diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 7c5f749fa0..bc7f7001af 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -64,6 +64,7 @@ void *rrc_nrue(void *args_p); void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc); void handle_rlf_detection(NR_UE_RRC_INST_t *rrc); +void handle_302_expired_stopped(NR_UE_RRC_INST_t *rrc); /**\brief RRC NSA UE task. \param void *args_p Pointer on arguments to start the task. */ diff --git a/openair2/RRC/NR_UE/rrc_timers_and_constants.c b/openair2/RRC/NR_UE/rrc_timers_and_constants.c index 9286494f0b..57f6be2eb6 100644 --- a/openair2/RRC/NR_UE/rrc_timers_and_constants.c +++ b/openair2/RRC/NR_UE/rrc_timers_and_constants.c @@ -144,6 +144,14 @@ void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc) nr_rrc_going_to_IDLE(rrc, RRC_CONNECTION_FAILURE, NULL); } + bool t302_expired = nr_timer_tick(&timers->T302); + // 5.3.14.4 in 38.331 + // consider the barring for this Access Category to be alleviated + if (t302_expired) { + LOG_W(NR_RRC, "Timer T302 expired! Access barring alleviated!\n"); + handle_302_expired_stopped(rrc); + } + bool t304_expired = nr_timer_tick(&timers->T304); if(t304_expired) { LOG_W(NR_RRC, "Timer T304 expired\n"); From f9cf458b1c1e613234d511803238fb68f2b33d37 Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 13 May 2025 11:00:52 +0200 Subject: [PATCH 6/8] function to verify if we can allocare RRC resources to UE with given ID --- openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c | 55 +++++++++++++++++--- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index d0d37bbab5..e3b750c796 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -238,6 +238,7 @@ static int get_nb_pucch2_per_slot(const NR_ServingCellConfigCommon_t *scc, int b int nb_pucch2 = (max_csi_reports / (available_report_occasions + 1)) + 1; // in current implementation we need (nb_pucch2 * PUCCH2_SIZE) prbs for PUCCH2 // and MAX_MOBILES_PER_GNB prbs for PUCCH1 + // checked for validity in verify_radio_configuration AssertFatal((nb_pucch2 * PUCCH2_SIZE) + MAX_MOBILES_PER_GNB <= bwp_size, "Cannot allocate all required PUCCH resources for max number of %d UEs in BWP with %d PRBs\n", MAX_MOBILES_PER_GNB, bwp_size); @@ -402,6 +403,7 @@ static void set_csirs_periodicity(NR_NZP_CSI_RS_Resource_t *nzpcsi0, else { nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots320; const int nb_dl_slots_period = get_full_dl_slots_per_period(fs); // full DL slots + // checked for validity in verify_radio_configuration AssertFatal(offset / 320 < nb_dl_slots_period, "Cannot allocate CSI-RS for BWP %d. Not enough resources for CSI-RS\n", id); nzpcsi0->periodicityAndOffset->choice.slots320 = (offset % 320) + (offset / 320); } @@ -661,7 +663,7 @@ static struct NR_SRS_Resource__resourceType__periodic *configure_periodic_srs(co { frame_structure_t *fs = &RC.nrmac[0]->frame_structure; int offset = get_ul_slot_offset(fs, uid, false); // only full UL slots for SRS - + // checked for validity in verify_radio_configuration AssertFatal(offset < 2560, "Cannot allocate SRS configuration for uid %d, not enough resources\n", uid); const int ideal_period = set_ideal_period(false); @@ -1169,6 +1171,7 @@ static void config_pucch_resset0(NR_PUCCH_Config_t *pucch_Config, NR_PUCCH_Resource_t *pucchres0 = calloc(1,sizeof(*pucchres0)); pucchres0->pucch_ResourceId = *pucchid; pucchres0->startingPRB = (PUCCH2_SIZE * num_pucch2) + uid; + // checked for validity in verify_radio_configuration AssertFatal(pucchres0->startingPRB < curr_bwp, "Not enough resources in current BWP (size %d) to allocate uid %d\n", curr_bwp, uid); pucchres0->intraSlotFrequencyHopping = NULL; pucchres0->secondHopPRB = NULL; @@ -1745,13 +1748,11 @@ static void set_csi_meas_periodicity(const NR_ServingCellConfigCommon_t *scc, const int ideal_period = set_ideal_period(true); const int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp); const int idx = (uid * 2 / num_pucch2) + is_rsrp; - frame_structure_t *fs = &RC.nrmac[0]->frame_structure; int offset = get_ul_slot_offset(fs, idx, true); - LOG_D(NR_MAC, "set_csi_meas_periodicity: uid = %d, offset = %d, ideal_period = %d", uid, offset, ideal_period); + // checked for validity in verify_radio_configuration AssertFatal(offset < 320, "Not enough UL slots to accomodate all possible UEs. Need to rework the implementation\n"); - if (check_periodicity(4, ideal_period, fs)) { csirep->reportConfigType.choice.periodic->reportSlotConfig.present = NR_CSI_ReportPeriodicityAndOffset_PR_slots4; csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots4 = offset; @@ -3492,16 +3493,58 @@ NR_RLC_BearerConfig_t *get_DRB_RLC_BearerConfig(long lcChannelId, return rlc_BearerConfig; } +static bool verify_radio_configuration(int uid, const NR_ServingCellConfigCommon_t *scc, const NR_ServingCellConfig_t *scd) +{ + frame_structure_t *fs = &RC.nrmac[0]->frame_structure; + int srs_offset = get_ul_slot_offset(fs, uid, false); + // see configure_periodic_srs + if (srs_offset >= 2560) { + LOG_E(NR_RRC, "UID %d, cannot allocate resources for SRS, rejecting UE\n", uid); + return false; + } + + int n_dl_bwp = scd->downlinkBWP_ToAddModList ? scd->downlinkBWP_ToAddModList->list.count : 1; + int csi_offset = fs->numb_slots_period * n_dl_bwp; + // see set_csirs_periodicity + if (csi_offset / 320 >= get_full_dl_slots_per_period(fs)) { + LOG_E(NR_RRC, "UID %d, cannot allocate resources for CSI-RS, rejecting UE\n", uid); + return false; // cannot allocate resources for CSI-RS + } + + int curr_bwp = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp); + int pucchres0_startingPRB = (PUCCH2_SIZE * num_pucch2) + uid; + // see config_pucch_resset0 + if (pucchres0_startingPRB >= curr_bwp) { + LOG_E(NR_RRC, "UID %d, cannot allocate resources for PUCCH0, rejecting UE\n", uid); + return false; // cannot allocate resources for PUCCH0 + } + // see get_nb_pucch2_per_slot + if ((num_pucch2 * PUCCH2_SIZE) + MAX_MOBILES_PER_GNB > curr_bwp) { + LOG_E(NR_RRC, "UID %d, cannot allocate resources for PUCCH2, rejecting UE\n", uid); + return false; // cannot allocate resources for PUCCH2 + } + const int idx = (uid * 2 / num_pucch2) + 1; + int offset = get_ul_slot_offset(fs, idx, true); + // see set_csi_meas_periodicity + if (offset >= 320) { + LOG_E(NR_RRC, "UID %d, cannot allocate resources for CSI reporting, rejecting UE\n", uid); + return false; // cannot allocate resources for CSI report + } + + return true; +} + NR_CellGroupConfig_t *get_initial_cellGroupConfig(int uid, const NR_ServingCellConfigCommon_t *scc, const NR_ServingCellConfig_t *servingcellconfigdedicated, const nr_mac_config_t *configuration, const nr_rlc_configuration_t *default_rlc_config) { - NR_SpCellConfig_t *spCellConfig = get_initial_SpCellConfig(uid, scc, servingcellconfigdedicated, configuration); - if (!spCellConfig) + if (!verify_radio_configuration(uid, scc, servingcellconfigdedicated)) return NULL; + NR_SpCellConfig_t *spCellConfig = get_initial_SpCellConfig(uid, scc, servingcellconfigdedicated, configuration); NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(*cellGroupConfig)); cellGroupConfig->cellGroupId = 0; From 41da4a3b3af385f155d4b3b5e08261668c5686e4 Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 13 May 2025 15:22:41 +0200 Subject: [PATCH 7/8] send reject if we reach the max number of UEs allowed --- openair2/LAYER2/NR_MAC_gNB/config.c | 2 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 5 ---- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 26 +++++++++++-------- .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 2 +- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index f87b4024b9..abe6e5218a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -971,7 +971,7 @@ bool nr_mac_add_test_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t NR_SCHED_LOCK(&nrmac->sched_lock); NR_UE_info_t *UE = get_new_nr_ue_inst(&nrmac->UE_info.uid_allocator, rnti, CellGroup); - DevAssert(UE != NULL); // test-mode: we assume we can always create a UE + DevAssert(UE->uid < MAX_MOBILES_PER_GNB); // test-mode: we assume we can always create a UE free_and_zero(UE->ra); // test-mode (sims, phy-test): UE will not do RA bool res = add_connected_nr_ue(nrmac, UE); if (!res) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index cbf414fb31..7459a99579 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -727,11 +727,6 @@ void nr_initiate_ra_proc(module_id_t module_idP, } UE = get_new_nr_ue_inst(&nr_mac->UE_info.uid_allocator, rnti, NULL); - if (!UE) { - LOG_E(NR_MAC, "FAILURE: %4d.%2d cannot create UE context, ignoring RA because RRC Reject not implemented yet\n", frame, slot); - NR_SCHED_UNLOCK(&nr_mac->sched_lock); - return; - } if (!add_new_UE_RA(nr_mac, UE)) { LOG_E(NR_MAC, "FAILURE: %4d.%2d initiating RA procedure for preamble index %d: no free RA process\n", frame, slot, preamble_index); delete_nr_ue_data(UE, NULL, &nr_mac->UE_info.uid_allocator); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 82fa6d828b..f3c604740a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2577,19 +2577,10 @@ static void init_bler_stats(const NR_bler_options_t *bler_options, NR_bler_stats * error handling). Remove with delete_nr_ue_data(). */ NR_UE_info_t *get_new_nr_ue_inst(uid_allocator_t *uia, rnti_t rnti, NR_CellGroupConfig_t *CellGroup) { - uid_t uid = uid_linear_allocator_new(uia); - /* if the UE list is full, we should reject the UE with an RRC reject - * message, but we do not have this functionality. To keep it simple, do not - * create a UE context here, so we can print an error message. */ - if (uid >= MAX_MOBILES_PER_GNB) { - uid_linear_allocator_free(uia, uid); - return NULL; - } - NR_UE_info_t *UE = calloc_or_fail(1, sizeof(NR_UE_info_t)); + UE->uid = uid_linear_allocator_new(uia); UE->rnti = rnti; UE->CellGroup = CellGroup; - UE->uid = uid; UE->ra = calloc(1, sizeof(*UE->ra)); NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; sched_ctrl->ta_update = 31; @@ -3324,6 +3315,19 @@ bool prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) if (!nr_rlc_activate_srb0(UE->rnti, UE, send_initial_ul_rrc_message)) return false; + if (UE->uid >= MAX_MOBILES_PER_GNB) { + // verifying if any UE left in the meantime and it is possible to get a valid UID + uid_linear_allocator_free(&mac->UE_info.uid_allocator, UE->uid); + UE->uid = uid_linear_allocator_new(&mac->UE_info.uid_allocator); + if (UE->uid >= MAX_MOBILES_PER_GNB) { + // if the UE list is full, we should reject the UE with an RRC reject message + // to signal the upper layers to send a reject we send an empty CellGroup information element + UE->CellGroup = NULL; + LOG_W(NR_MAC, "Maximum number of UE alllowed at DU reached. Cannot serve UE %04x", UE->rnti); + return true; + } + } + /* create this UE's initial CellGroup */ int CC_id = 0; int srb_id = 1; @@ -3335,7 +3339,7 @@ bool prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) if (!cellGroupConfig) return true; - + /* the cellGroup sent to CU specifies there is SRB1, so create it */ DevAssert(cellGroupConfig->rlc_BearerToAddModList->list.count == 1); const NR_RLC_BearerConfig_t *bearer = cellGroupConfig->rlc_BearerToAddModList->list.array[0]; 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 5d7642c815..5236f817cc 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -553,7 +553,7 @@ static NR_UE_info_t *create_new_UE(gNB_MAC_INST *mac, uint32_t cu_id, const NR_C DevAssert(success); NR_UE_info_t *UE = get_new_nr_ue_inst(&mac->UE_info.uid_allocator, rnti, NULL); - AssertFatal(UE != NULL, "cannot create UE context, UE context setup failure not implemented\n"); + AssertFatal(UE->uid < MAX_MOBILES_PER_GNB, "cannot create UE context, UE context setup failure not implemented\n"); NR_CellGroupConfig_t *cellGroupConfig = NULL; NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; From a830cc2e0aeb087cc11c1e435cd6c63c6ba39857 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 15 May 2025 12:53:14 +0200 Subject: [PATCH 8/8] When freeing UE contexts, check in both possible lists --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 2 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 7459a99579..839930960b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -2249,7 +2249,7 @@ void nr_release_ra_UE(gNB_MAC_INST *mac, rnti_t rnti) if (UE) { delete_nr_ue_data(UE, mac->common_channels, &UE_info->uid_allocator); } else { - LOG_W(NR_MAC,"Call to del rnti %04x, but not existing\n", rnti); + LOG_W(NR_MAC,"Call to release RA UE with rnti %04x, but not existing\n", rnti); } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index f3c604740a..908425651b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2612,6 +2612,8 @@ NR_UE_info_t *remove_UE_from_list(int list_size, NR_UE_info_t *list[list_size], { for (int i = 0; i < list_size; i++) { NR_UE_info_t *curr_UE = list[i]; + if (!curr_UE) + break; /* reached the end of the list */ if (curr_UE->rnti != rnti) continue; @@ -2620,7 +2622,6 @@ NR_UE_info_t *remove_UE_from_list(int list_size, NR_UE_info_t *list[list_size], list[list_size - 1] = NULL; return curr_UE; } - LOG_E(NR_MAC, "UE %04x to be removed not found in list\n", rnti); return NULL; } @@ -2726,8 +2727,10 @@ void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti) NR_SCHED_LOCK(&UE_info->mutex); NR_UE_info_t *UE = remove_UE_from_list(MAX_MOBILES_PER_GNB + 1, UE_info->connected_ue_list, rnti); NR_SCHED_UNLOCK(&UE_info->mutex); - - delete_nr_ue_data(UE, nr_mac->common_channels, &UE_info->uid_allocator); + if (UE) + delete_nr_ue_data(UE, nr_mac->common_channels, &UE_info->uid_allocator); + else + nr_release_ra_UE(nr_mac, rnti); } // all values passed to this function are in dB x10