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