From fd55fbc6ebb7ce1215c20fe8d6ce5f2a2f8df5d7 Mon Sep 17 00:00:00 2001 From: winckel <winckel@eurecom.fr> Date: Wed, 20 Nov 2013 12:17:18 +0000 Subject: [PATCH] Completed RRC handling of S1AP messages. Re-organized UE info in eNB. git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4459 818b1a75-f10b-46b9-bf7c-635c3b92a50f --- openair2/LAYER2/PDCP_v10.1.0/pdcp.h | 4 + openair2/RRC/LITE/L2_interface.c | 2 +- openair2/RRC/LITE/defs.h | 46 ++++-- openair2/RRC/LITE/rrc_eNB.c | 230 ++++++++++++++++++++-------- 4 files changed, 209 insertions(+), 73 deletions(-) diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index 0332e513f6..d2db564871 100755 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -82,8 +82,12 @@ #include "PMCH-InfoList-r9.h" #endif +#ifndef FALSE #define FALSE (0x00) +#endif +#ifndef TRUE #define TRUE !(FALSE) +#endif extern pthread_t pdcp_thread; extern pthread_attr_t pdcp_thread_attr; diff --git a/openair2/RRC/LITE/L2_interface.c b/openair2/RRC/LITE/L2_interface.c index 515271cf90..33b3ec8b12 100644 --- a/openair2/RRC/LITE/L2_interface.c +++ b/openair2/RRC/LITE/L2_interface.c @@ -597,7 +597,7 @@ void rrc_lite_out_of_sync_ind(u8 Mod_id, u32 frame, u16 eNB_index){ int mac_get_rrc_lite_status(u8 Mod_id,u8 eNB_flag,u8 index){ //-------------------------------------------------------------------------------------------// if(eNB_flag == 1) - return(eNB_rrc_inst[Mod_id].Info.Status[index]); + return(eNB_rrc_inst[Mod_id].Info.UE[index].Status); else return(UE_rrc_inst[Mod_id].Info[index].State); } diff --git a/openair2/RRC/LITE/defs.h b/openair2/RRC/LITE/defs.h index e8b8328d94..35330c437e 100644 --- a/openair2/RRC/LITE/defs.h +++ b/openair2/RRC/LITE/defs.h @@ -83,6 +83,10 @@ #include "rrc_rrm_interface.h" #endif +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +#endif + /** @defgroup _rrc_impl_ RRC Layer Reference Implementation * @ingroup _ref_implementation_ * @{ @@ -149,14 +153,38 @@ typedef struct{ u32 N311_cnt; }UE_RRC_INFO; +typedef struct UE_S_TMSI_s { + uint8_t presence; + uint8_t mme_code; + uint32_t m_tmsi; +}__attribute__ ((__packed__)) UE_S_TMSI; + typedef struct{ - u8 Status[NUMBER_OF_UE_MAX]; - u8 Nb_ue; - //unsigned short UE_index_list[NUMBER_OF_UE_MAX]; - //L2_ID UE_list[NUMBER_OF_UE_MAX]; - u8 UE_list[NUMBER_OF_UE_MAX][5]; - InitialUE_Identity_t UE_Initialue_identity[NUMBER_OF_UE_MAX]; - EstablishmentCause_t UE_establishment_cause[NUMBER_OF_UE_MAX]; + u8 Status; + +#if defined(ENABLE_ITTI) + /* Information from UE RRC ConnectionRequest */ + UE_S_TMSI Initialue_identity_s_TMSI; + EstablishmentCause_t establishment_cause; + + /* Information from S1AP initial_context_setup_req */ + unsigned eNB_ue_s1ap_id :24; + /* Number of e_rab to be setup in the list */ + uint8_t nb_of_e_rabs; + /* list of e_rab to be setup by RRC layers */ + e_rab_t e_rab_param[S1AP_MAX_E_RAB]; +#endif +}__attribute__ ((__packed__)) eNB_RRC_UE_INFO; + +typedef struct{ + /* Number of UE handle by the eNB */ + uint8_t Nb_ue; + + /* UE list for UE index allocation */ + uint8_t UE_list[NUMBER_OF_UE_MAX][5]; + + /* Information on UE */ + eNB_RRC_UE_INFO UE[NUMBER_OF_UE_MAX]; }__attribute__ ((__packed__)) eNB_RRC_INFO; typedef struct{ @@ -274,8 +302,8 @@ typedef struct{ SRB_INFO Srb0; SRB_INFO_TABLE_ENTRY Srb1[NUMBER_OF_UE_MAX+1]; SRB_INFO_TABLE_ENTRY Srb2[NUMBER_OF_UE_MAX+1]; - MeasConfig_t *measConfig[NUMBER_OF_UE_MAX]; - HANDOVER_INFO *handover_info[NUMBER_OF_UE_MAX]; + MeasConfig_t *measConfig[NUMBER_OF_UE_MAX]; + HANDOVER_INFO *handover_info[NUMBER_OF_UE_MAX]; uint8_t HO_flag; #if defined(ENABLE_SECURITY) /* KeNB as derived from KASME received from EPC */ diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index d1704fdaa9..c36785f2f4 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -61,10 +61,10 @@ //#endif #ifdef USER_MODE -#include "RRC/NAS/nas_config.h" -#include "RRC/NAS/rb_config.h" -#include "OCG.h" -#include "OCG_extern.h" +# include "RRC/NAS/nas_config.h" +# include "RRC/NAS/rb_config.h" +# include "OCG.h" +# include "OCG_extern.h" #endif #if defined(ENABLE_SECURITY) @@ -72,7 +72,9 @@ #endif #if defined(ENABLE_USE_MME) -#include "../../S1AP/s1ap_eNB.h" +# if !defined(ENABLE_ITTI) +# include "../../S1AP/s1ap_eNB.h" +# endif #endif #include "pdcp.h" @@ -448,7 +450,47 @@ static uint8_t get_next_rrc_transaction_identifier(u8 Mod_id) return rrc_transaction_identifier[Mod_id]; } -static +static u8 get_next_UE_index (u8 Mod_id, u8 *UE_identity) +{ + u8 i, first_index = 255, reg = 0; + static const u8 null_identity[5] = + {0, 0, 0, 0, 0}; + + DevCheck(Mod_id < NB_eNB_INST, Mod_id, NB_eNB_INST, 0); + + for (i = 0; i < NUMBER_OF_UE_MAX; i++) { + if ((first_index == 255) + && (memcmp (eNB_rrc_inst[Mod_id].Info.UE_list[i], null_identity, sizeof(eNB_rrc_inst[0].Info.UE_list[i]))) + == 0) { + first_index = i; // save first free position + } + + if (memcmp (eNB_rrc_inst[Mod_id].Info.UE_list[i], UE_identity, sizeof(eNB_rrc_inst[0].Info.UE_list[i])) == 0) { + // UE_identity already registered + reg = 1; + } + } + + if (reg == 0) { + LOG_I(RRC, "Adding UE %d\n", first_index); + return (first_index); + } + else { + return (255); + } +} + +void rrc_remove_UE (u8 Mod_id, u8 UE_id) +{ + DevCheck(Mod_id < NB_eNB_INST, Mod_id, UE_id, NB_eNB_INST); + DevCheck(UE_id < NUMBER_OF_UE_MAX, Mod_id, UE_id, NUMBER_OF_UE_MAX); + + LOG_I (RRC, "Removing UE %d\n", UE_id); + eNB_rrc_inst[Mod_id].Info.UE[UE_id].Status = RRC_IDLE; + memset(eNB_rrc_inst[Mod_id].Info.UE_list[UE_id], 0, sizeof(eNB_rrc_inst[0].Info.UE_list[0])); +} + +/*------------------------------------------------------------------------------*/ void rrc_lite_eNB_init_security(u8 Mod_id, u8 UE_index) { #if defined(ENABLE_SECURITY) @@ -476,7 +518,7 @@ char openair_rrc_lite_eNB_init (u8 Mod_id) LOG_D (RRC, "[MSC_NEW][FRAME 00000][IP][MOD %02d][]\n", Mod_id); for (j = 0; j < NUMBER_OF_UE_MAX; j++) - eNB_rrc_inst[Mod_id].Info.Status[j] = RRC_IDLE; //CH_READY; + eNB_rrc_inst[Mod_id].Info.UE[j].Status = RRC_IDLE; //CH_READY; /* Init security parameters */ for (j = 0; j < NUMBER_OF_UE_MAX; j++) { @@ -578,46 +620,6 @@ char openair_rrc_lite_eNB_init (u8 Mod_id) } -u8 get_next_UE_index (u8 Mod_id, u8 *UE_identity) -{ - u8 i, first_index = 255, reg = 0; - static const u8 null_identity[5] = - {0, 0, 0, 0, 0}; - - DevCheck(Mod_id < NB_eNB_INST, Mod_id, NB_eNB_INST, 0); - - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { - if ((first_index == 255) - && (memcmp (eNB_rrc_inst[Mod_id].Info.UE_list[i], null_identity, sizeof(eNB_rrc_inst[0].Info.UE_list[0]))) - == 0) { - first_index = i; // save first free position - } - - if (memcmp (eNB_rrc_inst[Mod_id].Info.UE_list[i], UE_identity, sizeof(eNB_rrc_inst[0].Info.UE_list[0])) == 0) { - // UE_identity already registered - reg = 1; - } - } - - if (reg == 0) { - LOG_I(RRC, "Adding UE %d\n", first_index); - return (first_index); - } - else { - return (255); - } -} - -void rrc_remove_UE (u8 Mod_id, u8 UE_id) -{ - DevCheck(Mod_id < NB_eNB_INST, Mod_id, UE_id, NB_eNB_INST); - DevCheck(UE_id < NUMBER_OF_UE_MAX, Mod_id, UE_id, NUMBER_OF_UE_MAX); - - LOG_I (RRC, "Removing UE %d\n", UE_id); - eNB_rrc_inst[Mod_id].Info.Status[UE_id] = RRC_IDLE; - memset(eNB_rrc_inst[Mod_id].Info.UE_list[UE_id], 0, sizeof(eNB_rrc_inst[0].Info.UE_list[0])); -} - /*------------------------------------------------------------------------------*/ int rrc_eNB_decode_dcch (u8 Mod_id, u32 frame, u8 Srb_id, u8 UE_index, u8 * Rx_sdu, u8 sdu_size) @@ -712,10 +714,45 @@ int rrc_eNB_decode_dcch (u8 Mod_id, u32 frame, u8 Srb_id, u8 UE_index, criticalExtensions. choice. rrcConnectionReconfigurationComplete_r8); - eNB_rrc_inst[Mod_id].Info.Status[UE_index] = RRC_RECONFIGURED; + eNB_rrc_inst[Mod_id].Info.UE[UE_index].Status = RRC_RECONFIGURED; LOG_I (RRC, "[eNB %d] UE %d State = RRC_RECONFIGURED \n", Mod_id, UE_index); } + +#if defined(ENABLE_USE_MME) + if (oai_emulation.info.mme_enabled == 1) + { + eNB_RRC_UE_INFO *UE_info = &eNB_rrc_inst[Mod_id].Info.UE[UE_index]; + +# if defined(ENABLE_ITTI) + /* Process e RAB parameters received from S1AP one by one (the previous one is completed, eventually process the next one) */ + if (UE_info->nb_of_e_rabs > 0) + { + int i; + + /* Search for the first e RAB to use */ + for (i = 0; i < S1AP_MAX_E_RAB; i++) + { + if (UE_info->e_rab_param[i].nas_pdu.buffer != NULL) + break; + } + + DevCheck(i < S1AP_MAX_E_RAB, Mod_id, UE_index, UE_info->nb_of_e_rabs); + + /* Process e RAB configuration from S1AP initial_context_setup_req */ + rrc_eNB_generate_defaultRRCConnectionReconfiguration (Mod_id, frame, + UE_index, + UE_info->e_rab_param[i].nas_pdu.buffer, + UE_info->e_rab_param[i].nas_pdu.length, + eNB_rrc_inst[Mod_id].HO_flag); + /* Free the NAS PDU buffer and invalidate it */ + free (UE_info->e_rab_param[i].nas_pdu.buffer); + UE_info->e_rab_param[i].nas_pdu.buffer = NULL; + UE_info->nb_of_e_rabs --; + } +# endif + } +#endif break; case UL_DCCH_MessageType__c1_PR_rrcConnectionReestablishmentComplete: @@ -750,7 +787,7 @@ int rrc_eNB_decode_dcch (u8 Mod_id, u32 frame, u8 Srb_id, u8 UE_index, choice.c1. choice. rrcConnectionSetupComplete_r8); - eNB_rrc_inst[Mod_id].Info.Status[UE_index] = RRC_CONNECTED; + eNB_rrc_inst[Mod_id].Info.UE[UE_index].Status = RRC_CONNECTED; LOG_I (RRC, "[eNB %d] UE %d State = RRC_CONNECTED \n", Mod_id, UE_index); LOG_D (RRC, @@ -777,6 +814,7 @@ int rrc_eNB_decode_dcch (u8 Mod_id, u32 frame, u8 Srb_id, u8 UE_index, // continue the procedure rrc_eNB_generate_UECapabilityEnquiry (Mod_id, frame, UE_index); break; + case UL_DCCH_MessageType__c1_PR_securityModeFailure: LOG_D (RRC, "[MSC_MSG][FRAME %05d][RLC][MOD %02d][RB %02d][--- RLC_DATA_IND %d bytes " @@ -820,9 +858,39 @@ int rrc_eNB_decode_dcch (u8 Mod_id, u32 frame, u8 Srb_id, u8 UE_index, xer_fprint (stdout, &asn_DEF_UE_EUTRA_Capability, (void *) UE_EUTRA_Capability); #endif - rrc_eNB_generate_defaultRRCConnectionReconfiguration (Mod_id, frame, - UE_index, - NULL, 0, eNB_rrc_inst[Mod_id].HO_flag); + +#if defined(ENABLE_USE_MME) + if (oai_emulation.info.mme_enabled == 1) + { + eNB_RRC_UE_INFO *UE_info = &eNB_rrc_inst[Mod_id].Info.UE[UE_index]; + +# if defined(ENABLE_ITTI) + /* Process e RAB parameters received from S1AP one by one (assuming that only one will be received from real network this should be OK) */ + if (UE_info->nb_of_e_rabs > 0) + { + /* The first e RAB should be set */ + DevCheck(UE_info->e_rab_param[0].nas_pdu.buffer != NULL, Mod_id, UE_index, UE_info->nb_of_e_rabs); + + /* Process e RAB configuration from S1AP initial_context_setup_req */ + rrc_eNB_generate_defaultRRCConnectionReconfiguration (Mod_id, frame, + UE_index, + UE_info->e_rab_param[0].nas_pdu.buffer, + UE_info->e_rab_param[0].nas_pdu.length, + eNB_rrc_inst[Mod_id].HO_flag); + /* Free the NAS PDU buffer and invalidate it */ + free (UE_info->e_rab_param[0].nas_pdu.buffer); + UE_info->e_rab_param[0].nas_pdu.buffer = NULL; + UE_info->nb_of_e_rabs --; + } +# endif + } + else +#endif + { + rrc_eNB_generate_defaultRRCConnectionReconfiguration (Mod_id, frame, + UE_index, + NULL, 0, eNB_rrc_inst[Mod_id].HO_flag); + } break; case UL_DCCH_MessageType__c1_PR_ulHandoverPreparationTransfer: @@ -1012,8 +1080,19 @@ for (i = 0; i < 8; i++) if (UE_index != 255) { - eNB_rrc_inst[Mod_id].Info.UE_Initialue_identity[UE_index] = rrcConnectionRequest->ue_Identity; - eNB_rrc_inst[Mod_id].Info.UE_establishment_cause[UE_index] = rrcConnectionRequest->establishmentCause; +#if defined(ENABLE_ITTI) + /* Check s-TMSI presence in message */ + eNB_rrc_inst[Mod_id].Info.UE[UE_index].Initialue_identity_s_TMSI.presence = + (rrcConnectionRequest->ue_Identity.present == InitialUE_Identity_PR_s_TMSI); + if (eNB_rrc_inst[Mod_id].Info.UE[UE_index].Initialue_identity_s_TMSI.presence) { + /* Save s-TMSI */ + S_TMSI_t s_TMSI = rrcConnectionRequest->ue_Identity.choice.s_TMSI; + + eNB_rrc_inst[Mod_id].Info.UE[UE_index].Initialue_identity_s_TMSI.mme_code = BIT_STRING_to_uint8 (&s_TMSI.mmec); + eNB_rrc_inst[Mod_id].Info.UE[UE_index].Initialue_identity_s_TMSI.m_tmsi = BIT_STRING_to_uint32 (&s_TMSI.m_TMSI); + } + eNB_rrc_inst[Mod_id].Info.UE[UE_index].establishment_cause = rrcConnectionRequest->establishmentCause; +#endif // memcpy(&Rrc_xface->UE_id[Mod_id][UE_index],(u8 *)rrcConnectionRequest->ue_Identity.choice.randomValue.buf,5); memcpy (&eNB_rrc_inst[Mod_id].Info.UE_list[UE_index], @@ -1111,6 +1190,7 @@ for (i = 0; i < 8; i++) default: LOG_E (RRC, "[eNB %d] Frame %d : Unknown message\n", Mod_id, frame); rval = -1; + break; } rval = 0; } @@ -1141,8 +1221,8 @@ void rrc_eNB_process_RRCConnectionSetupComplete (u8 Mod_id, S1AP_NAS_FIRST_REQ (message_p).rnti = eNB_mac_inst[Mod_id].UE_template[UE_index].rnti; // TODO check if this is the correct id to use /* Assume that cause is coded in the same way in RRC and S1ap, just check that the value is in S1ap range */ - DevCheck(eNB_rrc_inst[Mod_id].Info.UE_establishment_cause[UE_index] < RRC_CAUSE_LAST, eNB_rrc_inst[Mod_id].Info.UE_establishment_cause[UE_index], RRC_CAUSE_LAST, Mod_id); - S1AP_NAS_FIRST_REQ (message_p).establishment_cause = eNB_rrc_inst[Mod_id].Info.UE_establishment_cause[UE_index]; + DevCheck(eNB_rrc_inst[Mod_id].Info.UE[UE_index].establishment_cause < RRC_CAUSE_LAST, eNB_rrc_inst[Mod_id].Info.UE[UE_index].establishment_cause, RRC_CAUSE_LAST, Mod_id); + S1AP_NAS_FIRST_REQ (message_p).establishment_cause = eNB_rrc_inst[Mod_id].Info.UE[UE_index].establishment_cause; /* Forward NAS message */ S1AP_NAS_FIRST_REQ (message_p).nas_pdu.buffer = rrcConnectionSetupComplete->dedicatedInfoNAS.buf; @@ -1152,13 +1232,13 @@ void rrc_eNB_process_RRCConnectionSetupComplete (u8 Mod_id, { S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask = UE_IDENTITIES_NONE; - if (eNB_rrc_inst[Mod_id].Info.UE_Initialue_identity[UE_index].present == InitialUE_Identity_PR_s_TMSI) { + if (eNB_rrc_inst[Mod_id].Info.UE[UE_index].Initialue_identity_s_TMSI.presence) { /* Fill s-TMSI */ - S_TMSI_t s_TMSI = eNB_rrc_inst[Mod_id].Info.UE_Initialue_identity[UE_index].choice.s_TMSI; + UE_S_TMSI *s_TMSI = &eNB_rrc_inst[Mod_id].Info.UE[UE_index].Initialue_identity_s_TMSI; S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask |= UE_IDENTITIES_s_tmsi; - S1AP_NAS_FIRST_REQ (message_p).ue_identity.s_tmsi.mme_code = BIT_STRING_to_uint8 (&s_TMSI.mmec); - S1AP_NAS_FIRST_REQ (message_p).ue_identity.s_tmsi.m_tmsi = BIT_STRING_to_uint32 (&s_TMSI.m_TMSI); + S1AP_NAS_FIRST_REQ (message_p).ue_identity.s_tmsi.mme_code = s_TMSI->mme_code; + S1AP_NAS_FIRST_REQ (message_p).ue_identity.s_tmsi.m_tmsi = s_TMSI->m_tmsi; } if (rrcConnectionSetupComplete->registeredMME != NULL) { @@ -3096,13 +3176,37 @@ void *rrc_enb_task(void *args_p) { break; case S1AP_INITIAL_CONTEXT_SETUP_REQ: - ue_index = S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).eNB_ue_s1ap_id; // TOTO convert eNB_ue_s1ap_id into ue_index + eNB_rrc_inst[instance].Info.UE[ue_index].eNB_ue_s1ap_id = S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).eNB_ue_s1ap_id; + ue_index = eNB_rrc_inst[instance].Info.UE[ue_index].eNB_ue_s1ap_id; // TOTO convert eNB_ue_s1ap_id into ue_index + + /* Save e RAB information for later */ + { + int i; + + eNB_rrc_inst[instance].Info.UE[ue_index].nb_of_e_rabs = S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_e_rabs; + for (i=0; i< eNB_rrc_inst[instance].Info.UE[ue_index].nb_of_e_rabs; i++) + { + eNB_rrc_inst[instance].Info.UE[ue_index].e_rab_param[i] = S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).e_rab_param[i]; + } + } LOG_D(RRC, "Received %s: instance %d, eNB_ue_s1ap_id %d, nb_of_e_rabs %d\n", msg_name, instance, S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).eNB_ue_s1ap_id, S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_e_rabs); - rrc_eNB_generate_SecurityModeCommand (instance, 0 /* TODO put frame number ! */, ue_index); - // TODO process this message + { + uint8_t skip_security_mode_command = FALSE; + + // TODO evaluate if security mode command should be skipped + + if(skip_security_mode_command) + { + rrc_eNB_generate_SecurityModeCommand (instance, 0 /* TODO put frame number ! */, ue_index); + } + else + { + rrc_eNB_generate_UECapabilityEnquiry (instance, 0 /* TODO put frame number ! */, ue_index); + } + } break; default: -- GitLab