From c47ddc570f9ebeb06df91d7314475c28e888f774 Mon Sep 17 00:00:00 2001 From: francescomani Date: Sat, 8 Nov 2025 14:34:41 +0100 Subject: [PATCH 1/6] add check for CellGroup decoding at RRC UE (issue #1024) --- openair2/RRC/NR_UE/rrc_UE.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 15c713cb26..9086ad25eb 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -747,12 +747,15 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc, { AssertFatal(!fullConfig, "fullConfig not supported yet\n"); NR_CellGroupConfig_t *cellGroupConfig = NULL; - uper_decode(NULL, - &asn_DEF_NR_CellGroupConfig, //might be added prefix later - (void **)&cellGroupConfig, - (uint8_t *)masterCellGroup->buf, - masterCellGroup->size, 0, 0); - + asn_dec_rval_t dec_rval = uper_decode(NULL, + &asn_DEF_NR_CellGroupConfig, //might be added prefix later + (void **)&cellGroupConfig, + (uint8_t *)masterCellGroup->buf, + masterCellGroup->size, 0, 0); + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(NR_RRC, "CellGroupConfig decode error\n"); + return; + } if (LOG_DEBUGFLAG(DEBUG_ASN1)) { xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig); } From f4ff6c756c392d202d86b06897d689b73245d9a7 Mon Sep 17 00:00:00 2001 From: francescomani Date: Sat, 8 Nov 2025 14:41:42 +0100 Subject: [PATCH 2/6] add a check for rlc-Config presence (even if it should be mandatory at setup) --- openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 2 +- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 5 ++--- openair2/RRC/NR_UE/rrc_UE.c | 9 +++++++-- 3 files changed, 10 insertions(+), 6 deletions(-) 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 064857a8e3..ce59a31226 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -329,7 +329,7 @@ static int handle_ue_context_drbs_setup(NR_UE_info_t *UE, *rlc_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size12; *rlc_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size12; } - + AssertFatal(rlc_BearerConfig->rlc_Config, "We expect rlc-Config to be always present when we configure a DRB\n"); nr_rlc_add_drb(UE->rnti, drb->id, rlc_BearerConfig); nr_lc_config_t c = {.lcid = rlc_BearerConfig->logicalChannelIdentity, .nssai = drb->nr.nssai}; diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index e187541fd5..126f9fb51c 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -672,7 +672,7 @@ void nr_rlc_reconfigure_entity(int ue_id, int lc_id, NR_RLC_Config_t *rlc_Config void nr_rlc_add_srb(int ue_id, int srb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig) { - struct NR_RLC_Config *r = rlc_BearerConfig->rlc_Config; + NR_RLC_Config_t *r = rlc_BearerConfig->rlc_Config; int t_status_prohibit; int t_poll_retransmit; int poll_pdu; @@ -682,8 +682,7 @@ void nr_rlc_add_srb(int ue_id, int srb_id, const NR_RLC_BearerConfig_t *rlc_Bear int sn_field_length; LOG_D(RLC, "Trying to add SRB %d\n", srb_id); - AssertFatal(srb_id > 0 && srb_id < 4, - "Invalid srb id %d\n", srb_id); + AssertFatal(srb_id > 0 && srb_id < 4, "Invalid srb id %d\n", srb_id); if (r && r->present == NR_RLC_Config_PR_am) { struct NR_RLC_Config__am *am; diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 9086ad25eb..4bb0e8bdb3 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1684,8 +1684,13 @@ static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc, const NR_CellGroupC nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication); } else { // DRB NR_DRB_Identity_t drb_id = rlc_bearer->servedRadioBearer->choice.drb_Identity; - nr_rlc_add_drb(rrc->ue_id, drb_id, rlc_bearer); - nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication); + if (!rlc_bearer->rlc_Config) { + LOG_E(RLC, "RLC-Config not present but is mandatory for setup\n"); + rrc->active_RLC_entity[lcid] = false; + } else { + nr_rlc_add_drb(rrc->ue_id, drb_id, rlc_bearer); + nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication); + } } } } From 566da5317fad6d2c2c3d9877f87ae07ffa084cf4 Mon Sep 17 00:00:00 2001 From: francescomani Date: Sat, 8 Nov 2025 14:48:31 +0100 Subject: [PATCH 3/6] add a check for cell ID presence in handling reconfigurationWithSync --- openair2/RRC/NR_UE/rrc_UE.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 4bb0e8bdb3..818bb26be3 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1718,7 +1718,10 @@ static void nr_rrc_process_reconfigurationWithSync(NR_UE_RRC_INST_t *rrc, rrc->arfcn_ssb = *dcc->frequencyInfoDL->absoluteFrequencySSB; // consider the target SpCell to be one with a physical cell identity indicated by the physCellId - rrc->phyCellID = *reconfigurationWithSync->spCellConfigCommon->physCellId; + if (!reconfigurationWithSync->spCellConfigCommon->physCellId) + LOG_E(NR_RRC, "physCellId absent but should be mandatory present upon cell change and cell addition\n"); + else + rrc->phyCellID = *reconfigurationWithSync->spCellConfigCommon->physCellId; } NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants; From 88baba8948cc2b9b7f3c8ccc8d9f93c3d7922013 Mon Sep 17 00:00:00 2001 From: francescomani Date: Sat, 8 Nov 2025 14:52:53 +0100 Subject: [PATCH 4/6] do not handle not decoded cellGroupConfig (issue #1031) --- openair2/RRC/NR_UE/rrc_UE.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 818bb26be3..a1b8616c60 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1161,20 +1161,19 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, int gNB_ LOG_E(NR_RRC, "\n"); // free the memory SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)cellGroupConfig, 1); + } else { + if (LOG_DEBUGFLAG(DEBUG_ASN1)) + xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig); + + nr_rrc_cellgroup_configuration(rrc, cellGroupConfig, gNB_index); + AssertFatal(!IS_SA_MODE(get_softmodem_params()), "secondaryCellGroup only used in NSA for now\n"); + nr_mac_rrc_message_t rrc_msg = {0}; + rrc_msg.payload_type = NR_MAC_RRC_CONFIG_CG; + nr_mac_rrc_config_cg_t *config_cg = &rrc_msg.payload.config_cg; + config_cg->cellGroupConfig = cellGroupConfig; + config_cg->UE_NR_Capability = rrc->UECap.UE_NR_Capability; + nr_rrc_send_msg_to_mac(rrc, &rrc_msg); } - - if (LOG_DEBUGFLAG(DEBUG_ASN1)) - xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig); - - nr_rrc_cellgroup_configuration(rrc, cellGroupConfig, gNB_index); - - AssertFatal(!IS_SA_MODE(get_softmodem_params()), "secondaryCellGroup only used in NSA for now\n"); - nr_mac_rrc_message_t rrc_msg = {0}; - rrc_msg.payload_type = NR_MAC_RRC_CONFIG_CG; - nr_mac_rrc_config_cg_t *config_cg = &rrc_msg.payload.config_cg; - config_cg->cellGroupConfig = cellGroupConfig; - config_cg->UE_NR_Capability = rrc->UECap.UE_NR_Capability; - nr_rrc_send_msg_to_mac(rrc, &rrc_msg); } if (ie->measConfig) { LOG_I(NR_RRC, "RRCReconfiguration includes Measurement Configuration\n"); From 9c3c65f5c943575ada45e3b4809912678854e00b Mon Sep 17 00:00:00 2001 From: francescomani Date: Sat, 8 Nov 2025 15:00:38 +0100 Subject: [PATCH 5/6] check presence of optional nonCriticalExtension before handling (issue #1026) --- openair2/RRC/NR_UE/rrc_UE.c | 46 +++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index a1b8616c60..177ef621b3 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -826,28 +826,30 @@ static void nr_rrc_process_reconfiguration_v1530(NR_UE_RRC_INST_t *rrc, NR_RRCRe NR_RRCReconfiguration_v1540_IEs_t *rec_1540 = rec_1530->nonCriticalExtension; if (rec_1540) { NR_RRCReconfiguration_v1560_IEs_t *rec_1560 = rec_1540->nonCriticalExtension; - if (rec_1560->sk_Counter) { - // TODO perform AS security key update procedure as specified in 5.3.5.7 - LOG_E(NR_RRC, "RRCReconfiguration includes sk-Counter but this is not implemented yet\n"); - } - if (rec_1560->mrdc_SecondaryCellGroupConfig) { - // TODO perform handling of mrdc-SecondaryCellGroupConfig as specified in 5.3.5.3 - LOG_E(NR_RRC, "RRCReconfiguration includes mrdc-SecondaryCellGroupConfig but this is not handled yet\n"); - } - if (rec_1560->radioBearerConfig2) { - NR_RadioBearerConfig_t *RadioBearerConfig = NULL; - asn_dec_rval_t dec_rval = uper_decode(NULL, - &asn_DEF_NR_RadioBearerConfig, - (void **)&RadioBearerConfig, - (uint8_t *)rec_1560->radioBearerConfig2->buf, - rec_1560->radioBearerConfig2->size, - 0, - 0); - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - LOG_E(NR_RRC, "radioBearerConfig2 decode error\n"); - SEQUENCE_free(&asn_DEF_NR_RadioBearerConfig, RadioBearerConfig, 1); - } else - nr_rrc_ue_process_RadioBearerConfig(rrc, RadioBearerConfig); + if (rec_1560) { + if (rec_1560->sk_Counter) { + // TODO perform AS security key update procedure as specified in 5.3.5.7 + LOG_E(NR_RRC, "RRCReconfiguration includes sk-Counter but this is not implemented yet\n"); + } + if (rec_1560->mrdc_SecondaryCellGroupConfig) { + // TODO perform handling of mrdc-SecondaryCellGroupConfig as specified in 5.3.5.3 + LOG_E(NR_RRC, "RRCReconfiguration includes mrdc-SecondaryCellGroupConfig but this is not handled yet\n"); + } + if (rec_1560->radioBearerConfig2) { + NR_RadioBearerConfig_t *RadioBearerConfig = NULL; + asn_dec_rval_t dec_rval = uper_decode(NULL, + &asn_DEF_NR_RadioBearerConfig, + (void **)&RadioBearerConfig, + (uint8_t *)rec_1560->radioBearerConfig2->buf, + rec_1560->radioBearerConfig2->size, + 0, + 0); + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(NR_RRC, "radioBearerConfig2 decode error\n"); + SEQUENCE_free(&asn_DEF_NR_RadioBearerConfig, RadioBearerConfig, 1); + } else + nr_rrc_ue_process_RadioBearerConfig(rrc, RadioBearerConfig); + } } } } From 789564fa8eddc5da61abc3d3781938b56abf636e Mon Sep 17 00:00:00 2001 From: francescomani Date: Sat, 8 Nov 2025 15:09:58 +0100 Subject: [PATCH 6/6] add UE capability container for each element of request list (issue #1025) --- openair2/RRC/NR_UE/rrc_UE.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 177ef621b3..6b7688c19c 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -2247,13 +2247,7 @@ static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECa AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); rrc->UECap.sdu_size = (enc_rval.encoded + 7) / 8; LOG_I(PHY, "[RRC]UE NR Capability encoded, %d bytes (%zd bits)\n", rrc->UECap.sdu_size, enc_rval.encoded + 7); - /* RAT Container */ - NR_UE_CapabilityRAT_Container_t *ue_CapabilityRAT_Container = CALLOC(1, sizeof(NR_UE_CapabilityRAT_Container_t)); - ue_CapabilityRAT_Container->rat_Type = NR_RAT_Type_nr; - OCTET_STRING_fromBuf(&ue_CapabilityRAT_Container->ue_CapabilityRAT_Container, (const char *)rrc->UECap.sdu, rrc->UECap.sdu_size); NR_UECapabilityEnquiry_IEs_t *ueCapabilityEnquiry_ie = UECapabilityEnquiry->criticalExtensions.choice.ueCapabilityEnquiry; - // ue_CapabilityRAT_Container.ueCapabilityRAT_Container.buf = UE_rrc_inst[ue_mod_idP].UECapability; - // ue_CapabilityRAT_Container.ueCapabilityRAT_Container.size = UE_rrc_inst[ue_mod_idP].UECapability_size; AssertFatal(UECapabilityEnquiry->criticalExtensions.present == NR_UECapabilityEnquiry__criticalExtensions_PR_ueCapabilityEnquiry, "UECapabilityEnquiry->criticalExtensions.present (%d) != UECapabilityEnquiry__criticalExtensions_PR_c1 (%d)\n", UECapabilityEnquiry->criticalExtensions.present,NR_UECapabilityEnquiry__criticalExtensions_PR_ueCapabilityEnquiry); @@ -2266,6 +2260,10 @@ static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECa for (int i = 0; i < ueCapabilityEnquiry_ie->ue_CapabilityRAT_RequestList.list.count; i++) { if (ueCapabilityEnquiry_ie->ue_CapabilityRAT_RequestList.list.array[i]->rat_Type == NR_RAT_Type_nr) { + /* RAT Container */ + NR_UE_CapabilityRAT_Container_t *ue_CapabilityRAT_Container = CALLOC(1, sizeof(NR_UE_CapabilityRAT_Container_t)); + ue_CapabilityRAT_Container->rat_Type = NR_RAT_Type_nr; + OCTET_STRING_fromBuf(&ue_CapabilityRAT_Container->ue_CapabilityRAT_Container, (const char *)rrc->UECap.sdu, rrc->UECap.sdu_size); asn1cSeqAdd(&UEcapList->list, ue_CapabilityRAT_Container); uint8_t buffer[500]; asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, NULL, (void *)&ul_dcch_msg, buffer, 500); @@ -2279,8 +2277,7 @@ static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECa nr_pdcp_data_req_srb(rrc->ue_id, srb_id, 0, (enc_rval.encoded + 7) / 8, buffer, deliver_pdu_srb_rlc, NULL); } } - /* Free struct members after it's done - including locally allocated ue_CapabilityRAT_Container */ + /* Free struct members after it's done including locally allocated ue_CapabilityRAT_Container */ ASN_STRUCT_RESET(asn_DEF_NR_UL_DCCH_Message, &ul_dcch_msg); }