From 78b75acef9a74559f34316d09daff8b8a94f034c Mon Sep 17 00:00:00 2001 From: winckel <winckel@eurecom.fr> Date: Thu, 2 Jan 2014 12:25:25 +0000 Subject: [PATCH] Created a RRC sub-state field. Created RRC state ans sub-state handling functions. Completed handling of NAS_CONN_ESTABLI_REQ. git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4815 818b1a75-f10b-46b9-bf7c-635c3b92a50f --- openair2/RRC/LITE/defs.h | 16 ++-- openair2/RRC/LITE/rrc_UE.c | 186 ++++++++++++++++++++++++++++++------- 2 files changed, 156 insertions(+), 46 deletions(-) diff --git a/openair2/RRC/LITE/defs.h b/openair2/RRC/LITE/defs.h index 8d2496a2b2..d86bcbdf93 100644 --- a/openair2/RRC/LITE/defs.h +++ b/openair2/RRC/LITE/defs.h @@ -46,6 +46,7 @@ #include <string.h> #endif +#include "rrc_types.h" #include "PHY/defs.h" #include "COMMON/platform_constants.h" @@ -110,13 +111,6 @@ typedef struct rrc_ral_threshold_key_s { #define UE_INDEX_INVALID ((uint8_t) ~0) -typedef enum RRC_STATE_e { - RRC_STATE_INACTIVE=0, - RRC_STATE_IDLE, - RRC_STATE_CONNECTED, -} RRC_STATE_t; - - typedef enum UE_STATE_e { RRC_INACTIVE=0, RRC_IDLE, @@ -365,10 +359,12 @@ typedef struct OAI_UECapability_s { } OAI_UECapability_t; typedef struct UE_RRC_INST_s { - RRC_STATE_t RrcState; + Rrc_State_t RrcState; + Rrc_Sub_State_t RrcSubState; # if defined(ENABLE_USE_MME) - plmn_t plmnID; - Byte_t rat; + plmn_t plmnID; + Byte_t rat; + as_nas_info_t initialNasMsg; # endif uint8_t *UECapability; uint8_t UECapability_size; diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c index f2bb916088..404ac103a6 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LITE/rrc_UE.c @@ -103,6 +103,70 @@ extern void *bigphys_malloc(int); extern inline unsigned int taus(void); extern s8 dB_fixed2(u32 x,u32 y); +/*------------------------------------------------------------------------------*/ +static Rrc_State_t rrc_get_state (u8 Mod_id) { + return UE_rrc_inst[Mod_id].RrcState; +} + +static Rrc_Sub_State_t rrc_get_sub_state (u8 Mod_id) { + return UE_rrc_inst[Mod_id].RrcSubState; +} + +static int rrc_set_state (u8 Mod_id, Rrc_State_t state) { + AssertFatal ((RRC_STATE_FIRST <= state) && (state <= RRC_STATE_LAST), + "Invalid state %d!\n", state); + + if (UE_rrc_inst[Mod_id].RrcState != state) { + MessageDef *msg_p; + + UE_rrc_inst[Mod_id].RrcState = state; + + msg_p = itti_alloc_new_message(TASK_RRC_UE, RRC_STATE_IND); + RRC_STATE_IND(msg_p).state = UE_rrc_inst[Mod_id].RrcState; + RRC_STATE_IND(msg_p).sub_state = UE_rrc_inst[Mod_id].RrcSubState; + + itti_send_msg_to_task(TASK_UNKNOWN, NB_eNB_INST + Mod_id, msg_p); + return (1); + } + + return (0); +} + +static int rrc_set_sub_state (u8 Mod_id, Rrc_Sub_State_t subState) { + switch (UE_rrc_inst[Mod_id].RrcState) { + case RRC_STATE_INACTIVE: + AssertFatal ((RRC_SUB_STATE_INACTIVE_FIRST <= subState) && (subState <= RRC_SUB_STATE_INACTIVE_LAST), + "Invalid sub state %d for state %d!\n", subState, UE_rrc_inst[Mod_id].RrcState); + break; + + case RRC_STATE_IDLE: + AssertFatal ((RRC_SUB_STATE_IDLE_FIRST <= subState) && (subState <= RRC_SUB_STATE_IDLE_LAST), + "Invalid sub state %d for state %d!\n", subState, UE_rrc_inst[Mod_id].RrcState); + break; + + case RRC_STATE_CONNECTED: + AssertFatal ((RRC_SUB_STATE_CONNECTED_FIRST <= subState) && (subState <= RRC_SUB_STATE_CONNECTED_LAST), + "Invalid sub state %d for state %d!\n", subState, UE_rrc_inst[Mod_id].RrcState); + break; + } + + if (UE_rrc_inst[Mod_id].RrcSubState != subState) { + MessageDef *msg_p; + + UE_rrc_inst[Mod_id].RrcSubState = subState; + + msg_p = itti_alloc_new_message(TASK_RRC_UE, RRC_STATE_IND); + RRC_STATE_IND(msg_p).state = UE_rrc_inst[Mod_id].RrcState; + RRC_STATE_IND(msg_p).sub_state = UE_rrc_inst[Mod_id].RrcSubState; + + itti_send_msg_to_task(TASK_UNKNOWN, NB_eNB_INST + Mod_id, msg_p); + return (1); + } + + return (0); +} + +/*------------------------------------------------------------------------------*/ void init_SI_UE(u8 Mod_id,u8 eNB_index) { int i; @@ -121,8 +185,6 @@ void init_SI_UE(u8 Mod_id,u8 eNB_index) { UE_rrc_inst[Mod_id].Info[eNB_index].SIB1Status = 0; UE_rrc_inst[Mod_id].Info[eNB_index].SIStatus = 0; - - } #ifdef Rel10 @@ -159,6 +221,9 @@ void openair_rrc_lite_ue_init_security(u8 Mod_id) /*------------------------------------------------------------------------------*/ char openair_rrc_lite_ue_init(u8 Mod_id, unsigned char eNB_index){ /*-----------------------------------------------------------------------------*/ + rrc_set_state (Mod_id, RRC_STATE_INACTIVE); + rrc_set_sub_state (Mod_id, RRC_SUB_STATE_INACTIVE); + LOG_D(RRC,"[UE %d] INIT State = RRC_IDLE (eNB %d)\n",Mod_id,eNB_index); LOG_D(RRC,"[MSC_NEW][FRAME 00000][RRC_UE][MOD %02d][]\n", Mod_id+NB_eNB_INST); LOG_D(RRC, "[MSC_NEW][FRAME 00000][IP][MOD %02d][]\n", Mod_id+NB_eNB_INST); @@ -277,11 +342,20 @@ static const char nas_attach_req_guti[] = void rrc_ue_generate_RRCConnectionSetupComplete(u8 Mod_id, u32 frame, u8 eNB_index, uint8_t Transaction_id){ /*------------------------------------------------------------------------------*/ - u8 buffer[100]; - u8 size; + u8 buffer[100]; + u8 size; + char *nas_msg; + int nas_msg_length; -// size = do_RRCConnectionSetupComplete(buffer, Transaction_id, sizeof(nas_attach_req_guti), nas_attach_req_guti); - size = do_RRCConnectionSetupComplete(buffer, Transaction_id, sizeof(nas_attach_req_imsi), nas_attach_req_imsi); +#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME) + nas_msg = (char *) UE_rrc_inst[Mod_id].initialNasMsg.data; + nas_msg_length = UE_rrc_inst[Mod_id].initialNasMsg.length; +#else + nas_msg = nas_attach_req_imsi; + nas_msg_length = sizeof(nas_attach_req_imsi); +#endif + + size = do_RRCConnectionSetupComplete(buffer, Transaction_id, nas_msg_length, nas_msg); LOG_I(RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCConnectionSetupComplete (bytes%d, eNB %d)\n", Mod_id,frame, size, eNB_index); @@ -418,6 +492,8 @@ int rrc_ue_decode_ccch(u8 Mod_id, u32 frame, SRB_INFO *Srb_info, u8 eNB_index){ rrc_ue_process_radioResourceConfigDedicated(Mod_id, frame, eNB_index, &dl_ccch_msg->message.choice.c1.choice.rrcConnectionSetup.criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated); + rrc_set_state (Mod_id, RRC_STATE_CONNECTED); + rrc_set_sub_state (Mod_id, RRC_SUB_STATE_CONNECTED); rrc_ue_generate_RRCConnectionSetupComplete(Mod_id, frame, eNB_index, dl_ccch_msg->message.choice.c1.choice.rrcConnectionSetup.rrc_TransactionIdentifier); rval = 0; @@ -1211,10 +1287,10 @@ void rrc_ue_process_rrcConnectionReconfiguration(u8 Mod_id, u32 frame, pdu_length = rrcConnectionReconfiguration_r8->dedicatedInfoNASList->list.array[list_count]->size; pdu_buffer = rrcConnectionReconfiguration_r8->dedicatedInfoNASList->list.array[list_count]->buf; - msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_CONN_ESTABLI_CNF); - NAS_CONN_ESTABLI_CNF(msg_p).errCode = AS_SUCCESS; - NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length = pdu_length; - NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data = pdu_buffer; + msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_CONN_ESTABLI_CNF); + NAS_CONN_ESTABLI_CNF(msg_p).errCode = AS_SUCCESS; + NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length = pdu_length; + NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data = pdu_buffer; itti_send_msg_to_task(TASK_NAS_UE, Mod_id, msg_p); } @@ -1681,6 +1757,8 @@ int decode_BCCH_DLSCH_Message(u8 Mod_id,u32 frame,u8 eNB_index,u8 *Sdu,u8 Sdu_le } else { + rrc_set_sub_state (Mod_id, RRC_SUB_STATE_IDLE_RECEIVING_SIB); + //memset(&bcch_message,0,sizeof(BCCH_DL_SCH_Message_t)); // LOG_D(RRC,"[UE %d] Decoding DL_BCCH_DLSCH_Message\n",Mod_id) /* @@ -1704,29 +1782,29 @@ int decode_BCCH_DLSCH_Message(u8 Mod_id,u32 frame,u8 eNB_index,u8 *Sdu,u8 Sdu_le #if defined(ENABLE_ITTI) # if defined(DISABLE_ITTI_XER_PRINT) - { - MessageDef *msg_p; + { + MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_RRC_UE, RRC_DL_BCCH_MESSAGE); - memcpy (&msg_p->ittiMsg, (void *) bcch_message, sizeof(RrcDlBcchMessage)); + msg_p = itti_alloc_new_message (TASK_RRC_UE, RRC_DL_BCCH_MESSAGE); + memcpy (&msg_p->ittiMsg, (void *) bcch_message, sizeof(RrcDlBcchMessage)); - itti_send_msg_to_task (TASK_UNKNOWN, Mod_id + NB_eNB_INST, msg_p); - } + itti_send_msg_to_task (TASK_UNKNOWN, Mod_id + NB_eNB_INST, msg_p); + } # else - { - char message_string[15000]; - size_t message_string_size; - - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_BCCH_DL_SCH_Message, (void *)bcch_message)) > 0) { - MessageDef *msg_p; + char message_string[15000]; + size_t message_string_size; - msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, GENERIC_LOG, message_string_size); - memcpy(&msg_p->ittiMsg.generic_log, message_string, message_string_size); + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_BCCH_DL_SCH_Message, (void *)bcch_message)) > 0) + { + MessageDef *msg_p; - itti_send_msg_to_task(TASK_UNKNOWN, Mod_id + NB_eNB_INST, msg_p); + msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, GENERIC_LOG, message_string_size); + memcpy(&msg_p->ittiMsg.generic_log, message_string, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, Mod_id + NB_eNB_INST, msg_p); + } } - } # endif #endif @@ -1767,6 +1845,14 @@ int decode_BCCH_DLSCH_Message(u8 Mod_id,u32 frame,u8 eNB_index,u8 *Sdu,u8 Sdu_le } } } + + if ((rrc_get_sub_state(Mod_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE) && (UE_rrc_inst[Mod_id].initialNasMsg.data != NULL)) { + rrc_ue_generate_RRCConnectionRequest(Mod_id, frame, 0); + LOG_I(RRC, "not sending connection request\n"); + + rrc_set_sub_state (Mod_id, RRC_SUB_STATE_IDLE_CONNECTING); + } + /* if ((UE_rrc_inst[Mod_id].Info[eNB_index].SIB1Status == 1) && (UE_rrc_inst[Mod_id].Info[eNB_index].SIStatus == 1) && (frame >= Mod_id * 20 + 10)) SEQUENCE_free(&asn_DEF_BCCH_DL_SCH_Message, (void*)bcch_message, 0);*/ @@ -2072,8 +2158,10 @@ int decode_SI(u8 Mod_id,u32 frame,u8 eNB_index,u8 si_window) { #ifdef Rel10 if (UE_rrc_inst[Mod_id].MBMS_flag < 3) // see -Q option #endif +#if !(defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)) rrc_ue_generate_RRCConnectionRequest(Mod_id,frame,eNB_index); LOG_I(RRC, "not sending connection request\n"); +#endif if (UE_rrc_inst[Mod_id].Info[eNB_index].State == RRC_IDLE) { LOG_I(RRC,"[UE %d] Received SIB1/SIB2/SIB3 Switching to RRC_SI_RECEIVED\n",Mod_id); @@ -2111,6 +2199,8 @@ int decode_SI(u8 Mod_id,u32 frame,u8 eNB_index,u8 si_window) { LOG_I(RRC,"[UE %d] Frame %d Found SIB3 from eNB %d\n",Mod_id,frame,eNB_index); dump_sib3(UE_rrc_inst[Mod_id].sib3[eNB_index]); UE_rrc_inst[Mod_id].Info[eNB_index].SIStatus = 1; + + rrc_set_sub_state (Mod_id, RRC_SUB_STATE_IDLE_SIB_COMPLETE); break; case SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib4: UE_rrc_inst[Mod_id].sib4[eNB_index] = &typeandinfo->choice.sib4; @@ -2650,7 +2740,7 @@ void *rrc_ue_task(void *args_p) { case NAS_CELL_SELECTION_REQ: Mod_id = 0; /* TODO force Mod_id to first UE, NAS UE not virtualized yet */ - LOG_I(RRC, "[UE %d] Received %s: state %d, plmnID %d, rat %x\n", Mod_id, msg_name, UE_rrc_inst[Mod_id].RrcState, + LOG_I(RRC, "[UE %d] Received %s: state %d, plmnID %d, rat %x\n", Mod_id, msg_name, rrc_get_state(Mod_id), NAS_CELL_SELECTION_REQ (msg_p).plmnID, NAS_CELL_SELECTION_REQ (msg_p).rat); /* Save cell selection criterion */ @@ -2659,7 +2749,7 @@ void *rrc_ue_task(void *args_p) { UE_rrc_inst[Mod_id].rat = NAS_CELL_SELECTION_REQ (msg_p).rat; } - switch (UE_rrc_inst[Mod_id].RrcState) { + switch (rrc_get_state(Mod_id)) { case RRC_STATE_INACTIVE: { /* Need to first activate lower layers */ @@ -2669,7 +2759,7 @@ void *rrc_ue_task(void *args_p) { itti_send_msg_to_task(TASK_L2L1, NB_eNB_INST + Mod_id, message_p); - UE_rrc_inst[Mod_id].RrcState = RRC_STATE_IDLE; + rrc_set_state (Mod_id, RRC_STATE_IDLE); /* Fall through to next case */ } @@ -2684,27 +2774,51 @@ void *rrc_ue_task(void *args_p) { PHY_FIND_CELL_REQ (message_p).earfcn_end = 1; itti_send_msg_to_task(TASK_PHY_UE, NB_eNB_INST + Mod_id, message_p); + rrc_set_sub_state (Mod_id, RRC_SUB_STATE_IDLE_SEARCHING); break; } case RRC_STATE_CONNECTED: - /* should not happen */ - LOG_E(RRC, "[UE %d] request %s in RRC state %d\n", Mod_id, msg_name, UE_rrc_inst[Mod_id].RrcState); - break; + /* should not happen */ + LOG_E(RRC, "[UE %d] request %s in RRC state %d\n", Mod_id, msg_name, rrc_get_state(Mod_id)); + break; default: - LOG_C(RRC, "[UE %d] Invalid RRC state %d\n", Mod_id, UE_rrc_inst[Mod_id].RrcState); - break; + LOG_C(RRC, "[UE %d] Invalid RRC state %d\n", Mod_id, rrc_get_state(Mod_id)); + break; } - /* TODO process message */ break; case NAS_CONN_ESTABLI_REQ: LOG_I(RRC, "[UE %d] Received %s: cause %d, type %d, s_tmsi %d, plmnID %d\n", Mod_id, msg_name, NAS_CONN_ESTABLI_REQ (msg_p).cause, NAS_CONN_ESTABLI_REQ (msg_p).type, NAS_CONN_ESTABLI_REQ (msg_p).s_tmsi, NAS_CONN_ESTABLI_REQ (msg_p).plmnID); - /* TODO process message */ + UE_rrc_inst[Mod_id].initialNasMsg = NAS_CONN_ESTABLI_REQ (msg_p).initialNasMsg; + + switch (rrc_get_state(Mod_id)) { + case RRC_STATE_IDLE: + { + if (rrc_get_sub_state(Mod_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE) + { + rrc_ue_generate_RRCConnectionRequest(Mod_id, frame, 0); + LOG_I(RRC, "not sending connection request\n"); + + rrc_set_sub_state (Mod_id, RRC_SUB_STATE_IDLE_CONNECTING); + } + break; + } + + case RRC_STATE_INACTIVE: + case RRC_STATE_CONNECTED: + /* should not happen */ + LOG_E(RRC, "[UE %d] request %s in RRC state %d\n", Mod_id, msg_name, rrc_get_state(Mod_id)); + break; + + default: + LOG_C(RRC, "[UE %d] Invalid RRC state %d\n", Mod_id, rrc_get_state(Mod_id)); + break; + } break; case NAS_UPLINK_DATA_REQ: -- GitLab