diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 3a5532af43..753738923f 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -402,6 +402,7 @@ static void trigger_deregistration(int sig) { if (!stop_immediately) { MessageDef *msg = itti_alloc_new_message(TASK_RRC_UE_SIM, 0, NAS_DEREGISTRATION_REQ); + NAS_DEREGISTRATION_REQ(msg).cause = AS_DETACH; itti_send_msg_to_task(TASK_NAS_NRUE, 0, msg); stop_immediately = true; static const char m[] = "Press ^C again to trigger immediate shutdown\n"; diff --git a/openair2/COMMON/as_message.h b/openair2/COMMON/as_message.h index c4724b5458..4973939976 100644 --- a/openair2/COMMON/as_message.h +++ b/openair2/COMMON/as_message.h @@ -327,15 +327,6 @@ typedef struct nas_establish_req_s { as_nas_info_t initialNasMsg; /* Initial NAS message to transfer */ } nas_establish_req_t; -/* - * fill me - */ -typedef struct nas_deregistration_req_s { - // This dummy element is to avoid CLANG warning: empty struct has size 0 in C, size 1 in C++ - // To be removed if the structure is filled - uint32_t dummy; -} nas_deregistration_req_t; - /* * AS->NAS - NAS signalling connection establishment indication * AS transfers the initial NAS message to the NAS. @@ -406,6 +397,10 @@ typedef struct nas_release_ind_s { release_cause_t cause; /* Release cause */ } nas_release_ind_t; +typedef struct nas_deregistration_req_s { + release_cause_t cause; +} nas_deregistration_req_t; + /* * -------------------------------------------------------------------------- * NAS information transfer diff --git a/openair2/COMMON/rrc_messages_def.h b/openair2/COMMON/rrc_messages_def.h index e1e9fce355..f43d7a8dc5 100644 --- a/openair2/COMMON/rrc_messages_def.h +++ b/openair2/COMMON/rrc_messages_def.h @@ -73,6 +73,7 @@ MESSAGE_DEF(NAS_CELL_SELECTION_IND, MESSAGE_PRIORITY_MED, NasCellSelec MESSAGE_DEF(NAS_PAGING_IND, MESSAGE_PRIORITY_MED, NasPagingInd, nas_paging_ind) MESSAGE_DEF(NAS_CONN_ESTABLI_CNF, MESSAGE_PRIORITY_MED, NasConnEstabCnf, nas_conn_establi_cnf) MESSAGE_DEF(NAS_CONN_RELEASE_IND, MESSAGE_PRIORITY_MED, NasConnReleaseInd, nas_conn_release_ind) +MESSAGE_DEF(NR_NAS_CONN_RELEASE_IND, MESSAGE_PRIORITY_MED, NRNasConnReleaseInd, nr_nas_conn_release_ind) MESSAGE_DEF(NAS_UPLINK_DATA_CNF, MESSAGE_PRIORITY_MED, NasUlDataCnf, nas_ul_data_cnf) MESSAGE_DEF(NAS_DOWNLINK_DATA_IND, MESSAGE_PRIORITY_MED, NasDlDataInd, nas_dl_data_ind) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 2810dcfdd6..b57db907d7 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -82,6 +82,7 @@ #define NAS_PAGING_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_paging_ind #define NAS_CONN_ESTABLI_CNF(mSGpTR) (mSGpTR)->ittiMsg.nas_conn_establi_cnf #define NAS_CONN_RELEASE_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_conn_release_ind +#define NR_NAS_CONN_RELEASE_IND(mSGpTR) (mSGpTR)->ittiMsg.nr_nas_conn_release_ind #define NAS_UPLINK_DATA_CNF(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_data_cnf #define NAS_DOWNLINK_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_data_ind @@ -452,6 +453,16 @@ typedef struct nrrrc_frame_process_s { int gnb_id; } NRRrcFrameProcess; +typedef enum NR_Release_Cause_e { + RRC_CONNECTION_FAILURE, + RRC_RESUME_FAILURE, + OTHER, +} NR_Release_Cause_t; + +typedef struct nr_nas_conn_release_ind { + NR_Release_Cause_t cause; +} NRNasConnReleaseInd; + // eNB: RLC -> RRC messages typedef struct rlc_sdu_indication_s { int rnti; diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 258510c29c..84e5de5099 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1334,19 +1334,13 @@ static int nr_rrc_ue_decode_dcch(instance_t instance, case NR_DL_DCCH_MessageType__c1_PR_rrcResume: LOG_I(NR_RRC, "Received rrcResume on DL-DCCH-Message\n"); break; - case NR_DL_DCCH_MessageType__c1_PR_rrcRelease: { - struct NR_RRCRelease__criticalExtensions *ext = &c1->choice.rrcRelease->criticalExtensions; - LOG_I(NR_RRC, "Received RRC Release (gNB %d)\n", gNB_indexP); - MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_RELEASE_IND); - // FixMe: this code do nothing !!!! - if (ext->present == NR_RRCRelease__criticalExtensions_PR_rrcRelease) { - ext->choice.rrcRelease->deprioritisationReq->deprioritisationTimer = - NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min5; - ext->choice.rrcRelease->deprioritisationReq->deprioritisationType = - NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency; - } - itti_send_msg_to_task(TASK_NAS_NRUE, instance, msg_p); - } break; + case NR_DL_DCCH_MessageType__c1_PR_rrcRelease: + LOG_I(NR_RRC, "[UE %ld] Received RRC Release (gNB %d)\n", + instance, gNB_indexP); + // TODO properly implement procedures in 5.3.8.3 of 38.331 + NR_Release_Cause_t cause = OTHER; + nr_rrc_going_to_IDLE(instance, cause, dl_dcch_msg->message.choice.c1->choice.rrcRelease); + break; case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry: LOG_I(NR_RRC, "Received Capability Enquiry (gNB %d)\n", gNB_indexP); @@ -1847,6 +1841,7 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l } void nr_rrc_going_to_IDLE(instance_t instance, + NR_Release_Cause_t release_cause, NR_RRCRelease_t *RRCRelease) { NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[instance]; @@ -1867,9 +1862,8 @@ void nr_rrc_going_to_IDLE(instance_t instance, // start timer T302 with the value set to the waitTime tac->T302_active = true; tac->T302_k = *waitTime * 1000; // waitTime is in seconds - // inform upper layers that access barring is applicable + // TODO inform upper layers that access barring is applicable // for all access categories except categories '0' and '2'. - // TODO no idea what that means LOG_E(NR_RRC,"Go to IDLE. Handling RRCRelease message including a waitTime not implemented\n"); } } @@ -1995,12 +1989,14 @@ void nr_rrc_going_to_IDLE(instance_t instance, nr_rrc_mac_config_req_release(instance); - // TODO indicate the release of the RRC connection to upper layers - // together with the release cause - // enter RRC_IDLE rrc->nrRrcState = RRC_STATE_IDLE_NR; rrc->rnti = 0; + + // Indicate the release of the RRC connection to upper layers + MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_NAS_CONN_RELEASE_IND); + NR_NAS_CONN_RELEASE_IND(msg_p).cause = release_cause; + itti_send_msg_to_task(TASK_NAS_NRUE, instance, msg_p); } void nr_ue_rrc_timer_trigger(int instance, int frame, int gnb_id) diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 2d9d19423c..4c2e43ee68 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -92,6 +92,11 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, void nr_mac_rrc_sync_ind(const module_id_t module_id, const frame_t frame, const bool in_sync); + +void nr_rrc_going_to_IDLE(instance_t instance, + NR_Release_Cause_t release_cause, + NR_RRCRelease_t *RRCRelease); + void nr_mac_rrc_ra_ind(const module_id_t mod_id, int frame, bool success); void nr_mac_rrc_msg3_ind(const module_id_t mod_id, int rnti); diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index f83f1138b6..4b7c4cc45c 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -1137,14 +1137,19 @@ void *nas_nrue(void *args_p) break; } - case NAS_CONN_RELEASE_IND: - LOG_I(NAS, "[UE %ld] Received %s: cause %u\n", instance, ITTI_MSG_NAME(msg_p), NAS_CONN_RELEASE_IND(msg_p).cause); - /* the following is not clean, but probably necessary: we need to give - * time to RLC to Ack the SRB1 PDU which contained the RRC release - * message. Hence, we just below wait some time, before finally - * unblocking the nr-uesoftmodem, which will terminate the process. */ - usleep(100000); - itti_wait_tasks_unblock(); /* will unblock ITTI to stop nr-uesoftmodem */ + case NR_NAS_CONN_RELEASE_IND: + LOG_I(NAS, "[UE %ld] Received %s: cause %u\n", + instance, ITTI_MSG_NAME (msg_p), NR_NAS_CONN_RELEASE_IND (msg_p).cause); + nr_ue_nas_t *nas = get_ue_nas_info(0); + // TODO handle connection release + if (nas->termination_procedure) { + /* the following is not clean, but probably necessary: we need to give + * time to RLC to Ack the SRB1 PDU which contained the RRC release + * message. Hence, we just below wait some time, before finally + * unblocking the nr-uesoftmodem, which will terminate the process. */ + usleep(100000); + itti_wait_tasks_unblock(); /* will unblock ITTI to stop nr-uesoftmodem */ + } break; case NAS_UPLINK_DATA_CNF: @@ -1162,6 +1167,8 @@ void *nas_nrue(void *args_p) nr_ue_nas_t *nas = get_ue_nas_info(0); if (nas->guti) { nas_deregistration_req_t *req = &NAS_DEREGISTRATION_REQ(msg_p); + if (req->cause == AS_DETACH) + nas->termination_procedure = true; as_nas_info_t initialNasMsg = {0}; generateDeregistrationRequest(nas, &initialNasMsg, req); send_nas_uplink_data_req(instance, &initialNasMsg); diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.h b/openair3/NAS/NR_UE/nr_nas_msg_sim.h index b1a1d25d1e..b5bb026c0b 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.h +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.h @@ -98,6 +98,7 @@ typedef struct { uicc_t *uicc; ue_sa_security_key_t security; Guti5GSMobileIdentity_t *guti; + bool termination_procedure; } nr_ue_nas_t; typedef enum fgs_protocol_discriminator_e {