From 90c8e7dfd119ad15a05419c3f00406d6e7d828e4 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 22 Dec 2023 11:32:12 +0100 Subject: [PATCH] improvements in UE detachment, including sending a message from NAS and signaling to MAC and fixing some memory leaks when terminating UE --- openair2/COMMON/as_message.h | 4 + openair2/COMMON/rrc_messages_def.h | 1 + openair2/COMMON/rrc_messages_types.h | 2 + openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 50 +++++----- openair2/LAYER2/NR_MAC_UE/config_ue.c | 35 +++++-- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 1 + openair2/LAYER2/NR_MAC_UE/main_ue_nr.c | 1 + .../NR_MAC_UE/nr_ue_dci_configuration.c | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 9 +- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 2 +- openair2/RRC/NR/MESSAGES/asn1_msg.c | 68 +++++++------- openair2/RRC/NR_UE/rrc_UE.c | 92 +++++++++---------- openair2/RRC/NR_UE/rrc_defs.h | 4 +- openair3/NAS/NR_UE/nr_nas_msg_sim.c | 18 +++- 14 files changed, 165 insertions(+), 124 deletions(-) diff --git a/openair2/COMMON/as_message.h b/openair2/COMMON/as_message.h index 4973939976..180b580916 100644 --- a/openair2/COMMON/as_message.h +++ b/openair2/COMMON/as_message.h @@ -401,6 +401,10 @@ typedef struct nas_deregistration_req_s { release_cause_t cause; } nas_deregistration_req_t; +typedef struct nas_detach_req_s { + bool wait_release; +} nas_detach_req_t; + /* * -------------------------------------------------------------------------- * NAS information transfer diff --git a/openair2/COMMON/rrc_messages_def.h b/openair2/COMMON/rrc_messages_def.h index f43d7a8dc5..355b8b3e90 100644 --- a/openair2/COMMON/rrc_messages_def.h +++ b/openair2/COMMON/rrc_messages_def.h @@ -61,6 +61,7 @@ MESSAGE_DEF(NAS_KENB_REFRESH_REQ, MESSAGE_PRIORITY_MED, NasKenbRefre MESSAGE_DEF(NAS_CELL_SELECTION_REQ, MESSAGE_PRIORITY_MED, NasCellSelectionReq, nas_cell_selection_req) MESSAGE_DEF(NAS_CONN_ESTABLI_REQ, MESSAGE_PRIORITY_MED, NasConnEstabliReq, nas_conn_establi_req) MESSAGE_DEF(NAS_UPLINK_DATA_REQ, MESSAGE_PRIORITY_MED, NasUlDataReq, nas_ul_data_req) +MESSAGE_DEF(NAS_DETACH_REQ, MESSAGE_PRIORITY_MED, NasDetachReq, nas_detach_req) MESSAGE_DEF(NAS_DEREGISTRATION_REQ, MESSAGE_PRIORITY_MED, NasDeregistrationReq, nas_deregistration_req) MESSAGE_DEF(NAS_RAB_ESTABLI_RSP, MESSAGE_PRIORITY_MED, NasRabEstRsp, nas_rab_est_rsp) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 8fc3a8514a..ccc2d9f030 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -74,6 +74,7 @@ #define NAS_CELL_SELECTION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_cell_selection_req #define NAS_CONN_ESTABLI_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_conn_establi_req #define NAS_UPLINK_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_data_req +#define NAS_DETACH_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_detach_req #define NAS_DEREGISTRATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_deregistration_req #define NAS_RAB_ESTABLI_RSP(mSGpTR) (mSGpTR)->ittiMsg.nas_rab_est_rsp @@ -429,6 +430,7 @@ typedef cell_info_req_t NasCellSelectionReq; typedef nas_establish_req_t NasConnEstabliReq; typedef ul_info_transfer_req_t NasUlDataReq; typedef nas_deregistration_req_t NasDeregistrationReq; +typedef nas_detach_req_t NasDetachReq; typedef rab_establish_rsp_t NasRabEstRsp; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 018cfcb406..1080ee7faa 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -4431,20 +4431,18 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD type0_PDCCH_CSS_config->cset_start_rb = ssb_offset_point_a - type0_PDCCH_CSS_config->rb_offset; } -void fill_coresetZero(NR_ControlResourceSet_t *coreset0, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config) { - - int32_t duration; - +void fill_coresetZero(NR_ControlResourceSet_t *coreset0, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config) +{ if (coreset0 == NULL) coreset0 = calloc(1,sizeof(*coreset0)); - coreset0->controlResourceSetId = 0; - AssertFatal(type0_PDCCH_CSS_config!=NULL,"No type0 CSS configuration\n"); - duration = type0_PDCCH_CSS_config->num_symbols; + coreset0->controlResourceSetId = 0; + int duration = type0_PDCCH_CSS_config->num_symbols; - if(coreset0->frequencyDomainResources.buf == NULL) coreset0->frequencyDomainResources.buf = calloc(1,6); + if(coreset0->frequencyDomainResources.buf == NULL) + coreset0->frequencyDomainResources.buf = calloc(1,6); switch(type0_PDCCH_CSS_config->num_rbs){ case 24: @@ -4470,8 +4468,9 @@ void fill_coresetZero(NR_ControlResourceSet_t *coreset0, NR_Type0_PDCCH_CSS_conf coreset0->frequencyDomainResources.bits_unused = 3; coreset0->duration = duration; - coreset0->cce_REG_MappingType.present=NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved; - coreset0->cce_REG_MappingType.choice.interleaved=calloc(1,sizeof(*coreset0->cce_REG_MappingType.choice.interleaved)); + coreset0->cce_REG_MappingType.present = NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved; + if (!coreset0->cce_REG_MappingType.choice.interleaved) + coreset0->cce_REG_MappingType.choice.interleaved = calloc(1,sizeof(*coreset0->cce_REG_MappingType.choice.interleaved)); coreset0->cce_REG_MappingType.choice.interleaved->reg_BundleSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6; coreset0->cce_REG_MappingType.choice.interleaved->interleaverSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n2; coreset0->cce_REG_MappingType.choice.interleaved->shiftIndex = NULL; // -> use cell_id @@ -4481,23 +4480,28 @@ void fill_coresetZero(NR_ControlResourceSet_t *coreset0, NR_Type0_PDCCH_CSS_conf coreset0->tci_StatesPDCCH_ToReleaseList = NULL; coreset0->tci_PresentInDCI = NULL; coreset0->pdcch_DMRS_ScramblingID = NULL; - } void fill_searchSpaceZero(NR_SearchSpace_t *ss0, int slots_per_frame, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config) { - - if(ss0 == NULL) ss0=calloc(1,sizeof(*ss0)); - if(ss0->controlResourceSetId == NULL) ss0->controlResourceSetId=calloc(1,sizeof(*ss0->controlResourceSetId)); - if(ss0->monitoringSymbolsWithinSlot == NULL) ss0->monitoringSymbolsWithinSlot = calloc(1,sizeof(*ss0->monitoringSymbolsWithinSlot)); - if(ss0->monitoringSymbolsWithinSlot->buf == NULL) ss0->monitoringSymbolsWithinSlot->buf = calloc(1,2); - if(ss0->nrofCandidates == NULL) ss0->nrofCandidates = calloc(1,sizeof(*ss0->nrofCandidates)); - if(ss0->searchSpaceType == NULL) ss0->searchSpaceType = calloc(1,sizeof(*ss0->searchSpaceType)); - if(ss0->searchSpaceType->choice.common == NULL) ss0->searchSpaceType->choice.common=calloc(1,sizeof(*ss0->searchSpaceType->choice.common)); + if(ss0 == NULL) + ss0 = calloc(1, sizeof(*ss0)); + if(ss0->controlResourceSetId == NULL) + ss0->controlResourceSetId = calloc(1, sizeof(*ss0->controlResourceSetId)); + if(ss0->monitoringSymbolsWithinSlot == NULL) + ss0->monitoringSymbolsWithinSlot = calloc(1, sizeof(*ss0->monitoringSymbolsWithinSlot)); + if(ss0->monitoringSymbolsWithinSlot->buf == NULL) + ss0->monitoringSymbolsWithinSlot->buf = calloc(1, 2); + if(ss0->nrofCandidates == NULL) + ss0->nrofCandidates = calloc(1, sizeof(*ss0->nrofCandidates)); + if(ss0->searchSpaceType == NULL) + ss0->searchSpaceType = calloc(1, sizeof(*ss0->searchSpaceType)); + if(ss0->searchSpaceType->choice.common == NULL) + ss0->searchSpaceType->choice.common = calloc(1, sizeof(*ss0->searchSpaceType->choice.common)); if(ss0->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 == NULL) - ss0->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 = calloc(1,sizeof(*ss0->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0)); + ss0->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 = calloc(1, sizeof(*ss0->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0)); AssertFatal(type0_PDCCH_CSS_config!=NULL,"No type0 CSS configuration\n"); @@ -4508,13 +4512,15 @@ void fill_searchSpaceZero(NR_SearchSpace_t *ss0, ss0->searchSpaceId = 0; *ss0->controlResourceSetId = 0; - ss0->monitoringSlotPeriodicityAndOffset = calloc(1,sizeof(*ss0->monitoringSlotPeriodicityAndOffset)); + if(ss0->monitoringSlotPeriodicityAndOffset == NULL) + ss0->monitoringSlotPeriodicityAndOffset = calloc(1, sizeof(*ss0->monitoringSlotPeriodicityAndOffset)); set_monitoring_periodicity_offset(ss0,periodicity,offset); const uint32_t duration = type0_PDCCH_CSS_config->search_space_duration; if (duration==1) ss0->duration = NULL; else{ - ss0->duration = calloc(1,sizeof(*ss0->duration)); + if (!ss0->duration) + ss0->duration = calloc(1, sizeof(*ss0->duration)); *ss0->duration = duration; } diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 146e7a6f4f..7e7da9c4f8 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -795,6 +795,22 @@ void ue_init_config_request(NR_UE_MAC_INST_t *mac, int scs) pthread_mutex_init(&(mac->ul_config_request[i].mutex_ul_config), NULL); } +static void update_mib_conf(NR_MIB_t *target, NR_MIB_t *source) +{ + target->systemFrameNumber.size = source->systemFrameNumber.size; + target->systemFrameNumber.bits_unused = source->systemFrameNumber.bits_unused; + if (!target->systemFrameNumber.buf) + target->systemFrameNumber.buf = calloc(target->systemFrameNumber.size, sizeof(*target->systemFrameNumber.buf)); + for (int i = 0; i < target->systemFrameNumber.size; i++) + target->systemFrameNumber.buf[i] = source->systemFrameNumber.buf[i]; + target->subCarrierSpacingCommon = source->subCarrierSpacingCommon; + target->ssb_SubcarrierOffset = source->ssb_SubcarrierOffset; + target->dmrs_TypeA_Position = source->dmrs_TypeA_Position; + target->pdcch_ConfigSIB1 = source->pdcch_ConfigSIB1; + target->cellBarred = source->cellBarred; + target->intraFreqReselection = source->intraFreqReselection; +} + void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mib, @@ -802,16 +818,16 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id, { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); AssertFatal(mib, "MIB should not be NULL\n"); - // initialize dl and ul config_request upon first reception of MIB - mac->mib = mib; // update by every reception + if (!mac->mib) + mac->mib = calloc(1, sizeof(*mac->mib)); + update_mib_conf(mac->mib, mib); mac->phy_config.Mod_id = module_id; mac->phy_config.CC_id = cc_idP; if (sched_sib == 1) mac->get_sib1 = true; else if (sched_sib == 2) mac->get_otherSI = true; - nr_ue_decode_mib(module_id, - cc_idP); + nr_ue_decode_mib(module_id, cc_idP); } static void setup_puschpowercontrol(NR_PUSCH_PowerControl_t *source, NR_PUSCH_PowerControl_t *target) @@ -1365,11 +1381,12 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, // Sending to PHY a request to resync // with no target cell ID - mac->synch_request.Mod_id = module_id; - mac->synch_request.CC_id = 0; - mac->synch_request.synch_req.target_Nid_cell = -1; - mac->if_module->synch_request(&mac->synch_request); - + if (reset_cause != DETACH) { + mac->synch_request.Mod_id = module_id; + mac->synch_request.CC_id = 0; + mac->synch_request.synch_req.target_Nid_cell = -1; + mac->if_module->synch_request(&mac->synch_request); + } } void nr_rrc_mac_config_req_sib1(module_id_t module_id, diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index d92e0c4fa7..0cf1d6da82 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -167,6 +167,7 @@ typedef enum { typedef enum { GO_TO_IDLE, + DETACH, RE_ESTABLISHMENT } NR_UE_MAC_reset_cause_t; diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 0131551ed2..6ae2df12eb 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -198,6 +198,7 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac) free(sc->nrofHARQ_ProcessesForPDSCH); free(sc->rateMatching_PUSCH); free(sc->xOverhead_PUSCH); + free(sc->maxMIMO_Layers_PDSCH); free(sc->maxMIMO_Layers_PUSCH); memset(&mac->sc_info, 0, sizeof(mac->sc_info)); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index 075afc2bd9..1bd991f7c5 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -263,7 +263,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, case NR_RNTI_SP_CSI: break; case NR_RNTI_SI: - sps=14; + sps = 14; // for SPS=14 8 MSBs in positions 13 down to 6 monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); rel15->rnti = SI_RNTI; // SI-RNTI - 3GPP TS 38.321 Table 7.1-1: RNTI values diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 91cc805d22..9118fce36a 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2352,8 +2352,7 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, frame_t frame, int slot) { NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; - NR_PUCCH_Config_t *pucch_Config = current_UL_BWP->pucch_Config; - const int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs]; + NR_PUCCH_Config_t *pucch_Config = current_UL_BWP ? current_UL_BWP->pucch_Config : NULL; if(!pucch_Config || !pucch_Config->schedulingRequestResourceToAddModList || @@ -2366,6 +2365,7 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *p int SR_period; int SR_offset; find_period_offset_SR(SchedulingRequestResourceConfig,&SR_period,&SR_offset); + const int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs]; int sfn_sf = frame * n_slots_frame + slot; if ((sfn_sf - SR_offset) % SR_period == 0) { @@ -2454,8 +2454,7 @@ int compute_csi_priority(NR_UE_MAC_INST_t *mac, NR_CSI_ReportConfig_t *csirep) int nr_get_csi_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sched_t *pucch) { NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; - NR_BWP_Id_t bwp_id = current_UL_BWP->bwp_id; - NR_PUCCH_Config_t *pucch_Config = current_UL_BWP->pucch_Config; + NR_PUCCH_Config_t *pucch_Config = current_UL_BWP ? current_UL_BWP->pucch_Config : NULL; int num_csi = 0; if (mac->sc_info.csi_MeasConfig) { @@ -2476,7 +2475,7 @@ int nr_get_csi_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCC for (int i = 0; i < csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.count; i++) { const NR_PUCCH_CSI_Resource_t *pucchcsires = csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.array[i]; - if (pucchcsires->uplinkBandwidthPartId == bwp_id) { + if (pucchcsires->uplinkBandwidthPartId == current_UL_BWP->bwp_id) { csi_res_id = pucchcsires->pucch_Resource; break; } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 8107f97abc..75e959f6cc 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -885,7 +885,7 @@ bool nr_ue_periodic_srs_scheduling(module_id_t mod_id, frame_t frame, slot_t slo NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; - NR_SRS_Config_t *srs_config = current_UL_BWP->srs_Config; + NR_SRS_Config_t *srs_config = current_UL_BWP ? current_UL_BWP->srs_Config : NULL; if (!srs_config) { return false; diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index f5e060e251..4a1295af9e 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -877,55 +877,57 @@ uint8_t do_NR_RRCReconfigurationComplete(uint8_t *buffer, size_t buffer_size, co return((enc_rval.encoded+7)/8); } -uint8_t do_RRCSetupComplete(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, - const uint8_t Transaction_id, uint8_t sel_plmn_id, const int dedicatedInfoNASLength, const char *dedicatedInfoNAS){ - asn_enc_rval_t enc_rval; - - NR_UL_DCCH_Message_t ul_dcch_msg; - NR_RRCSetupComplete_t *RrcSetupComplete; - memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t)); - - uint8_t buf[6]; +uint8_t do_RRCSetupComplete(uint8_t Mod_id, + uint8_t *buffer, + size_t buffer_size, + const uint8_t Transaction_id, + uint8_t sel_plmn_id, + const int dedicatedInfoNASLength, + const char *dedicatedInfoNAS) +{ + NR_UL_DCCH_Message_t ul_dcch_msg = {0}; ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1; ul_dcch_msg.message.choice.c1 = CALLOC(1,sizeof(struct NR_UL_DCCH_MessageType__c1)); ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_rrcSetupComplete; ul_dcch_msg.message.choice.c1->choice.rrcSetupComplete = CALLOC(1, sizeof(NR_RRCSetupComplete_t)); - RrcSetupComplete = ul_dcch_msg.message.choice.c1->choice.rrcSetupComplete; - RrcSetupComplete->rrc_TransactionIdentifier = Transaction_id; - RrcSetupComplete->criticalExtensions.present = NR_RRCSetupComplete__criticalExtensions_PR_rrcSetupComplete; + NR_RRCSetupComplete_t *RrcSetupComplete = ul_dcch_msg.message.choice.c1->choice.rrcSetupComplete; + RrcSetupComplete->rrc_TransactionIdentifier = Transaction_id; + RrcSetupComplete->criticalExtensions.present = NR_RRCSetupComplete__criticalExtensions_PR_rrcSetupComplete; RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete = CALLOC(1, sizeof(NR_RRCSetupComplete_IEs_t)); - // RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->nonCriticalExtension = CALLOC(1, - // sizeof(*RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->nonCriticalExtension)); - RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->selectedPLMN_Identity = sel_plmn_id; - RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->registeredAMF = NULL; + NR_RRCSetupComplete_IEs_t *ies = RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete; + ies->selectedPLMN_Identity = sel_plmn_id; + ies->registeredAMF = NULL; - RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value = CALLOC(1, sizeof(struct NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value)); - RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->present = NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI; - RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size = 6; - RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf = buf; - RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[0] = 0x12; - RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[1] = 0x34; - RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[2] = 0x56; - RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[3] = 0x78; - RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[4] = 0x9A; - RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[5] = 0xBC; + ies->ng_5G_S_TMSI_Value = CALLOC(1, sizeof(struct NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value)); + ies->ng_5G_S_TMSI_Value->present = NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI; + NR_NG_5G_S_TMSI_t *stmsi = &ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI; + stmsi->size = 6; + stmsi->buf = calloc(stmsi->size, sizeof(*stmsi->buf)); + AssertFatal(stmsi->buf != NULL, "out of memory\n"); + stmsi->buf[0] = 0x12; + stmsi->buf[1] = 0x34; + stmsi->buf[2] = 0x56; + stmsi->buf[3] = 0x78; + stmsi->buf[4] = 0x9A; + stmsi->buf[5] = 0xBC; - memset(&RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->dedicatedNAS_Message,0,sizeof(OCTET_STRING_t)); - OCTET_STRING_fromBuf(&RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->dedicatedNAS_Message,dedicatedInfoNAS,dedicatedInfoNASLength); + memset(&ies->dedicatedNAS_Message,0,sizeof(OCTET_STRING_t)); + OCTET_STRING_fromBuf(&ies->dedicatedNAS_Message, dedicatedInfoNAS, dedicatedInfoNASLength); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg); } - enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, - NULL, - (void *)&ul_dcch_msg, - buffer, - buffer_size); + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, + NULL, + (void *)&ul_dcch_msg, + buffer, + buffer_size); AssertFatal(enc_rval.encoded > 0,"ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name,enc_rval.encoded); LOG_D(NR_RRC,"RRCSetupComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_UL_DCCH_Message, &ul_dcch_msg); return((enc_rval.encoded+7)/8); } diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 98f67918d3..4991149d85 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -229,12 +229,8 @@ static void nr_rrc_ue_process_rrcReconfiguration(const instance_t instance, } if (ie->measConfig != NULL) { LOG_I(NR_RRC, "Measurement Configuration is present\n"); - if (rrc->meas_config == NULL) { - rrc->meas_config = ie->measConfig; - } else { - // if some element need to be updated - nr_rrc_ue_process_measConfig(rrcNB, ie->measConfig); - } + // if some element need to be updated + nr_rrc_ue_process_measConfig(rrcNB, ie->measConfig); } if (ie->lateNonCriticalExtension != NULL) { // unuse now @@ -447,13 +443,14 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(const instance_t instance, } int get_sib = 0; - if (get_softmodem_params()->sa && bcch_message->message.choice.mib->cellBarred == NR_MIB__cellBarred_notBarred) { + if (get_softmodem_params()->sa && + bcch_message->message.choice.mib->cellBarred == NR_MIB__cellBarred_notBarred && + NR_UE_rrc_inst[instance].nrRrcState != RRC_STATE_DETACH_NR) { NR_UE_RRC_SI_INFO *SI_info = &NR_UE_rrc_inst[instance].perNB[gNB_index].SInfo; // to schedule MAC to get SI if required get_sib = check_si_status(SI_info); } nr_rrc_mac_config_req_mib(instance, 0, bcch_message->message.choice.mib, get_sib); - bcch_message->message.choice.mib = NULL; ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, bcch_message); return; } @@ -809,10 +806,6 @@ void nr_rrc_cellgroup_configuration(rrcPerNB_t *rrcNB, } } - if(cellGroupConfig->mac_CellGroupConfig != NULL) { - // TODO handle MAC CellGroupConfig - } - // TODO verify why we need this limitation if (get_softmodem_params()->sa || get_softmodem_params()->nsa) nr_rrc_manage_rlc_bearers(instance, cellGroupConfig, rrcNB, rrc->rnti); @@ -843,9 +836,7 @@ static void nr_rrc_ue_process_masterCellGroup(instance_t instance, xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig); } - nr_rrc_cellgroup_configuration(rrcNB, - instance, - cellGroupConfig); + nr_rrc_cellgroup_configuration(rrcNB, instance, cellGroupConfig); LOG_D(RRC,"Sending CellGroupConfig to MAC\n"); nr_rrc_mac_config_req_cg(instance, 0, cellGroupConfig); @@ -884,7 +875,7 @@ static int8_t nr_rrc_ue_decode_ccch(const instance_t instance, { NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[instance]; - NR_DL_CCCH_Message_t *dl_ccch_msg=NULL; + NR_DL_CCCH_Message_t *dl_ccch_msg = NULL; asn_dec_rval_t dec_rval; int rval=0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN); @@ -920,22 +911,21 @@ static int8_t nr_rrc_ue_decode_ccch(const instance_t instance, // Release T300 timer rrc->timers_and_constants.T300_active = 0; rrc->rnti = rnti; - nr_rrc_ue_process_masterCellGroup( - instance, - rnti, - rrc->perNB + gNB_index, - &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup, - NULL); - nr_rrc_ue_process_RadioBearerConfig( - rrc, - rnti, - rrc->perNB + gNB_index, - &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig); + NR_RRCSetup_t *rrcSetup = dl_ccch_msg->message.choice.c1->choice.rrcSetup; + nr_rrc_ue_process_masterCellGroup(instance, + rnti, + rrc->perNB + gNB_index, + &rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup, + NULL); + nr_rrc_ue_process_RadioBearerConfig(rrc, + rnti, + rrc->perNB + gNB_index, + &rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig); rrc->nrRrcState = RRC_STATE_CONNECTED_NR; rrc_ue_generate_RRCSetupComplete(instance, rnti, - dl_ccch_msg->message.choice.c1->choice.rrcSetup->rrc_TransactionIdentifier, + rrcSetup->rrc_TransactionIdentifier, rrc->selected_plmn_identity); rval = 0; break; @@ -947,6 +937,7 @@ static int8_t nr_rrc_ue_decode_ccch(const instance_t instance, } } + ASN_STRUCT_FREE(asn_DEF_NR_DL_CCCH_Message, dl_ccch_msg); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT); return rval; } @@ -1418,24 +1409,24 @@ void *rrc_nrue(void *notUsed) itti_receive_msg(TASK_RRC_NRUE, &msg_p); instance_t instance = ITTI_MSG_DESTINATION_INSTANCE(msg_p); NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[instance]; - + LOG_D(NR_RRC, "[UE %ld] Received %s\n", instance, ITTI_MSG_NAME(msg_p)); - + switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: LOG_W(NR_RRC, " *** Exiting RRC thread\n"); itti_exit_task(); break; - + case MESSAGE_TEST: break; - + case NR_RRC_MAC_SYNC_IND: { nr_sync_msg_t sync_msg = NR_RRC_MAC_SYNC_IND(msg_p).in_sync ? IN_SYNC : OUT_OF_SYNC; NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants; handle_rlf_sync(tac, sync_msg); } break; - + case NRRRC_FRAME_PROCESS: LOG_D(NR_RRC, "Received %s: frame %d\n", ITTI_MSG_NAME(msg_p), NRRRC_FRAME_PROCESS(msg_p).frame); // increase the timers every 10ms (every new frame) @@ -1444,11 +1435,11 @@ void *rrc_nrue(void *notUsed) NR_UE_RRC_SI_INFO *SInfo = &NR_UE_rrc_inst[instance].perNB[NRRRC_FRAME_PROCESS(msg_p).gnb_id].SInfo; nr_rrc_SI_timers(SInfo); break; - + case NR_RRC_MAC_MSG3_IND: nr_rrc_ue_generate_ra_msg(instance, INITIAL_ACCESS_FROM_RRC_IDLE, NR_RRC_MAC_MSG3_IND(msg_p).rnti); break; - + case NR_RRC_MAC_RA_IND: LOG_D(NR_RRC, "[UE %ld] Received %s: frame %d RA %s\n", @@ -1458,7 +1449,7 @@ void *rrc_nrue(void *notUsed) NR_RRC_MAC_RA_IND(msg_p).RA_succeeded ? "successful" : "failed"); nr_rrc_handle_ra_indication(rrc, NR_RRC_MAC_RA_IND(msg_p).RA_succeeded); break; - + case NR_RRC_MAC_BCCH_DATA_IND: LOG_D(NR_RRC, "[UE %ld] Received %s: gNB %d\n", instance, ITTI_MSG_NAME(msg_p), NR_RRC_MAC_BCCH_DATA_IND(msg_p).gnb_index); NRRrcMacBcchDataInd *bcch = &NR_RRC_MAC_BCCH_DATA_IND(msg_p); @@ -1467,13 +1458,12 @@ void *rrc_nrue(void *notUsed) else nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(instance, bcch->gnb_index, bcch->sdu, bcch->sdu_size, bcch->rsrq, bcch->rsrp); break; - + case NR_RRC_MAC_CCCH_DATA_IND: { NRRrcMacCcchDataInd *ind = &NR_RRC_MAC_CCCH_DATA_IND(msg_p); nr_rrc_ue_decode_ccch(instance, ind->rnti, ind, 0); } break; - - /* PDCP messages */ + case NR_RRC_DCCH_DATA_IND: nr_rrc_ue_decode_dcch(instance, NR_RRC_DCCH_DATA_IND(msg_p).rnti, @@ -1482,11 +1472,19 @@ void *rrc_nrue(void *notUsed) NR_RRC_DCCH_DATA_IND(msg_p).sdu_size, NR_RRC_DCCH_DATA_IND(msg_p).gNB_index); break; - + case NAS_KENB_REFRESH_REQ: memcpy(rrc->kgnb, NAS_KENB_REFRESH_REQ(msg_p).kenb, sizeof(rrc->kgnb)); break; - + + case NAS_DETACH_REQ: + if (!NAS_DETACH_REQ(msg_p).wait_release) { + rrc->nrRrcState = RRC_STATE_DETACH_NR; + NR_Release_Cause_t release_cause = OTHER; + nr_rrc_going_to_IDLE(instance, release_cause, NULL); + } + break; + case NAS_UPLINK_DATA_REQ: { uint32_t length; uint8_t *buffer; @@ -1500,7 +1498,7 @@ void *rrc_nrue(void *notUsed) nr_pdcp_data_req_srb(rrc->rnti, srb_id, 0, length, buffer, deliver_pdu_srb_rlc, NULL); break; } - + default: LOG_E(NR_RRC, "[UE %ld] Received unexpected message %s\n", instance, ITTI_MSG_NAME(msg_p)); break; @@ -1915,9 +1913,6 @@ void nr_rrc_going_to_IDLE(instance_t instance, } } - asn1cFreeStruc(asn_DEF_NR_MeasConfig, rrc->meas_config); - rrc->meas_config = NULL; - for (int i = 0; i < NB_CNX_UE; i++) { rrcPerNB_t *nb = &rrc->perNB[i]; NR_UE_RRC_SI_INFO *SI_info = &nb->SInfo; @@ -1938,11 +1933,14 @@ void nr_rrc_going_to_IDLE(instance_t instance, } // reset MAC - NR_UE_MAC_reset_cause_t cause = GO_TO_IDLE; + NR_UE_MAC_reset_cause_t cause = (rrc->nrRrcState == RRC_STATE_DETACH_NR) ? DETACH : GO_TO_IDLE; nr_rrc_mac_config_req_reset(instance, cause); // enter RRC_IDLE - rrc->nrRrcState = RRC_STATE_IDLE_NR; + LOG_I(NR_RRC, "RRC moved into IDLE state\n"); + if (rrc->nrRrcState != RRC_STATE_DETACH_NR) + rrc->nrRrcState = RRC_STATE_IDLE_NR; + rrc->rnti = 0; // Indicate the release of the RRC connection to upper layers diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index 4266716799..768d4caf1a 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -83,7 +83,7 @@ typedef enum Rrc_State_NR_e { RRC_STATE_IDLE_NR = 0, RRC_STATE_INACTIVE_NR, RRC_STATE_CONNECTED_NR, - + RRC_STATE_DETACH_NR, RRC_STATE_FIRST_NR = RRC_STATE_IDLE_NR, RRC_STATE_LAST_NR = RRC_STATE_CONNECTED_NR, } Rrc_State_NR_t; @@ -206,8 +206,6 @@ typedef struct rrcPerNB { } rrcPerNB_t; typedef struct NR_UE_RRC_INST_s { - NR_MeasConfig_t *meas_config; - rrcPerNB_t perNB[NB_CNX_UE]; char *uecap_file; diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index 4b7c4cc45c..26e5eb6f25 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -911,6 +911,14 @@ static void send_nas_uplink_data_req(instance_t instance, const as_nas_info_t *i itti_send_msg_to_task(TASK_RRC_NRUE, instance, msg); } +static void send_nas_detach_req(instance_t instance, bool wait_release) +{ + MessageDef *msg = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_DETACH_REQ); + nas_detach_req_t *req = &NAS_DETACH_REQ(msg); + req->wait_release = wait_release; + itti_send_msg_to_task(TASK_RRC_NRUE, instance, msg); +} + static void parse_allowed_nssai(nr_nas_msg_snssai_t nssaiList[8], const uint8_t *buf, const uint32_t len) { int nssai_cnt = 0; @@ -1165,15 +1173,19 @@ void *nas_nrue(void *args_p) case NAS_DEREGISTRATION_REQ: { LOG_I(NAS, "[UE %ld] Received %s\n", instance, ITTI_MSG_NAME(msg_p)); nr_ue_nas_t *nas = get_ue_nas_info(0); + nas_deregistration_req_t *req = &NAS_DEREGISTRATION_REQ(msg_p); if (nas->guti) { - nas_deregistration_req_t *req = &NAS_DEREGISTRATION_REQ(msg_p); - if (req->cause == AS_DETACH) + if (req->cause == AS_DETACH) { nas->termination_procedure = true; + send_nas_detach_req(instance, true); + } as_nas_info_t initialNasMsg = {0}; generateDeregistrationRequest(nas, &initialNasMsg, req); send_nas_uplink_data_req(instance, &initialNasMsg); } else { - LOG_E(NAS, "no GUTI, cannot trigger deregistration request\n"); + LOG_W(NAS, "No GUTI, cannot trigger deregistration request.\n"); + if (req->cause == AS_DETACH) + send_nas_detach_req(instance, false); } } break;