Commit 284b0721 authored by francescomani's avatar francescomani

procedure to indicate the release of the RRC connection to upper layers

parent e3e158a7
...@@ -402,6 +402,7 @@ static void trigger_deregistration(int sig) ...@@ -402,6 +402,7 @@ static void trigger_deregistration(int sig)
{ {
if (!stop_immediately) { if (!stop_immediately) {
MessageDef *msg = itti_alloc_new_message(TASK_RRC_UE_SIM, 0, NAS_DEREGISTRATION_REQ); 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); itti_send_msg_to_task(TASK_NAS_NRUE, 0, msg);
stop_immediately = true; stop_immediately = true;
static const char m[] = "Press ^C again to trigger immediate shutdown\n"; static const char m[] = "Press ^C again to trigger immediate shutdown\n";
......
...@@ -327,15 +327,6 @@ typedef struct nas_establish_req_s { ...@@ -327,15 +327,6 @@ typedef struct nas_establish_req_s {
as_nas_info_t initialNasMsg; /* Initial NAS message to transfer */ as_nas_info_t initialNasMsg; /* Initial NAS message to transfer */
} nas_establish_req_t; } 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->NAS - NAS signalling connection establishment indication
* AS transfers the initial NAS message to the NAS. * AS transfers the initial NAS message to the NAS.
...@@ -406,6 +397,10 @@ typedef struct nas_release_ind_s { ...@@ -406,6 +397,10 @@ typedef struct nas_release_ind_s {
release_cause_t cause; /* Release cause */ release_cause_t cause; /* Release cause */
} nas_release_ind_t; } nas_release_ind_t;
typedef struct nas_deregistration_req_s {
release_cause_t cause;
} nas_deregistration_req_t;
/* /*
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* NAS information transfer * NAS information transfer
......
...@@ -73,6 +73,7 @@ MESSAGE_DEF(NAS_CELL_SELECTION_IND, MESSAGE_PRIORITY_MED, NasCellSelec ...@@ -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_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_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(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_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) MESSAGE_DEF(NAS_DOWNLINK_DATA_IND, MESSAGE_PRIORITY_MED, NasDlDataInd, nas_dl_data_ind)
......
...@@ -82,6 +82,7 @@ ...@@ -82,6 +82,7 @@
#define NAS_PAGING_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_paging_ind #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_ESTABLI_CNF(mSGpTR) (mSGpTR)->ittiMsg.nas_conn_establi_cnf
#define NAS_CONN_RELEASE_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_conn_release_ind #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_UPLINK_DATA_CNF(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_data_cnf
#define NAS_DOWNLINK_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_data_ind #define NAS_DOWNLINK_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_data_ind
...@@ -452,6 +453,16 @@ typedef struct nrrrc_frame_process_s { ...@@ -452,6 +453,16 @@ typedef struct nrrrc_frame_process_s {
int gnb_id; int gnb_id;
} NRRrcFrameProcess; } 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 // eNB: RLC -> RRC messages
typedef struct rlc_sdu_indication_s { typedef struct rlc_sdu_indication_s {
int rnti; int rnti;
......
...@@ -1334,19 +1334,13 @@ static int nr_rrc_ue_decode_dcch(instance_t instance, ...@@ -1334,19 +1334,13 @@ static int nr_rrc_ue_decode_dcch(instance_t instance,
case NR_DL_DCCH_MessageType__c1_PR_rrcResume: case NR_DL_DCCH_MessageType__c1_PR_rrcResume:
LOG_I(NR_RRC, "Received rrcResume on DL-DCCH-Message\n"); LOG_I(NR_RRC, "Received rrcResume on DL-DCCH-Message\n");
break; break;
case NR_DL_DCCH_MessageType__c1_PR_rrcRelease: { case NR_DL_DCCH_MessageType__c1_PR_rrcRelease:
struct NR_RRCRelease__criticalExtensions *ext = &c1->choice.rrcRelease->criticalExtensions; LOG_I(NR_RRC, "[UE %ld] Received RRC Release (gNB %d)\n",
LOG_I(NR_RRC, "Received RRC Release (gNB %d)\n", gNB_indexP); instance, gNB_indexP);
MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_RELEASE_IND); // TODO properly implement procedures in 5.3.8.3 of 38.331
// FixMe: this code do nothing !!!! NR_Release_Cause_t cause = OTHER;
if (ext->present == NR_RRCRelease__criticalExtensions_PR_rrcRelease) { nr_rrc_going_to_IDLE(instance, cause, dl_dcch_msg->message.choice.c1->choice.rrcRelease);
ext->choice.rrcRelease->deprioritisationReq->deprioritisationTimer = break;
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_ueCapabilityEnquiry: case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry:
LOG_I(NR_RRC, "Received Capability Enquiry (gNB %d)\n", gNB_indexP); 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 ...@@ -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, void nr_rrc_going_to_IDLE(instance_t instance,
NR_Release_Cause_t release_cause,
NR_RRCRelease_t *RRCRelease) NR_RRCRelease_t *RRCRelease)
{ {
NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[instance]; NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[instance];
...@@ -1867,9 +1862,8 @@ void nr_rrc_going_to_IDLE(instance_t instance, ...@@ -1867,9 +1862,8 @@ void nr_rrc_going_to_IDLE(instance_t instance,
// start timer T302 with the value set to the waitTime // start timer T302 with the value set to the waitTime
tac->T302_active = true; tac->T302_active = true;
tac->T302_k = *waitTime * 1000; // waitTime is in seconds 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'. // 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"); 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, ...@@ -1995,12 +1989,14 @@ void nr_rrc_going_to_IDLE(instance_t instance,
nr_rrc_mac_config_req_release(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 // enter RRC_IDLE
rrc->nrRrcState = RRC_STATE_IDLE_NR; rrc->nrRrcState = RRC_STATE_IDLE_NR;
rrc->rnti = 0; 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) void nr_ue_rrc_timer_trigger(int instance, int frame, int gnb_id)
......
...@@ -92,6 +92,11 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, ...@@ -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, void nr_mac_rrc_sync_ind(const module_id_t module_id,
const frame_t frame, const frame_t frame,
const bool in_sync); 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_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); void nr_mac_rrc_msg3_ind(const module_id_t mod_id, int rnti);
......
...@@ -1137,14 +1137,19 @@ void *nas_nrue(void *args_p) ...@@ -1137,14 +1137,19 @@ void *nas_nrue(void *args_p)
break; break;
} }
case NAS_CONN_RELEASE_IND: case NR_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); LOG_I(NAS, "[UE %ld] Received %s: cause %u\n",
/* the following is not clean, but probably necessary: we need to give instance, ITTI_MSG_NAME (msg_p), NR_NAS_CONN_RELEASE_IND (msg_p).cause);
* time to RLC to Ack the SRB1 PDU which contained the RRC release nr_ue_nas_t *nas = get_ue_nas_info(0);
* message. Hence, we just below wait some time, before finally // TODO handle connection release
* unblocking the nr-uesoftmodem, which will terminate the process. */ if (nas->termination_procedure) {
usleep(100000); /* the following is not clean, but probably necessary: we need to give
itti_wait_tasks_unblock(); /* will unblock ITTI to stop nr-uesoftmodem */ * 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; break;
case NAS_UPLINK_DATA_CNF: case NAS_UPLINK_DATA_CNF:
...@@ -1162,6 +1167,8 @@ void *nas_nrue(void *args_p) ...@@ -1162,6 +1167,8 @@ void *nas_nrue(void *args_p)
nr_ue_nas_t *nas = get_ue_nas_info(0); nr_ue_nas_t *nas = get_ue_nas_info(0);
if (nas->guti) { if (nas->guti) {
nas_deregistration_req_t *req = &NAS_DEREGISTRATION_REQ(msg_p); 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}; as_nas_info_t initialNasMsg = {0};
generateDeregistrationRequest(nas, &initialNasMsg, req); generateDeregistrationRequest(nas, &initialNasMsg, req);
send_nas_uplink_data_req(instance, &initialNasMsg); send_nas_uplink_data_req(instance, &initialNasMsg);
......
...@@ -98,6 +98,7 @@ typedef struct { ...@@ -98,6 +98,7 @@ typedef struct {
uicc_t *uicc; uicc_t *uicc;
ue_sa_security_key_t security; ue_sa_security_key_t security;
Guti5GSMobileIdentity_t *guti; Guti5GSMobileIdentity_t *guti;
bool termination_procedure;
} nr_ue_nas_t; } nr_ue_nas_t;
typedef enum fgs_protocol_discriminator_e { typedef enum fgs_protocol_discriminator_e {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment