/* * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * * http://www.openairinterface.org/?page_id=698 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ /*! \file rrc_UE.c * \brief rrc procedures for UE * \author Navid Nikaein and Raymond Knopp * \date 2011 - 2014 * \version 1.0 * \company Eurecom * \email: navid.nikaein@eurecom.fr and raymond.knopp@eurecom.fr */ #define RRC_UE #define RRC_UE_C #define _GNU_SOURCE #include "assertions.h" #include "hashtable.h" #include "asn1_conversions.h" #include "rrc_defs.h" #include "rrc_extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "openair1/PHY/LTE_ESTIMATION/lte_estimation.h" #include "LAYER2/RLC/rlc.h" #include "COMMON/mac_rrc_primitives.h" #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" #ifndef CELLULAR #include "RRC/LTE/MESSAGES/asn1_msg.h" #endif #include "LTE_RRCConnectionRequest.h" #include "LTE_RRCConnectionReconfiguration.h" #include "LTE_UL-CCCH-Message.h" #include "LTE_DL-CCCH-Message.h" #include "LTE_UL-DCCH-Message.h" #include "LTE_DL-DCCH-Message.h" #include "LTE_BCCH-DL-SCH-Message.h" #include "LTE_PCCH-Message.h" #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) #include "LTE_MCCH-Message.h" #endif #include "LTE_MeasConfig.h" #include "LTE_MeasGapConfig.h" #include "LTE_MeasObjectEUTRA.h" #include "LTE_TDD-Config.h" #include "LTE_UECapabilityEnquiry.h" #include "LTE_UE-CapabilityRequest.h" #include "RRC/NAS/nas_config.h" #include "RRC/NAS/rb_config.h" #if ENABLE_RAL #include "rrc_UE_ral.h" #endif #include "UTIL/OSA/osa_defs.h" #include "pdcp.h" #include "plmn_data.h" #include "msc.h" #include "intertask_interface.h" #include "SIMULATION/TOOLS/sim.h" // for taus #include "openair2/LAYER2/MAC/mac_extern.h" #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) #include "LTE_SL-Preconfiguration-r12.h" //for D2D int ctrl_sock_fd; #define BUFSIZE 1024 struct sockaddr_in prose_app_addr; int slrb_id; int send_ue_information = 0; #endif // for malloc_clear #include "PHY/defs_UE.h" extern void pdcp_config_set_security( const protocol_ctxt_t *const ctxt_pP, pdcp_t *const pdcp_pP, const rb_id_t rb_idP, const uint16_t lc_idP, const uint8_t security_modeP, uint8_t *const kRRCenc, uint8_t *const kRRCint, uint8_t *const kUPenc); // internal prototypes void rrc_ue_process_securityModeCommand( const protocol_ctxt_t *const ctxt_pP, LTE_SecurityModeCommand_t *const securityModeCommand, const uint8_t eNB_index ); static int decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ); static int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t rsrq, const uint8_t rsrp ); /** \brief Generates/Encodes RRCConnnectionSetupComplete message at UE * \param ctxt_pP Running context * \param eNB_index Index of corresponding eNB/CH * \param Transaction_id Transaction identifier */ static void rrc_ue_generate_RRCConnectionSetupComplete( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t Transaction_id ); /** \brief Generates/Encodes RRCConnectionReconfigurationComplete message at UE * \param ctxt_pP Running context * \param eNB_index Index of corresponding eNB/CH * \param Transaction_id RRC transaction identifier */ static void rrc_ue_generate_RRCConnectionReconfigurationComplete( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t Transaction_id ); static void rrc_ue_generate_MeasurementReport(protocol_ctxt_t *const ctxt_pP, uint8_t eNB_index ); static uint8_t check_trigger_meas_event( module_id_t module_idP, frame_t frameP, uint8_t eNB_index, uint8_t ue_cnx_index, uint8_t meas_index, LTE_Q_OffsetRange_t ofn, LTE_Q_OffsetRange_t ocn, LTE_Hysteresis_t hys, LTE_Q_OffsetRange_t ofs, LTE_Q_OffsetRange_t ocs, long a3_offset, LTE_TimeToTrigger_t ttt); #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) static void decode_MBSFNAreaConfiguration(module_id_t module_idP, uint8_t eNB_index, frame_t frameP,uint8_t mbsfn_sync_area); uint8_t rrc_ue_generate_SidelinkUEInformation( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index,LTE_SL_DestinationInfoList_r12_t *destinationInfoList, long *discTxResourceReq, SL_TRIGGER_t mode); #endif /*------------------------------------------------------------------------------*/ static Rrc_State_t rrc_get_state (module_id_t ue_mod_idP) { return UE_rrc_inst[ue_mod_idP].RrcState; } static Rrc_Sub_State_t rrc_get_sub_state (module_id_t ue_mod_idP) { return UE_rrc_inst[ue_mod_idP].RrcSubState; } static int rrc_set_state (module_id_t ue_mod_idP, Rrc_State_t state) { AssertFatal ((RRC_STATE_FIRST <= state) && (state <= RRC_STATE_LAST), "Invalid state %d!\n", state); if (UE_rrc_inst[ue_mod_idP].RrcState != state) { UE_rrc_inst[ue_mod_idP].RrcState = state; return (1); } return (0); } //----------------------------------------------------------------------------- static int rrc_set_sub_state( module_id_t ue_mod_idP, Rrc_Sub_State_t subState ) { if (EPC_MODE_ENABLED) { switch (UE_rrc_inst[ue_mod_idP].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[ue_mod_idP].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[ue_mod_idP].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[ue_mod_idP].RrcState); break; } } if (UE_rrc_inst[ue_mod_idP].RrcSubState != subState) { UE_rrc_inst[ue_mod_idP].RrcSubState = subState; return (1); } return (0); } //----------------------------------------------------------------------------- void openair_rrc_on_ue( const protocol_ctxt_t *const ctxt_pP ) //----------------------------------------------------------------------------- { unsigned short i; LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" UE?:OPENAIR RRC IN....\n", PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); for (i = 0; i < NB_eNB_INST; i++) { LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" Activating CCCH (eNB %d)\n", PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), i); UE_rrc_inst[ctxt_pP->module_id].Srb0[i].Srb_id = CCCH; memcpy (&UE_rrc_inst[ctxt_pP->module_id].Srb0[i].Lchan_desc[0], &CCCH_LCHAN_DESC, LCHAN_DESC_SIZE); memcpy (&UE_rrc_inst[ctxt_pP->module_id].Srb0[i].Lchan_desc[1], &CCCH_LCHAN_DESC, LCHAN_DESC_SIZE); rrc_config_buffer (&UE_rrc_inst[ctxt_pP->module_id].Srb0[i], CCCH, 1); UE_rrc_inst[ctxt_pP->module_id].Srb0[i].Active = 1; } } //----------------------------------------------------------------------------- static void init_SI_UE( protocol_ctxt_t const *ctxt_pP, const uint8_t eNB_index ) { UE_rrc_inst[ctxt_pP->module_id].sizeof_SIB1[eNB_index] = 0; UE_rrc_inst[ctxt_pP->module_id].sizeof_SI[eNB_index] = 0; UE_rrc_inst[ctxt_pP->module_id].SIB1[eNB_index] = (uint8_t *)malloc16_clear( 32 ); UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType1_t) ); UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType2_t) ); UE_rrc_inst[ctxt_pP->module_id].sib3[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType3_t) ); UE_rrc_inst[ctxt_pP->module_id].sib4[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType4_t) ); UE_rrc_inst[ctxt_pP->module_id].sib5[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType5_t) ); UE_rrc_inst[ctxt_pP->module_id].sib6[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType6_t) ); UE_rrc_inst[ctxt_pP->module_id].sib7[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType7_t) ); UE_rrc_inst[ctxt_pP->module_id].sib8[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType8_t) ); UE_rrc_inst[ctxt_pP->module_id].sib9[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType9_t) ); UE_rrc_inst[ctxt_pP->module_id].sib10[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType10_t) ); UE_rrc_inst[ctxt_pP->module_id].sib11[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType11_t) ); #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) UE_rrc_inst[ctxt_pP->module_id].sib12[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType12_r9_t) ); UE_rrc_inst[ctxt_pP->module_id].sib13[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType13_r9_t) ); UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType18_r12_t) ); UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType19_r12_t) ); UE_rrc_inst[ctxt_pP->module_id].sib21[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType21_r14_t) ); #endif UE_rrc_inst[ctxt_pP->module_id].SI[eNB_index] = (uint8_t *)malloc16_clear( 64 ); UE_rrc_inst[ctxt_pP->module_id].si[eNB_index] = (LTE_SystemInformation_t *)malloc16_clear( sizeof(LTE_SystemInformation_t) ); UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus = 0; UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt = 0; } #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void init_SL_preconfig(UE_RRC_INST *UE, const uint8_t eNB_index ) { LOG_I(RRC,"Initializing Sidelink Pre-configuration for UE\n"); UE->SL_Preconfiguration[eNB_index] = malloc16_clear( sizeof(struct LTE_SL_Preconfiguration_r12) ); UE->SL_Preconfiguration[eNB_index]->preconfigGeneral_r12.rohc_Profiles_r12.profile0x0001_r12 = true; UE->SL_Preconfiguration[eNB_index]->preconfigGeneral_r12.carrierFreq_r12 = 3350; UE->SL_Preconfiguration[eNB_index]->preconfigGeneral_r12.maxTxPower_r12 = 0; UE->SL_Preconfiguration[eNB_index]->preconfigGeneral_r12.additionalSpectrumEmission_r12 = 0; UE->SL_Preconfiguration[eNB_index]->preconfigGeneral_r12.sl_bandwidth_r12 = LTE_SL_PreconfigGeneral_r12__sl_bandwidth_r12_n50; UE->SL_Preconfiguration[eNB_index]->preconfigGeneral_r12.tdd_ConfigSL_r12.subframeAssignmentSL_r12 = LTE_TDD_ConfigSL_r12__subframeAssignmentSL_r12_none; UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncCP_Len_r12 = LTE_SL_CP_Len_r12_normal; UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncOffsetIndicator1_r12 = 0; UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncOffsetIndicator2_r12 = 0; UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncTxParameters_r12 = 0; UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncTxThreshOoC_r12 = 0; UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.filterCoefficient_r12 = LTE_FilterCoefficient_fc0; UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncRefMinHyst_r12 = LTE_SL_PreconfigSync_r12__syncRefMinHyst_r12_dB0; UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncRefDiffHyst_r12 = LTE_SL_PreconfigSync_r12__syncRefDiffHyst_r12_dB0; UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.ext1 = malloc16_clear(sizeof(struct LTE_SL_PreconfigSync_r12__ext1)); UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.ext1->syncTxPeriodic_r13 = NULL; struct LTE_SL_PreconfigCommPool_r12 *preconfigpool = malloc16_clear(sizeof(struct LTE_SL_PreconfigCommPool_r12)); preconfigpool->sc_CP_Len_r12 = LTE_SL_CP_Len_r12_normal; preconfigpool->sc_Period_r12 = LTE_SL_PeriodComm_r12_sf40; // 20 PRBs for SL communications preconfigpool->sc_TF_ResourceConfig_r12.prb_Num_r12 = 20; preconfigpool->sc_TF_ResourceConfig_r12.prb_Start_r12 = 5; preconfigpool->sc_TF_ResourceConfig_r12.prb_End_r12 = 44; // Offset set to 0 subframes preconfigpool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.present = LTE_SL_OffsetIndicator_r12_PR_small_r12; preconfigpool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = 0; // 40 ms SL Period preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present = LTE_SubframeBitmapSL_r12_PR_bs40_r12; preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = CALLOC(1,5); preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = 5; preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = 0; // 1st 4 subframes for PSCCH preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[0] = 0xF; preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[1] = 0; preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[2] = 0; preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[3] = 0; preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[4] = 0; preconfigpool->sc_TxParameters_r12 = 0; preconfigpool->data_CP_Len_r12 = LTE_SL_CP_Len_r12_normal; // 20 PRBs for SL communications preconfigpool->data_TF_ResourceConfig_r12.prb_Num_r12 = 20; preconfigpool->data_TF_ResourceConfig_r12.prb_Start_r12 = 5; preconfigpool->data_TF_ResourceConfig_r12.prb_End_r12 = 44; // Offset set to 0 subframes preconfigpool->data_TF_ResourceConfig_r12.offsetIndicator_r12.present = LTE_SL_OffsetIndicator_r12_PR_small_r12; preconfigpool->data_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = 0; // 40 ms SL Period preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.present = LTE_SubframeBitmapSL_r12_PR_bs40_r12; preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = CALLOC(1,5); preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = 5; preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = 0; // last 36 subframes for PSCCH preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[0] = 0xF0; preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[1] = 0xFF; preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[2] = 0xFF; preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[3] = 0xFF; preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[5] = 0xFF; preconfigpool->dataHoppingConfig_r12.hoppingParameter_r12 = 0; preconfigpool->dataHoppingConfig_r12.numSubbands_r12 = LTE_SL_HoppingConfigComm_r12__numSubbands_r12_ns1; preconfigpool->dataHoppingConfig_r12.rb_Offset_r12 = 0; preconfigpool->dataTxParameters_r12 = 0; ASN_SEQUENCE_ADD(&UE->SL_Preconfiguration[eNB_index]->preconfigComm_r12.list,preconfigpool); // Rel13 extensions UE->SL_Preconfiguration[eNB_index]->ext1 = NULL; /* // Establish a SLRB (using DRB 3 for now) protocol_ctxt_t ctxt; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0); UE->DRB_config[0][0] = CALLOC(1,sizeof(struct DRB_ToAddMod)); UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); UE->DRB_config[0][0]->drb_Identity = 3; UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); // allowed value 5..15, value : x+4 *(UE->DRB_config[0][0]->eps_BearerIdentity) = 3; UE->DRB_config[0][0]->logicalChannelIdentity = CALLOC(1, sizeof(long)); *(UE->DRB_config[0][0]->logicalChannelIdentity) = UE->DRB_config[0][0]->drb_Identity; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2 // TTN - Establish a new SLRB for PC5-S (using DRB 10 for now) UE->DRB_config[0][1] = CALLOC(1,sizeof(struct DRB_ToAddMod)); UE->DRB_config[0][1]->eps_BearerIdentity = CALLOC(1, sizeof(long)); UE->DRB_config[0][1]->drb_Identity = 10; UE->DRB_config[0][1]->eps_BearerIdentity = CALLOC(1, sizeof(long)); // allowed value 5..15, value : x+4 *(UE->DRB_config[0][1]->eps_BearerIdentity) = 10; UE->DRB_config[0][1]->logicalChannelIdentity = CALLOC(1, sizeof(long)); *(UE->DRB_config[0][1]->logicalChannelIdentity) = UE->DRB_config[0][1]->drb_Identity; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2 struct RLC_Config *DRB_rlc_config = CALLOC(1,sizeof(struct RLC_Config)); struct PDCP_Config *DRB_pdcp_config = CALLOC(1,sizeof(struct PDCP_Config)); struct PDCP_Config__rlc_UM *PDCP_rlc_UM = CALLOC(1,sizeof(struct PDCP_Config__rlc_UM)); struct LogicalChannelConfig *DRB_lchan_config = CALLOC(1,sizeof(struct LogicalChannelConfig)); struct LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters = CALLOC(1, sizeof(struct LogicalChannelConfig__ul_SpecificParameters)); long *logicalchannelgroup_drb = CALLOC(1, sizeof(long)); DRB_rlc_config->present = RLC_Config_PR_um_Bi_Directional; DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = SN_FieldLength_size10; DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = SN_FieldLength_size10; DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = T_Reordering_ms35; UE->DRB_config[0][0]->rlc_Config = DRB_rlc_config; UE->DRB_config[0][1]->rlc_Config = DRB_rlc_config; DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); UE->DRB_config[0][0]->pdcp_Config = DRB_pdcp_config; UE->DRB_config[0][1]->pdcp_Config = DRB_pdcp_config; DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); *DRB_pdcp_config->discardTimer = PDCP_Config__discardTimer_infinity; DRB_pdcp_config->rlc_AM = NULL; DRB_pdcp_config->rlc_UM = NULL; // avoid gcc warnings (void)PDCP_rlc_UM; DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; PDCP_rlc_UM->pdcp_SN_Size = PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; DRB_pdcp_config->headerCompression.present = PDCP_Config__headerCompression_PR_notUsed; UE->DRB_config[0][0]->logicalChannelConfig = DRB_lchan_config; UE->DRB_config[0][1]->logicalChannelConfig = DRB_lchan_config; DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters)); DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; DRB_ul_SpecificParameters->priority = 12; // lower priority than srb1, srb2 and other dedicated bearer DRB_ul_SpecificParameters->prioritisedBitRate =LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; DRB_ul_SpecificParameters->bucketSizeDuration = LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM) *logicalchannelgroup_drb = 1; DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; UE->DRB_configList = CALLOC(1,sizeof(DRB_ToAddModList_t)); ASN_SEQUENCE_ADD(&UE->DRB_configList->list,UE->DRB_config[0][0]); ASN_SEQUENCE_ADD(&UE->DRB_configList->list,UE->DRB_config[0][1]); rrc_pdcp_config_asn1_req(&ctxt, (SRB_ToAddModList_t *) NULL, UE->DRB_configList, (DRB_ToReleaseList_t*) NULL, 0xff, NULL, NULL, NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) , (LTE_PMCH_InfoList_r9_t *) NULL #endif ,NULL); rrc_rlc_config_asn1_req(&ctxt, (SRB_ToAddModList_t*)NULL, UE->DRB_configList, (DRB_ToReleaseList_t*)NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,(LTE_PMCH_InfoList_r9_t *)NULL #endif ); */ } #endif //----------------------------------------------------------------------------- void openair_rrc_ue_init_security( const protocol_ctxt_t *const ctxt_pP ) { // uint8_t *kRRCenc; // uint8_t *kRRCint; char ascii_buffer[65]; uint8_t i; memset(UE_rrc_inst[ctxt_pP->module_id].kenb, ctxt_pP->module_id, 32); for (i = 0; i < 32; i++) { sprintf(&ascii_buffer[2 * i], "%02X", UE_rrc_inst[ctxt_pP->module_id].kenb[i]); } LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT"[OSA] kenb = %s\n", PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), ascii_buffer); } //----------------------------------------------------------------------------- char openair_rrc_ue_init( const module_id_t ue_mod_idP, const unsigned char eNB_index ) { protocol_ctxt_t ctxt; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_idP, ENB_FLAG_NO, NOT_A_RNTI, 0, 0,eNB_index); LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Init...\n", PROTOCOL_RRC_CTXT_ARGS(&ctxt)); rrc_set_state (ue_mod_idP, RRC_STATE_INACTIVE); rrc_set_sub_state (ue_mod_idP, RRC_SUB_STATE_INACTIVE); LOG_I(RRC,"[UE %d] INIT State = RRC_IDLE (eNB %d)\n",ctxt.module_id,eNB_index); UE_rrc_inst[ctxt.module_id].Info[eNB_index].State=RRC_IDLE; UE_rrc_inst[ctxt.module_id].Info[eNB_index].T300_active = 0; UE_rrc_inst[ctxt.module_id].Info[eNB_index].T304_active = 0; UE_rrc_inst[ctxt.module_id].Info[eNB_index].T310_active = 0; UE_rrc_inst[ctxt.module_id].Info[eNB_index].UE_index=0xffff; UE_rrc_inst[ctxt.module_id].Srb0[eNB_index].Active=0; UE_rrc_inst[ctxt.module_id].Srb1[eNB_index].Active=0; UE_rrc_inst[ctxt.module_id].Srb2[eNB_index].Active=0; UE_rrc_inst[ctxt.module_id].HandoverInfoUe.measFlag=1; UE_rrc_inst[ctxt.module_id].ciphering_algorithm = LTE_CipheringAlgorithm_r12_eea0; #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 2, 0)) UE_rrc_inst[ctxt.module_id].integrity_algorithm = LTE_SecurityAlgorithmConfig__integrityProtAlgorithm_eia0_v920; #else UE_rrc_inst[ctxt.module_id].integrity_algorithm = LTE_SecurityAlgorithmConfig__integrityProtAlgorithm_reserved; #endif openair_rrc_ue_init_security(&ctxt); init_SI_UE(&ctxt,eNB_index); LOG_D(RRC,PROTOCOL_RRC_CTXT_FMT" INIT: phy_sync_2_ch_ind\n", PROTOCOL_RRC_CTXT_ARGS(&ctxt)); #ifndef NO_RRM send_msg(&S_rrc,msg_rrc_phy_synch_to_CH_ind(ctxt.module_id,eNB_index,UE_rrc_inst[ctxt.module_id].Mac_id)); #endif #ifndef NO_RRM send_msg(&S_rrc,msg_rrc_phy_synch_to_CH_ind(ctxt.module_id,eNB_index,UE_rrc_inst[ctxt.module_id].Mac_id)); #endif #ifdef NO_RRM //init ch SRB0, SRB1 & BDTCH openair_rrc_on_ue(&ctxt); #endif #ifdef CBA int j; for(j=0; j<NUM_MAX_CBA_GROUP; j++) { UE_rrc_inst[ue_mod_idP].cba_rnti[j] = 0x0000; } UE_rrc_inst[ue_mod_idP].num_active_cba_groups = 0; #endif return 0; } //----------------------------------------------------------------------------- void rrc_ue_generate_RRCConnectionRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) { uint8_t i=0,rv[6]; if(UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Tx_buffer.payload_size ==0) { // Get RRCConnectionRequest, fill random for now // Generate random byte stream for contention resolution for (i=0; i<6; i++) { #ifdef SMBV // if SMBV is configured the contention resolution needs to be fix for the connection procedure to succeed rv[i]=i; #else rv[i]=taus()&0xff; #endif LOG_T(RRC,"%x.",rv[i]); } LOG_T(RRC,"\n"); UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Tx_buffer.payload_size = do_RRCConnectionRequest( ctxt_pP->module_id, (uint8_t *)UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Tx_buffer.Payload, rv); LOG_I(RRC,"[UE %d] : Frame %d, Logical Channel UL-CCCH (SRB0), Generating RRCConnectionRequest (bytes %d, eNB %d)\n", ctxt_pP->module_id, ctxt_pP->frame, UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Tx_buffer.payload_size, eNB_index); for (i=0; i<UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Tx_buffer.payload_size; i++) { LOG_T(RRC,"%x.",UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Tx_buffer.Payload[i]); } LOG_T(RRC,"\n"); /*UE_rrc_inst[ue_mod_idP].Srb0[Idx].Tx_buffer.Payload[i] = taus()&0xff; UE_rrc_inst[ue_mod_idP].Srb0[Idx].Tx_buffer.payload_size =i; */ } } mui_t rrc_mui=0; /* NAS Attach request with IMSI */ static const char nas_attach_req_imsi[] = { 0x07, 0x41, /* EPS Mobile identity = IMSI */ 0x71, 0x08, 0x29, 0x80, 0x43, 0x21, 0x43, 0x65, 0x87, 0xF9, /* End of EPS Mobile Identity */ 0x02, 0xE0, 0xE0, 0x00, 0x20, 0x02, 0x03, 0xD0, 0x11, 0x27, 0x1A, 0x80, 0x80, 0x21, 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00, 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x0A, 0x00, 0x52, 0x12, 0xF2, 0x01, 0x27, 0x11, }; //----------------------------------------------------------------------------- void rrc_t310_expiration( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) //----------------------------------------------------------------------------- { if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State != RRC_CONNECTED) { LOG_D(RRC, "Timer 310 expired, going to RRC_IDLE\n"); UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State = RRC_IDLE; UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].UE_index = 0xffff; UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Rx_buffer.payload_size = 0; UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Tx_buffer.payload_size = 0; UE_rrc_inst[ctxt_pP->module_id].Srb1[eNB_index].Srb_info.Rx_buffer.payload_size = 0; UE_rrc_inst[ctxt_pP->module_id].Srb1[eNB_index].Srb_info.Tx_buffer.payload_size = 0; if (UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Active == 1) { LOG_D (RRC,"[Inst %d] eNB_index %d, Remove RB %d\n ", ctxt_pP->module_id, eNB_index, UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Srb_info.Srb_id); rrc_pdcp_config_req (ctxt_pP, SRB_FLAG_YES, CONFIG_ACTION_REMOVE, UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Srb_info.Srb_id, 0); rrc_rlc_config_req (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, CONFIG_ACTION_REMOVE, UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Srb_info.Srb_id, Rlc_info_um); UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Active = 0; UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Status = IDLE; UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Next_check_frame = 0; } } else { // Restablishment procedure LOG_D(RRC, "Timer 310 expired, trying RRCRestablishment ...\n"); } } //----------------------------------------------------------------------------- static void rrc_ue_generate_RRCConnectionSetupComplete( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t Transaction_id ) { uint8_t buffer[100]; uint8_t size; const char *nas_msg; int nas_msg_length; if (EPC_MODE_ENABLED) { nas_msg = (char *) UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data; nas_msg_length = UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.length; } else { nas_msg = nas_attach_req_imsi; nas_msg_length = sizeof(nas_attach_req_imsi); } size = do_RRCConnectionSetupComplete(ctxt_pP->module_id, 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", ctxt_pP->module_id,ctxt_pP->frame, size, eNB_index); LOG_D(RLC, "[FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCConnectionSetupComplete to eNB %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n", ctxt_pP->frame, ctxt_pP->module_id+NB_eNB_INST, size, eNB_index, rrc_mui, ctxt_pP->module_id+NB_eNB_INST, DCCH); rrc_data_req_ue ( ctxt_pP, DCCH, rrc_mui++, SDU_CONFIRM_NO, size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); } //----------------------------------------------------------------------------- void rrc_ue_generate_RRCConnectionReconfigurationComplete( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t Transaction_id ) { uint8_t buffer[32], size; size = do_RRCConnectionReconfigurationComplete(ctxt_pP, buffer, Transaction_id); LOG_I(RRC,PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel UL-DCCH (SRB1), Generating RRCConnectionReconfigurationComplete (bytes %d, eNB_index %d)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), size, eNB_index); LOG_D(RLC, "[FRAME %05d][RRC_UE][INST %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCConnectionReconfigurationComplete to eNB %d MUI %d) --->][PDCP][INST %02d][RB %02d]\n", ctxt_pP->frame, UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), size, eNB_index, rrc_mui, UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), DCCH); rrc_data_req_ue ( ctxt_pP, DCCH, rrc_mui++, SDU_CONFIRM_NO, size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); } //----------------------------------------------------------------------------- // Called by L2 interface (MAC) int rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const SRB_INFO *const Srb_info, const uint8_t eNB_index ) { LTE_DL_CCCH_Message_t *dl_ccch_msg=NULL; asn_dec_rval_t dec_rval; int rval=0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN); // LOG_D(RRC,"[UE %d] Decoding DL-CCCH message (%d bytes), State %d\n",ue_mod_idP,Srb_info->Rx_buffer.payload_size, // UE_rrc_inst[ue_mod_idP].Info[eNB_index].State); dec_rval = uper_decode(NULL, &asn_DEF_LTE_DL_CCCH_Message, (void **)&dl_ccch_msg, (uint8_t *)Srb_info->Rx_buffer.Payload, 100,0,0); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout,&asn_DEF_LTE_DL_CCCH_Message,(void *)dl_ccch_msg); } if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) { LOG_E(RRC,"[UE %d] Frame %d : Failed to decode DL-CCCH-Message (%zu bytes)\n",ctxt_pP->module_id,ctxt_pP->frame,dec_rval.consumed); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT); return -1; } if (dl_ccch_msg->message.present == LTE_DL_CCCH_MessageType_PR_c1) { if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State == RRC_SI_RECEIVED) { switch (dl_ccch_msg->message.choice.c1.present) { case LTE_DL_CCCH_MessageType__c1_PR_NOTHING: LOG_I(RRC, "[UE%d] Frame %d : Received PR_NOTHING on DL-CCCH-Message\n", ctxt_pP->module_id, ctxt_pP->frame); rval = 0; break; case LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishment: LOG_I(RRC, "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReestablishment\n", ctxt_pP->module_id, ctxt_pP->frame); rval = 0; break; case LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentReject: LOG_I(RRC, "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReestablishmentReject\n", ctxt_pP->module_id, ctxt_pP->frame); rval = 0; break; case LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionReject: LOG_I(RRC, "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReject \n", ctxt_pP->module_id, ctxt_pP->frame); rval = 0; break; case LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionSetup: LOG_I(RRC, "[UE%d][RAPROC] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionSetup RNTI %x\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rnti); // Get configuration // Release T300 timer UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].T300_active = 0; rrc_ue_process_radioResourceConfigDedicated( ctxt_pP, eNB_index, &dl_ccch_msg->message.choice.c1.choice.rrcConnectionSetup.criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated); rrc_set_state (ctxt_pP->module_id, RRC_STATE_CONNECTED); rrc_set_sub_state (ctxt_pP->module_id, RRC_SUB_STATE_CONNECTED); UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].rnti = ctxt_pP->rnti; rrc_ue_generate_RRCConnectionSetupComplete( ctxt_pP, eNB_index, dl_ccch_msg->message.choice.c1.choice.rrcConnectionSetup.rrc_TransactionIdentifier); rval = 0; break; default: LOG_E(RRC, "[UE%d] Frame %d : Unknown message\n", ctxt_pP->module_id, ctxt_pP->frame); rval = -1; break; } } } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT); return rval; } //----------------------------------------------------------------------------- int32_t rrc_ue_establish_srb1( module_id_t ue_mod_idP, frame_t frameP, uint8_t eNB_index, struct LTE_SRB_ToAddMod *SRB_config ) //----------------------------------------------------------------------------- { // add descriptor from RRC PDU UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Active = 1; UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Status = RADIO_CONFIG_OK;//RADIO CFG UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Srb_info.Srb_id = 1; // copy default configuration for now // memcpy(&UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Srb_info.Lchan_desc[0],&DCCH_LCHAN_DESC,LCHAN_DESC_SIZE); // memcpy(&UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Srb_info.Lchan_desc[1],&DCCH_LCHAN_DESC,LCHAN_DESC_SIZE); LOG_I(RRC,"[UE %d], CONFIG_SRB1 %d corresponding to eNB_index %d\n", ue_mod_idP,DCCH,eNB_index); //rrc_pdcp_config_req (ue_mod_idP+NB_eNB_INST, frameP, 0, CONFIG_ACTION_ADD, lchan_id,UNDEF_SECURITY_MODE); // rrc_rlc_config_req(ue_mod_idP+NB_eNB_INST,frameP,0,CONFIG_ACTION_ADD,lchan_id,SIGNALLING_RADIO_BEARER,Rlc_info_am_config); // UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Srb_info.Tx_buffer.payload_size=DEFAULT_MEAS_IND_SIZE+1; return(0); } //----------------------------------------------------------------------------- int32_t rrc_ue_establish_srb2( module_id_t ue_mod_idP, frame_t frameP, uint8_t eNB_index, struct LTE_SRB_ToAddMod *SRB_config ) //----------------------------------------------------------------------------- { // add descriptor from RRC PDU UE_rrc_inst[ue_mod_idP].Srb2[eNB_index].Active = 1; UE_rrc_inst[ue_mod_idP].Srb2[eNB_index].Status = RADIO_CONFIG_OK;//RADIO CFG UE_rrc_inst[ue_mod_idP].Srb2[eNB_index].Srb_info.Srb_id = 2; // copy default configuration for now // memcpy(&UE_rrc_inst[ue_mod_idP].Srb2[eNB_index].Srb_info.Lchan_desc[0],&DCCH_LCHAN_DESC,LCHAN_DESC_SIZE); // memcpy(&UE_rrc_inst[ue_mod_idP].Srb2[eNB_index].Srb_info.Lchan_desc[1],&DCCH_LCHAN_DESC,LCHAN_DESC_SIZE); LOG_I(RRC,"[UE %d], CONFIG_SRB2 %d corresponding to eNB_index %d\n",ue_mod_idP,DCCH1,eNB_index); //rrc_pdcp_config_req (ue_mod_idP+NB_eNB_INST, frameP, 0, CONFIG_ACTION_ADD, lchan_id, UNDEF_SECURITY_MODE); // rrc_rlc_config_req(ue_mod_idP+NB_eNB_INST,frameP,0,CONFIG_ACTION_ADD,lchan_id,SIGNALLING_RADIO_BEARER,Rlc_info_am_config); // UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Srb_info.Tx_buffer.payload_size=DEFAULT_MEAS_IND_SIZE+1; return(0); } //----------------------------------------------------------------------------- int32_t rrc_ue_establish_drb( module_id_t ue_mod_idP, frame_t frameP, uint8_t eNB_index, struct LTE_DRB_ToAddMod *DRB_config ) //----------------------------------------------------------------------------- { // add descriptor from RRC PDU int oip_ifup=0,ip_addr_offset3=0,ip_addr_offset4=0; /* avoid gcc warnings */ (void)oip_ifup; (void)ip_addr_offset3; (void)ip_addr_offset4; LOG_I(RRC,"[UE %d] Frame %d: processing RRCConnectionReconfiguration: reconfiguring DRB %ld/LCID %d\n", ue_mod_idP, frameP, DRB_config->drb_Identity, (int)*DRB_config->logicalChannelIdentity); /* rrc_pdcp_config_req (ue_mod_idP+NB_eNB_INST, frameP, 0, CONFIG_ACTION_ADD, (eNB_index * NB_RB_MAX) + *DRB_config->logicalChannelIdentity, UNDEF_SECURITY_MODE); rrc_rlc_config_req(ue_mod_idP+NB_eNB_INST,frameP,0,CONFIG_ACTION_ADD, (eNB_index * NB_RB_MAX) + *DRB_config->logicalChannelIdentity, RADIO_ACCESS_BEARER,Rlc_info_um); */ if(PDCP_USE_NETLINK) { # if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(ETHERNET) && !defined(LINK_ENB_PDCP_TO_GTPV1U) ip_addr_offset3 = 0; ip_addr_offset4 = 1; LOG_I(OIP,"[UE %d] trying to bring up the OAI interface oai%d, IP 10.0.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP, ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1); oip_ifup=nas_config(ip_addr_offset3+ue_mod_idP, // interface_id ip_addr_offset3+ue_mod_idP+1, // third_octet ip_addr_offset4+ue_mod_idP+1); // fourth_octet if (oip_ifup == 0 ) { // interface is up --> send a config the DRB LOG_I(OIP,"[UE %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP, (long int)((eNB_index * maxDRB) + DRB_config->drb_Identity)); rb_conf_ipv4(0,//add ue_mod_idP,//cx align with the UE index ip_addr_offset3+ue_mod_idP,//inst num_enb+ue_index (eNB_index * maxDRB) + DRB_config->drb_Identity,//rb 0,//dscp ipv4_address(ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1),//saddr ipv4_address(ip_addr_offset3+ue_mod_idP+1,eNB_index+1));//daddr LOG_D(RRC,"[UE %d] State = Attached (eNB %d)\n",ue_mod_idP,eNB_index); } # endif } return(0); } //----------------------------------------------------------------------------- void rrc_ue_process_measConfig( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, LTE_MeasConfig_t *const measConfig ) //----------------------------------------------------------------------------- { // This is the procedure described in 36.331 Section 5.5.2.1 int i; long ind; LTE_MeasObjectToAddMod_t *measObj; if (measConfig->measObjectToRemoveList != NULL) { for (i=0; i<measConfig->measObjectToRemoveList->list.count; i++) { ind = *measConfig->measObjectToRemoveList->list.array[i]; free(UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index][ind-1]); } } if (measConfig->measObjectToAddModList != NULL) { LOG_D(RRC,"Measurement Object List is present\n"); for (i=0; i<measConfig->measObjectToAddModList->list.count; i++) { measObj = measConfig->measObjectToAddModList->list.array[i]; ind = measConfig->measObjectToAddModList->list.array[i]->measObjectId; if (UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index][ind-1]) { LOG_D(RRC,"Modifying measurement object %ld\n",ind); memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index][ind-1], (char *)measObj, sizeof(LTE_MeasObjectToAddMod_t)); } else { LOG_I(RRC,"Adding measurement object %ld\n",ind); if (measObj->measObject.present == LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA) { LOG_I(RRC,"EUTRA Measurement : carrierFreq %ld, allowedMeasBandwidth %ld,presenceAntennaPort1 %d, neighCellConfig %d\n", measObj->measObject.choice.measObjectEUTRA.carrierFreq, measObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth, measObj->measObject.choice.measObjectEUTRA.presenceAntennaPort1, measObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf[0]); UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index][ind-1]=measObj; } } } LOG_I(RRC,"call rrc_mac_config_req \n"); rrc_mac_config_req_ue(ctxt_pP->module_id,0,eNB_index, (LTE_RadioResourceConfigCommonSIB_t *)NULL, (struct LTE_PhysicalConfigDedicated *)NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (LTE_SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index], (LTE_MAC_MainConfig_t *)NULL, 0, (struct LTE_LogicalChannelConfig *)NULL, (LTE_MeasGapConfig_t *)NULL, (LTE_TDD_Config_t *)NULL, (LTE_MobilityControlInfo_t *)NULL, NULL, NULL, NULL, NULL, NULL, NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,0, (LTE_MBSFN_AreaInfoList_r9_t *)NULL, (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA , 0, 0 #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , 0, NULL, NULL #endif ); } if (measConfig->reportConfigToRemoveList != NULL) { for (i=0; i<measConfig->reportConfigToRemoveList->list.count; i++) { ind = *measConfig->reportConfigToRemoveList->list.array[i]; free(UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1]); } } if (measConfig->reportConfigToAddModList != NULL) { LOG_I(RRC,"Report Configuration List is present\n"); for (i=0; i<measConfig->reportConfigToAddModList->list.count; i++) { ind = measConfig->reportConfigToAddModList->list.array[i]->reportConfigId; if (UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1]) { LOG_I(RRC,"Modifying Report Configuration %ld\n",ind-1); memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1], (char *)measConfig->reportConfigToAddModList->list.array[i], sizeof(LTE_ReportConfigToAddMod_t)); } else { LOG_D(RRC,"Adding Report Configuration %ld %p \n",ind-1,measConfig->reportConfigToAddModList->list.array[i]); UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1] = measConfig->reportConfigToAddModList->list.array[i]; } } } if (measConfig->quantityConfig != NULL) { if (UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index]) { LOG_D(RRC,"Modifying Quantity Configuration \n"); memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index], (char *)measConfig->quantityConfig, sizeof(LTE_QuantityConfig_t)); } else { LOG_D(RRC,"Adding Quantity configuration\n"); UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index] = measConfig->quantityConfig; } } if (measConfig->measIdToRemoveList != NULL) { for (i=0; i<measConfig->measIdToRemoveList->list.count; i++) { ind = *measConfig->measIdToRemoveList->list.array[i]; free(UE_rrc_inst[ctxt_pP->module_id].MeasId[eNB_index][ind-1]); } } if (measConfig->measIdToAddModList != NULL) { for (i=0; i<measConfig->measIdToAddModList->list.count; i++) { ind = measConfig->measIdToAddModList->list.array[i]->measId; if (UE_rrc_inst[ctxt_pP->module_id].MeasId[eNB_index][ind-1]) { LOG_D(RRC,"Modifying Measurement ID %ld\n",ind-1); memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].MeasId[eNB_index][ind-1], (char *)measConfig->measIdToAddModList->list.array[i], sizeof(LTE_MeasIdToAddMod_t)); } else { LOG_D(RRC,"Adding Measurement ID %ld %p\n",ind-1,measConfig->measIdToAddModList->list.array[i]); UE_rrc_inst[ctxt_pP->module_id].MeasId[eNB_index][ind-1] = measConfig->measIdToAddModList->list.array[i]; } } } if (measConfig->measGapConfig !=NULL) { if (UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index]) { memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index], (char *)measConfig->measGapConfig, sizeof(LTE_MeasGapConfig_t)); } else { UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index] = measConfig->measGapConfig; } } if (measConfig->quantityConfig != NULL) { if (UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index]) { LOG_I(RRC,"Modifying Quantity Configuration \n"); memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index], (char *)measConfig->quantityConfig, sizeof(LTE_QuantityConfig_t)); } else { LOG_I(RRC,"Adding Quantity configuration\n"); UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index] = measConfig->quantityConfig; } UE_rrc_inst[ctxt_pP->module_id].filter_coeff_rsrp = 1./pow(2, (*UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRP)/4); UE_rrc_inst[ctxt_pP->module_id].filter_coeff_rsrq = 1./pow(2, (*UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRQ)/4); LOG_I(RRC,"[UE %d] set rsrp-coeff for eNB %d: %ld rsrq-coeff: %ld rsrp_factor: %f rsrq_factor: %f \n", ctxt_pP->module_id, eNB_index, // UE_rrc_inst[ue_mod_idP].Info[eNB_index].UE_index, *UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRP, *UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRQ, UE_rrc_inst[ctxt_pP->module_id].filter_coeff_rsrp, UE_rrc_inst[ctxt_pP->module_id].filter_coeff_rsrq); } if (measConfig->s_Measure != NULL) { UE_rrc_inst[ctxt_pP->module_id].s_measure = *measConfig->s_Measure; } if (measConfig->speedStatePars != NULL) { if (UE_rrc_inst[ctxt_pP->module_id].speedStatePars) { memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].speedStatePars,(char *)measConfig->speedStatePars,sizeof(struct LTE_MeasConfig__speedStatePars)); } else { UE_rrc_inst[ctxt_pP->module_id].speedStatePars = measConfig->speedStatePars; } LOG_I(RRC,"[UE %d] Configuring mobility optimization params for UE %d \n", ctxt_pP->module_id,UE_rrc_inst[ctxt_pP->module_id].Info[0].UE_index); } } void rrc_ue_update_radioResourceConfigDedicated(LTE_RadioResourceConfigDedicated_t *radioResourceConfigDedicated, const protocol_ctxt_t *const ctxt_pP, uint8_t eNB_index) { LTE_PhysicalConfigDedicated_t *physicalConfigDedicated2 = NULL; physicalConfigDedicated2 = CALLOC(1,sizeof(*physicalConfigDedicated2)); physicalConfigDedicated2->pdsch_ConfigDedicated = CALLOC(1,sizeof(*physicalConfigDedicated2->pdsch_ConfigDedicated)); physicalConfigDedicated2->pusch_ConfigDedicated = CALLOC(1,sizeof(*physicalConfigDedicated2->pusch_ConfigDedicated)); physicalConfigDedicated2->pucch_ConfigDedicated = CALLOC(1,sizeof(*physicalConfigDedicated2->pucch_ConfigDedicated)); physicalConfigDedicated2->cqi_ReportConfig = CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig)); physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic = CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic)); physicalConfigDedicated2->soundingRS_UL_ConfigDedicated = CALLOC(1,sizeof(*physicalConfigDedicated2->soundingRS_UL_ConfigDedicated)); physicalConfigDedicated2->schedulingRequestConfig = CALLOC(1,sizeof(*physicalConfigDedicated2->schedulingRequestConfig)); physicalConfigDedicated2->antennaInfo = CALLOC(1,sizeof(*physicalConfigDedicated2->antennaInfo)); physicalConfigDedicated2->uplinkPowerControlDedicated = CALLOC(1,sizeof(*physicalConfigDedicated2->uplinkPowerControlDedicated)); physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH = CALLOC(1,sizeof(*physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH)); physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH = CALLOC(1,sizeof(*physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH)); // Update pdsch_ConfigDedicated if(radioResourceConfigDedicated->physicalConfigDedicated->pdsch_ConfigDedicated != NULL) { LOG_I(RRC,"Update pdsch_ConfigDedicated config \n"); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pdsch_ConfigDedicated == NULL) UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pdsch_ConfigDedicated = CALLOC(1,sizeof(LTE_PDSCH_ConfigDedicated_t)); memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pdsch_ConfigDedicated, (char *)radioResourceConfigDedicated->physicalConfigDedicated->pdsch_ConfigDedicated, sizeof(physicalConfigDedicated2->pdsch_ConfigDedicated)); } else { LOG_I(RRC,"Keep old config for pdsch_ConfigDedicated\n"); } // Update pusch_ConfigDedicated if(radioResourceConfigDedicated->physicalConfigDedicated->pusch_ConfigDedicated != NULL) { LOG_I(RRC,"Update pusch_ConfigDedicated config \n"); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pusch_ConfigDedicated == NULL) UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pusch_ConfigDedicated = CALLOC(1,sizeof(LTE_PUSCH_ConfigDedicated_t)); memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pusch_ConfigDedicated, (char *)radioResourceConfigDedicated->physicalConfigDedicated->pusch_ConfigDedicated, sizeof(physicalConfigDedicated2->pusch_ConfigDedicated)); } else { LOG_I(RRC,"Keep old config for pusch_ConfigDedicated\n"); } // Update pucch_ConfigDedicated if(radioResourceConfigDedicated->physicalConfigDedicated->pucch_ConfigDedicated != NULL) { LOG_I(RRC,"Update pucch_ConfigDedicated config \n"); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pucch_ConfigDedicated == NULL) UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pucch_ConfigDedicated = CALLOC(1,sizeof(LTE_PUCCH_ConfigDedicated_t)); memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pucch_ConfigDedicated, (char *)radioResourceConfigDedicated->physicalConfigDedicated->pucch_ConfigDedicated, sizeof(physicalConfigDedicated2->pucch_ConfigDedicated)); } else { LOG_I(RRC,"Keep old config for pucch_ConfigDedicated\n"); } // Update cqi_ReportConfig if(radioResourceConfigDedicated->physicalConfigDedicated->cqi_ReportConfig != NULL) { LOG_I(RRC,"Update cqi_ReportConfig config (size=%zu,%zu)\n", sizeof(*physicalConfigDedicated2->cqi_ReportConfig), sizeof(LTE_CQI_ReportConfig_t)); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig == NULL) UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig = CALLOC(1,sizeof(LTE_CQI_ReportConfig_t)); memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig, (char *)radioResourceConfigDedicated->physicalConfigDedicated->cqi_ReportConfig, sizeof(*physicalConfigDedicated2->cqi_ReportConfig)); if (radioResourceConfigDedicated->physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic != NULL) { LOG_I(RRC,"Update cqi_ReportPeriodic config (size=%zu,%zu)\n", sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic), sizeof(LTE_CQI_ReportPeriodic_t)); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig->cqi_ReportPeriodic == NULL) UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig->cqi_ReportPeriodic = CALLOC(1,sizeof(LTE_CQI_ReportPeriodic_t)); memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig->cqi_ReportPeriodic, (char *)radioResourceConfigDedicated->physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic, sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic)); } } else { LOG_I(RRC,"Keep old config for cqi_ReportConfig\n"); } // Update schedulingRequestConfig if(radioResourceConfigDedicated->physicalConfigDedicated->schedulingRequestConfig != NULL) { LOG_I(RRC,"Update schedulingRequestConfig config \n"); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->schedulingRequestConfig == NULL) UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->schedulingRequestConfig = CALLOC(1,sizeof(LTE_SchedulingRequestConfig_t)); memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->schedulingRequestConfig, (char *)radioResourceConfigDedicated->physicalConfigDedicated->schedulingRequestConfig, sizeof(physicalConfigDedicated2->schedulingRequestConfig)); } else { LOG_I(RRC,"Keep old config for schedulingRequestConfig\n"); } // Update soundingRS_UL_ConfigDedicated if(radioResourceConfigDedicated->physicalConfigDedicated->soundingRS_UL_ConfigDedicated != NULL) { LOG_I(RRC,"Update soundingRS_UL_ConfigDedicated config \n"); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->soundingRS_UL_ConfigDedicated == NULL) UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->soundingRS_UL_ConfigDedicated = CALLOC(1,sizeof(LTE_SoundingRS_UL_ConfigDedicated_t)); memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->soundingRS_UL_ConfigDedicated, (char *)radioResourceConfigDedicated->physicalConfigDedicated->soundingRS_UL_ConfigDedicated, sizeof(physicalConfigDedicated2->soundingRS_UL_ConfigDedicated)); } else { LOG_I(RRC,"Keep old config for soundingRS_UL_ConfigDedicated\n"); } // Update antennaInfo if(radioResourceConfigDedicated->physicalConfigDedicated->antennaInfo != NULL) { LOG_I(RRC,"Update antennaInfo config \n"); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo == NULL) UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo = CALLOC(1,sizeof(struct LTE_PhysicalConfigDedicated__antennaInfo)); memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo, (char *)radioResourceConfigDedicated->physicalConfigDedicated->antennaInfo, sizeof(physicalConfigDedicated2->antennaInfo)); UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo->choice.explicitValue.transmissionMode = radioResourceConfigDedicated->physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode; UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo->choice.explicitValue.codebookSubsetRestriction = radioResourceConfigDedicated->physicalConfigDedicated->antennaInfo->choice.explicitValue.codebookSubsetRestriction; UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection = radioResourceConfigDedicated->physicalConfigDedicated->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection; LOG_I(PHY,"New Transmission Mode %ld \n",radioResourceConfigDedicated->physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode); LOG_I(PHY,"Configured Transmission Mode %ld \n",UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo->choice.explicitValue.transmissionMode); } else { LOG_I(RRC,"Keep old config for antennaInfo\n"); } // Update uplinkPowerControlDedicated if(radioResourceConfigDedicated->physicalConfigDedicated->uplinkPowerControlDedicated != NULL) { LOG_I(RRC,"Update uplinkPowerControlDedicated config \n"); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->uplinkPowerControlDedicated == NULL) UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->uplinkPowerControlDedicated = CALLOC(1,sizeof(LTE_UplinkPowerControlDedicated_t)); memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->uplinkPowerControlDedicated, (char *)radioResourceConfigDedicated->physicalConfigDedicated->uplinkPowerControlDedicated, sizeof(physicalConfigDedicated2->uplinkPowerControlDedicated)); } else { LOG_I(RRC,"Keep old config for uplinkPowerControlDedicated\n"); } // Update tpc_PDCCH_ConfigPUCCH if(radioResourceConfigDedicated->physicalConfigDedicated->tpc_PDCCH_ConfigPUCCH != NULL) { LOG_I(RRC,"Update tpc_PDCCH_ConfigPUCCH config \n"); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->tpc_PDCCH_ConfigPUCCH == NULL) UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->tpc_PDCCH_ConfigPUCCH = CALLOC(1,sizeof(LTE_TPC_PDCCH_Config_t)); memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->tpc_PDCCH_ConfigPUCCH, (char *)radioResourceConfigDedicated->physicalConfigDedicated->tpc_PDCCH_ConfigPUCCH, sizeof(physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH)); } else { LOG_I(RRC,"Keep old config for tpc_PDCCH_ConfigPUCCH\n"); } // Update tpc_PDCCH_ConfigPUSCH if(radioResourceConfigDedicated->physicalConfigDedicated->tpc_PDCCH_ConfigPUSCH != NULL) { LOG_I(RRC,"Update tpc_PDCCH_ConfigPUSCH config \n"); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->tpc_PDCCH_ConfigPUSCH == NULL) UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->tpc_PDCCH_ConfigPUSCH = CALLOC(1,sizeof(LTE_TPC_PDCCH_Config_t)); memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->tpc_PDCCH_ConfigPUSCH, (char *)radioResourceConfigDedicated->physicalConfigDedicated->tpc_PDCCH_ConfigPUSCH, sizeof(physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH)); } else { LOG_I(RRC,"Keep old config for tpc_PDCCH_ConfigPUSCH\n"); } } //----------------------------------------------------------------------------- void rrc_ue_process_radioResourceConfigDedicated( const protocol_ctxt_t *const ctxt_pP, uint8_t eNB_index, LTE_RadioResourceConfigDedicated_t *radioResourceConfigDedicated ) //----------------------------------------------------------------------------- { long SRB_id,DRB_id; int i,cnt; LTE_LogicalChannelConfig_t *SRB1_logicalChannelConfig,*SRB2_logicalChannelConfig; #ifdef CBA uint8_t cba_found = 0; uint16_t cba_RNTI; #endif // Save physicalConfigDedicated if present if (radioResourceConfigDedicated->physicalConfigDedicated) { LOG_I(RRC,"Save physicalConfigDedicated if present \n"); if (UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]) { #if 1 rrc_ue_update_radioResourceConfigDedicated(radioResourceConfigDedicated, ctxt_pP, eNB_index); #else memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index],(char *)radioResourceConfigDedicated->physicalConfigDedicated, sizeof(struct PhysicalConfigDedicated)); #endif } else { LOG_I(RRC,"Init physicalConfigDedicated UE_rrc_inst to radioResourceConfigDedicated->physicalConfigDedicated\n"); UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index] = radioResourceConfigDedicated->physicalConfigDedicated; } } // Apply macMainConfig if present if (radioResourceConfigDedicated->mac_MainConfig) { if (radioResourceConfigDedicated->mac_MainConfig->present == LTE_RadioResourceConfigDedicated__mac_MainConfig_PR_explicitValue) { if (UE_rrc_inst[ctxt_pP->module_id].mac_MainConfig[eNB_index]) { memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].mac_MainConfig[eNB_index],(char *)&radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue, sizeof(LTE_MAC_MainConfig_t)); } else { UE_rrc_inst[ctxt_pP->module_id].mac_MainConfig[eNB_index] = &radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue; } } } // Apply spsConfig if present if (radioResourceConfigDedicated->sps_Config) { if (UE_rrc_inst[ctxt_pP->module_id].sps_Config[eNB_index]) { memcpy(UE_rrc_inst[ctxt_pP->module_id].sps_Config[eNB_index],radioResourceConfigDedicated->sps_Config, sizeof(struct LTE_SPS_Config)); } else { UE_rrc_inst[ctxt_pP->module_id].sps_Config[eNB_index] = radioResourceConfigDedicated->sps_Config; } } #ifdef CBA if (radioResourceConfigDedicated->cba_RNTI_vlola) { cba_RNTI = (uint16_t) (((radioResourceConfigDedicated->cba_RNTI_vlola->buf[1]&0xff) << 8) | (radioResourceConfigDedicated->cba_RNTI_vlola->buf[0]&0xff)); for (i=0 ; i< NUM_MAX_CBA_GROUP; i++) { if (UE_rrc_inst[ctxt_pP->module_id].cba_rnti[i] == cba_RNTI ) { cba_found=1; break; } else if (UE_rrc_inst[ctxt_pP->module_id].cba_rnti[i] == 0 ) { break; } } if (cba_found==0) { UE_rrc_inst[ctxt_pP->module_id].num_active_cba_groups++; UE_rrc_inst[ctxt_pP->module_id].cba_rnti[i]=cba_RNTI; LOG_D(RRC, "[UE %d] Frame %d: radioResourceConfigDedicated reveived CBA_RNTI = %x for group %d from eNB %d \n", ctxt_pP->module_id,frameP, UE_rrc_inst[ctxt_pP->module_id].cba_rnti[i], i, eNB_index); } } #endif // Establish SRBs if present // loop through SRBToAddModList if (radioResourceConfigDedicated->srb_ToAddModList) { uint8_t *kRRCenc = NULL; uint8_t *kRRCint = NULL; derive_key_rrc_enc(UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, &kRRCenc); derive_key_rrc_int(UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, &kRRCint); // Refresh SRBs rrc_pdcp_config_asn1_req(ctxt_pP, radioResourceConfigDedicated->srb_ToAddModList, (LTE_DRB_ToAddModList_t *)NULL, (LTE_DRB_ToReleaseList_t *)NULL, UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm | (UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm << 4), kRRCenc, kRRCint, NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,(LTE_PMCH_InfoList_r9_t *)NULL #endif ,NULL); // Refresh SRBs rrc_rlc_config_asn1_req(ctxt_pP, radioResourceConfigDedicated->srb_ToAddModList, (LTE_DRB_ToAddModList_t *)NULL, (LTE_DRB_ToReleaseList_t *)NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,(LTE_PMCH_InfoList_r9_t *)NULL , 0, 0 #endif ); #if ENABLE_RAL // first msg that includes srb config UE_rrc_inst[ctxt_pP->module_id].num_srb=radioResourceConfigDedicated->srb_ToAddModList->list.count; #endif for (cnt=0; cnt<radioResourceConfigDedicated->srb_ToAddModList->list.count; cnt++) { // connection_reestablishment_ind.num_srb+=1; SRB_id = radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]->srb_Identity; LOG_D(RRC,"[UE %d]: Frame %d SRB config cnt %d (SRB%ld)\n",ctxt_pP->module_id,ctxt_pP->frame,cnt,SRB_id); if (SRB_id == 1) { if (UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index]) { memcpy(UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index],radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt], sizeof(struct LTE_SRB_ToAddMod)); } else { UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index] = radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]; rrc_ue_establish_srb1(ctxt_pP->module_id,ctxt_pP->frame,eNB_index,radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]); if (UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index]->logicalChannelConfig) { if (UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index]->logicalChannelConfig->present == LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { SRB1_logicalChannelConfig = &UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index]->logicalChannelConfig->choice.explicitValue; } else { SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; } } else { SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; } LOG_I(RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB1 eNB %d) --->][MAC_UE][MOD %02d][]\n", ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id); rrc_mac_config_req_ue(ctxt_pP->module_id,0,eNB_index, (LTE_RadioResourceConfigCommonSIB_t *)NULL, UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index], #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (LTE_SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif (LTE_MeasObjectToAddMod_t **)NULL, UE_rrc_inst[ctxt_pP->module_id].mac_MainConfig[eNB_index], 1, SRB1_logicalChannelConfig, (LTE_MeasGapConfig_t *)NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , 0, (LTE_MBSFN_AreaInfoList_r9_t *)NULL, (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA , 0, 0 #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , 0, NULL, NULL #endif ); } } else { if (UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index]) { memcpy(UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index],radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt], sizeof(struct LTE_SRB_ToAddMod)); } else { UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index] = radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]; rrc_ue_establish_srb2(ctxt_pP->module_id,ctxt_pP->frame,eNB_index,radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]); if (UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index]->logicalChannelConfig) { if (UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index]->logicalChannelConfig->present == LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { LOG_I(RRC,"Applying Explicit SRB2 logicalChannelConfig\n"); SRB2_logicalChannelConfig = &UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index]->logicalChannelConfig->choice.explicitValue; } else { LOG_I(RRC,"Applying default SRB2 logicalChannelConfig\n"); SRB2_logicalChannelConfig = &SRB2_logicalChannelConfig_defaultValue; } } else { SRB2_logicalChannelConfig = &SRB2_logicalChannelConfig_defaultValue; } LOG_I(RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB2 eNB %d) --->][MAC_UE][MOD %02d][]\n", ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id); rrc_mac_config_req_ue(ctxt_pP->module_id,0,eNB_index, (LTE_RadioResourceConfigCommonSIB_t *)NULL, UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index], #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (LTE_SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif (LTE_MeasObjectToAddMod_t **)NULL, UE_rrc_inst[ctxt_pP->module_id].mac_MainConfig[eNB_index], 2, SRB2_logicalChannelConfig, UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index], (LTE_TDD_Config_t *)NULL, (LTE_MobilityControlInfo_t *)NULL, NULL, NULL, NULL, NULL, NULL, NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , 0, (LTE_MBSFN_AreaInfoList_r9_t *)NULL, (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA , 0, 0 #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , 0, NULL, NULL #endif ); } } } } // Establish DRBs if present if (radioResourceConfigDedicated->drb_ToAddModList) { if ( (UE_rrc_inst[ctxt_pP->module_id].defaultDRB == NULL) && (radioResourceConfigDedicated->drb_ToAddModList->list.count >= 1) ) { // configure the first DRB ID as the default DRB ID UE_rrc_inst[ctxt_pP->module_id].defaultDRB = malloc(sizeof(rb_id_t)); *UE_rrc_inst[ctxt_pP->module_id].defaultDRB = radioResourceConfigDedicated->drb_ToAddModList->list.array[0]->drb_Identity; LOG_I(RRC,"[UE %d] default DRB = %d\n",ctxt_pP->module_id, *UE_rrc_inst[ctxt_pP->module_id].defaultDRB); } uint8_t *kUPenc = NULL; derive_key_up_enc(UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, &kUPenc); MSC_LOG_TX_MESSAGE( MSC_RRC_UE, MSC_PDCP_UE, NULL, 0, MSC_AS_TIME_FMT" CONFIG_REQ UE %x DRB (security %X)", MSC_AS_TIME_ARGS(ctxt_pP), ctxt_pP->rnti, UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm | (UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm << 4)); // Refresh DRBs rrc_pdcp_config_asn1_req(ctxt_pP, (LTE_SRB_ToAddModList_t *)NULL, radioResourceConfigDedicated->drb_ToAddModList, (LTE_DRB_ToReleaseList_t *)NULL, UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm | (UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm << 4), NULL, NULL, kUPenc #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,(LTE_PMCH_InfoList_r9_t *)NULL #endif , UE_rrc_inst[ctxt_pP->module_id].defaultDRB); // Refresh DRBs rrc_rlc_config_asn1_req(ctxt_pP, (LTE_SRB_ToAddModList_t *)NULL, radioResourceConfigDedicated->drb_ToAddModList, (LTE_DRB_ToReleaseList_t *)NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,(LTE_PMCH_InfoList_r9_t *)NULL , 0, 0 #endif ); for (i=0; i<radioResourceConfigDedicated->drb_ToAddModList->list.count; i++) { DRB_id = radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity-1; if (UE_rrc_inst[ctxt_pP->module_id].DRB_config[eNB_index][DRB_id]) { memcpy(UE_rrc_inst[ctxt_pP->module_id].DRB_config[eNB_index][DRB_id], radioResourceConfigDedicated->drb_ToAddModList->list.array[i], sizeof(struct LTE_DRB_ToAddMod)); } else { UE_rrc_inst[ctxt_pP->module_id].DRB_config[eNB_index][DRB_id] = radioResourceConfigDedicated->drb_ToAddModList->list.array[i]; rrc_ue_establish_drb(ctxt_pP->module_id,ctxt_pP->frame,eNB_index,radioResourceConfigDedicated->drb_ToAddModList->list.array[i]); // MAC/PHY Configuration LOG_I(RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (DRB %ld eNB %d) --->][MAC_UE][MOD %02d][]\n", ctxt_pP->frame, ctxt_pP->module_id, radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity, eNB_index, ctxt_pP->module_id); rrc_mac_config_req_ue(ctxt_pP->module_id,0,eNB_index, (LTE_RadioResourceConfigCommonSIB_t *)NULL, UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index], #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (LTE_SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif (LTE_MeasObjectToAddMod_t **)NULL, UE_rrc_inst[ctxt_pP->module_id].mac_MainConfig[eNB_index], *UE_rrc_inst[ctxt_pP->module_id].DRB_config[eNB_index][DRB_id]->logicalChannelIdentity, UE_rrc_inst[ctxt_pP->module_id].DRB_config[eNB_index][DRB_id]->logicalChannelConfig, UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index], (LTE_TDD_Config_t *)NULL, (LTE_MobilityControlInfo_t *)NULL, NULL, NULL, NULL, NULL, NULL, NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , 0, (LTE_MBSFN_AreaInfoList_r9_t *)NULL, (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA , UE_rrc_inst[ue_mod_idP].num_active_cba_groups, // UE_rrc_inst[ue_mod_idP].cba_rnti[0] #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , 0, NULL, NULL #endif ); } } } UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State = RRC_CONNECTED; LOG_I(RRC,"[UE %d] State = RRC_CONNECTED (eNB %d)\n",ctxt_pP->module_id,eNB_index); } //----------------------------------------------------------------------------- void rrc_ue_process_securityModeCommand( const protocol_ctxt_t *const ctxt_pP, LTE_SecurityModeCommand_t *const securityModeCommand, const uint8_t eNB_index ) //----------------------------------------------------------------------------- { asn_enc_rval_t enc_rval; LTE_UL_DCCH_Message_t ul_dcch_msg; // SecurityModeCommand_t SecurityModeCommand; uint8_t buffer[200]; int i, securityMode; LOG_I(RRC,"[UE %d] SFN/SF %d/%d: Receiving from SRB1 (DL-DCCH), Processing securityModeCommand (eNB %d)\n", ctxt_pP->module_id,ctxt_pP->frame, ctxt_pP->subframe, eNB_index); switch (securityModeCommand->criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm) { case LTE_CipheringAlgorithm_r12_eea0: LOG_I(RRC,"[UE %d] Security algorithm is set to eea0\n", ctxt_pP->module_id); securityMode= LTE_CipheringAlgorithm_r12_eea0; break; case LTE_CipheringAlgorithm_r12_eea1: LOG_I(RRC,"[UE %d] Security algorithm is set to eea1\n",ctxt_pP->module_id); securityMode= LTE_CipheringAlgorithm_r12_eea1; break; case LTE_CipheringAlgorithm_r12_eea2: LOG_I(RRC,"[UE %d] Security algorithm is set to eea2\n", ctxt_pP->module_id); securityMode = LTE_CipheringAlgorithm_r12_eea2; break; default: LOG_I(RRC,"[UE %d] Security algorithm is set to none\n",ctxt_pP->module_id); securityMode = LTE_CipheringAlgorithm_r12_spare1; break; } switch (securityModeCommand->criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm) { case LTE_SecurityAlgorithmConfig__integrityProtAlgorithm_eia1: LOG_I(RRC,"[UE %d] Integrity protection algorithm is set to eia1\n",ctxt_pP->module_id); securityMode |= 1 << 5; break; case LTE_SecurityAlgorithmConfig__integrityProtAlgorithm_eia2: LOG_I(RRC,"[UE %d] Integrity protection algorithm is set to eia2\n",ctxt_pP->module_id); securityMode |= 1 << 6; break; default: LOG_I(RRC,"[UE %d] Integrity protection algorithm is set to none\n",ctxt_pP->module_id); securityMode |= 0x70 ; break; } LOG_D(RRC,"[UE %d] security mode is %x \n",ctxt_pP->module_id, securityMode); /* Store the parameters received */ UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm = securityModeCommand->criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm; UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm = securityModeCommand->criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm; memset((void *)&ul_dcch_msg,0,sizeof(LTE_UL_DCCH_Message_t)); //memset((void *)&SecurityModeCommand,0,sizeof(SecurityModeCommand_t)); ul_dcch_msg.message.present = LTE_UL_DCCH_MessageType_PR_c1; if (securityMode >= NO_SECURITY_MODE) { LOG_I(RRC, "rrc_ue_process_securityModeCommand, security mode complete case \n"); ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_securityModeComplete; } else { LOG_I(RRC, "rrc_ue_process_securityModeCommand, security mode failure case \n"); ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_securityModeFailure; } uint8_t *kRRCenc = NULL; uint8_t *kUPenc = NULL; uint8_t *kRRCint = NULL; pdcp_t *pdcp_p = NULL; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, DCCH, SRB_FLAG_YES); h_rc = hashtable_get(pdcp_coll_p, key, (void **) &pdcp_p); if (h_rc == HASH_TABLE_OK) { LOG_D(RRC, "PDCP_COLL_KEY_VALUE() returns valid key = %ld\n", key); LOG_D(RRC, "driving kRRCenc, kRRCint and kUPenc from KeNB=" "%02x%02x%02x%02x" "%02x%02x%02x%02x" "%02x%02x%02x%02x" "%02x%02x%02x%02x" "%02x%02x%02x%02x" "%02x%02x%02x%02x" "%02x%02x%02x%02x" "%02x%02x%02x%02x\n", UE_rrc_inst[ctxt_pP->module_id].kenb[0], UE_rrc_inst[ctxt_pP->module_id].kenb[1], UE_rrc_inst[ctxt_pP->module_id].kenb[2], UE_rrc_inst[ctxt_pP->module_id].kenb[3], UE_rrc_inst[ctxt_pP->module_id].kenb[4], UE_rrc_inst[ctxt_pP->module_id].kenb[5], UE_rrc_inst[ctxt_pP->module_id].kenb[6], UE_rrc_inst[ctxt_pP->module_id].kenb[7], UE_rrc_inst[ctxt_pP->module_id].kenb[8], UE_rrc_inst[ctxt_pP->module_id].kenb[9], UE_rrc_inst[ctxt_pP->module_id].kenb[10], UE_rrc_inst[ctxt_pP->module_id].kenb[11], UE_rrc_inst[ctxt_pP->module_id].kenb[12], UE_rrc_inst[ctxt_pP->module_id].kenb[13], UE_rrc_inst[ctxt_pP->module_id].kenb[14], UE_rrc_inst[ctxt_pP->module_id].kenb[15], UE_rrc_inst[ctxt_pP->module_id].kenb[16], UE_rrc_inst[ctxt_pP->module_id].kenb[17], UE_rrc_inst[ctxt_pP->module_id].kenb[18], UE_rrc_inst[ctxt_pP->module_id].kenb[19], UE_rrc_inst[ctxt_pP->module_id].kenb[20], UE_rrc_inst[ctxt_pP->module_id].kenb[21], UE_rrc_inst[ctxt_pP->module_id].kenb[22], UE_rrc_inst[ctxt_pP->module_id].kenb[23], UE_rrc_inst[ctxt_pP->module_id].kenb[24], UE_rrc_inst[ctxt_pP->module_id].kenb[25], UE_rrc_inst[ctxt_pP->module_id].kenb[26], UE_rrc_inst[ctxt_pP->module_id].kenb[27], UE_rrc_inst[ctxt_pP->module_id].kenb[28], UE_rrc_inst[ctxt_pP->module_id].kenb[29], UE_rrc_inst[ctxt_pP->module_id].kenb[30], UE_rrc_inst[ctxt_pP->module_id].kenb[31]); derive_key_rrc_enc(UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, &kRRCenc); derive_key_rrc_int(UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, &kRRCint); derive_key_up_enc(UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, &kUPenc); if (securityMode != 0xff) { pdcp_config_set_security(ctxt_pP, pdcp_p, 0, 0, UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm | (UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm << 4), kRRCenc, kRRCint, kUPenc); } else { LOG_I(RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x", securityMode); } } else { LOG_I(RRC, "Could not get PDCP instance where key=0x%ld\n", key); } if (securityModeCommand->criticalExtensions.present == LTE_SecurityModeCommand__criticalExtensions_PR_c1) { if (securityModeCommand->criticalExtensions.choice.c1.present != LTE_SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8) LOG_W(RRC,"securityModeCommand->criticalExtensions.choice.c1.present (%d) != SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8\n", securityModeCommand->criticalExtensions.choice.c1.present); ul_dcch_msg.message.choice.c1.choice.securityModeComplete.rrc_TransactionIdentifier = securityModeCommand->rrc_TransactionIdentifier; ul_dcch_msg.message.choice.c1.choice.securityModeComplete.criticalExtensions.present = LTE_SecurityModeCommand__criticalExtensions_PR_c1; ul_dcch_msg.message.choice.c1.choice.securityModeComplete.criticalExtensions.choice.securityModeComplete_r8.nonCriticalExtension =NULL; LOG_I(RRC,"[UE %d] SFN/SF %d/%d: Receiving from SRB1 (DL-DCCH), encoding securityModeComplete (eNB %d), rrc_TransactionIdentifier: %ld\n", ctxt_pP->module_id,ctxt_pP->frame, ctxt_pP->subframe, eNB_index, securityModeCommand->rrc_TransactionIdentifier); enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_DCCH_Message, NULL, (void *)&ul_dcch_msg, buffer, 100); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", enc_rval.failed_type->name, enc_rval.encoded); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)&ul_dcch_msg); } LOG_D(RRC, "securityModeComplete Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8); for (i = 0; i < (enc_rval.encoded + 7) / 8; i++) { LOG_T(RRC, "%02x.", buffer[i]); } LOG_T(RRC, "\n"); rrc_data_req ( ctxt_pP, DCCH, rrc_mui++, SDU_CONFIRM_NO, (enc_rval.encoded + 7) / 8, buffer, PDCP_TRANSMISSION_MODE_CONTROL); } else LOG_W(RRC,"securityModeCommand->criticalExtensions.present (%d) != SecurityModeCommand__criticalExtensions_PR_c1\n", securityModeCommand->criticalExtensions.present); } //----------------------------------------------------------------------------- void rrc_ue_process_ueCapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, LTE_UECapabilityEnquiry_t *UECapabilityEnquiry, uint8_t eNB_index ) //----------------------------------------------------------------------------- { asn_enc_rval_t enc_rval; LTE_UL_DCCH_Message_t ul_dcch_msg; LTE_UE_CapabilityRAT_Container_t ue_CapabilityRAT_Container; uint8_t buffer[200]; int i; LOG_I(RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing UECapabilityEnquiry (eNB %d)\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index); memset((void *)&ul_dcch_msg,0,sizeof(LTE_UL_DCCH_Message_t)); memset((void *)&ue_CapabilityRAT_Container,0,sizeof(LTE_UE_CapabilityRAT_Container_t)); ul_dcch_msg.message.present = LTE_UL_DCCH_MessageType_PR_c1; ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation; ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.rrc_TransactionIdentifier = UECapabilityEnquiry->rrc_TransactionIdentifier; ue_CapabilityRAT_Container.rat_Type = LTE_RAT_Type_eutra; OCTET_STRING_fromBuf(&ue_CapabilityRAT_Container.ueCapabilityRAT_Container, (const char *)UE_rrc_inst[ctxt_pP->module_id].UECapability, UE_rrc_inst[ctxt_pP->module_id].UECapability_size); // ue_CapabilityRAT_Container.ueCapabilityRAT_Container.buf = UE_rrc_inst[ue_mod_idP].UECapability; // ue_CapabilityRAT_Container.ueCapabilityRAT_Container.size = UE_rrc_inst[ue_mod_idP].UECapability_size; AssertFatal(UECapabilityEnquiry->criticalExtensions.present == LTE_UECapabilityEnquiry__criticalExtensions_PR_c1, "UECapabilityEnquiry->criticalExtensions.present (%d) != UECapabilityEnquiry__criticalExtensions_PR_c1 (%d)\n", UECapabilityEnquiry->criticalExtensions.present,LTE_UECapabilityEnquiry__criticalExtensions_PR_c1); if (UECapabilityEnquiry->criticalExtensions.choice.c1.present != LTE_UECapabilityEnquiry__criticalExtensions__c1_PR_ueCapabilityEnquiry_r8) LOG_I(RRC,"UECapabilityEnquiry->criticalExtensions.choice.c1.present (%d) != UECapabilityEnquiry__criticalExtensions__c1_PR_ueCapabilityEnquiry_r8)\n", UECapabilityEnquiry->criticalExtensions.choice.c1.present); ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.present = LTE_UECapabilityInformation__criticalExtensions_PR_c1; ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.present = LTE_UECapabilityInformation__criticalExtensions__c1_PR_ueCapabilityInformation_r8; ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.count =0; for (i=0; i<UECapabilityEnquiry->criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list.count; i++) { if (*UECapabilityEnquiry->criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list.array[i] == LTE_RAT_Type_eutra) { ASN_SEQUENCE_ADD( &ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list, &ue_CapabilityRAT_Container); enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_DCCH_Message, NULL, (void *) &ul_dcch_msg, buffer, 100); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", enc_rval.failed_type->name, enc_rval.encoded); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)&ul_dcch_msg); } LOG_I(RRC,"UECapabilityInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); rrc_data_req_ue ( ctxt_pP, DCCH, rrc_mui++, SDU_CONFIRM_NO, (enc_rval.encoded + 7) / 8, buffer, PDCP_TRANSMISSION_MODE_CONTROL); } } } //----------------------------------------------------------------------------- void rrc_ue_process_rrcConnectionReconfiguration( const protocol_ctxt_t *const ctxt_pP, LTE_RRCConnectionReconfiguration_t *rrcConnectionReconfiguration, uint8_t eNB_index ) //----------------------------------------------------------------------------- { LOG_I(RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing RRCConnectionReconfiguration (eNB %d)\n", ctxt_pP->module_id,ctxt_pP->frame,eNB_index); if (rrcConnectionReconfiguration->criticalExtensions.present == LTE_RRCConnectionReconfiguration__criticalExtensions_PR_c1) { if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.present == LTE_RRCConnectionReconfiguration__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r8) { LTE_RRCConnectionReconfiguration_r8_IEs_t *rrcConnectionReconfiguration_r8 = &rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8; if (rrcConnectionReconfiguration_r8->mobilityControlInfo) { LOG_I(RRC,"Mobility Control Information is present\n"); rrc_ue_process_mobilityControlInfo( ctxt_pP, eNB_index, rrcConnectionReconfiguration_r8->mobilityControlInfo); } if (rrcConnectionReconfiguration_r8->measConfig != NULL) { LOG_I(RRC,"Measurement Configuration is present\n"); rrc_ue_process_measConfig(ctxt_pP, eNB_index, rrcConnectionReconfiguration_r8->measConfig); } if (rrcConnectionReconfiguration_r8->radioResourceConfigDedicated) { LOG_I(RRC,"Radio Resource Configuration is present\n"); rrc_ue_process_radioResourceConfigDedicated(ctxt_pP,eNB_index, rrcConnectionReconfiguration_r8->radioResourceConfigDedicated); } //TTN for D2D //if RRCConnectionReconfiguration message includes the sl-CommConfig if ((rrcConnectionReconfiguration_r8->nonCriticalExtension != NULL) && (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension != NULL) && (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension != NULL) && (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension != NULL) && (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension != NULL) && (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12 != NULL)) { if (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12->commTxResources_r12->present != LTE_SL_CommConfig_r12__commTxResources_r12_PR_NOTHING) { LOG_I(RRC,"sl-CommConfig is present\n"); //process sl-CommConfig rrc_ue_process_sidelink_radioResourceConfig(ctxt_pP->module_id,eNB_index, (LTE_SystemInformationBlockType18_r12_t *)NULL, (LTE_SystemInformationBlockType19_r12_t *)NULL, rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12, (LTE_SL_DiscConfig_r12_t *)NULL ); } } /* //if RRCConnectionReconfiguration message includes the sl-DiscConfig if (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_DiscConfig_r12->discTxResources_r12->present != SL_DiscConfig_r12__discTxResources_r12_PR_NOTHING ){ LOG_I(RRC,"sl-DiscConfig is present\n"); //process sl-DiscConfig rrc_ue_process_sidelink_radioResourceConfig(ctxt_pP->module_id,eNB_index, (SystemInformationBlockType18_r12_t *)NULL, (SystemInformationBlockType19_r12_t *)NULL, (SL_CommConfig_r12_t* )NULL, rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_DiscConfig_r12 ); } */ /* Check if there is dedicated NAS information to forward to NAS */ if (rrcConnectionReconfiguration_r8->dedicatedInfoNASList != NULL) { int list_count; uint32_t pdu_length; uint8_t *pdu_buffer; MessageDef *msg_p; for (list_count = 0; list_count < rrcConnectionReconfiguration_r8->dedicatedInfoNASList->list.count; list_count++) { 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; itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p); } free (rrcConnectionReconfiguration_r8->dedicatedInfoNASList); } #if ENABLE_RAL { MessageDef *message_ral_p = NULL; rrc_ral_connection_reestablishment_ind_t connection_reestablishment_ind; int i; message_ral_p = itti_alloc_new_message (TASK_RRC_UE, RRC_RAL_CONNECTION_REESTABLISHMENT_IND); memset(&connection_reestablishment_ind, 0, sizeof(rrc_ral_connection_reestablishment_ind_t)); // TO DO ral_si_ind.plmn_id = 0; connection_reestablishment_ind.ue_id = ctxt_pP->rnti; if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList != NULL) { connection_reestablishment_ind.num_drb = rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.count; for (i=0; ( i<rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.count) && (i < maxDRB); i++) { // why minus 1 in RRC code for drb_identity ? connection_reestablishment_ind.drb_id[i] = rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity; } } else { connection_reestablishment_ind.num_drb = 0; } if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->srb_ToAddModList != NULL) { connection_reestablishment_ind.num_srb = rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->srb_ToAddModList->list.count + UE_rrc_inst[ctxt_pP->module_id].num_srb; } else { connection_reestablishment_ind.num_srb += UE_rrc_inst[ctxt_pP->module_id].num_srb; } if (connection_reestablishment_ind.num_srb > 2) { // fixme: only 2 srbs can exist, adjust the value connection_reestablishment_ind.num_srb =2; } memcpy (&message_ral_p->ittiMsg, (void *) &connection_reestablishment_ind, sizeof(rrc_ral_connection_reestablishment_ind_t)); //#warning "ue_mod_idP ? for instance ? => YES" LOG_I(RRC, "Sending RRC_RAL_CONNECTION_REESTABLISHMENT_IND to mRAL\n"); itti_send_msg_to_task (TASK_RAL_UE, ctxt_pP->instance, message_ral_p); } #endif } // c1 present } // critical extensions present } /* 36.331, 5.3.5.4 Reception of an RRCConnectionReconfiguration including the mobilityControlInfo by the UE (handover) */ //----------------------------------------------------------------------------- void rrc_ue_process_mobilityControlInfo( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, struct LTE_MobilityControlInfo *const mobilityControlInfo ) //----------------------------------------------------------------------------- { /* DRB_ToReleaseList_t* drb2release_list; DRB_Identity_t *lcid; */ LOG_I(RRC,"Note: This function needs some updates\n"); if(UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].T310_active == 1) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].T310_active = 0; } UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].T304_active = 1; UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].T304_cnt = T304[mobilityControlInfo->t304]; /* drb2release_list = CALLOC (1, sizeof (*drb2release_list)); lcid= CALLOC (1, sizeof (DRB_Identity_t)); // long for (*lcid=0;*lcid<NB_RB_MAX;*lcid++) { ASN_SEQUENCE_ADD (&(drb2release_list)->list,lcid); } */ //Removing SRB1 and SRB2 and DRB0 LOG_I(RRC,"[UE %d] : Update needed for rrc_pdcp_config_req (deprecated) and rrc_rlc_config_req commands(deprecated)\n", ctxt_pP->module_id); rrc_pdcp_config_req (ctxt_pP, SRB_FLAG_YES, CONFIG_ACTION_REMOVE, DCCH,UNDEF_SECURITY_MODE); rrc_rlc_config_req(ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, CONFIG_ACTION_REMOVE,ctxt_pP->module_id+DCCH,Rlc_info_am_config); rrc_pdcp_config_req (ctxt_pP, SRB_FLAG_YES, CONFIG_ACTION_REMOVE, DCCH1,UNDEF_SECURITY_MODE); rrc_rlc_config_req(ctxt_pP, SRB_FLAG_YES,CONFIG_ACTION_REMOVE, MBMS_FLAG_NO,ctxt_pP->module_id+DCCH1,Rlc_info_am_config); rrc_pdcp_config_req (ctxt_pP, SRB_FLAG_NO, CONFIG_ACTION_REMOVE, DTCH,UNDEF_SECURITY_MODE); rrc_rlc_config_req(ctxt_pP, SRB_FLAG_NO,CONFIG_ACTION_REMOVE, MBMS_FLAG_NO,ctxt_pP->module_id+DTCH,Rlc_info_um); /* rrc_pdcp_config_asn1_req(NB_eNB_INST+ue_mod_idP,frameP, 0,eNB_index, NULL, // SRB_ToAddModList NULL, // DRB_ToAddModList drb2release_list, 0, // security mode NULL, // key rrc encryption NULL, // key rrc integrity NULL // key encryption #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,NULL #endif ,NULL); rrc_rlc_config_asn1_req(NB_eNB_INST+ue_mod_idP, frameP,0,eNB_index, NULL,// SRB_ToAddModList NULL,// DRB_ToAddModList drb2release_list // DRB_ToReleaseList #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,NULL #endif ,NULL); */ //A little cleanup at RRC... //Copying current queue config to free RRC index /* memcpy((void *)UE_rrc_inst[ue_mod_idP].SRB1_config[~(7<<eNB_index)],(void *)UE_rrc_inst[ue_mod_idP].SRB1_config[7<<eNB_index],sizeof(SRB_ToAddMod_t)); memcpy((void *)UE_rrc_inst[ue_mod_idP].SRB2_config[~(7<<eNB_index)],(void *)UE_rrc_inst[ue_mod_idP].SRB2_config[7<<eNB_index],sizeof(SRB_ToAddMod_t)); memcpy((void *)UE_rrc_inst[ue_mod_idP].DRB_config[~(7<<eNB_index)][0],(void *)UE_rrc_inst[ue_mod_idP].DRB_config[7<<eNB_index][0],sizeof(DRB_ToAddMod_t)); */ /* LOG_I(RRC,"Not sure if Freeing the current queue config works properly: Fix me\n"); free((void *)&UE_rrc_inst[ue_mod_idP].SRB1_config[eNB_index]); free((void *)&UE_rrc_inst[ue_mod_idP].SRB2_config[eNB_index]); free((void *)&UE_rrc_inst[ue_mod_idP].DRB_config[eNB_index][0]); UE_rrc_inst[ue_mod_idP].SRB1_config[eNB_index] = NULL; UE_rrc_inst[ue_mod_idP].SRB2_config[eNB_index] = NULL; UE_rrc_inst[ue_mod_idP].DRB_config[eNB_index][0] = NULL; */ //Synchronisation to DL of target cell LOG_I(RRC, "HO: Reset PDCP and RLC for configured RBs.. \n[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB2 eNB %d) --->][MAC_UE][MOD %02d][]\n", ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id); // Reset MAC and configure PHY rrc_mac_config_req_ue(ctxt_pP->module_id, 0, eNB_index, (LTE_RadioResourceConfigCommonSIB_t *)NULL, (struct LTE_PhysicalConfigDedicated *)NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (LTE_SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif (LTE_MeasObjectToAddMod_t **)NULL, (LTE_MAC_MainConfig_t *)NULL, 0, (struct LTE_LogicalChannelConfig *)NULL, (LTE_MeasGapConfig_t *)NULL, (LTE_TDD_Config_t *)NULL, mobilityControlInfo, (uint8_t *)NULL, (uint16_t *)NULL, NULL, NULL, NULL, NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,0, (LTE_MBSFN_AreaInfoList_r9_t *)NULL, (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA ,0, 0 #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , 0, NULL, NULL #endif ); // Re-establish PDCP for all RBs that are established // rrc_pdcp_config_req (ue_mod_idP+NB_eNB_INST, frameP, 0, CONFIG_ACTION_ADD, ue_mod_idP+DCCH); // rrc_pdcp_config_req (ue_mod_idP+NB_eNB_INST, frameP, 0, CONFIG_ACTION_ADD, ue_mod_idP+DCCH1); // rrc_pdcp_config_req (ue_mod_idP+NB_eNB_INST, frameP, 0, CONFIG_ACTION_ADD, ue_mod_idP+DTCH); // Re-establish RLC for all RBs that are established // rrc_rlc_config_req(ue_mod_idP+NB_eNB_INST,frameP,0,CONFIG_ACTION_ADD,ue_mod_idP+DCCH,SIGNALLING_RADIO_BEARER,Rlc_info_am_config); // rrc_rlc_config_req(ue_mod_idP+NB_eNB_INST,frameP,0,CONFIG_ACTION_ADD,ue_mod_idP+DCCH1,SIGNALLING_RADIO_BEARER,Rlc_info_am_config); // rrc_rlc_config_req(ue_mod_idP+NB_eNB_INST,frameP,0,CONFIG_ACTION_ADD,ue_mod_idP+DTCH,RADIO_ACCESS_BEARER,Rlc_info_um); UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State = RRC_SI_RECEIVED; } //----------------------------------------------------------------------------- void rrc_detach_from_eNB( module_id_t ue_mod_idP, uint8_t eNB_index ) //----------------------------------------------------------------------------- { //UE_rrc_inst[ue_mod_idP].DRB_config[eNB_index] } //----------------------------------------------------------------------------- void rrc_ue_decode_dcch( const protocol_ctxt_t *const ctxt_pP, const rb_id_t Srb_id, const uint8_t *const Buffer, const uint8_t eNB_indexP ) //----------------------------------------------------------------------------- { //DL_DCCH_Message_t dldcchmsg; LTE_DL_DCCH_Message_t *dl_dcch_msg=NULL;//&dldcchmsg; // asn_dec_rval_t dec_rval; // int i; uint8_t target_eNB_index=0xFF; MessageDef *msg_p; if (Srb_id != 1) { LOG_E(RRC,"[UE %d] Frame %d: Received message on DL-DCCH (SRB%d), should not have ...\n", ctxt_pP->module_id, ctxt_pP->frame, Srb_id); return; } uper_decode(NULL, &asn_DEF_LTE_DL_DCCH_Message, (void **)&dl_dcch_msg, (uint8_t *)Buffer, RRC_BUF_SIZE,0,0); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout,&asn_DEF_LTE_DL_DCCH_Message,(void *)dl_dcch_msg); } if (dl_dcch_msg->message.present == LTE_DL_DCCH_MessageType_PR_c1) { if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_indexP].State >= RRC_CONNECTED) { switch (dl_dcch_msg->message.choice.c1.present) { case LTE_DL_DCCH_MessageType__c1_PR_NOTHING: LOG_I(RRC, "[UE %d] Frame %d : Received PR_NOTHING on DL-DCCH-Message\n", ctxt_pP->module_id, ctxt_pP->frame); return; case LTE_DL_DCCH_MessageType__c1_PR_csfbParametersResponseCDMA2000: break; case LTE_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: { LTE_DLInformationTransfer_t *dlInformationTransfer = &dl_dcch_msg->message.choice.c1.choice.dlInformationTransfer; if ((dlInformationTransfer->criticalExtensions.present == LTE_DLInformationTransfer__criticalExtensions_PR_c1) && (dlInformationTransfer->criticalExtensions.choice.c1.present == LTE_DLInformationTransfer__criticalExtensions__c1_PR_dlInformationTransfer_r8) && (dlInformationTransfer->criticalExtensions.choice.c1.choice.dlInformationTransfer_r8.dedicatedInfoType.present == LTE_DLInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS)) { /* This message hold a dedicated info NAS payload, forward it to NAS */ struct LTE_DLInformationTransfer_r8_IEs__dedicatedInfoType *dedicatedInfoType = &dlInformationTransfer->criticalExtensions.choice.c1.choice.dlInformationTransfer_r8.dedicatedInfoType; uint32_t pdu_length; uint8_t *pdu_buffer; MessageDef *msg_p; pdu_length = dedicatedInfoType->choice.dedicatedInfoNAS.size; pdu_buffer = dedicatedInfoType->choice.dedicatedInfoNAS.buf; msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_DOWNLINK_DATA_IND); NAS_DOWNLINK_DATA_IND(msg_p).UEid = ctxt_pP->module_id; // TODO set the UEid to something else ? NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length = pdu_length; NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data = pdu_buffer; itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p); } break; } case LTE_DL_DCCH_MessageType__c1_PR_handoverFromEUTRAPreparationRequest: break; case LTE_DL_DCCH_MessageType__c1_PR_mobilityFromEUTRACommand: break; case LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionReconfiguration: // first check if mobilityControlInfo is present if (dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo != NULL) { /* 36.331, 5.3.5.4 Reception of an RRCConnectionReconfiguration including the mobilityControlInfo by the UE (handover)*/ if (UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.targetCellId != dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo->targetPhysCellId) { LOG_W(RRC, "[UE %d] Frame %d: Handover target (%ld) is different from RSRP measured target (%ld)..\n", ctxt_pP->module_id, ctxt_pP->frame, dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo->targetPhysCellId, UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.targetCellId); return; } else if ((target_eNB_index = get_adjacent_cell_mod_id(UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.targetCellId)) == 0xFF) { LOG_W(RRC, "[UE %d] Frame %d: ue_mod_idP of the target eNB not found, check the network topology\n", ctxt_pP->module_id, ctxt_pP->frame); return; } else { LOG_I(RRC, "[UE% d] Frame %d: Received rrcConnectionReconfiguration with mobilityControlInfo \n", ctxt_pP->module_id, ctxt_pP->frame); UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.measFlag = 1; // Ready to send more MeasReports if required } } rrc_ue_process_rrcConnectionReconfiguration( ctxt_pP, &dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration, eNB_indexP); if (target_eNB_index != 0xFF) { rrc_ue_generate_RRCConnectionReconfigurationComplete( ctxt_pP, target_eNB_index, dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.rrc_TransactionIdentifier); UE_rrc_inst[ctxt_pP->module_id].Info[eNB_indexP].State = RRC_HO_EXECUTION; UE_rrc_inst[ctxt_pP->module_id].Info[target_eNB_index].State = RRC_RECONFIGURED; LOG_I(RRC, "[UE %d] State = RRC_RECONFIGURED during HO (eNB %d)\n", ctxt_pP->module_id, target_eNB_index); #if ENABLE_RAL { MessageDef *message_ral_p = NULL; rrc_ral_connection_reconfiguration_ho_ind_t connection_reconfiguration_ho_ind; int i; message_ral_p = itti_alloc_new_message (TASK_RRC_UE, RRC_RAL_CONNECTION_RECONFIGURATION_HO_IND); memset(&connection_reconfiguration_ho_ind, 0, sizeof(rrc_ral_connection_reconfiguration_ho_ind_t)); connection_reconfiguration_ho_ind.ue_id = ctxt_pP->module_id; if (dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList != NULL) { connection_reconfiguration_ho_ind.num_drb = dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.count; for (i=0; ( i<dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.count) && (i < maxDRB); i++) { // why minus 1 in RRC code for drb_identity ? connection_reconfiguration_ho_ind.drb_id[i] = dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity; } } else { connection_reconfiguration_ho_ind.num_drb = 0; } if (dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->srb_ToAddModList != NULL) { connection_reconfiguration_ho_ind.num_srb = dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->srb_ToAddModList->list.count + UE_rrc_inst[ctxt_pP->module_id].num_srb; } else { connection_reconfiguration_ho_ind.num_srb += UE_rrc_inst[ctxt_pP->module_id].num_srb; } if (connection_reconfiguration_ho_ind.num_srb > 2 ) { connection_reconfiguration_ho_ind.num_srb =2; } memcpy (&message_ral_p->ittiMsg, (void *) &connection_reconfiguration_ho_ind, sizeof(rrc_ral_connection_reconfiguration_ho_ind_t)); //#warning "ue_mod_idP ? for instance ? => YES" LOG_I(RRC, "Sending RRC_RAL_CONNECTION_RECONFIGURATION_HO_IND to mRAL\n"); itti_send_msg_to_task (TASK_RAL_UE, ctxt_pP->instance, message_ral_p); } #endif } else { rrc_ue_generate_RRCConnectionReconfigurationComplete( ctxt_pP, eNB_indexP, dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.rrc_TransactionIdentifier); UE_rrc_inst[ctxt_pP->module_id].Info[eNB_indexP].State = RRC_RECONFIGURED; LOG_I(RRC, "[UE %d] State = RRC_RECONFIGURED (eNB %d)\n", ctxt_pP->module_id, eNB_indexP); #if ENABLE_RAL { MessageDef *message_ral_p = NULL; rrc_ral_connection_reconfiguration_ind_t connection_reconfiguration_ind; int i; message_ral_p = itti_alloc_new_message (TASK_RRC_UE, RRC_RAL_CONNECTION_RECONFIGURATION_IND); memset(&connection_reconfiguration_ind, 0, sizeof(rrc_ral_connection_reconfiguration_ind_t)); connection_reconfiguration_ind.ue_id = ctxt_pP->module_id; if (dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList != NULL) { connection_reconfiguration_ind.num_drb = dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.count; for (i=0; ( i<dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.count) && (i < maxDRB); i++) { // why minus 1 in RRC code for drb_identity ? connection_reconfiguration_ind.drb_id[i] = dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity; } } else { connection_reconfiguration_ind.num_drb = 0; } if (dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->srb_ToAddModList != NULL) { connection_reconfiguration_ind.num_srb = dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->srb_ToAddModList->list.count + UE_rrc_inst[ctxt_pP->module_id].num_srb; } else { connection_reconfiguration_ind.num_srb +=UE_rrc_inst[ctxt_pP->module_id].num_srb; } if (connection_reconfiguration_ind.num_srb > 2 ) { connection_reconfiguration_ind.num_srb =2; } memcpy (&message_ral_p->ittiMsg, (void *) &connection_reconfiguration_ind, sizeof(rrc_ral_connection_reconfiguration_ind_t)); //#warning "ue_mod_idP ? for instance ? => YES" LOG_I(RRC, "Sending RRC_RAL_CONNECTION_RECONFIGURATION_IND to mRAL\n"); itti_send_msg_to_task (TASK_RAL_UE, ctxt_pP->instance, message_ral_p); } #endif } //TTN test D2D (should not be here - in reality, this message will be triggered from ProSeApp) if (send_ue_information == 0) { LOG_I(RRC, "TEST SidelinkUEInformation [UE %d] Received (eNB %d)\n", ctxt_pP->module_id, eNB_indexP); LTE_SL_DestinationInfoList_r12_t *destinationInfoList = CALLOC(1, sizeof(LTE_SL_DestinationInfoList_r12_t)); LTE_SL_DestinationIdentity_r12_t *sl_destination_identity = CALLOC(1, sizeof(LTE_SL_DestinationIdentity_r12_t)); sl_destination_identity->size = 3; sl_destination_identity->buf = CALLOC(1,3); sl_destination_identity->buf[0] = 0x00; sl_destination_identity->buf[1] = 0x00; sl_destination_identity->buf[2] = 0x01; sl_destination_identity->bits_unused = 0; ASN_SEQUENCE_ADD(&destinationInfoList->list,sl_destination_identity); rrc_ue_generate_SidelinkUEInformation(ctxt_pP, eNB_indexP, destinationInfoList, NULL, SL_TRANSMIT_NON_RELAY_ONE_TO_ONE); send_ue_information ++; } break; case LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionRelease: msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_CONN_RELEASE_IND); if ((dl_dcch_msg->message.choice.c1.choice.rrcConnectionRelease.criticalExtensions.present == LTE_RRCConnectionRelease__criticalExtensions_PR_c1) && (dl_dcch_msg->message.choice.c1.choice.rrcConnectionRelease.criticalExtensions.choice.c1.present == LTE_RRCConnectionRelease__criticalExtensions__c1_PR_rrcConnectionRelease_r8)) { NAS_CONN_RELEASE_IND(msg_p).cause = dl_dcch_msg->message.choice.c1.choice.rrcConnectionRelease.criticalExtensions.choice.c1.choice.rrcConnectionRelease_r8.releaseCause; } itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p); #if ENABLE_RAL msg_p = itti_alloc_new_message(TASK_RRC_UE, RRC_RAL_CONNECTION_RELEASE_IND); RRC_RAL_CONNECTION_RELEASE_IND(msg_p).ue_id = ctxt_pP->module_id; itti_send_msg_to_task(TASK_RAL_UE, ctxt_pP->instance, msg_p); #endif break; case LTE_DL_DCCH_MessageType__c1_PR_securityModeCommand: LOG_I(RRC, "[UE %d] Received securityModeCommand (eNB %d)\n", ctxt_pP->module_id, eNB_indexP); rrc_ue_process_securityModeCommand( ctxt_pP, &dl_dcch_msg->message.choice.c1.choice.securityModeCommand, eNB_indexP); break; case LTE_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry: LOG_I(RRC, "[UE %d] Received Capability Enquiry (eNB %d)\n", ctxt_pP->module_id, eNB_indexP); rrc_ue_process_ueCapabilityEnquiry( ctxt_pP, &dl_dcch_msg->message.choice.c1.choice.ueCapabilityEnquiry, eNB_indexP); break; case LTE_DL_DCCH_MessageType__c1_PR_counterCheck: break; #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) case LTE_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r9: break; #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) case LTE_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r10: break; case LTE_DL_DCCH_MessageType__c1_PR_rnReconfiguration_r10: break; #endif case LTE_DL_DCCH_MessageType__c1_PR_spare1: case LTE_DL_DCCH_MessageType__c1_PR_spare2: case LTE_DL_DCCH_MessageType__c1_PR_spare3: #if (LTE_RRC_VERSION < MAKE_VERSION(14, 0, 0)) case LTE_DL_DCCH_MessageType__c1_PR_spare4: #endif break; default: break; } } } #ifndef NO_RRM send_msg(&S_rrc,msg_rrc_end_scan_req(ctxt_pP->module_id,eNB_indexP)); #endif } const char siWindowLength[8][5] = {"1ms","2ms","5ms","10ms","15ms","20ms","40ms","ERR"}; const char siWindowLength_int[7] = {1,2,5,10,15,20,40}; const char SIBType[12][6] = {"SIB3","SIB4","SIB5","SIB6","SIB7","SIB8","SIB9","SIB10","SIB11","SIB12","SIB13","Spare"}; const char SIBPeriod[8][6]= {"rf8","rf16","rf32","rf64","rf128","rf256","rf512","ERR"}; int siPeriod_int[7] = {80,160,320,640,1280,2560,5120}; const char *SIBreserved( long value ) { if (value < 0 || value > 1) return "ERR"; if (value) return "notReserved"; return "reserved"; } const char *SIBbarred( long value ) { if (value < 0 || value > 1) return "ERR"; if (value) return "notBarred"; return "barred"; } const char *SIBallowed( long value ) { if (value < 0 || value > 1) return "ERR"; if (value) return "notAllowed"; return "allowed"; } const char *SIB2SoundingPresent( int value ) { switch (value) { case LTE_SoundingRS_UL_ConfigCommon_PR_NOTHING: return "NOTHING"; case LTE_SoundingRS_UL_ConfigCommon_PR_release: return "release"; case LTE_SoundingRS_UL_ConfigCommon_PR_setup: return "setup"; } return "ERR"; } const char *SIB2numberOfRA_Preambles( long value ) { static char temp[4] = {0}; if (value < 0 || value > 15) return "ERR"; snprintf( temp, sizeof(temp), "n%ld", value*4 + 4 ); temp[3] = 0; // terminate string return temp; } const char *SIB2powerRampingStep( long value ) { if (value < 0 || value > 3) return "ERR"; static const char str[4][4] = {"dB0","dB2","dB4","dB6"}; return str[value]; } const char *SIB2preambleInitialReceivedTargetPower( long value ) { static char temp[8] = {0}; if (value < 0 || value > 15) return "ERR"; snprintf( temp, sizeof(temp), "dBm-%ld", 120 - value*2 ); temp[7] = 0; // terminate string return temp; } const char *SIB2preambleTransMax( long value ) { static char temp[5] = {0}; if (value < 0 || value > 10) return "ERR"; if (value <= 5) { snprintf( temp, sizeof(temp), "n%ld", value+3 ); return temp; } switch (value) { case 6: return "n10"; case 7: return "n20"; case 8: return "n50"; case 9: return "n100"; case 10: return "n200"; } /* unreachable but gcc warns... */ return "ERR"; } const char *SIB2ra_ResponseWindowSize( long value ) { static char temp[4] = {0}; if (value < 0 || value > 7) return "ERR"; if (value == 7) return "sf10"; snprintf( temp, sizeof(temp), "sf%ld", value+2 ); return temp; } const char *SIB2mac_ContentionResolutionTimer( long value ) { static char temp[5] = {0}; if (value < 0 || value > 7) return "ERR"; snprintf( temp, sizeof(temp), "sf%ld", 8 + value*8 ); return temp; } const char *SIB2modificationPeriodCoeff( long value ) { static char temp[32] = {0}; if (value < 0 || value > 3) return "ERR"; snprintf( temp, sizeof(temp), "n%d", (int)pow(2,value+1) ); return temp; } const char *SIB2defaultPagingCycle( long value ) { static char temp[32] = {0}; if (value < 0 || value > 3) return "ERR"; snprintf( temp, sizeof(temp), "rf%d", (int)pow(2,value+4) ); return temp; } const char *SIB2nB( long value ) { if (value < 0 || value > 7) return "ERR"; static const char str[8][17] = {"fourT","twoT","oneT","halfT","quarterT","oneEigthT","oneSixteenthT","oneThirtySecondT"}; return str[value]; } //----------------------------------------------------------------------------- int decode_BCCH_DLSCH_Message( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, uint8_t *const Sdu, const uint8_t Sdu_len, const uint8_t rsrq, const uint8_t rsrp ) { LTE_BCCH_DL_SCH_Message_t *bcch_message = NULL; LTE_SystemInformationBlockType1_t *sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_IN ); if (((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&1) == 1) && // SIB1 received (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt == sib1->schedulingInfoList.list.count)) { // Avoid decoding SystemInformationBlockType1_t* sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]; // to prevent memory bloating VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT ); return 0; } rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_RECEIVING_SIB ); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_LTE_BCCH_DL_SCH_Message,(void *)bcch_message ); } asn_dec_rval_t dec_rval = uper_decode_complete( NULL, &asn_DEF_LTE_BCCH_DL_SCH_Message, (void **)&bcch_message, (const void *)Sdu, Sdu_len ); if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { LOG_E( RRC, "[UE %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n", ctxt_pP->module_id, dec_rval.consumed ); log_dump(RRC, Sdu, Sdu_len, LOG_DUMP_CHAR," Received bytes:\n" ); // free the memory SEQUENCE_free( &asn_DEF_LTE_BCCH_DL_SCH_Message, (void *)bcch_message, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT ); return -1; } if (bcch_message->message.present == LTE_BCCH_DL_SCH_MessageType_PR_c1) { switch (bcch_message->message.choice.c1.present) { case LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1: if ((ctxt_pP->frame % 2) == 0) { // even frame if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&1) == 0) { LTE_SystemInformationBlockType1_t *sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]; memcpy( (void *)sib1, (void *)&bcch_message->message.choice.c1.choice.systemInformationBlockType1, sizeof(LTE_SystemInformationBlockType1_t) ); LOG_D( RRC, "[UE %"PRIu8"] Decoding First SIB1\n", ctxt_pP->module_id ); decode_SIB1( ctxt_pP, eNB_index, rsrq, rsrp ); } } break; case LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformation: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&1) == 1) { // SIB1 with schedulingInfoList is available LTE_SystemInformation_t *si = UE_rrc_inst[ctxt_pP->module_id].si[eNB_index]; memcpy( si, &bcch_message->message.choice.c1.choice.systemInformation, sizeof(LTE_SystemInformation_t) ); LOG_I( RRC, "[UE %"PRIu8"] Decoding SI for frameP %"PRIu32"\n", ctxt_pP->module_id, ctxt_pP->frame ); decode_SI( ctxt_pP, eNB_index ); //if (nfapi_mode == 3) UE_mac_inst[ctxt_pP->module_id].SI_Decoded = 1; } break; case LTE_BCCH_DL_SCH_MessageType__c1_PR_NOTHING: default: break; } } // if ((rrc_get_sub_state(ctxt_pP->module_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE) //#if defined(ENABLE_USE_MME) // && (UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data != NULL) //#endif // ) { if (rrc_get_sub_state(ctxt_pP->module_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE) { if ( (UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data != NULL) || (!EPC_MODE_ENABLED)) { rrc_ue_generate_RRCConnectionRequest(ctxt_pP, 0); rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_CONNECTING ); } } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT ); return 0; } //----------------------------------------------------------------------------- int decode_PCCH_DLSCH_Message( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, uint8_t *const Sdu, const uint8_t Sdu_len) { LTE_PCCH_Message_t *pcch_message = NULL; int i; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_PCCH, VCD_FUNCTION_IN ); asn_dec_rval_t dec_rval = uper_decode_complete( NULL, &asn_DEF_LTE_PCCH_Message, (void **)&pcch_message, (const void *)Sdu, Sdu_len ); if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { LOG_E( RRC, "[UE %"PRIu8"] Failed to decode PCCH_MESSAGE (%zu bits)\n", ctxt_pP->module_id, dec_rval.consumed ); for (i=0; i<Sdu_len; i++) printf("%02x ",Sdu[i]); printf("\n"); // free the memory SEQUENCE_free( &asn_DEF_LTE_PCCH_Message, (void *)pcch_message, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_PCCH, VCD_FUNCTION_OUT ); return -1; } return(0); } //----------------------------------------------------------------------------- int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t rsrq, const uint8_t rsrp ) { LTE_SystemInformationBlockType1_t *sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_IN ); LOG_I( RRC, "[UE %d] : Dumping SIB 1\n", ctxt_pP->module_id ); LTE_PLMN_Identity_t *PLMN_identity = &sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->plmn_Identity; int mccdigits = PLMN_identity->mcc->list.count; int mncdigits = PLMN_identity->mnc.list.count; int mcc; if (mccdigits == 2) { mcc = *PLMN_identity->mcc->list.array[0]*10 + *PLMN_identity->mcc->list.array[1]; } else { mcc = *PLMN_identity->mcc->list.array[0]*100 + *PLMN_identity->mcc->list.array[1]*10 + *PLMN_identity->mcc->list.array[2]; } int mnc; if (mncdigits == 2) { mnc = *PLMN_identity->mnc.list.array[0]*10 + *PLMN_identity->mnc.list.array[1]; } else { mnc = *PLMN_identity->mnc.list.array[0]*100 + *PLMN_identity->mnc.list.array[1]*10 + *PLMN_identity->mnc.list.array[2]; } LOG_I( RRC, "PLMN MCC %0*d, MNC %0*d, TAC 0x%04x\n", mccdigits, mcc, mncdigits, mnc, ((sib1->cellAccessRelatedInfo.trackingAreaCode.size == 2)?((sib1->cellAccessRelatedInfo.trackingAreaCode.buf[0]<<8) + sib1->cellAccessRelatedInfo.trackingAreaCode.buf[1]):0)); LOG_I( RRC, "cellReservedForOperatorUse : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellReservedForOperatorUse, SIBreserved(sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellReservedForOperatorUse) ); // search internal table for provider name int plmn_ind = 0; while (plmn_data[plmn_ind].mcc > 0) { if ((plmn_data[plmn_ind].mcc == mcc) && (plmn_data[plmn_ind].mnc == mnc)) { LOG_I( RRC, "Found %s (name from internal table)\n", plmn_data[plmn_ind].oper_short ); break; } plmn_ind++; } if (plmn_data[plmn_ind].mcc < 0) { LOG_I( RRC, "Found Unknown operator (no entry in internal table)\n" ); } LOG_I( RRC, "cellAccessRelatedInfo.cellIdentity : raw:%"PRIu32" decoded:%02x.%02x.%02x.%02x\n", BIT_STRING_to_uint32( &sib1->cellAccessRelatedInfo.cellIdentity ), sib1->cellAccessRelatedInfo.cellIdentity.buf[0], sib1->cellAccessRelatedInfo.cellIdentity.buf[1], sib1->cellAccessRelatedInfo.cellIdentity.buf[2], sib1->cellAccessRelatedInfo.cellIdentity.buf[3] >> sib1->cellAccessRelatedInfo.cellIdentity.bits_unused); LOG_I( RRC, "cellAccessRelatedInfo.cellBarred : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.cellBarred, SIBbarred(sib1->cellAccessRelatedInfo.cellBarred) ); LOG_I( RRC, "cellAccessRelatedInfo.intraFreqReselection : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.intraFreqReselection, SIBallowed(sib1->cellAccessRelatedInfo.intraFreqReselection) ); LOG_I( RRC, "cellAccessRelatedInfo.csg_Indication : %d\n", sib1->cellAccessRelatedInfo.csg_Indication ); if (sib1->cellAccessRelatedInfo.csg_Identity) LOG_I( RRC, "cellAccessRelatedInfo.csg_Identity : %"PRIu32"\n", BIT_STRING_to_uint32(sib1->cellAccessRelatedInfo.csg_Identity) ); else LOG_I( RRC, "cellAccessRelatedInfo.csg_Identity : not defined\n" ); LOG_I( RRC, "cellSelectionInfo.q_RxLevMin : %ld\n", sib1->cellSelectionInfo.q_RxLevMin ); if (sib1->cellSelectionInfo.q_RxLevMinOffset) LOG_I( RRC, "cellSelectionInfo.q_RxLevMinOffset : %ld\n", *sib1->cellSelectionInfo.q_RxLevMinOffset ); else LOG_I( RRC, "cellSelectionInfo.q_RxLevMinOffset : not defined\n" ); if (sib1->p_Max) LOG_I( RRC, "p_Max : %ld\n", *sib1->p_Max ); else LOG_I( RRC, "p_Max : not defined\n" ); LOG_I( RRC, "freqBandIndicator : %ld\n", sib1->freqBandIndicator ); if (sib1->schedulingInfoList.list.count > 0) { for (int i=0; i<sib1->schedulingInfoList.list.count; i++) { LOG_I( RRC, "si_Periodicity[%d] : %s\n", i, SIBPeriod[min(sib1->schedulingInfoList.list.array[i]->si_Periodicity,7)]); if (sib1->schedulingInfoList.list.array[i]->sib_MappingInfo.list.count > 0) { char temp[32 * sizeof(SIBType[0])] = {0}; // maxSIB==32 for (int j=0; j<sib1->schedulingInfoList.list.array[i]->sib_MappingInfo.list.count; j++) { sprintf( temp + j*sizeof(SIBType[0]), "%*s ", (int)sizeof(SIBType[0])-1, SIBType[min(*sib1->schedulingInfoList.list.array[i]->sib_MappingInfo.list.array[0],11)] ); } LOG_I( RRC, "siSchedulingInfoSIBType[%d] : %s\n", i, temp ); } else { LOG_I( RRC, "mapping list %d is null\n", i ); } } } else { LOG_E( RRC, "siSchedulingInfoPeriod[0] : PROBLEM!!!\n" ); return -1; } if (sib1->tdd_Config) { LOG_I( RRC, "TDD subframeAssignment : %ld\n", sib1->tdd_Config->subframeAssignment ); LOG_I( RRC, "TDD specialSubframePatterns : %ld\n", sib1->tdd_Config->specialSubframePatterns ); } LOG_I( RRC, "siWindowLength : %s\n", siWindowLength[min(sib1->si_WindowLength,7)] ); LOG_I( RRC, "systemInfoValueTag : %ld\n", sib1->systemInfoValueTag ); UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod = siPeriod_int[sib1->schedulingInfoList.list.array[0]->si_Periodicity]; UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIwindowsize = siWindowLength_int[sib1->si_WindowLength]; LOG_I( RRC, "[FRAME unknown][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB1 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", ctxt_pP->module_id, eNB_index, ctxt_pP->module_id ); rrc_mac_config_req_ue(ctxt_pP->module_id, 0, eNB_index, (LTE_RadioResourceConfigCommonSIB_t *)NULL, (struct LTE_PhysicalConfigDedicated *)NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (LTE_SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif (LTE_MeasObjectToAddMod_t **)NULL, (LTE_MAC_MainConfig_t *)NULL, 0, (struct LTE_LogicalChannelConfig *)NULL, (LTE_MeasGapConfig_t *)NULL, UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->tdd_Config, (LTE_MobilityControlInfo_t *) NULL, &UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIwindowsize, &UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod, NULL, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *)NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,0, (LTE_MBSFN_AreaInfoList_r9_t *)NULL, (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA , 0, 0 #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , 0, NULL, NULL #endif ); LOG_I(RRC,"Setting SIStatus bit 0 to 1\n"); UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus = 1; UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIB1systemInfoValueTag = sib1->systemInfoValueTag; //#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME) if (EPC_MODE_ENABLED) { int cell_valid = 0; if (sib1->cellAccessRelatedInfo.cellBarred == LTE_SystemInformationBlockType1__cellAccessRelatedInfo__cellBarred_notBarred) { /* Cell is not barred */ int plmn; int plmn_number; plmn_number = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.count; /* Compare requested PLMN and PLMNs from SIB1*/ for (plmn = 0; plmn < plmn_number; plmn++) { LTE_PLMN_Identity_t *plmn_Identity; plmn_Identity = &sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[plmn]->plmn_Identity; if ( ( (plmn_Identity->mcc == NULL) || ( (UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit1 == *(plmn_Identity->mcc->list.array[0])) && (UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit2 == *(plmn_Identity->mcc->list.array[1])) && (UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit3 == *(plmn_Identity->mcc->list.array[2])) ) ) && (UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit1 == *(plmn_Identity->mnc.list.array[0])) && (UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit2 == *(plmn_Identity->mnc.list.array[1])) && ( ((UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit3 == 0xf) && (plmn_Identity->mnc.list.count == 2)) || (UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit3 == *(plmn_Identity->mnc.list.array[2])) ) ) { /* PLMN match, send a confirmation to NAS */ MessageDef *msg_p; msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_CELL_SELECTION_CNF); NAS_CELL_SELECTION_CNF (msg_p).errCode = AS_SUCCESS; NAS_CELL_SELECTION_CNF (msg_p).cellID = BIT_STRING_to_uint32(&sib1->cellAccessRelatedInfo.cellIdentity); NAS_CELL_SELECTION_CNF (msg_p).tac = BIT_STRING_to_uint16(&sib1->cellAccessRelatedInfo.trackingAreaCode); NAS_CELL_SELECTION_CNF (msg_p).rat = 0xFF; NAS_CELL_SELECTION_CNF (msg_p).rsrq = rsrq; NAS_CELL_SELECTION_CNF (msg_p).rsrp = rsrp; itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p); cell_valid = 1; break; } } /* for plmn = 0;... */ } if (cell_valid == 0) { /* Cell can not be used, ask PHY to try the next one */ MessageDef *msg_p; msg_p = itti_alloc_new_message(TASK_RRC_UE, PHY_FIND_NEXT_CELL_REQ); itti_send_msg_to_task(TASK_PHY_UE, ctxt_pP->instance, msg_p); LOG_E(RRC, "Synched with a cell, but PLMN doesn't match our SIM, the message PHY_FIND_NEXT_CELL_REQ is sent but lost in current UE implementation! \n"); } }/* EPC_MODE_ENABLED */ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_OUT ); return 0; } //----------------------------------------------------------------------------- void dump_sib2( LTE_SystemInformationBlockType2_t *sib2 ) { // ac_BarringInfo if (sib2->ac_BarringInfo) { LOG_I( RRC, "ac_BarringInfo->ac_BarringForEmergency : %d\n", sib2->ac_BarringInfo->ac_BarringForEmergency ); if (sib2->ac_BarringInfo->ac_BarringForMO_Signalling) { LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Signalling->ac_BarringFactor : %ld\n", sib2->ac_BarringInfo->ac_BarringForMO_Signalling->ac_BarringFactor ); LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Signalling->ac_BarringTime : %ld\n", sib2->ac_BarringInfo->ac_BarringForMO_Signalling->ac_BarringTime ); LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Signalling->ac_BarringForSpecialAC : %"PRIu32"\n", BIT_STRING_to_uint32(&sib2->ac_BarringInfo->ac_BarringForMO_Signalling->ac_BarringForSpecialAC) ); } else LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Signalling : not defined\n" ); if (sib2->ac_BarringInfo->ac_BarringForMO_Data) { LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Data->ac_BarringFactor : %ld\n", sib2->ac_BarringInfo->ac_BarringForMO_Data->ac_BarringFactor ); LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Data->ac_BarringTime : %ld\n", sib2->ac_BarringInfo->ac_BarringForMO_Data->ac_BarringTime ); LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Data->ac_BarringForSpecialAC : %"PRIu32"\n", BIT_STRING_to_uint32(&sib2->ac_BarringInfo->ac_BarringForMO_Data->ac_BarringForSpecialAC) ); } else LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Data : not defined\n" ); } else LOG_I( RRC, "ac_BarringInfo : not defined\n" ); // RACH LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.numberOfRA_Preambles : raw:%ld decoded:%s\n", sib2->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.numberOfRA_Preambles, SIB2numberOfRA_Preambles(sib2->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.numberOfRA_Preambles) ); if (sib2->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig) { LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA : %ld\n", sib2->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA ); LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig->messageSizeGroupA : %ld\n", sib2->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig->messageSizeGroupA ); LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig->messagePowerOffsetGroupB : %ld\n", sib2->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig->messagePowerOffsetGroupB ); } else { LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig : not defined\n" ); } LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.powerRampingStep : raw:%ld decoded:%s\n", sib2->radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.powerRampingStep, SIB2powerRampingStep(sib2->radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.powerRampingStep) ); LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.preambleInitialReceivedTargetPower : raw:%ld decoded:%s\n", sib2->radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.preambleInitialReceivedTargetPower, SIB2preambleInitialReceivedTargetPower(sib2->radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.preambleInitialReceivedTargetPower) ); LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.preambleTransMax : raw:%ld decoded:%s\n", sib2->radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.preambleTransMax, SIB2preambleTransMax(sib2->radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.preambleTransMax) ); LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.ra_ResponseWindowSize : raw:%ld decoded:%s\n", sib2->radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.ra_ResponseWindowSize, SIB2ra_ResponseWindowSize(sib2->radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.ra_ResponseWindowSize) ); LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.mac_ContentionResolutionTimer : raw:%ld decoded:%s\n", sib2->radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.mac_ContentionResolutionTimer, SIB2mac_ContentionResolutionTimer(sib2->radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.mac_ContentionResolutionTimer) ); LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.maxHARQ_Msg3Tx : %ld\n", sib2->radioResourceConfigCommon.rach_ConfigCommon.maxHARQ_Msg3Tx ); // BCCH LOG_I( RRC, "radioResourceConfigCommon.bcch_Config.modificationPeriodCoeff : raw:%ld decoded:%s\n", sib2->radioResourceConfigCommon.bcch_Config.modificationPeriodCoeff, SIB2modificationPeriodCoeff(sib2->radioResourceConfigCommon.bcch_Config.modificationPeriodCoeff) ); // PCCH LOG_I( RRC, "radioResourceConfigCommon.pcch_Config.defaultPagingCycle : raw:%ld decoded:%s\n", sib2->radioResourceConfigCommon.pcch_Config.defaultPagingCycle, SIB2defaultPagingCycle(sib2->radioResourceConfigCommon.pcch_Config.defaultPagingCycle) ); LOG_I( RRC, "radioResourceConfigCommon.pcch_Config.nB : raw:%ld decoded:%s\n", sib2->radioResourceConfigCommon.pcch_Config.nB, SIB2nB(sib2->radioResourceConfigCommon.pcch_Config.nB) ); // PRACH LOG_I( RRC, "radioResourceConfigCommon.prach_Config.rootSequenceIndex : %ld\n", sib2->radioResourceConfigCommon.prach_Config.rootSequenceIndex ); LOG_I( RRC, "radioResourceConfigCommon.prach_Config.prach_ConfigInfo.prach_ConfigIndex : %ld\n", sib2->radioResourceConfigCommon.prach_Config.prach_ConfigInfo.prach_ConfigIndex ); LOG_I( RRC, "radioResourceConfigCommon.prach_Config.prach_ConfigInfo.highSpeedFlag : %d\n", sib2->radioResourceConfigCommon.prach_Config.prach_ConfigInfo.highSpeedFlag ); LOG_I( RRC, "radioResourceConfigCommon.prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig : %ld\n", sib2->radioResourceConfigCommon.prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig ); LOG_I( RRC, "radioResourceConfigCommon.prach_Config.prach_ConfigInfo.prach_FreqOffset : %ld\n", sib2->radioResourceConfigCommon.prach_Config.prach_ConfigInfo.prach_FreqOffset ); // PDSCH-Config LOG_I( RRC, "radioResourceConfigCommon.pdsch_ConfigCommon.referenceSignalPower : %ld\n", sib2->radioResourceConfigCommon.pdsch_ConfigCommon.referenceSignalPower ); LOG_I( RRC, "radioResourceConfigCommon.pdsch_ConfigCommon.p_b : %ld\n", sib2->radioResourceConfigCommon.pdsch_ConfigCommon.p_b ); // PUSCH-Config LOG_I( RRC, "radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.n_SB : %ld\n", sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.n_SB ); LOG_I( RRC, "radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode : %ld\n", sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode ); LOG_I( RRC, "radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset : %ld\n", sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset ); LOG_I( RRC, "radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM : %d\n", sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM ); LOG_I( RRC, "radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled : %d\n", sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled ); LOG_I( RRC, "radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH : %ld\n", sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH ); LOG_I( RRC, "radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled : %d\n", sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled ); LOG_I( RRC, "radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift : %ld\n", sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift ); // PUCCH-Config LOG_I( RRC, "radioResourceConfigCommon.pucch_ConfigCommon.deltaPUCCH_Shift : %ld\n", sib2->radioResourceConfigCommon.pucch_ConfigCommon.deltaPUCCH_Shift ); LOG_I( RRC, "radioResourceConfigCommon.pucch_ConfigCommon.nRB_CQI : %ld\n", sib2->radioResourceConfigCommon.pucch_ConfigCommon.nRB_CQI ); LOG_I( RRC, "radioResourceConfigCommon.pucch_ConfigCommon.nCS_AN : %ld\n", sib2->radioResourceConfigCommon.pucch_ConfigCommon.nCS_AN ); LOG_I( RRC, "radioResourceConfigCommon.pucch_ConfigCommon.n1PUCCH_AN : %ld\n", sib2->radioResourceConfigCommon.pucch_ConfigCommon.n1PUCCH_AN ); // SoundingRS_UL_Config LOG_I( RRC, "radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present : raw:%d decoded:%s\n", sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present, SIB2SoundingPresent(sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present) ); if (sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present == LTE_SoundingRS_UL_ConfigCommon_PR_setup) { LOG_I( RRC, "radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig : %ld\n", sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig ); LOG_I( RRC, "radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig : %ld\n", sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig ); LOG_I( RRC, "radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission : %d\n", sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission ); if(sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) { LOG_I( RRC, "radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts : %ld\n", /* TODO: check that it's okay to access [0] */ sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts[0] ); } } // uplinkPowerControlCommon LOG_I( RRC, "radioResourceConfigCommon.uplinkPowerControlCommon.p0_NominalPUSCH : %ld\n", sib2->radioResourceConfigCommon.uplinkPowerControlCommon.p0_NominalPUSCH ); LOG_I( RRC, "radioResourceConfigCommon.uplinkPowerControlCommon.alpha : %ld\n", sib2->radioResourceConfigCommon.uplinkPowerControlCommon.alpha ); LOG_I( RRC, "radioResourceConfigCommon.uplinkPowerControlCommon.p0_NominalPUCCH : %ld\n", sib2->radioResourceConfigCommon.uplinkPowerControlCommon.p0_NominalPUCCH ); LOG_I( RRC, "radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1 : %ld\n", sib2->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1 ); LOG_I( RRC, "radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1b : %ld\n", sib2->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1b ); LOG_I( RRC, "radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2 : %ld\n", sib2->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2 ); LOG_I( RRC, "radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2a : %ld\n", sib2->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2a ); LOG_I( RRC, "radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2b : %ld\n", sib2->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2b ); LOG_I( RRC, "radioResourceConfigCommon.uplinkPowerControlCommon.deltaPreambleMsg3 : %ld\n", sib2->radioResourceConfigCommon.uplinkPowerControlCommon.deltaPreambleMsg3 ); LOG_I( RRC, "radioResourceConfigCommon.ul_CyclicPrefixLength : %ld\n", sib2->radioResourceConfigCommon.ul_CyclicPrefixLength ); #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 2, 0)) // UplinkPowerControlCommon_v1020 // ... #endif LOG_I( RRC, "ue_TimersAndConstants.t300 : %ld\n", sib2->ue_TimersAndConstants.t300 ); LOG_I( RRC, "ue_TimersAndConstants.t301 : %ld\n", sib2->ue_TimersAndConstants.t301 ); LOG_I( RRC, "ue_TimersAndConstants.t310 : %ld\n", sib2->ue_TimersAndConstants.t310 ); LOG_I( RRC, "ue_TimersAndConstants.n310 : %ld\n", sib2->ue_TimersAndConstants.n310 ); LOG_I( RRC, "ue_TimersAndConstants.t311 : %ld\n", sib2->ue_TimersAndConstants.t311 ); LOG_I( RRC, "ue_TimersAndConstants.n311 : %ld\n", sib2->ue_TimersAndConstants.n311 ); if (sib2->freqInfo.ul_CarrierFreq) LOG_I( RRC, "freqInfo.ul_CarrierFreq : %ld\n", *sib2->freqInfo.ul_CarrierFreq ); else LOG_I( RRC, "freqInfo.ul_CarrierFreq : not defined\n" ); if (sib2->freqInfo.ul_Bandwidth) LOG_I( RRC, "freqInfo.ul_Bandwidth : %ld\n", *sib2->freqInfo.ul_Bandwidth ); else LOG_I( RRC, "freqInfo.ul_Bandwidth : not defined\n" ); LOG_I( RRC, "freqInfo.additionalSpectrumEmission : %ld\n", sib2->freqInfo.additionalSpectrumEmission ); if (sib2->mbsfn_SubframeConfigList) { LOG_I( RRC, "mbsfn_SubframeConfigList : %p\n", sib2->mbsfn_SubframeConfigList ); // FIXME } else LOG_I( RRC, "mbsfn_SubframeConfigList : not defined\n" ); LOG_I( RRC, "timeAlignmentTimerCommon : %ld\n", sib2->timeAlignmentTimerCommon ); #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) if (sib2->lateNonCriticalExtension) { LOG_I( RRC, "lateNonCriticalExtension : %p\n", sib2->lateNonCriticalExtension ); } else LOG_I( RRC, "lateNonCriticalExtension : not defined\n" ); #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) if (sib2->ext1 && sib2->ext1->ssac_BarringForMMTEL_Voice_r9) { LOG_I( RRC, "ssac_BarringForMMTEL_Voice_r9->ac_BarringFactor : %ld\n", sib2->ext1->ssac_BarringForMMTEL_Voice_r9->ac_BarringFactor ); LOG_I( RRC, "ssac_BarringForMMTEL_Voice_r9->ac_BarringTime : %ld\n", sib2->ext1->ssac_BarringForMMTEL_Voice_r9->ac_BarringTime ); LOG_I( RRC, "ssac_BarringForMMTEL_Voice_r9->ac_BarringForSpecialAC : %"PRIu32"\n", BIT_STRING_to_uint32(&sib2->ext1->ssac_BarringForMMTEL_Voice_r9->ac_BarringForSpecialAC) ); } else LOG_I( RRC, "ssac_BarringForMMTEL_Voice_r9 : not defined\n" ); if (sib2->ext1 && sib2->ext1->ssac_BarringForMMTEL_Video_r9) { LOG_I( RRC, "ssac_BarringForMMTEL_Video_r9->ac_BarringFactor : %ld\n", sib2->ext1->ssac_BarringForMMTEL_Video_r9->ac_BarringFactor ); LOG_I( RRC, "ssac_BarringForMMTEL_Video_r9->ac_BarringTime : %ld\n", sib2->ext1->ssac_BarringForMMTEL_Video_r9->ac_BarringTime ); LOG_I( RRC, "ssac_BarringForMMTEL_Video_r9->ac_BarringForSpecialAC : %"PRIu32"\n", BIT_STRING_to_uint32(&sib2->ext1->ssac_BarringForMMTEL_Video_r9->ac_BarringForSpecialAC) ); } else LOG_I( RRC, "ssac_BarringForMMTEL_Video_r9 : not defined\n" ); #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (sib2->ext2 && sib2->ext2->ac_BarringForCSFB_r10) { LOG_I( RRC, "ac_BarringForCSFB_r10->ac_BarringFactor : %ld\n", sib2->ext2->ac_BarringForCSFB_r10->ac_BarringFactor ); LOG_I( RRC, "ac_BarringForCSFB_r10->ac_BarringTime : %ld\n", sib2->ext2->ac_BarringForCSFB_r10->ac_BarringTime ); LOG_I( RRC, "ac_BarringForCSFB_r10->ac_BarringForSpecialAC : %"PRIu32"\n", BIT_STRING_to_uint32(&sib2->ext2->ac_BarringForCSFB_r10->ac_BarringForSpecialAC) ); } else LOG_I( RRC, "ac_BarringForCSFB_r10 : not defined\n" ); #endif } //----------------------------------------------------------------------------- void dump_sib3( LTE_SystemInformationBlockType3_t *sib3 ) { LOG_I( RRC, "Dumping SIB3 (see TS36.331 V8.21.0)\n" ); int q_Hyst_dB = sib3->cellReselectionInfoCommon.q_Hyst; // sib3->cellReselectionInfoCommon.q_Hyst is a enumerated value if (q_Hyst_dB > 6) q_Hyst_dB = (q_Hyst_dB-6) * 2 + 6; LOG_I( RRC, "cellReselectionInfoCommon.q_Hyst : raw:%ld decoded:%d dB\n", sib3->cellReselectionInfoCommon.q_Hyst, q_Hyst_dB ); if (sib3->cellReselectionInfoCommon.speedStateReselectionPars) { LOG_I( RRC, "cellReselectionInfoCommon.speedStateReselectionPars->mobilityStateParameters.t_Evaluation : %ld\n", sib3->cellReselectionInfoCommon.speedStateReselectionPars->mobilityStateParameters.t_Evaluation ); LOG_I( RRC, "cellReselectionInfoCommon.speedStateReselectionPars->mobilityStateParameters.t_HystNormal : %ld\n", sib3->cellReselectionInfoCommon.speedStateReselectionPars->mobilityStateParameters.t_HystNormal ); LOG_I( RRC, "cellReselectionInfoCommon.speedStateReselectionPars->mobilityStateParameters.n_CellChangeMedium : %ld\n", sib3->cellReselectionInfoCommon.speedStateReselectionPars->mobilityStateParameters.n_CellChangeMedium ); LOG_I( RRC, "cellReselectionInfoCommon.speedStateReselectionPars->mobilityStateParameters.n_CellChangeHigh : %ld\n", sib3->cellReselectionInfoCommon.speedStateReselectionPars->mobilityStateParameters.n_CellChangeHigh ); LOG_I( RRC, "cellReselectionInfoCommon.speedStateReselectionPars->q_HystSF.sf_Medium : raw:%ld decoded:%ld dB\n", sib3->cellReselectionInfoCommon.speedStateReselectionPars->q_HystSF.sf_Medium, 6 - 2 * sib3->cellReselectionInfoCommon.speedStateReselectionPars->q_HystSF.sf_Medium ); LOG_I( RRC, "cellReselectionInfoCommon.speedStateReselectionPars->q_HystSF.sf_High : raw:%ld decoded:%ld dB\n", sib3->cellReselectionInfoCommon.speedStateReselectionPars->q_HystSF.sf_High, 6 - 2 * sib3->cellReselectionInfoCommon.speedStateReselectionPars->q_HystSF.sf_High ); } else { LOG_I( RRC, "cellReselectionInfoCommon.speedStateReselectionPars : not defined\n" ); } if (sib3->cellReselectionServingFreqInfo.s_NonIntraSearch) { LOG_I( RRC, "cellReselectionServingFreqInfo.s_NonIntraSearch : %ld\n", *(sib3->cellReselectionServingFreqInfo.s_NonIntraSearch) ); } else { LOG_I( RRC, "cellReselectionServingFreqInfo.s_NonIntraSearch : not defined\n" ); } LOG_I( RRC, "cellReselectionServingFreqInfo.threshServingLow : %ld\n", sib3->cellReselectionServingFreqInfo.threshServingLow ); LOG_I( RRC, "cellReselectionServingFreqInfo.cellReselectionPriority : %ld\n", sib3->cellReselectionServingFreqInfo.cellReselectionPriority ); LOG_I( RRC, "intraFreqCellReselectionInfo.q_RxLevMin : %ld\n", sib3->intraFreqCellReselectionInfo.q_RxLevMin ); if (sib3->intraFreqCellReselectionInfo.p_Max) { LOG_I( RRC, "intraFreqCellReselectionInfo.p_Max : %ld\n", *(sib3->intraFreqCellReselectionInfo.p_Max) ); } else { LOG_I( RRC, "intraFreqCellReselectionInfo.p_Max : not defined\n" ); } if (sib3->intraFreqCellReselectionInfo.s_IntraSearch) { LOG_I( RRC, "intraFreqCellReselectionInfo.s_IntraSearch : %ld\n", *(sib3->intraFreqCellReselectionInfo.s_IntraSearch) ); } else { LOG_I( RRC, "intraFreqCellReselectionInfo.s_IntraSearch : not defined\n" ); } if (sib3->intraFreqCellReselectionInfo.allowedMeasBandwidth) { LOG_I( RRC, "intraFreqCellReselectionInfo.allowedMeasBandwidth : %ld\n", *(sib3->intraFreqCellReselectionInfo.allowedMeasBandwidth) ); } else { LOG_I( RRC, "intraFreqCellReselectionInfo.allowedMeasBandwidth : not defined\n" ); } LOG_I( RRC, "intraFreqCellReselectionInfo.presenceAntennaPort1 : %d\n", sib3->intraFreqCellReselectionInfo.presenceAntennaPort1 ); LOG_I( RRC, "intraFreqCellReselectionInfo.neighCellConfig : %"PRIu8"\n", BIT_STRING_to_uint8( &(sib3->intraFreqCellReselectionInfo.neighCellConfig) ) ); LOG_I( RRC, "intraFreqCellReselectionInfo.t_ReselectionEUTRA : %ld\n", sib3->intraFreqCellReselectionInfo.t_ReselectionEUTRA ); if (sib3->intraFreqCellReselectionInfo.t_ReselectionEUTRA_SF) { LOG_I( RRC, "intraFreqCellReselectionInfo.t_ReselectionEUTRA_SF->sf_Medium : %ld\n", sib3->intraFreqCellReselectionInfo.t_ReselectionEUTRA_SF->sf_Medium ); LOG_I( RRC, "intraFreqCellReselectionInfo.t_ReselectionEUTRA_SF->sf_High : %ld\n", sib3->intraFreqCellReselectionInfo.t_ReselectionEUTRA_SF->sf_High ); } else { LOG_I( RRC, "intraFreqCellReselectionInfo.t_ReselectionEUTRA_SF : not defined\n" ); } } int Qoffsettab[31] = {-24,-22,-20,-18,-16,-14,-12,-10,-8,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,8,10,12,14,16,18,20,22,24}; int PhysCellIdRange[16] = {4,8,12,16,24,32,48,64,84,96,128,168,252,504,0,0}; uint64_t arfcn_to_freq(long arfcn) { if (arfcn < 600) // Band 1 return((uint64_t)2110000000 + (arfcn*100000)); else if (arfcn <1200) // Band 2 return((uint64_t)1930000000 + ((arfcn-600)*100000)); else if (arfcn <1950) // Band 3 return((uint64_t)1805000000 + ((arfcn-1200)*100000)); else if (arfcn <2400) // Band 4 return((uint64_t)2110000000 + ((arfcn-1950)*100000)); else if (arfcn <2650) // Band 5 return((uint64_t)869000000 + ((arfcn-2400)*100000)); else if (arfcn <2750) // Band 6 return((uint64_t)875000000 + ((arfcn-2650)*100000)); else if (arfcn <3450) // Band 7 return((uint64_t)2620000000 + ((arfcn-2750)*100000)); else if (arfcn <3800) // Band 8 return((uint64_t)925000000 + ((arfcn-3450)*100000)); else if (arfcn <4150) // Band 9 return((uint64_t)1844900000 + ((arfcn-3800)*100000)); else if (arfcn <4650) // Band 10 return((uint64_t)2110000000 + ((arfcn-4150)*100000)); else if (arfcn <5010) // Band 11 return((uint64_t)1475900000 + ((arfcn-4750)*100000)); else if (arfcn <5180) // Band 12 return((uint64_t)729000000 + ((arfcn-5010)*100000)); else if (arfcn <5280) // Band 13 return((uint64_t)746000000 + ((arfcn-5180)*100000)); else if (arfcn <5730) // Band 14 return((uint64_t)758000000 + ((arfcn-5280)*100000)); else if (arfcn <5850) // Band 17 return((uint64_t)734000000 + ((arfcn-5730)*100000)); else if (arfcn <6000) // Band 18 return((uint64_t)860000000 + ((arfcn-5850)*100000)); else if (arfcn <6150) // Band 19 return((uint64_t)875000000 + ((arfcn-6000)*100000)); else if (arfcn <6450) // Band 20 return((uint64_t)791000000 + ((arfcn-6150)*100000)); else if (arfcn <6600) // Band 21 return((uint64_t)1495900000 + ((arfcn-6450)*100000)); else if (arfcn <7500) // Band 22 return((uint64_t)351000000 + ((arfcn-6600)*100000)); else if (arfcn <7700) // Band 23 return((uint64_t)2180000000 + ((arfcn-7500)*100000)); else if (arfcn <8040) // Band 24 return((uint64_t)1525000000 + ((arfcn-7700)*100000)); else if (arfcn <8690) // Band 25 return((uint64_t)1930000000 + ((arfcn-8040)*100000)); else if (arfcn <36200) // Band 33 return((uint64_t)1900000000 + ((arfcn-36000)*100000)); else if (arfcn <36350) // Band 34 return((uint64_t)2010000000 + ((arfcn-36200)*100000)); else if (arfcn <36950) // Band 35 return((uint64_t)1850000000 + ((arfcn-36350)*100000)); else if (arfcn <37550) // Band 36 return((uint64_t)1930000000 + ((arfcn-36950)*100000)); else if (arfcn <37750) // Band 37 return((uint64_t)1910000000 + ((arfcn-37550)*100000)); else if (arfcn <38250) // Band 38 return((uint64_t)2570000000 + ((arfcn-37750)*100000)); else if (arfcn <38650) // Band 39 return((uint64_t)1880000000 + ((arfcn-38250)*100000)); else if (arfcn <39650) // Band 40 return((uint64_t)2300000000 + ((arfcn-38650)*100000)); else if (arfcn <41590) // Band 41 return((uint64_t)2496000000 + ((arfcn-39650)*100000)); else if (arfcn <43590) // Band 42 return((uint64_t)3400000000 + ((arfcn-41590)*100000)); else if (arfcn <45590) // Band 43 return((uint64_t)3600000000 + ((arfcn-43950)*100000)); else { LOG_E(RRC,"Unknown EARFCN %ld\n",arfcn); exit(1); } } void dump_sib5( LTE_SystemInformationBlockType5_t *sib5 ) { LTE_InterFreqCarrierFreqList_t interFreqCarrierFreqList = sib5->interFreqCarrierFreqList; int i,j; LTE_InterFreqCarrierFreqInfo_t *ifcfInfo; LOG_I( RRC, "Dumping SIB5 (see TS36.331 V8.21.0)\n" ); for (i=0; i<interFreqCarrierFreqList.list.count; i++) { LOG_I(RRC, "SIB5 InterFreqCarrierFreq element %d/%d\n",i,interFreqCarrierFreqList.list.count); ifcfInfo = interFreqCarrierFreqList.list.array[i]; LOG_I(RRC, " DL Carrier Frequency/ARFCN : %ld/%ld\n", arfcn_to_freq(ifcfInfo->dl_CarrierFreq), ifcfInfo->dl_CarrierFreq); LOG_I(RRC," Q_RXLevMin : %ld\n", ifcfInfo->q_RxLevMin); if (ifcfInfo->p_Max != NULL) LOG_I(RRC," P_max : %ld\n", *ifcfInfo->p_Max); LOG_I(RRC," T_ReselectionEUTRA : %ld\n",ifcfInfo->t_ReselectionEUTRA); if (ifcfInfo->t_ReselectionEUTRA_SF) { LOG_I(RRC," t_ReselectionEUTRA_SF.sf_Medium %ld, t_ReselectionEUTRA_SF.sf_High %ld", ifcfInfo->t_ReselectionEUTRA_SF->sf_Medium, ifcfInfo->t_ReselectionEUTRA_SF->sf_High); } LOG_I(RRC," threshX_High : %ld\n",ifcfInfo->threshX_High); LOG_I(RRC," threshX_Low : %ld\n",ifcfInfo->threshX_Low); switch(ifcfInfo->allowedMeasBandwidth) { case LTE_AllowedMeasBandwidth_mbw6: LOG_I(RRC," AllowedMeasBandwidth : 6\n"); break; case LTE_AllowedMeasBandwidth_mbw15: LOG_I(RRC," AllowedMeasBandwidth : 15\n"); break; case LTE_AllowedMeasBandwidth_mbw25: LOG_I(RRC," AllowedMeasBandwidth : 25\n"); break; case LTE_AllowedMeasBandwidth_mbw50: LOG_I(RRC," AllowedMeasBandwidth : 50\n"); break; case LTE_AllowedMeasBandwidth_mbw75: LOG_I(RRC," AllowedMeasBandwidth : 75\n"); break; case LTE_AllowedMeasBandwidth_mbw100: LOG_I(RRC," AllowedMeasBandwidth : 100\n"); break; } if (ifcfInfo->presenceAntennaPort1) LOG_I(RRC," PresenceAntennaPort1 : True\n"); else LOG_I(RRC," PresenceAntennaPort1 : False\n"); if (ifcfInfo->cellReselectionPriority) { LOG_I(RRC," CellReselectionPriority : %ld\n", *ifcfInfo->cellReselectionPriority); } LOG_I(RRC," NeighCellConfig : "); for (j=0; j<ifcfInfo->neighCellConfig.size; j++) { printf("%2x ",ifcfInfo->neighCellConfig.buf[j]); } printf("\n"); if (ifcfInfo->q_OffsetFreq) LOG_I(RRC," Q_OffsetFreq : %d\n",Qoffsettab[*ifcfInfo->q_OffsetFreq]); if (ifcfInfo->interFreqNeighCellList) { for (j=0; j<ifcfInfo->interFreqNeighCellList->list.count; j++) { LOG_I(RRC," Cell %d\n", j); LOG_I(RRC," PhysCellId : %ld\n",ifcfInfo->interFreqNeighCellList->list.array[j]->physCellId); LOG_I(RRC," Q_OffsetRange : %ld\n",ifcfInfo->interFreqNeighCellList->list.array[j]->q_OffsetCell); } } if (ifcfInfo->interFreqBlackCellList) { for (j=0; j<ifcfInfo->interFreqBlackCellList->list.count; j++) { LOG_I(RRC," Cell %d\n", j); LOG_I(RRC," PhysCellId start: %ld\n",ifcfInfo->interFreqBlackCellList->list.array[j]->start); if (ifcfInfo->interFreqBlackCellList->list.array[i]->range) { LOG_I(RRC," PhysCellId Range : %ld\n",*ifcfInfo->interFreqBlackCellList->list.array[j]->range); } } } #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) if (ifcfInfo->ext1 && ifcfInfo->ext1->q_QualMin_r9) LOG_I(RRC," Q_QualMin_r9 : %ld\n",*ifcfInfo->ext1->q_QualMin_r9); if (ifcfInfo->ext1 && ifcfInfo->ext1->threshX_Q_r9) { LOG_I(RRC," threshX_HighQ_r9 : %ld\n",ifcfInfo->ext1->threshX_Q_r9->threshX_HighQ_r9); LOG_I(RRC," threshX_LowQ_r9: %ld\n",ifcfInfo->ext1->threshX_Q_r9->threshX_LowQ_r9); } #endif } } #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) void dump_sib13( LTE_SystemInformationBlockType13_r9_t *sib13 ) { LOG_I( RRC, "[UE] Dumping SIB13\n" ); LOG_I( RRC, "[UE] dumping sib13 second time\n" ); LOG_I( RRC, "[UE] NotificationRepetitionCoeff-r9 : %ld\n", sib13->notificationConfig_r9.notificationRepetitionCoeff_r9 ); LOG_I( RRC, "[UE] NotificationOffset-r9 : %d\n", (int)sib13->notificationConfig_r9.notificationOffset_r9 ); LOG_I( RRC, "[UE] NotificationSF-Index-r9 : %d\n", (int)sib13->notificationConfig_r9.notificationSF_Index_r9 ); } //TTN - SIB18 //----------------------------------------------------------------------------- void dump_sib18(LTE_SystemInformationBlockType18_r12_t *sib18) { LOG_I( RRC, "[UE] Dumping SIB18\n" ); for (int i = 0; i < sib18->commConfig_r12->commRxPool_r12.list.count; i++) { LOG_I(RRC, " Contents of SIB18 %d/%d \n", i+1, sib18->commConfig_r12->commRxPool_r12.list.count); LOG_I(RRC, " SIB18 rxPool_sc_CP_Len: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->sc_CP_Len_r12); LOG_I(RRC, " SIB18 sc_Period_r12: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->sc_Period_r12); LOG_I(RRC, " SIB18 data_CP_Len_r12: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->data_CP_Len_r12); LOG_I(RRC, " SIB18 prb_Num_r12: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->sc_TF_ResourceConfig_r12.prb_Num_r12); LOG_I(RRC, " SIB18 prb_Start_r12: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->sc_TF_ResourceConfig_r12.prb_Start_r12); LOG_I(RRC, " SIB18 prb_End_r12: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->sc_TF_ResourceConfig_r12.prb_End_r12); //to add more log } } //TTN - SIB19 //----------------------------------------------------------------------------- void dump_sib19(LTE_SystemInformationBlockType19_r12_t *sib19) { LOG_I( RRC, "[UE] Dumping SIB19\n" ); for (int i = 0; i < sib19->discConfig_r12->discRxPool_r12.list.count; i++) { LOG_I(RRC, " Contents of SIB19 %d/%d \n", i+1, sib19->discConfig_r12->discRxPool_r12.list.count); LOG_I(RRC, " SIB19 cp_Len_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->cp_Len_r12); LOG_I(RRC, " SIB19 discPeriod_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->discPeriod_r12); LOG_I(RRC, " SIB19 numRetx_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->numRetx_r12); LOG_I(RRC, " SIB19 numRepetition_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->numRepetition_r12); LOG_I(RRC, " SIB19 prb_Num_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->tf_ResourceConfig_r12.prb_Num_r12); LOG_I(RRC, " SIB19 prb_Start_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->tf_ResourceConfig_r12.prb_Start_r12); LOG_I(RRC, " SIB19 prb_End_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->tf_ResourceConfig_r12.prb_End_r12); //to add more log } } void dump_sib21(LTE_SystemInformationBlockType21_r14_t *sib21) { if ((sib21->sl_V2X_ConfigCommon_r14 != NULL) && (sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14 !=NULL) ) { for (int i = 0; i < sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.count; i++) { LOG_I(RRC, " Contents of SIB21 %d/%d \n", i+1, sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.count); LOG_I(RRC, " SIB21 sl_Subframe_r14: %d \n", sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.array[i]->sl_Subframe_r14.present); LOG_I(RRC, " SIB21 adjacencyPSCCH_PSSCH_r14: %d \n", sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.array[i]->adjacencyPSCCH_PSSCH_r14); LOG_I(RRC, " SIB21 sizeSubchannel_r14: %ld \n", sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.array[i]->sizeSubchannel_r14); LOG_I(RRC, " SIB21 numSubchannel_r14: %ld \n", sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.array[i]->numSubchannel_r14); LOG_I(RRC, " SIB21 startRB_Subchannel_r14: %ld \n", sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.array[i]->startRB_Subchannel_r14); //to add more log } } } #endif //----------------------------------------------------------------------------- int decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) { LTE_SystemInformation_t **si = &UE_rrc_inst[ctxt_pP->module_id].si[eNB_index]; int new_sib = 0; LTE_SystemInformationBlockType1_t *sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_IN ); // Dump contents if ((*si)->criticalExtensions.present == LTE_SystemInformation__criticalExtensions_PR_systemInformation_r8 || #if (LTE_RRC_VERSION >= MAKE_VERSION(15, 3, 0)) (*si)->criticalExtensions.present == LTE_SystemInformation__criticalExtensions_PR_criticalExtensionsFuture_r15) { #else (*si)->criticalExtensions.present == LTE_SystemInformation__criticalExtensions_PR_criticalExtensionsFuture) { #endif LOG_D( RRC, "[UE] (*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count %d\n", (*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count ); } else { LOG_D( RRC, "[UE] Unknown criticalExtension version (not Rel8)\n" ); return -1; } for (int i=0; i<(*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count; i++) { struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *typeandinfo; typeandinfo = (*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.array[i]; switch(typeandinfo->present) { case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&2) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=2; new_sib=1; memcpy( UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index], &typeandinfo->choice.sib2, sizeof(LTE_SystemInformationBlockType2_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB2 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); dump_sib2( UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index] ); LOG_I( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB2 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id ); rrc_mac_config_req_ue(ctxt_pP->module_id, 0, eNB_index, &UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->radioResourceConfigCommon, (struct LTE_PhysicalConfigDedicated *)NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (LTE_SCellToAddMod_r10_t *)NULL, #endif (LTE_MeasObjectToAddMod_t **)NULL, (LTE_MAC_MainConfig_t *)NULL, 0, (struct LTE_LogicalChannelConfig *)NULL, (LTE_MeasGapConfig_t *)NULL, (LTE_TDD_Config_t *)NULL, (LTE_MobilityControlInfo_t *)NULL, NULL, NULL, UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->freqInfo.ul_CarrierFreq, UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->freqInfo.ul_Bandwidth, &UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->freqInfo.additionalSpectrumEmission, UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->mbsfn_SubframeConfigList #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,0, (LTE_MBSFN_AreaInfoList_r9_t *)NULL, (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA ,0, 0 #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , 0, NULL, NULL #endif ); // After SI is received, prepare RRCConnectionRequest #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (UE_rrc_inst[ctxt_pP->module_id].MBMS_flag < 3) // see -Q option #endif if (EPC_MODE_ENABLED) { rrc_ue_generate_RRCConnectionRequest( ctxt_pP, eNB_index ); } if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State == RRC_IDLE) { LOG_I( RRC, "[UE %d] Received SIB1/SIB2/SIB3 Switching to RRC_SI_RECEIVED\n", ctxt_pP->module_id ); UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State = RRC_SI_RECEIVED; #if ENABLE_RAL { MessageDef *message_ral_p = NULL; rrc_ral_system_information_ind_t ral_si_ind; message_ral_p = itti_alloc_new_message (TASK_RRC_UE, RRC_RAL_SYSTEM_INFORMATION_IND); memset(&ral_si_ind, 0, sizeof(rrc_ral_system_information_ind_t)); ral_si_ind.plmn_id.MCCdigit2 = '0'; ral_si_ind.plmn_id.MCCdigit1 = '2'; ral_si_ind.plmn_id.MNCdigit3 = '0'; ral_si_ind.plmn_id.MCCdigit3 = '8'; ral_si_ind.plmn_id.MNCdigit2 = '9'; ral_si_ind.plmn_id.MNCdigit1 = '9'; ral_si_ind.cell_id = 1; ral_si_ind.dbm = 0; //ral_si_ind.dbm = fifo_dump_emos_UE.PHY_measurements->rx_rssi_dBm[eNB_index]; // TO DO ral_si_ind.sinr = 0; //ral_si_ind.sinr = fifo_dump_emos_UE.PHY_measurements->subband_cqi_dB[eNB_index][phy_vars_ue->lte_frame_parms.nb_antennas_rx][0]; // TO DO ral_si_ind.link_data_rate = 0; memcpy (&message_ral_p->ittiMsg, (void *) &ral_si_ind, sizeof(rrc_ral_system_information_ind_t)); #warning "ue_mod_idP ? for instance ?" itti_send_msg_to_task (TASK_RAL_UE, UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), message_ral_p); } #endif } } break; // case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2 case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib3: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&4) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=4; new_sib=1; memcpy( UE_rrc_inst[ctxt_pP->module_id].sib3[eNB_index], &typeandinfo->choice.sib3, sizeof(LTE_SystemInformationBlockType3_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB3 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); dump_sib3( UE_rrc_inst[ctxt_pP->module_id].sib3[eNB_index] ); } break; case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib4: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&8) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=8; new_sib=1; memcpy( UE_rrc_inst[ctxt_pP->module_id].sib4[eNB_index], &typeandinfo->choice.sib4, sizeof(LTE_SystemInformationBlockType4_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB4 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); } break; case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib5: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&16) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=16; new_sib=1; memcpy( UE_rrc_inst[ctxt_pP->module_id].sib5[eNB_index], &typeandinfo->choice.sib5, sizeof(LTE_SystemInformationBlockType5_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB5 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); dump_sib5(UE_rrc_inst[ctxt_pP->module_id].sib5[eNB_index]); } break; case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib6: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&32) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=32; new_sib=1; memcpy( UE_rrc_inst[ctxt_pP->module_id].sib6[eNB_index], &typeandinfo->choice.sib6, sizeof(LTE_SystemInformationBlockType6_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB6 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); } break; case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib7: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&64) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=64; new_sib=1; memcpy( UE_rrc_inst[ctxt_pP->module_id].sib7[eNB_index], &typeandinfo->choice.sib7, sizeof(LTE_SystemInformationBlockType7_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB7 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); } break; case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib8: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&128) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=128; new_sib=1; memcpy( UE_rrc_inst[ctxt_pP->module_id].sib8[eNB_index], &typeandinfo->choice.sib8, sizeof(LTE_SystemInformationBlockType8_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB8 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); } break; case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib9: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&256) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=256; new_sib=1; memcpy( UE_rrc_inst[ctxt_pP->module_id].sib9[eNB_index], &typeandinfo->choice.sib9, sizeof(LTE_SystemInformationBlockType9_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB9 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); } break; case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib10: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&512) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=512; new_sib=1; memcpy( UE_rrc_inst[ctxt_pP->module_id].sib10[eNB_index], &typeandinfo->choice.sib10, sizeof(LTE_SystemInformationBlockType10_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB10 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); } break; case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib11: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&1024) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=1024; new_sib=1; memcpy( UE_rrc_inst[ctxt_pP->module_id].sib11[eNB_index], &typeandinfo->choice.sib11, sizeof(LTE_SystemInformationBlockType11_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB11 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); } break; #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 2, 0)) case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib12_v920: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&2048) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=2048; new_sib=1; memcpy( UE_rrc_inst[ctxt_pP->module_id].sib12[eNB_index], &typeandinfo->choice.sib12_v920, sizeof(LTE_SystemInformationBlockType12_r9_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB12 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); } break; case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&4096) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=4096; new_sib=1; memcpy( UE_rrc_inst[ctxt_pP->module_id].sib13[eNB_index], &typeandinfo->choice.sib13_v920, sizeof(LTE_SystemInformationBlockType13_r9_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB13 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); dump_sib13( UE_rrc_inst[ctxt_pP->module_id].sib13[eNB_index] ); // adding here function to store necessary parameters for using in decode_MCCH_Message + maybe transfer to PHY layer LOG_I( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB13 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id); rrc_mac_config_req_ue(ctxt_pP->module_id,0,eNB_index, (LTE_RadioResourceConfigCommonSIB_t *)NULL, (struct LTE_PhysicalConfigDedicated *)NULL, (LTE_SCellToAddMod_r10_t *)NULL, (LTE_MeasObjectToAddMod_t **)NULL, (LTE_MAC_MainConfig_t *)NULL, 0, (struct LTE_LogicalChannelConfig *)NULL, (LTE_MeasGapConfig_t *)NULL, (LTE_TDD_Config_t *)NULL, (LTE_MobilityControlInfo_t *)NULL, NULL, NULL, NULL, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *)NULL, 0, &UE_rrc_inst[ctxt_pP->module_id].sib13[eNB_index]->mbsfn_AreaInfoList_r9, (LTE_PMCH_InfoList_r9_t *)NULL #ifdef CBA ,0, 0 #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , 0, NULL, NULL #endif ); break; } #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) //SIB18 case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib18_v1250: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&8192) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=8192; new_sib=1; memcpy( UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index], &typeandinfo->choice.sib18_v1250, sizeof(LTE_SystemInformationBlockType18_r12_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB18 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); dump_sib18( UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index] ); // adding here function to store necessary parameters to transfer to PHY layer LOG_I( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB18 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id); //process SIB18 to transfer SL-related parameters to PHY rrc_ue_process_sidelink_radioResourceConfig(ctxt_pP->module_id,eNB_index, UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index], (LTE_SystemInformationBlockType19_r12_t *)NULL, (LTE_SL_CommConfig_r12_t *)NULL, (LTE_SL_DiscConfig_r12_t *)NULL ); } break; //SIB19 case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib19_v1250: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&16384) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=16384; new_sib=1; memcpy( UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index], &typeandinfo->choice.sib19_v1250, sizeof(LTE_SystemInformationBlockType19_r12_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB19 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); dump_sib19( UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index] ); // adding here function to store necessary parameters to transfer to PHY layer LOG_I( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB19 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id); //process SIB19 to transfer SL-related parameters to PHY rrc_ue_process_sidelink_radioResourceConfig(ctxt_pP->module_id,eNB_index, (LTE_SystemInformationBlockType18_r12_t *)NULL, UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index], (LTE_SL_CommConfig_r12_t *)NULL, (LTE_SL_DiscConfig_r12_t *)NULL ); } break; //SIB21 case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib21_v1430: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&32768) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=32768; new_sib=1; memcpy( UE_rrc_inst[ctxt_pP->module_id].sib21[eNB_index], &typeandinfo->choice.sib21_v1430, sizeof(LTE_SystemInformationBlockType21_r14_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB21 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); dump_sib21( UE_rrc_inst[ctxt_pP->module_id].sib21[eNB_index] ); // adding here function to store necessary parameters to transfer to PHY layer LOG_I( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB21 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id); //process SIB21 //TODO } break; #endif default: break; } } if (new_sib == 1) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt++; if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt == sib1->schedulingInfoList.list.count) rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_SIB_COMPLETE ); LOG_I(RRC,"SIStatus %x, SIcnt %d/%d\n", UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus, UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt, sib1->schedulingInfoList.list.count); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_OUT); return 0; } // layer 3 filtering of RSRP (EUTRA) measurements: 36.331, Sec. 5.5.3.2 //----------------------------------------------------------------------------- void ue_meas_filtering( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) { float a = UE_rrc_inst[ctxt_pP->module_id].filter_coeff_rsrp; // 'a' in 36.331 Sec. 5.5.3.2 float a1 = UE_rrc_inst[ctxt_pP->module_id].filter_coeff_rsrq; //float rsrp_db, rsrq_db; uint8_t eNB_offset; if(UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[0] != NULL) { // Only consider 1 serving cell (index: 0) if (UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[0]->quantityConfigEUTRA != NULL) { if(UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[0]->quantityConfigEUTRA->filterCoefficientRSRP != NULL) { for (eNB_offset = 0; eNB_offset<1+get_n_adj_cells(ctxt_pP->module_id,0); eNB_offset++) { UE_rrc_inst[ctxt_pP->module_id].rsrp_db[eNB_offset] = get_RSRP(ctxt_pP->module_id,0,eNB_offset); /* (dB_fixed_times10(get_RSRP(ctxt_pP->module_id,0,eNB_offset))/10.0) - get_rx_total_gain_dB(ctxt_pP->module_id,0) - get_bw_gain_dB(ctxt_pP->module_id); */ UE_rrc_inst[ctxt_pP->module_id].rsrp_db_filtered[eNB_offset] = (1.0-a)*UE_rrc_inst[ctxt_pP->module_id].rsrp_db_filtered[eNB_offset] + a*UE_rrc_inst[ctxt_pP->module_id].rsrp_db[eNB_offset]; LOG_D(RRC,"RSRP_dBm: %3.2f \n",get_RSRP(ctxt_pP->module_id,0,eNB_offset));; /* LOG_D(RRC,"gain_loss_dB: %d \n",get_rx_total_gain_dB(ctxt_pP->module_id,0)); LOG_D(RRC,"gain_fixed_dB: %d \n",dB_fixed(frame_parms->N_RB_DL*12));*/ LOG_D(PHY,"[UE %d] Frame %d, RRC Measurements => rssi %3.1f dBm (digital: %3.1f dB)\n", ctxt_pP->module_id, ctxt_pP->frame, 10*log10(get_RSSI(ctxt_pP->module_id,0))-get_rx_total_gain_dB(ctxt_pP->module_id,0), 10*log10(get_RSSI(ctxt_pP->module_id,0))); LOG_D(RRC,"[UE %d] Frame %d: Meas RSRP: eNB_offset: %d rsrp_coef: %3.1f filter_coef: %ld before L3 filtering: rsrp: %3.1f after L3 filtering: rsrp: %3.1f \n ", ctxt_pP->module_id, ctxt_pP->frame, eNB_offset,a, *UE_rrc_inst->QuantityConfig[0]->quantityConfigEUTRA->filterCoefficientRSRP, UE_rrc_inst[ctxt_pP->module_id].rsrp_db[eNB_offset], UE_rrc_inst[ctxt_pP->module_id].rsrp_db_filtered[eNB_offset]); } } } else { for (eNB_offset = 0; eNB_offset<1+get_n_adj_cells(ctxt_pP->module_id,0); eNB_offset++) { UE_rrc_inst[ctxt_pP->module_id].rsrp_db_filtered[eNB_offset]= get_RSRP(ctxt_pP->module_id,0,eNB_offset); } } if (UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[0]->quantityConfigEUTRA != NULL) { if(UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[0]->quantityConfigEUTRA->filterCoefficientRSRQ != NULL) { for (eNB_offset = 0; eNB_offset<1+get_n_adj_cells(ctxt_pP->module_id,0); eNB_offset++) { UE_rrc_inst[ctxt_pP->module_id].rsrq_db[eNB_offset] = (10*log10(get_RSRQ(ctxt_pP->module_id,0,eNB_offset)))-20; UE_rrc_inst[ctxt_pP->module_id].rsrq_db_filtered[eNB_offset]=(1-a1)*UE_rrc_inst[ctxt_pP->module_id].rsrq_db_filtered[eNB_offset] + a1 *UE_rrc_inst[ctxt_pP->module_id].rsrq_db[eNB_offset]; } } } else { for (eNB_offset = 0; eNB_offset<1+get_n_adj_cells(ctxt_pP->module_id,0); eNB_offset++) { UE_rrc_inst[ctxt_pP->module_id].rsrq_db_filtered[eNB_offset]= get_RSRQ(ctxt_pP->module_id,0,eNB_offset); } } } } //Below routine implements Measurement Reporting procedure from 36.331 Section 5.5.5 //----------------------------------------------------------------------------- void rrc_ue_generate_MeasurementReport(protocol_ctxt_t *const ctxt_pP, uint8_t eNB_index ) { uint8_t buffer[32], size; uint8_t i; uint8_t target_eNB_offset; LTE_MeasId_t measId; LTE_PhysCellId_t targetCellId; long rsrp_t,rsrq_t; long rsrp_s,rsrq_s; long nElem, nElem1; float rsrp_filtered, rsrq_filtered; static frame_t pframe=0; int result; nElem = 98; nElem1 = 35; target_eNB_offset = UE_rrc_inst[ctxt_pP->module_id].Info[0].handoverTarget; // eNB_offset of target eNB: used to obtain the mod_id of target eNB for (i=0; i<MAX_MEAS_ID; i++) { if (UE_rrc_inst[ctxt_pP->module_id].measReportList[0][i] != NULL) { measId = UE_rrc_inst[ctxt_pP->module_id].measReportList[0][i]->measId; // Note: Values in the meas report have to be the mapped values...to implement binary search for LUT rsrp_filtered = UE_rrc_inst[ctxt_pP->module_id].rsrp_db_filtered[eNB_index];//nid_cell]; rsrp_s = binary_search_float(RSRP_meas_mapping,nElem, rsrp_filtered); rsrq_filtered = UE_rrc_inst[ctxt_pP->module_id].rsrq_db_filtered[eNB_index];//nid_cell]; //RSRQ of serving cell rsrq_s = binary_search_float(RSRQ_meas_mapping,nElem1,rsrq_filtered);//mapped RSRQ of serving cell LOG_D(RRC,"[UE %d] Frame %d: source eNB %d :rsrp_s: %ld rsrq_s: %ld rsrp_filtered: %f rsrq_filtered: %f \n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index, rsrp_s, rsrq_s, rsrp_filtered, rsrq_filtered); rsrp_t = binary_search_float(RSRP_meas_mapping,nElem,UE_rrc_inst[ctxt_pP->module_id].rsrp_db_filtered[target_eNB_offset]); //RSRP of target cell rsrq_t = binary_search_float(RSRQ_meas_mapping,nElem1,UE_rrc_inst[ctxt_pP->module_id].rsrq_db_filtered[target_eNB_offset]); //RSRQ of target cell LOG_D(RRC,"[UE %d] Frame %d: target eNB %d :rsrp_t: %ld rsrq_t: %ld rsrp_filtered: %f rsrq_filtered: %f \n", ctxt_pP->module_id, ctxt_pP->frame, target_eNB_offset, rsrp_t, rsrq_t, UE_rrc_inst[ctxt_pP->module_id].rsrp_db_filtered[target_eNB_offset], UE_rrc_inst[ctxt_pP->module_id].rsrq_db_filtered[target_eNB_offset]); // if (measFlag == 1) { targetCellId = UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.targetCellId ;//get_adjacent_cell_id(ue_mod_idP,target_eNB_offset); //PhycellId of target cell if (pframe!=ctxt_pP->frame) { pframe=ctxt_pP->frame; LOG_D(RRC, "[UE %d] Frame %ld: doing MeasReport: servingCell(%ld) targetCell(%ld) rsrp_s(%ld) rsrq_s(%ld) rsrp_t(%ld) rsrq_t(%ld) \n", ctxt_pP->module_id, (long int)ctxt_pP->frame, (long int)get_adjacent_cell_id(ctxt_pP->module_id, eNB_index), (long int)targetCellId, (long int)rsrp_s, (long int)rsrq_s, (long int)rsrp_t, (long int)rsrq_t); size = do_MeasurementReport(ctxt_pP->module_id, buffer,measId,targetCellId,rsrp_s,rsrq_s,rsrp_t,rsrq_t); LOG_I(RRC, "[UE %d] Frame %d : Generating Measurement Report for eNB %d\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index); result = pdcp_data_req(ctxt_pP, SRB_FLAG_YES, DCCH, rrc_mui++, 0, size, buffer, PDCP_TRANSMISSION_MODE_DATA #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,NULL, NULL #endif ); AssertFatal (result == TRUE, "PDCP data request failed!\n"); //LOG_D(RRC, "[UE %d] Frame %d Sending MeasReport (%d bytes) through DCCH%d to PDCP \n",ue_mod_idP,frameP, size, DCCH); } // measFlag = 0; //re-setting measFlag so that no more MeasReports are sent in this frameP // } } } } // Measurement report triggering, described in 36.331 Section 5.5.4.1: called periodically //----------------------------------------------------------------------------- void ue_measurement_report_triggering(protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) { uint8_t i,j; LTE_Hysteresis_t hys; LTE_TimeToTrigger_t ttt_ms; LTE_Q_OffsetRange_t ofn; LTE_Q_OffsetRange_t ocn; LTE_Q_OffsetRange_t ofs = 0; LTE_Q_OffsetRange_t ocs = 0; long a3_offset; LTE_MeasObjectId_t measObjId; LTE_ReportConfigId_t reportConfigId; for(i=0 ; i<NB_CNX_UE ; i++) { for(j=0 ; j<MAX_MEAS_ID ; j++) { if(UE_rrc_inst[ctxt_pP->module_id].MeasId[i][j] != NULL) { measObjId = UE_rrc_inst[ctxt_pP->module_id].MeasId[i][j]->measObjectId; reportConfigId = UE_rrc_inst[ctxt_pP->module_id].MeasId[i][j]->reportConfigId; if( /*UE_rrc_inst[ctxt_pP->module_id].MeasId[i][j] != NULL && */ UE_rrc_inst[ctxt_pP->module_id].MeasObj[i][measObjId-1] != NULL) { if(UE_rrc_inst[ctxt_pP->module_id].MeasObj[i][measObjId-1]->measObject.present == LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA) { /* consider any neighboring cell detected on the associated frequency to be * applicable when the concerned cell is not included in the blackCellsToAddModList * defined within the VarMeasConfig for this measId */ // LOG_I(RRC,"event %d %d %p \n", measObjId,reportConfigId, UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1]); if((UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1] != NULL) && (UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1]->reportConfig.present == LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA) && (UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.present == LTE_ReportConfigEUTRA__triggerType_PR_event)) { hys = UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis; ttt_ms = timeToTrigger_ms[UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId -1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger]; // Freq specific offset of neighbor cell freq ofn = 5;//((UE_rrc_inst[ctxt_pP->module_id].MeasObj[i][measObjId-1]->measObject.choice.measObjectEUTRA.offsetFreq != NULL) ? // *UE_rrc_inst[ctxt_pP->module_id].MeasObj[i][measObjId-1]->measObject.choice.measObjectEUTRA.offsetFreq : 15); // /* 15 is the Default */ // cellIndividualOffset of neighbor cell - not defined yet ocn = 0; a3_offset = UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId -1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset; switch (UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present) { case LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1: LOG_D(RRC,"[UE %d] Frame %d : A1 event: check if serving becomes better than threshold\n", ctxt_pP->module_id, ctxt_pP->frame); break; case LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2: LOG_D(RRC,"[UE %d] Frame %d : A2 event, check if serving becomes worse than a threshold\n", ctxt_pP->module_id, ctxt_pP->frame); break; case LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3: LOG_D(RRC,"[UE %d] Frame %d : A3 event: check if a neighboring cell becomes offset better than serving to trigger a measurement event \n", ctxt_pP->module_id, ctxt_pP->frame); if ((check_trigger_meas_event( ctxt_pP->module_id, ctxt_pP->frame, eNB_index, i,j,ofn,ocn,hys,ofs,ocs,a3_offset,ttt_ms)) && (UE_rrc_inst[ctxt_pP->module_id].Info[0].State >= RRC_CONNECTED) && (UE_rrc_inst[ctxt_pP->module_id].Info[0].T304_active == 0 ) && (UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.measFlag == 1)) { //trigger measurement reporting procedure (36.331, section 5.5.5) if (UE_rrc_inst[ctxt_pP->module_id].measReportList[i][j] == NULL) { UE_rrc_inst[ctxt_pP->module_id].measReportList[i][j] = malloc(sizeof(MEAS_REPORT_LIST)); } UE_rrc_inst[ctxt_pP->module_id].measReportList[i][j]->measId = UE_rrc_inst[ctxt_pP->module_id].MeasId[i][j]->measId; UE_rrc_inst[ctxt_pP->module_id].measReportList[i][j]->numberOfReportsSent = 0; rrc_ue_generate_MeasurementReport( ctxt_pP, eNB_index); UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.measFlag = 1; LOG_I(RRC,"[UE %d] Frame %d: A3 event detected, state: %d \n", ctxt_pP->module_id, ctxt_pP->frame, UE_rrc_inst[ctxt_pP->module_id].Info[0].State); } else { if(UE_rrc_inst[ctxt_pP->module_id].measReportList[i][j] != NULL) { free(UE_rrc_inst[ctxt_pP->module_id].measReportList[i][j]); } UE_rrc_inst[ctxt_pP->module_id].measReportList[i][j] = NULL; } break; case LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4: LOG_D(RRC,"[UE %d] Frame %d : received an A4 event, neighbor becomes offset better than a threshold\n", ctxt_pP->module_id, ctxt_pP->frame); break; case LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA5: LOG_D(RRC,"[UE %d] Frame %d: received an A5 event, serving becomes worse than threshold 1 and neighbor becomes better than threshold 2\n", ctxt_pP->module_id, ctxt_pP->frame); break; default: LOG_D(RRC,"Invalid ReportConfigEUTRA__triggerType__event__eventId: %d", UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][j]->reportConfig.choice.reportConfigEUTRA.triggerType.present); break; } } } } } } } } //check_trigger_meas_event(ue_mod_idP, frameP, eNB_index, i,j,ofn,ocn,hys,ofs,ocs,a3_offset,ttt_ms) //----------------------------------------------------------------------------- uint8_t check_trigger_meas_event( module_id_t ue_mod_idP, frame_t frameP, uint8_t eNB_index, uint8_t ue_cnx_index, uint8_t meas_index, LTE_Q_OffsetRange_t ofn, LTE_Q_OffsetRange_t ocn, LTE_Hysteresis_t hys, LTE_Q_OffsetRange_t ofs, LTE_Q_OffsetRange_t ocs, long a3_offset, LTE_TimeToTrigger_t ttt ) { uint8_t eNB_offset; // uint8_t currentCellIndex = frame_parms->Nid_cell; uint8_t tmp_offset; LOG_D(RRC,"[UE %d] ofn(%ld) ocn(%ld) hys(%ld) ofs(%ld) ocs(%ld) a3_offset(%ld) ttt(%ld) rssi %3.1f\n", ue_mod_idP, ofn,ocn,hys,ofs,ocs,a3_offset,ttt, 10*log10(get_RSSI(ue_mod_idP,0))-get_rx_total_gain_dB(ue_mod_idP,0)); for (eNB_offset = 0; eNB_offset<1+get_n_adj_cells(ue_mod_idP,0); eNB_offset++) { /* RHS: Verify that idx 0 corresponds to currentCellIndex in rsrp array */ if((eNB_offset!=eNB_index)&&(eNB_offset<NB_eNB_INST)) { if(eNB_offset<eNB_index) { tmp_offset = eNB_offset; } else { tmp_offset = eNB_offset-1; } if(UE_rrc_inst[ue_mod_idP].rsrp_db_filtered[eNB_offset]+ofn+ocn-hys > UE_rrc_inst[ue_mod_idP].rsrp_db_filtered[eNB_index]+ofs+ocs-1/*+a3_offset*/) { UE_rrc_inst->measTimer[ue_cnx_index][meas_index][tmp_offset] += 2; //Called every subframe = 2ms LOG_D(RRC,"[UE %d] Frame %d: Entry measTimer[%d][%d][%d]: %d currentCell: %d betterCell: %d \n", ue_mod_idP, frameP, ue_cnx_index,meas_index,tmp_offset,UE_rrc_inst->measTimer[ue_cnx_index][meas_index][tmp_offset],0,eNB_offset); } else { UE_rrc_inst->measTimer[ue_cnx_index][meas_index][tmp_offset] = 0; //Exit condition: Resetting the measurement timer LOG_D(RRC,"[UE %d] Frame %d: Exit measTimer[%d][%d][%d]: %d currentCell: %d betterCell: %d \n", ue_mod_idP, frameP, ue_cnx_index,meas_index,tmp_offset,UE_rrc_inst->measTimer[ue_cnx_index][meas_index][tmp_offset],0,eNB_offset); } if (UE_rrc_inst->measTimer[ue_cnx_index][meas_index][tmp_offset] >= ttt) { UE_rrc_inst->HandoverInfoUe.targetCellId = get_adjacent_cell_id(ue_mod_idP,tmp_offset); //WARNING!!!...check this! LOG_D(RRC,"[UE %d] Frame %d eNB %d: Handover triggered: targetCellId: %ld currentCellId: %d eNB_offset: %d rsrp source: %3.1f rsrp target: %3.1f\n", ue_mod_idP, frameP, eNB_index, UE_rrc_inst->HandoverInfoUe.targetCellId,ue_cnx_index,eNB_offset, get_RSRP(ue_mod_idP,0,0), get_RSRP(ue_mod_idP,0,1)); UE_rrc_inst->Info[0].handoverTarget = eNB_offset; //LOG_D(RRC,"PHY_ID: %d \n",UE_rrc_inst->HandoverInfoUe.targetCellId); return 1; } // else{ // LOG_D(RRC,"Condition does not hold\n"); // } } } return 0; } #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) //----------------------------------------------------------------------------- int decode_MCCH_Message( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t *const Sdu, const uint8_t Sdu_len, const uint8_t mbsfn_sync_area ) { LTE_MCCH_Message_t *mcch=NULL; LTE_MBSFNAreaConfiguration_r9_t **mcch_message=&UE_rrc_inst[ctxt_pP->module_id].mcch_message[eNB_index]; asn_dec_rval_t dec_rval; if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].MCCHStatus[mbsfn_sync_area] == 1) { LOG_D(RRC,"[UE %d] Frame %d: MCCH MESSAGE for MBSFN sync area %d has been already received!\n", ctxt_pP->module_id, ctxt_pP->frame, mbsfn_sync_area); return 0; // avoid decoding to prevent memory bloating } else { dec_rval = uper_decode_complete(NULL, &asn_DEF_LTE_MCCH_Message, (void **)&mcch, (const void *)Sdu, Sdu_len); if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) { LOG_E(RRC,"[UE %d] Failed to decode MCCH__MESSAGE (%lu bits)\n", ctxt_pP->module_id, dec_rval.consumed); //free the memory SEQUENCE_free(&asn_DEF_LTE_MCCH_Message, (void *)mcch, 1); return -1; } if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_LTE_MCCH_Message, (void *)mcch); } if (mcch->message.present == LTE_MCCH_MessageType_PR_c1) { LOG_D(RRC,"[UE %d] Found mcch message \n", ctxt_pP->module_id); if(mcch->message.choice.c1.present == LTE_MCCH_MessageType__c1_PR_mbsfnAreaConfiguration_r9) { /* memcpy((void*)*mcch_message, (void*)&mcch->message.choice.c1.choice.mbsfnAreaConfiguration_r9, sizeof(MBSFNAreaConfiguration_r9_t)); */ *mcch_message = &mcch->message.choice.c1.choice.mbsfnAreaConfiguration_r9; LOG_I(RRC,"[UE %d] Frame %d : Found MBSFNAreaConfiguration from eNB %d \n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index); decode_MBSFNAreaConfiguration( ctxt_pP->module_id, eNB_index, ctxt_pP->frame, mbsfn_sync_area); } } } return 0; } //----------------------------------------------------------------------------- void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_index, frame_t frameP, uint8_t mbsfn_sync_area ) { uint8_t i; protocol_ctxt_t ctxt; LOG_I(RRC,"[UE %d] Frame %d : Number of MCH(s) in the MBSFN Sync Area %d is %d\n", ue_mod_idP, frameP, mbsfn_sync_area, UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->pmch_InfoList_r9.list.count); // Configure commonSF_Alloc for(i=0; i< UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.count; i++) { LOG_W(RRC,"[UE %d] Frame %d, commonSF_Alloc_r9: radioframeAllocationPeriod(%ldn),radioframeAllocationOffset(%ld), subframeAllocation(%x,%x,%x)\n", ue_mod_idP, frameP, UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]->radioframeAllocationPeriod<<1, UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]->radioframeAllocationOffset, UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]->subframeAllocation.choice.oneFrame.buf[0], UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]->subframeAllocation.choice.oneFrame.buf[1], UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]->subframeAllocation.choice.oneFrame.buf[2]); UE_mac_inst[ue_mod_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] = UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]; } LOG_W(RRC,"[UE %d] Frame %d, commonSF_AllocPeriod_r9 %drf \n", ue_mod_idP, frameP, 4<<UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_AllocPeriod_r9); // Configure commonSF_AllocPeriod UE_mac_inst[ue_mod_idP].commonSF_AllocPeriod_r9 = UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_AllocPeriod_r9; // store to MAC/PHY necessary parameters for receiving MTCHs rrc_mac_config_req_ue(ue_mod_idP,0,eNB_index, (LTE_RadioResourceConfigCommonSIB_t *)NULL, (struct LTE_PhysicalConfigDedicated *)NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (LTE_SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif (LTE_MeasObjectToAddMod_t **)NULL, (LTE_MAC_MainConfig_t *)NULL, 0, (struct LTE_LogicalChannelConfig *)NULL, (LTE_MeasGapConfig_t *)NULL, (LTE_TDD_Config_t *)NULL, (LTE_MobilityControlInfo_t *)NULL, NULL, NULL, NULL, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *)NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , 0, (LTE_MBSFN_AreaInfoList_r9_t *)NULL, &UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->pmch_InfoList_r9 #endif #ifdef CBA , 0, 0 #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , 0, NULL, NULL #endif ); UE_rrc_inst[ue_mod_idP].Info[eNB_index].MCCHStatus[mbsfn_sync_area] = 1; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_idP, ENB_FLAG_NO, UE_rrc_inst[ue_mod_idP].Info[eNB_index].rnti, frameP, 0,eNB_index); // Config Radio Bearer for MBMS user data (similar way to configure for eNB side in init_MBMS function) rrc_pdcp_config_asn1_req(&ctxt, NULL, // SRB_ToAddModList NULL, // DRB_ToAddModList (LTE_DRB_ToReleaseList_t *)NULL, 0, // security mode NULL, // key rrc encryption NULL, // key rrc integrity NULL // key encryption #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,&(UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->pmch_InfoList_r9) #endif ,NULL); rrc_rlc_config_asn1_req(&ctxt, NULL,// SRB_ToAddModList NULL,// DRB_ToAddModList NULL,// DRB_ToReleaseList #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) &(UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->pmch_InfoList_r9) , 0, 0 #endif ); // */ } #endif // rel10 //----------------------------------------------------------------------------- void *rrc_ue_task( void *args_p ) { MessageDef *msg_p; instance_t instance; unsigned int ue_mod_id; int result; SRB_INFO *srb_info_p; protocol_ctxt_t ctxt; itti_mark_task_ready (TASK_RRC_UE); while(1) { // Wait for a message itti_receive_msg (TASK_RRC_UE, &msg_p); instance = ITTI_MSG_INSTANCE (msg_p); ue_mod_id = UE_INSTANCE_TO_MODULE_ID(instance); switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: LOG_W(RRC, " *** Exiting RRC thread\n"); itti_exit_task (); break; case MESSAGE_TEST: LOG_D(RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); break; /* MAC messages */ case RRC_MAC_IN_SYNC_IND: LOG_D(RRC, "[UE %d] Received %s: frameP %d, eNB %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), RRC_MAC_IN_SYNC_IND (msg_p).frame, RRC_MAC_IN_SYNC_IND (msg_p).enb_index); UE_rrc_inst[ue_mod_id].Info[RRC_MAC_IN_SYNC_IND (msg_p).enb_index].N310_cnt = 0; if (UE_rrc_inst[ue_mod_id].Info[RRC_MAC_IN_SYNC_IND (msg_p).enb_index].T310_active == 1) { UE_rrc_inst[ue_mod_id].Info[RRC_MAC_IN_SYNC_IND (msg_p).enb_index].N311_cnt++; } break; case RRC_MAC_OUT_OF_SYNC_IND: LOG_D(RRC, "[UE %d] Received %s: frameP %d, eNB %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), RRC_MAC_OUT_OF_SYNC_IND (msg_p).frame, RRC_MAC_OUT_OF_SYNC_IND (msg_p).enb_index); UE_rrc_inst[ue_mod_id].Info[RRC_MAC_OUT_OF_SYNC_IND (msg_p).enb_index].N310_cnt ++; break; case RRC_MAC_BCCH_DATA_IND: LOG_D(RRC, "[UE %d] Received %s: frameP %d, eNB %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), RRC_MAC_BCCH_DATA_IND (msg_p).frame, RRC_MAC_BCCH_DATA_IND (msg_p).enb_index); // PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_NO, NOT_A_RNTI, RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, ENB_FLAG_NO, NOT_A_RNTI, RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0,RRC_MAC_BCCH_DATA_IND (msg_p).enb_index); decode_BCCH_DLSCH_Message (&ctxt, RRC_MAC_BCCH_DATA_IND (msg_p).enb_index, RRC_MAC_BCCH_DATA_IND (msg_p).sdu, RRC_MAC_BCCH_DATA_IND (msg_p).sdu_size, RRC_MAC_BCCH_DATA_IND (msg_p).rsrq, RRC_MAC_BCCH_DATA_IND (msg_p).rsrp); break; case RRC_MAC_CCCH_DATA_CNF: LOG_D(RRC, "[UE %d] Received %s: eNB %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), RRC_MAC_CCCH_DATA_CNF (msg_p).enb_index); // reset the tx buffer to indicate RRC that ccch was successfully transmitted (for example if contention resolution succeeds) UE_rrc_inst[ue_mod_id].Srb0[RRC_MAC_CCCH_DATA_CNF (msg_p).enb_index].Tx_buffer.payload_size = 0; break; case RRC_MAC_CCCH_DATA_IND: LOG_D(RRC, "[UE %d] RNTI %x Received %s: frameP %d, eNB %d\n", ue_mod_id, RRC_MAC_CCCH_DATA_IND (msg_p).rnti, ITTI_MSG_NAME (msg_p), RRC_MAC_CCCH_DATA_IND (msg_p).frame, RRC_MAC_CCCH_DATA_IND (msg_p).enb_index); srb_info_p = &UE_rrc_inst[ue_mod_id].Srb0[RRC_MAC_CCCH_DATA_IND (msg_p).enb_index]; memcpy (srb_info_p->Rx_buffer.Payload, RRC_MAC_CCCH_DATA_IND (msg_p).sdu, RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size); srb_info_p->Rx_buffer.payload_size = RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size; // PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_NO, RRC_MAC_CCCH_DATA_IND (msg_p).rnti, RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, ENB_FLAG_NO, RRC_MAC_CCCH_DATA_IND (msg_p).rnti, RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0, RRC_MAC_CCCH_DATA_IND (msg_p).enb_index); rrc_ue_decode_ccch (&ctxt, srb_info_p, RRC_MAC_CCCH_DATA_IND (msg_p).enb_index); break; #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) case RRC_MAC_MCCH_DATA_IND: LOG_D(RRC, "[UE %d] Received %s: frameP %d, eNB %d, mbsfn SA %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), RRC_MAC_MCCH_DATA_IND (msg_p).frame, RRC_MAC_MCCH_DATA_IND (msg_p).enb_index, RRC_MAC_MCCH_DATA_IND (msg_p).mbsfn_sync_area); //PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_NO, M_RNTI, RRC_MAC_MCCH_DATA_IND (msg_p).frame, 0); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, ENB_FLAG_NO, M_RNTI, RRC_MAC_MCCH_DATA_IND (msg_p).frame, 0,RRC_MAC_MCCH_DATA_IND (msg_p).enb_index); decode_MCCH_Message ( &ctxt, RRC_MAC_MCCH_DATA_IND (msg_p).enb_index, RRC_MAC_MCCH_DATA_IND (msg_p).sdu, RRC_MAC_MCCH_DATA_IND (msg_p).sdu_size, RRC_MAC_MCCH_DATA_IND (msg_p).mbsfn_sync_area); break; /* //TTN (for D2D) case RRC_MAC_SL_DISCOVERY_DATA_IND: LOG_D(RRC, "[UE %d] Received %s: frameP %d, eNB %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), RRC_MAC_SL_DISCOVERY_DATA_IND (msg_p).frame, RRC_MAC_SL_DISCOVERY_DATA_IND (msg_p).enb_index); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, ENB_FLAG_NO, M_RNTI, RRC_MAC_SL_DISCOVERY_DATA_IND (msg_p).frame, 0,RRC_MAC_SL_DISCOVERY_DATA_IND (msg_p).enb_index); //send to ProSeApp break; */ # endif /* PDCP messages */ case RRC_DCCH_DATA_IND: PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, RRC_DCCH_DATA_IND (msg_p).module_id, ENB_FLAG_NO, RRC_DCCH_DATA_IND (msg_p).rnti, RRC_DCCH_DATA_IND (msg_p).frame, 0,RRC_DCCH_DATA_IND (msg_p).eNB_index); LOG_D(RRC, "[UE %d] Received %s: frameP %d, DCCH %d, eNB %d\n", RRC_DCCH_DATA_IND (msg_p).module_id, ITTI_MSG_NAME (msg_p), RRC_DCCH_DATA_IND (msg_p).frame, RRC_DCCH_DATA_IND (msg_p).dcch_index, RRC_DCCH_DATA_IND (msg_p).eNB_index); LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT"Received %s DCCH %d, eNB %d\n", PROTOCOL_RRC_CTXT_UE_ARGS(&ctxt), ITTI_MSG_NAME (msg_p), RRC_DCCH_DATA_IND (msg_p).dcch_index, RRC_DCCH_DATA_IND (msg_p).eNB_index); rrc_ue_decode_dcch ( &ctxt, RRC_DCCH_DATA_IND (msg_p).dcch_index, RRC_DCCH_DATA_IND (msg_p).sdu_p, RRC_DCCH_DATA_IND (msg_p).eNB_index); // Message buffer has been processed, free it now. result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), RRC_DCCH_DATA_IND (msg_p).sdu_p); AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); break; case NAS_KENB_REFRESH_REQ: memcpy((void *)UE_rrc_inst[ue_mod_id].kenb, (void *)NAS_KENB_REFRESH_REQ(msg_p).kenb, sizeof(UE_rrc_inst[ue_mod_id].kenb)); LOG_D(RRC, "[UE %d] Received %s: refreshed RRC::KeNB = " "%02x%02x%02x%02x" "%02x%02x%02x%02x" "%02x%02x%02x%02x" "%02x%02x%02x%02x" "%02x%02x%02x%02x" "%02x%02x%02x%02x" "%02x%02x%02x%02x" "%02x%02x%02x%02x\n", ue_mod_id, ITTI_MSG_NAME (msg_p), UE_rrc_inst[ue_mod_id].kenb[0], UE_rrc_inst[ue_mod_id].kenb[1], UE_rrc_inst[ue_mod_id].kenb[2], UE_rrc_inst[ue_mod_id].kenb[3], UE_rrc_inst[ue_mod_id].kenb[4], UE_rrc_inst[ue_mod_id].kenb[5], UE_rrc_inst[ue_mod_id].kenb[6], UE_rrc_inst[ue_mod_id].kenb[7], UE_rrc_inst[ue_mod_id].kenb[8], UE_rrc_inst[ue_mod_id].kenb[9], UE_rrc_inst[ue_mod_id].kenb[10], UE_rrc_inst[ue_mod_id].kenb[11], UE_rrc_inst[ue_mod_id].kenb[12], UE_rrc_inst[ue_mod_id].kenb[13], UE_rrc_inst[ue_mod_id].kenb[14], UE_rrc_inst[ue_mod_id].kenb[15], UE_rrc_inst[ue_mod_id].kenb[16], UE_rrc_inst[ue_mod_id].kenb[17], UE_rrc_inst[ue_mod_id].kenb[18], UE_rrc_inst[ue_mod_id].kenb[19], UE_rrc_inst[ue_mod_id].kenb[20], UE_rrc_inst[ue_mod_id].kenb[21], UE_rrc_inst[ue_mod_id].kenb[22], UE_rrc_inst[ue_mod_id].kenb[23], UE_rrc_inst[ue_mod_id].kenb[24], UE_rrc_inst[ue_mod_id].kenb[25], UE_rrc_inst[ue_mod_id].kenb[26], UE_rrc_inst[ue_mod_id].kenb[27], UE_rrc_inst[ue_mod_id].kenb[28], UE_rrc_inst[ue_mod_id].kenb[29], UE_rrc_inst[ue_mod_id].kenb[30], UE_rrc_inst[ue_mod_id].kenb[31]); break; /* NAS messages */ case NAS_CELL_SELECTION_REQ: LOG_D(RRC, "[UE %d] Received %s: state %d, plmnID (%d%d%d.%d%d%d), rat %x\n", ue_mod_id, ITTI_MSG_NAME (msg_p), rrc_get_state(ue_mod_id), NAS_CELL_SELECTION_REQ (msg_p).plmnID.MCCdigit1, NAS_CELL_SELECTION_REQ (msg_p).plmnID.MCCdigit2, NAS_CELL_SELECTION_REQ (msg_p).plmnID.MCCdigit3, NAS_CELL_SELECTION_REQ (msg_p).plmnID.MNCdigit1, NAS_CELL_SELECTION_REQ (msg_p).plmnID.MNCdigit2, NAS_CELL_SELECTION_REQ (msg_p).plmnID.MNCdigit3, NAS_CELL_SELECTION_REQ (msg_p).rat); if (rrc_get_state(ue_mod_id) == RRC_STATE_INACTIVE) { // have a look at MAC/main.c void dl_phy_sync_success(...) openair_rrc_ue_init(ue_mod_id,0); } /* Save cell selection criterion */ { UE_rrc_inst[ue_mod_id].plmnID = NAS_CELL_SELECTION_REQ (msg_p).plmnID; UE_rrc_inst[ue_mod_id].rat = NAS_CELL_SELECTION_REQ (msg_p).rat; LOG_D(RRC, "[UE %d] Save cell selection criterion MCC %X%X%X MNC %X%X%X\n", ue_mod_id, UE_rrc_inst[ue_mod_id].plmnID.MCCdigit1, UE_rrc_inst[ue_mod_id].plmnID.MCCdigit2, UE_rrc_inst[ue_mod_id].plmnID.MCCdigit3, UE_rrc_inst[ue_mod_id].plmnID.MNCdigit1, UE_rrc_inst[ue_mod_id].plmnID.MNCdigit2, UE_rrc_inst[ue_mod_id].plmnID.MNCdigit3); } switch (rrc_get_state(ue_mod_id)) { case RRC_STATE_INACTIVE: { rrc_set_state (ue_mod_id, RRC_STATE_IDLE); /* Fall through to next case */ } case RRC_STATE_IDLE: { /* Ask to layer 1 to find a cell matching the criterion */ MessageDef *message_p; message_p = itti_alloc_new_message(TASK_RRC_UE, PHY_FIND_CELL_REQ); PHY_FIND_CELL_REQ (message_p).earfcn_start = 1; PHY_FIND_CELL_REQ (message_p).earfcn_end = 1; itti_send_msg_to_task(TASK_PHY_UE, UE_MODULE_ID_TO_INSTANCE(ue_mod_id), message_p); rrc_set_sub_state (ue_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", ue_mod_id, ITTI_MSG_NAME (msg_p), rrc_get_state(ue_mod_id)); break; default: LOG_E(RRC, "[UE %d] Invalid RRC state %d\n", ue_mod_id, rrc_get_state(ue_mod_id)); break; } break; case NAS_CONN_ESTABLI_REQ: LOG_D(RRC, "[UE %d] Received %s: cause %d, type %d, s_tmsi (mme code %"PRIu8", m-tmsi %"PRIu32"), plmnID (%d%d%d.%d%d%d)\n", ue_mod_id, ITTI_MSG_NAME (msg_p), NAS_CONN_ESTABLI_REQ (msg_p).cause, NAS_CONN_ESTABLI_REQ (msg_p).type, NAS_CONN_ESTABLI_REQ (msg_p).s_tmsi.MMEcode, NAS_CONN_ESTABLI_REQ (msg_p).s_tmsi.m_tmsi, NAS_CONN_ESTABLI_REQ (msg_p).plmnID.MCCdigit1, NAS_CONN_ESTABLI_REQ (msg_p).plmnID.MCCdigit2, NAS_CONN_ESTABLI_REQ (msg_p).plmnID.MCCdigit3, NAS_CONN_ESTABLI_REQ (msg_p).plmnID.MNCdigit1, NAS_CONN_ESTABLI_REQ (msg_p).plmnID.MNCdigit2, NAS_CONN_ESTABLI_REQ (msg_p).plmnID.MNCdigit3); //PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_NO, NOT_A_RNTI, 0, 0); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, ENB_FLAG_NO, NOT_A_RNTI, 0, 0, 0); UE_rrc_inst[ue_mod_id].initialNasMsg = NAS_CONN_ESTABLI_REQ (msg_p).initialNasMsg; switch (rrc_get_state(ue_mod_id)) { case RRC_STATE_IDLE: { if (rrc_get_sub_state(ue_mod_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE) { rrc_ue_generate_RRCConnectionRequest(&ctxt, 0); LOG_D(RRC, "not sending connection request\n"); rrc_set_sub_state (ue_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", ue_mod_id, ITTI_MSG_NAME (msg_p), rrc_get_state(ue_mod_id)); break; default: LOG_E(RRC, "[UE %d] Invalid RRC state %d\n", ue_mod_id, rrc_get_state(ue_mod_id)); break; } break; case NAS_UPLINK_DATA_REQ: { uint32_t length; uint8_t *buffer; LOG_D(RRC, "[UE %d] Received %s: UEid %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), NAS_UPLINK_DATA_REQ (msg_p).UEid); /* Create message for PDCP (ULInformationTransfer_t) */ length = do_ULInformationTransfer(&buffer, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.length, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.data); /* Transfer data to PDCP */ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, ENB_FLAG_NO, UE_rrc_inst[ue_mod_id].Info[0].rnti, 0, 0,0); // check if SRB2 is created, if yes request data_req on DCCH1 (SRB2) if(UE_rrc_inst[ue_mod_id].SRB2_config[0] == NULL) { rrc_data_req_ue (&ctxt, DCCH, rrc_mui++, SDU_CONFIRM_NO, length, buffer, PDCP_TRANSMISSION_MODE_CONTROL); } else { rrc_data_req_ue (&ctxt, DCCH1, rrc_mui++, SDU_CONFIRM_NO, length, buffer, PDCP_TRANSMISSION_MODE_CONTROL); } break; } # if ENABLE_RAL case RRC_RAL_SCAN_REQ: LOG_D(RRC, "[UE %d] Received %s: state %d\n", ue_mod_id,ITTI_MSG_NAME (msg_p) ); switch (rrc_get_state(ue_mod_id)) { case RRC_STATE_INACTIVE: { rrc_set_state (ue_mod_id, RRC_STATE_IDLE); /* Fall through to next case */ } case RRC_STATE_IDLE: { if (rrc_get_sub_state(ue_mod_id) != RRC_SUB_STATE_IDLE_SEARCHING) { /* Ask to layer 1 to find a cell matching the criterion */ MessageDef *message_p; message_p = itti_alloc_new_message(TASK_RRC_UE, PHY_FIND_CELL_REQ); rrc_set_sub_state (ue_mod_id, RRC_SUB_STATE_IDLE_SEARCHING); PHY_FIND_CELL_REQ (message_p).transaction_id = RRC_RAL_SCAN_REQ (msg_p).transaction_id; PHY_FIND_CELL_REQ (message_p).earfcn_start = 1; PHY_FIND_CELL_REQ (message_p).earfcn_end = 1; //44 itti_send_msg_to_task(TASK_PHY_UE, instance, message_p); } break; } case RRC_STATE_CONNECTED: /* should not happen */ LOG_E(RRC, "[UE %d] request %s in RRC state %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), rrc_get_state(ue_mod_id)); break; default: LOG_E(RRC, "[UE %d] Invalid RRC state %d\n", ue_mod_id, rrc_get_state(ue_mod_id)); break; } break; case PHY_FIND_CELL_IND: LOG_D(RRC, "[UE %d] Received %s: state %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), rrc_get_state(ue_mod_id)); switch (rrc_get_state(ue_mod_id)) { case RRC_STATE_IDLE: switch (rrc_get_sub_state(ue_mod_id)) { case RRC_SUB_STATE_IDLE_SEARCHING: { MessageDef *message_p; int i; message_p = itti_alloc_new_message(TASK_RRC_UE, RRC_RAL_SCAN_CONF); RRC_RAL_SCAN_CONF (message_p).transaction_id = PHY_FIND_CELL_IND(msg_p).transaction_id; RRC_RAL_SCAN_CONF (message_p).num_scan_resp = PHY_FIND_CELL_IND(msg_p).cell_nb; for (i = 0 ; i < PHY_FIND_CELL_IND(msg_p).cell_nb; i++) { // TO DO memset(&RRC_RAL_SCAN_CONF (message_p).link_scan_resp[i].link_addr, 0, sizeof(ral_link_addr_t)); // TO DO memset(&RRC_RAL_SCAN_CONF (message_p).link_scan_resp[i].network_id, 0, sizeof(ral_network_id_t)); RRC_RAL_SCAN_CONF (message_p).link_scan_resp[i].sig_strength.choice = RAL_SIG_STRENGTH_CHOICE_DBM; RRC_RAL_SCAN_CONF (message_p).link_scan_resp[i].sig_strength._union.dbm = PHY_FIND_CELL_IND(msg_p).cells[i].rsrp; } rrc_set_sub_state (ue_mod_id, RRC_SUB_STATE_IDLE); itti_send_msg_to_task(TASK_RAL_UE, instance, message_p); break; } default: LOG_E(RRC, "[UE %d] Invalid RRC state %d substate %d\n", ue_mod_id, rrc_get_state(ue_mod_id), rrc_get_sub_state(ue_mod_id)); } break; case RRC_STATE_INACTIVE: case RRC_STATE_CONNECTED: /* should not happen */ LOG_E(RRC, "[UE %d] indication %s in RRC state %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), rrc_get_state(ue_mod_id)); break; default: LOG_E(RRC, "[UE %d] Invalid RRC state %d\n", ue_mod_id, rrc_get_state(ue_mod_id)); break; } break; // PHY_FIND_CELL_IND case PHY_MEAS_REPORT_IND: { LOG_D(RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); MessageDef *message_p; message_p = itti_alloc_new_message(TASK_RRC_UE, RRC_RAL_MEASUREMENT_REPORT_IND); memcpy(&RRC_RAL_MEASUREMENT_REPORT_IND (message_p).threshold, &PHY_MEAS_REPORT_IND(msg_p).threshold, sizeof(RRC_RAL_MEASUREMENT_REPORT_IND (message_p).threshold)); memcpy(&RRC_RAL_MEASUREMENT_REPORT_IND (message_p).link_param, &PHY_MEAS_REPORT_IND(msg_p).link_param, sizeof(RRC_RAL_MEASUREMENT_REPORT_IND (message_p).link_param)); LOG_D(RRC, "[UE %d] PHY_MEAS_REPORT_IN: sending msg %s to %s \n", ue_mod_id, "RRC_RAL_MEASUREMENT_REPORT_IND", "TASK_RAL_UE"); itti_send_msg_to_task(TASK_RAL_UE, instance, message_p); break; } case RRC_RAL_CONFIGURE_THRESHOLD_REQ: LOG_D(RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); rrc_ue_ral_handle_configure_threshold_request(ue_mod_id, msg_p); break; case RRC_RAL_CONNECTION_ESTABLISHMENT_REQ: LOG_D(RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); switch (rrc_get_state(ue_mod_id)) { case RRC_STATE_IDLE: { if (rrc_get_sub_state(ue_mod_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE) { PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, ENB_FLAG_NO, UE_rrc_inst[ue_mod_id].Info[0].rnti, 0, 0, 0); rrc_ue_generate_RRCConnectionRequest(&ctxt, 0); LOG_D(RRC, "not sending connection request\n"); rrc_set_sub_state (ue_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", ue_mod_id, ITTI_MSG_NAME (msg_p), rrc_get_state(ue_mod_id)); break; default: LOG_E(RRC, "[UE %d] Invalid RRC state %d\n", ue_mod_id, rrc_get_state(ue_mod_id)); break; } break; case RRC_RAL_CONNECTION_RELEASE_REQ: LOG_D(RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); break; #endif default: LOG_E(RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); break; } result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); msg_p = NULL; } } /*------------------------------------------------------------------------------*/ void openair_rrc_top_init_ue( int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, uint8_t HO_active ) //----------------------------------------------------------------------------- { module_id_t module_id; OAI_UECapability_t *UECap = NULL; int CC_id; /* for no gcc warnings */ (void)CC_id; LOG_D(RRC, "[OPENAIR][INIT] Init function start: NB_UE_INST=%d, NB_eNB_INST=%d\n", NB_UE_INST, NB_eNB_INST); if (NB_UE_INST > 0) { UE_rrc_inst = (UE_RRC_INST *) malloc16(NB_UE_INST*sizeof(UE_RRC_INST)); memset (UE_rrc_inst, 0, NB_UE_INST * sizeof(UE_RRC_INST)); LOG_D(RRC, "ALLOCATE %d Bytes for UE_RRC_INST @ %p\n", (unsigned int)(NB_UE_INST*sizeof(UE_RRC_INST)), UE_rrc_inst); // fill UE capability UECap = fill_ue_capability (uecap_xer); for (module_id = 0; module_id < NB_UE_INST; module_id++) { UE_rrc_inst[module_id].UECap = UECap; UE_rrc_inst[module_id].UECapability = UECap->sdu; UE_rrc_inst[module_id].UECapability_size = UECap->sdu_size; } #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) LOG_I(RRC,"[UE] eMBMS active state is %d \n", eMBMS_active); for (module_id=0; module_id<NB_UE_INST; module_id++) { UE_rrc_inst[module_id].MBMS_flag = (uint8_t)eMBMS_active; } #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /* TODO: this is disabled for the moment because the standard UE * crashes when calling this function. */ //init_SL_preconfig(&UE_rrc_inst[module_id],0); #endif } else { UE_rrc_inst = NULL; } } //----------------------------------------------------------------------------- void rrc_top_cleanup_ue( void ) //----------------------------------------------------------------------------- { if (NB_UE_INST > 0) free (UE_rrc_inst); } //----------------------------------------------------------------------------- uint8_t rrc_ue_generate_SidelinkUEInformation( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index,LTE_SL_DestinationInfoList_r12_t *destinationInfoList, long *discTxResourceReq, SL_TRIGGER_t mode) { uint8_t size=0; uint8_t buffer[100]; //Generate SidelinkUEInformation if (((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&8192) > 0) && (destinationInfoList != NULL)) {//if SIB18 is available size = do_SidelinkUEInformation(ctxt_pP->module_id, buffer, destinationInfoList, NULL, mode); LOG_I(RRC,"[UE %d][RRC_UE] Frame %d : Logical Channel UL-DCCH, Generating SidelinkUEInformation (bytes%d, eNB %d)\n", ctxt_pP->module_id,ctxt_pP->frame, size, eNB_index); //return size; } if (((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&16384) > 0) && (discTxResourceReq != NULL)) {//if SIB19 is available size = do_SidelinkUEInformation(ctxt_pP->module_id, buffer, NULL, discTxResourceReq, mode); LOG_I(RRC,"[UE %d][RRC_UE] Frame %d : Logical Channel UL-DCCH, Generating SidelinkUEInformation (bytes%d, eNB %d)\n", ctxt_pP->module_id,ctxt_pP->frame, size, eNB_index); //return size; } rrc_data_req_ue ( ctxt_pP, DCCH, rrc_mui++, SDU_CONFIRM_NO, size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); return size; } // 3GPP 36.331 (Section 5.10.7.3) uint8_t fill_SLSS(const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, LTE_SLSSID_r12_t *slss_id, uint8_t *subframe, uint8_t mode) { long syncOffsetIndicator = 0; switch(mode) { case 1: //if triggered by SL discovery announcement and in-coverage //discSyncConfig_r12 contains only one element *slss_id = UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index]->discConfig_r12->discSyncConfig_r12->list.array[0]->slssid_r12; syncOffsetIndicator = UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index]->discConfig_r12->discSyncConfig_r12->list.array[0]->syncOffsetIndicator_r12; //select subframe for SLSS break; case 2: //if triggered by SL communication and in-coverage if (UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index]->commConfig_r12->commSyncConfig_r12->list.array[0]->txParameters_r12) { *slss_id = UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index]->commConfig_r12->commSyncConfig_r12->list.array[0]->slssid_r12; syncOffsetIndicator = UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index]->commConfig_r12->commSyncConfig_r12->list.array[0]->syncOffsetIndicator_r12; //if RRC_CONNECTED (Todo: and if networkControlledSyncTx (RRCConnectionReconfiguration) is configured and set to On) if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State == RRC_CONNECTED) { //select subframe(s) indicated by syncOffsetIndicator *subframe = syncOffsetIndicator; } else { //select subframe(s) indicated by syncOffsetIndicator within SC period } break; case 3: //if triggered by V2X communication and in coverage break; case 4: //if triggered by V2X communication and out-of-coverage break; case 5: //if triggered by V2X communication and UE has GNSS as the synchronization reference default: //if UE has a selected SyncRefUE //TODO //else (no SyncRefUE Selected) //Todo if trigger by V2X //else randomly select an SLSSID from the set defined for out-of-coverage *slss_id = 170;//hardcoded //select the subframe according to syncOffsetIndicator1/2 from the preconfigured parameters break; } } return 0; } //----------------------------------------------------------------------------- void rrc_ue_process_sidelink_radioResourceConfig( module_id_t Mod_idP, uint8_t eNB_index, LTE_SystemInformationBlockType18_r12_t *sib18, LTE_SystemInformationBlockType19_r12_t *sib19, LTE_SL_CommConfig_r12_t *sl_CommConfig, LTE_SL_DiscConfig_r12_t *sl_DiscConfig ) //----------------------------------------------------------------------------- { //process SIB18, configure MAC/PHY for receiving SL communication (RRC_IDLE and RRC_CONNECTED), for transmitting SL communication (RRC_IDLE) if (sib18 != NULL) { if (sib18->commConfig_r12 != NULL) { //do not consider commTXPoolExceptional for the moment //configure PHY/MAC to receive SL communication by using the RPs indicated by commRxPool //sib18->commConfig_r12->commRxPool_r12 //TODO if (sib18->commConfig_r12->commTxPoolNormalCommon_r12 !=NULL) { //commTxPoolNormalCommon - to transmit SL communication in RRC_IDLE //maybe we don't consider this case for the moment since UE will immediately establish a RRC connection after receiving SIB messages //configure PHY/MAC to transmit SL communication using the RPs indicated by the first entry in commTxPoolNormalCommon //SL_CommResourcePool_r12_t sl_CommResourcePool = sib18->commConfig_r12->commTxPoolNormalCommon_r12->list.array[0]; } } } //process SIB19, configure MAC/PHY for receiving SL discovery (RRC_IDLE and RRC_CONNECTED), for transmitting SL discovery (RRC_IDLE) if (sib19 != NULL) { //to receive non-PS related discovery announcements (discRxPool) //sib19->discConfig_r12->discRxPool_r12; //to receive PS related discovery announcements (discRxPoolPS) //sib19->ext1->discConfigPS_13->discRxPoolPS_r13; //to transmit non-PS related discovery in RRC_IDLE //sib19->discConfig_r12->discTxPoolCommon_r12; //to transmit PS related discovery in RRC_IDLE //sib19->ext1->discConfigPS_13->discTxPoolPS_Common_r13; } //process sl_CommConfig, configure MAC/PHY for transmitting SL communication (RRC_CONNECTED) if (sl_CommConfig != NULL) { if (sl_CommConfig->commTxResources_r12 != NULL) { switch (sl_CommConfig->commTxResources_r12->present) { case LTE_SL_CommConfig_r12__commTxResources_r12_PR_setup: if (sl_CommConfig->commTxResources_r12->choice.setup.present == LTE_SL_CommConfig_r12__commTxResources_r12__setup_PR_scheduled_r12 ) { LOG_I(RRC,"[UE %d][RRC_UE] scheduled resource for SL, sl_RNTI size %lu \n", Mod_idP, sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.size ); LOG_I(RRC,"[UE %d][RRC_UE] scheduled resource for SL, sl_RNTI buf 0x%p \n", Mod_idP, sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.buf ); LOG_I(RRC,"[UE %d][RRC_UE] scheduled resource for SL, Mac_MainConfig_r12.retx_BSR_TimerSL %ld \n", Mod_idP, sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.mac_MainConfig_r12.retx_BSR_TimerSL ); LOG_I(RRC,"[UE %d][RRC_UE] scheduled resource for SL, sc_CommTxConfig %ld \n", Mod_idP, sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.mac_MainConfig_r12.retx_BSR_TimerSL ); //configure scheduled resource for SL //TODO } else if (sl_CommConfig->commTxResources_r12->choice.setup.present == LTE_SL_CommConfig_r12__commTxResources_r12__setup_PR_ue_Selected_r12) { //configure dedicated resources (commTxPoolNormalDedicated) for SL from which UE can autonomously select //sl_CommConfig->commTxResources_r12->choice.setup.choice.ue_Selected_r12.commTxPoolNormalDedicated_r12; //for the moment, only pass the first entry (e.g., do not consider priorityList in commTxPoolNormalDedicated (3GPP 36.331 Section 5.10.4 1>2>3>4)) //sl_CommConfig->commTxResources_r12->choice.setup.choice.ue_Selected_r12.commTxPoolNormalDedicated_r12.poolToAddModList_r12->list.array[0]; } else { //SL_CommConfig_r12__commTxResources_r12__setup_PR_NOTHING /* No components present */ } break; case LTE_SL_CommConfig_r12__commTxResources_r12_PR_release: //release dedicated resources for SL communication break; case LTE_SL_CommConfig_r12__commTxResources_r12_PR_NOTHING: /* No components present */ break; default: break; } } } //process sl_DiscConfig, configure MAC/PHY for transmitting SL discovery announcements (RRC_CONNECTED) if (sl_DiscConfig != NULL) { //dedicated resources for transmitting non-PS related discovery if (sl_DiscConfig->discTxResources_r12 != NULL) { switch (sl_DiscConfig->discTxResources_r12->present) { case LTE_SL_DiscConfig_r12__discTxResources_r12_PR_setup: if (sl_DiscConfig->discTxResources_r12->choice.setup.present == LTE_SL_DiscConfig_r12__discTxResources_r12__setup_PR_scheduled_r12) { //sl_DiscConfig->discTxResources_r12->choice.setup.choice.scheduled_r12.discHoppingConfig_r12; //sl_DiscConfig->discTxResources_r12->choice.setup.choice.scheduled_r12.discTF_IndexList_r12; //sl_DiscConfig->discTxResources_r12->choice.setup.choice.scheduled_r12.discTxConfig_r12; } else if (sl_DiscConfig->discTxResources_r12->choice.setup.present == LTE_SL_DiscConfig_r12__discTxResources_r12__setup_PR_ue_Selected_r12) { //sl_DiscConfig->discTxResources_r12->choice.setup.choice.ue_Selected_r12.discTxPoolDedicated_r12; } else { //SL_DiscConfig_r12__discTxResources_r12__setup_PR_NOTHING, /* No components present */ } break; case LTE_SL_DiscConfig_r12__discTxResources_r12_PR_release: //release dedicated resources for SL discovery break; case LTE_SL_DiscConfig_r12__discTxResources_r12_PR_NOTHING: /* No components present */ break; default: break; } } //dedicated resources for transmitting PS related discovery if (sl_DiscConfig->ext2->discTxResourcesPS_r13 != NULL) { switch (sl_DiscConfig->ext2->discTxResourcesPS_r13->present) { case LTE_SL_DiscConfig_r12__ext2__discTxResourcesPS_r13_PR_setup: if (sl_DiscConfig->ext2->discTxResourcesPS_r13->choice.setup.present == LTE_SL_DiscConfig_r12__ext2__discTxResourcesPS_r13__setup_PR_scheduled_r13) { //sl_DiscConfig->ext2->discTxResourcesPS_r13->choice.setup.choice.scheduled_r13.discHoppingConfig_r13; //sl_DiscConfig->ext2->discTxResourcesPS_r13->choice.setup.choice.scheduled_r13.discTxConfig_r13 } else if (sl_DiscConfig->ext2->discTxResourcesPS_r13->choice.setup.present == LTE_SL_DiscConfig_r12__ext2__discTxResourcesPS_r13__setup_PR_ue_Selected_r13) { //sl_DiscConfig->ext2->discTxResourcesPS_r13->choice.setup.choice.ue_Selected_r13.discTxPoolPS_Dedicated_r13; } else { //SL_DiscConfig_r12__ext2__discTxResourcesPS_r13__setup_PR_NOTHING, /* No components present */ } break; case LTE_SL_DiscConfig_r12__ext2__discTxResourcesPS_r13_PR_release: break; case LTE_SL_DiscConfig_r12__ext2__discTxResourcesPS_r13_PR_NOTHING: /* No components present */ break; default: break; } } } } #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) //----------------------------------------------------------- void rrc_control_socket_init() { struct sockaddr_in rrc_ctrl_socket_addr; pthread_attr_t attr; struct sched_param sched_param; int optval; // flag value for setsockopt //int n; // message byte size // create the control socket ctrl_sock_fd = socket(AF_INET, SOCK_DGRAM, 0); if (ctrl_sock_fd == -1) { LOG_E(RRC,"[rrc_control_socket_init] :Error opening socket %d (%d:%s)\n",ctrl_sock_fd,errno, strerror(errno)); exit(EXIT_FAILURE); } // if (ctrl_sock_fd < 0) // error("ERROR: Failed on opening socket"); optval = 1; setsockopt(ctrl_sock_fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval, sizeof(int)); //build the server's address bzero((char *) &rrc_ctrl_socket_addr, sizeof(rrc_ctrl_socket_addr)); rrc_ctrl_socket_addr.sin_family = AF_INET; rrc_ctrl_socket_addr.sin_addr.s_addr = htonl(INADDR_ANY); rrc_ctrl_socket_addr.sin_port = htons(CONTROL_SOCKET_PORT_NO); // associate the parent socket with a port if (bind(ctrl_sock_fd, (struct sockaddr *) &rrc_ctrl_socket_addr, sizeof(rrc_ctrl_socket_addr)) < 0) { LOG_E(RRC,"[rrc_control_socket_init] ERROR: Failed on binding the socket\n"); exit(1); } //create thread to listen to incoming packets if (pthread_attr_init(&attr) != 0) { LOG_E(RRC, "[rrc_control_socket_init]Failed to initialize pthread attribute for ProSe -> RRC communication (%d:%s)\n", errno, strerror(errno)); exit(EXIT_FAILURE); } sched_param.sched_priority = 10; pthread_attr_setschedpolicy(&attr, SCHED_RR); pthread_attr_setschedparam(&attr, &sched_param); pthread_t rrc_control_socket_thread; if (pthread_create(&rrc_control_socket_thread, &attr, rrc_control_socket_thread_fct, NULL) != 0) { LOG_E(RRC, "[rrc_control_socket_init]Failed to create new thread for RRC/ProSeApp communication (%d:%s)\n", errno, strerror(errno)); exit(EXIT_FAILURE); } pthread_setname_np( rrc_control_socket_thread, "RRC Control Socket" ); } //-------------------------------------------------------- void *rrc_control_socket_thread_fct(void *arg) { int prose_addr_len; char send_buf[BUFSIZE]; char receive_buf[BUFSIZE]; //int optval; int n; struct sidelink_ctrl_element *sl_ctrl_msg_recv = NULL; struct sidelink_ctrl_element *sl_ctrl_msg_send = NULL; uint32_t sourceL2Id, groupL2Id, destinationL2Id; module_id_t module_id = 0; //hardcoded for testing only uint8_t type; UE_RRC_INST *UE = NULL; protocol_ctxt_t ctxt; struct LTE_RLC_Config *DRB_rlc_config = NULL; struct LTE_PDCP_Config *DRB_pdcp_config = NULL; struct LTE_PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; struct LTE_LogicalChannelConfig *DRB_lchan_config = NULL; struct LTE_LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters = NULL; long *logicalchannelgroup_drb = NULL; int j = 0; int i = 0; //from the main program, listen for the incoming messages from control socket (ProSe App) prose_addr_len = sizeof(prose_app_addr); //int enable_notification = 1; while (1) { LOG_I(RRC,"Listening to incoming connection from ProSe App \n"); // receive a message from ProSe App memset(receive_buf, 0, BUFSIZE); n = recvfrom(ctrl_sock_fd, receive_buf, BUFSIZE, 0, (struct sockaddr *) &prose_app_addr, (socklen_t *)&prose_addr_len); if (n < 0) { LOG_E(RRC, "ERROR: Failed to receive from ProSe App\n"); exit(EXIT_FAILURE); } //TODO: should store the address of ProSeApp [UE_rrc_inst] to be able to send UE state notification to the App //sl_ctrl_msg_recv = (struct sidelink_ctrl_element *) receive_buf; sl_ctrl_msg_recv = calloc(1, sizeof(struct sidelink_ctrl_element)); memcpy((void *)sl_ctrl_msg_recv, (void *)receive_buf, sizeof(struct sidelink_ctrl_element)); //process the message switch (sl_ctrl_msg_recv->type) { case SESSION_INIT_REQ: if (LOG_DEBUGFLAG(DEBUG_CTRLSOCKET)) { LOG_UI(RRC,"Received SessionInitializationRequest on socket from ProSe App (msg type: %d)\n", sl_ctrl_msg_recv->type); } //TODO: get SL_UE_STATE from lower layer LOG_I(RRC,"Send UEStateInformation to ProSe App \n"); memset(send_buf, 0, BUFSIZE); sl_ctrl_msg_send = calloc(1, sizeof(struct sidelink_ctrl_element)); sl_ctrl_msg_send->type = UE_STATUS_INFO; sl_ctrl_msg_send->sidelinkPrimitive.ue_state = UE_STATE_OFF_NETWORK; //off-network memcpy((void *)send_buf, (void *)sl_ctrl_msg_send, sizeof(struct sidelink_ctrl_element)); free(sl_ctrl_msg_send); prose_addr_len = sizeof(prose_app_addr); n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, (struct sockaddr *)&prose_app_addr, prose_addr_len); if (n < 0) { LOG_E(RRC, "ERROR: Failed to send to ProSe App\n"); exit(EXIT_FAILURE); } if (LOG_DEBUGFLAG(DEBUG_CTRLSOCKET)) { struct sidelink_ctrl_element *ptr_ctrl_msg = NULL; ptr_ctrl_msg = (struct sidelink_ctrl_element *) send_buf; LOG_UI(RRC,"[UEStateInformation] msg type: %d\n",ptr_ctrl_msg->type); LOG_UI(RRC,"[UEStateInformation] UE state: %d\n",ptr_ctrl_msg->sidelinkPrimitive.ue_state); } /* if (enable_notification > 0) { //create thread to send status notification (for testing purpose, status notification will be sent e.g., every 20 seconds) pthread_t notification_thread; if( pthread_create( ¬ification_thread , NULL , send_UE_status_notification , (void*) &sockfd) < 0) error("ERROR: could not create thread"); } enable_notification = 0; */ break; case GROUP_COMMUNICATION_ESTABLISH_REQ: sourceL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.sourceL2Id; groupL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupL2Id; if (LOG_DEBUGFLAG(DEBUG_CTRLSOCKET)) { LOG_UI(RRC,"[GroupCommunicationEstablishReq] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); LOG_UI(RRC,"[GroupCommunicationEstablishReq] source Id: 0x%08x\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.sourceL2Id); LOG_UI(RRC,"[GroupCommunicationEstablishReq] group Id: 0x%08x\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupL2Id); LOG_UI(RRC,"[GroupCommunicationEstablishReq] group IP Address: " IPV4_ADDR "\n",IPV4_ADDR_FORMAT(sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupIpAddress)); } //store sourceL2Id/groupL2Id UE_rrc_inst[module_id].sourceL2Id = sourceL2Id; UE_rrc_inst[module_id].groupL2Id = groupL2Id; j = 0; i = 0; for (i=0; i< MAX_NUM_DEST; i++) { if ((UE_rrc_inst[module_id].destinationList[i] == 0) && (j == 0)) j = i+1; if (UE_rrc_inst[module_id].destinationList[i] == groupL2Id) break; //group already exists! } if ((i == MAX_NUM_DEST) && (j > 0)) UE_mac_inst[module_id].destinationList[j-1] = groupL2Id; // configure lower layers PDCP/MAC/PHY for this communication //Establish a new RBID/LCID for this communication // Establish a SLRB (using DRB 3 for now) UE = &UE_rrc_inst[module_id]; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0); UE->DRB_config[0][0] = CALLOC(1,sizeof(struct LTE_DRB_ToAddMod)); UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); UE->DRB_config[0][0]->drb_Identity = 3; UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); // allowed value 5..15, value : x+4 *(UE->DRB_config[0][0]->eps_BearerIdentity) = 3; UE->DRB_config[0][0]->logicalChannelIdentity = CALLOC(1, sizeof(long)); *(UE->DRB_config[0][0]->logicalChannelIdentity) = UE->DRB_config[0][0]->drb_Identity; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2 DRB_rlc_config = CALLOC(1,sizeof(struct LTE_RLC_Config)); DRB_pdcp_config = CALLOC(1,sizeof(struct LTE_PDCP_Config)); PDCP_rlc_UM = CALLOC(1,sizeof(struct LTE_PDCP_Config__rlc_UM)); DRB_lchan_config = CALLOC(1,sizeof(struct LTE_LogicalChannelConfig)); DRB_ul_SpecificParameters = CALLOC(1, sizeof(struct LTE_LogicalChannelConfig__ul_SpecificParameters)); logicalchannelgroup_drb = CALLOC(1, sizeof(long)); DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional; DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; UE->DRB_config[0][0]->rlc_Config = DRB_rlc_config; DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); UE->DRB_config[0][0]->pdcp_Config = DRB_pdcp_config; DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity; DRB_pdcp_config->rlc_AM = NULL; DRB_pdcp_config->rlc_UM = NULL; /* avoid gcc warnings */ (void)PDCP_rlc_UM; DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed; UE->DRB_config[0][0]->logicalChannelConfig = DRB_lchan_config; DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters)); DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; DRB_ul_SpecificParameters->priority = 12; // lower priority than srb1, srb2 and other dedicated bearer DRB_ul_SpecificParameters->prioritisedBitRate =LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; DRB_ul_SpecificParameters->bucketSizeDuration = LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM) *logicalchannelgroup_drb = 1; DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; UE->DRB_configList = CALLOC(1,sizeof(LTE_DRB_ToAddModList_t)); ASN_SEQUENCE_ADD(&UE->DRB_configList->list,UE->DRB_config[0][0]); rrc_pdcp_config_asn1_req(&ctxt, (LTE_SRB_ToAddModList_t *) NULL, UE->DRB_configList, (LTE_DRB_ToReleaseList_t *) NULL, 0xff, NULL, NULL, NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) , (LTE_PMCH_InfoList_r9_t *) NULL #endif ,NULL); rrc_rlc_config_asn1_req(&ctxt, (LTE_SRB_ToAddModList_t *)NULL, UE->DRB_configList, (LTE_DRB_ToReleaseList_t *)NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,(LTE_PMCH_InfoList_r9_t *)NULL , 0, 0 #endif ); rrc_rlc_config_asn1_req(&ctxt, (LTE_SRB_ToAddModList_t *)NULL, UE->DRB_configList, (LTE_DRB_ToReleaseList_t *)NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,(LTE_PMCH_InfoList_r9_t *)NULL , sourceL2Id, groupL2Id #endif ); //configure MAC with sourceL2Id/groupL2ID rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0 (LTE_RadioResourceConfigCommonSIB_t *)NULL, (struct LTE_PhysicalConfigDedicated *)NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (LTE_SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif (LTE_MeasObjectToAddMod_t **)NULL, (LTE_MAC_MainConfig_t *)NULL, 3, //LCID (struct LTE_LogicalChannelConfig *)NULL, (LTE_MeasGapConfig_t *)NULL, (LTE_TDD_Config_t *)NULL, (LTE_MobilityControlInfo_t *)NULL, NULL, NULL, NULL, NULL, NULL, NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,0, (LTE_MBSFN_AreaInfoList_r9_t *)NULL, (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA , 0, 0 #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,CONFIG_ACTION_ADD, &sourceL2Id, &groupL2Id #endif ); LOG_I(RRC,"Send GroupCommunicationEstablishResp to ProSe App\n"); memset(send_buf, 0, BUFSIZE); sl_ctrl_msg_send = calloc(1, sizeof(struct sidelink_ctrl_element)); sl_ctrl_msg_send->type = GROUP_COMMUNICATION_ESTABLISH_RSP; sl_ctrl_msg_send->sidelinkPrimitive.slrb_id = 3; //slrb_id memcpy((void *)send_buf, (void *)sl_ctrl_msg_send, sizeof(struct sidelink_ctrl_element)); free(sl_ctrl_msg_send); prose_addr_len = sizeof(prose_app_addr); n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, (struct sockaddr *)&prose_app_addr, prose_addr_len); if (n < 0) { LOG_E(RRC, "ERROR: Failed to send to ProSe App\n"); exit(EXIT_FAILURE); } if (LOG_DEBUGFLAG(DEBUG_CTRLSOCKET)) { struct sidelink_ctrl_element *ptr_ctrl_msg = NULL; ptr_ctrl_msg = (struct sidelink_ctrl_element *) send_buf; LOG_UI(RRC,"[GroupCommunicationEstablishResponse] msg type: %d\n",ptr_ctrl_msg->type); LOG_UI(RRC,"[GroupCommunicationEstablishResponse] slrb_id: %d\n",ptr_ctrl_msg->sidelinkPrimitive.slrb_id); } break; case GROUP_COMMUNICATION_RELEASE_REQ: printf("-----------------------------------\n"); if (LOG_DEBUGFLAG(DEBUG_CTRLSOCKET)) { LOG_UI(RRC,"[GroupCommunicationReleaseRequest] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); LOG_UI(RRC,"[GroupCommunicationReleaseRequest] Slrb Id: %i\n",sl_ctrl_msg_recv->sidelinkPrimitive.slrb_id); } //reset groupL2ID from MAC LAYER UE_rrc_inst[module_id].groupL2Id = 0x00000000; sourceL2Id = UE_rrc_inst[module_id].sourceL2Id; rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0 (LTE_RadioResourceConfigCommonSIB_t *)NULL, (struct LTE_PhysicalConfigDedicated *)NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (LTE_SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif (LTE_MeasObjectToAddMod_t **)NULL, (LTE_MAC_MainConfig_t *)NULL, 0, (struct LTE_LogicalChannelConfig *)NULL, (LTE_MeasGapConfig_t *)NULL, (LTE_TDD_Config_t *)NULL, (LTE_MobilityControlInfo_t *)NULL, NULL, NULL, NULL, NULL, NULL, NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,0, (LTE_MBSFN_AreaInfoList_r9_t *)NULL, (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA , 0, 0 #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,CONFIG_ACTION_REMOVE, &sourceL2Id, &destinationL2Id #endif ); LOG_I(RRC,"Send GroupCommunicationReleaseResponse to ProSe App \n"); memset(send_buf, 0, BUFSIZE); sl_ctrl_msg_send = calloc(1, sizeof(struct sidelink_ctrl_element)); sl_ctrl_msg_send->type = GROUP_COMMUNICATION_RELEASE_RSP; //if the requested id exists -> release this ID if (sl_ctrl_msg_recv->sidelinkPrimitive.slrb_id == slrb_id) { sl_ctrl_msg_send->sidelinkPrimitive.group_comm_release_rsp = GROUP_COMMUNICATION_RELEASE_OK; slrb_id = 0; //Reset slrb_id } else { sl_ctrl_msg_send->sidelinkPrimitive.group_comm_release_rsp = GROUP_COMMUNICATION_RELEASE_FAILURE; } memcpy((void *)send_buf, (void *)sl_ctrl_msg_send, sizeof(struct sidelink_ctrl_element)); free(sl_ctrl_msg_send); prose_addr_len = sizeof(prose_app_addr); n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, (struct sockaddr *)&prose_app_addr, prose_addr_len); if (n < 0) { LOG_E(RRC, "ERROR: Failed to send to ProSe App\n"); exit(EXIT_FAILURE); } break; case DIRECT_COMMUNICATION_ESTABLISH_REQ: sourceL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.direct_comm_establish_req.sourceL2Id; destinationL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.direct_comm_establish_req.destinationL2Id; if (LOG_DEBUGFLAG(DEBUG_CTRLSOCKET)) { LOG_UI(RRC,"[DirectCommunicationEstablishReq] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); LOG_UI(RRC,"[DirectCommunicationEstablishReq] source Id: 0x%08x\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.sourceL2Id); LOG_UI(RRC,"[DirectCommunicationEstablishReq] destination Id: 0x%08x\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupL2Id); } //store sourceL2Id/destinationL2Id UE_rrc_inst[module_id].sourceL2Id = sourceL2Id; i = 0; j = 0; for (i=0; i< MAX_NUM_DEST; i++) { if ((UE_rrc_inst[module_id].destinationList[i] == 0) && (j == 0)) j = i+1; if (UE_rrc_inst[module_id].destinationList[i] == destinationL2Id) break; //destination already exists! } if ((i == MAX_NUM_DEST) && (j > 0)) UE_mac_inst[module_id].destinationList[j-1] = destinationL2Id; // configure lower layers PDCP/MAC/PHY for this communication //Establish a new RBID/LCID for this communication // Establish a SLRB (using DRB 3 for now) UE = &UE_rrc_inst[module_id]; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0); UE->DRB_config[0][0] = CALLOC(1,sizeof(struct LTE_DRB_ToAddMod)); UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); UE->DRB_config[0][0]->drb_Identity = 3; UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); // allowed value 5..15, value : x+4 *(UE->DRB_config[0][0]->eps_BearerIdentity) = 3; UE->DRB_config[0][0]->logicalChannelIdentity = CALLOC(1, sizeof(long)); *(UE->DRB_config[0][0]->logicalChannelIdentity) = UE->DRB_config[0][0]->drb_Identity; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2 DRB_rlc_config = CALLOC(1,sizeof(struct LTE_RLC_Config)); DRB_pdcp_config = CALLOC(1,sizeof(struct LTE_PDCP_Config)); PDCP_rlc_UM = CALLOC(1,sizeof(struct LTE_PDCP_Config__rlc_UM)); DRB_lchan_config = CALLOC(1,sizeof(struct LTE_LogicalChannelConfig)); DRB_ul_SpecificParameters = CALLOC(1, sizeof(struct LTE_LogicalChannelConfig__ul_SpecificParameters)); logicalchannelgroup_drb = CALLOC(1, sizeof(long)); DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional; DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; UE->DRB_config[0][0]->rlc_Config = DRB_rlc_config; DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); UE->DRB_config[0][0]->pdcp_Config = DRB_pdcp_config; DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity; DRB_pdcp_config->rlc_AM = NULL; DRB_pdcp_config->rlc_UM = NULL; /* avoid gcc warnings */ (void)PDCP_rlc_UM; DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed; UE->DRB_config[0][0]->logicalChannelConfig = DRB_lchan_config; DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters)); DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; DRB_ul_SpecificParameters->priority = 12; // lower priority than srb1, srb2 and other dedicated bearer DRB_ul_SpecificParameters->prioritisedBitRate =LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; DRB_ul_SpecificParameters->bucketSizeDuration = LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM) *logicalchannelgroup_drb = 1; DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; UE->DRB_configList = CALLOC(1,sizeof(LTE_DRB_ToAddModList_t)); ASN_SEQUENCE_ADD(&UE->DRB_configList->list,UE->DRB_config[0][0]); rrc_pdcp_config_asn1_req(&ctxt, (LTE_SRB_ToAddModList_t *) NULL, UE->DRB_configList, (LTE_DRB_ToReleaseList_t *) NULL, 0xff, NULL, NULL, NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) , (LTE_PMCH_InfoList_r9_t *) NULL #endif ,NULL); rrc_rlc_config_asn1_req(&ctxt, (LTE_SRB_ToAddModList_t *)NULL, UE->DRB_configList, (LTE_DRB_ToReleaseList_t *)NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,(LTE_PMCH_InfoList_r9_t *)NULL , 0, 0 #endif ); rrc_rlc_config_asn1_req(&ctxt, (LTE_SRB_ToAddModList_t *)NULL, UE->DRB_configList, (LTE_DRB_ToReleaseList_t *)NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,(LTE_PMCH_InfoList_r9_t *)NULL , sourceL2Id, destinationL2Id #endif ); //configure MAC with sourceL2Id/destinationL2Id rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0 (LTE_RadioResourceConfigCommonSIB_t *)NULL, (struct LTE_PhysicalConfigDedicated *)NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (LTE_SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif (LTE_MeasObjectToAddMod_t **)NULL, (LTE_MAC_MainConfig_t *)NULL, 3, //LCID (struct LTE_LogicalChannelConfig *)NULL, (LTE_MeasGapConfig_t *)NULL, (LTE_TDD_Config_t *)NULL, (LTE_MobilityControlInfo_t *)NULL, NULL, NULL, NULL, NULL, NULL, NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,0, (LTE_MBSFN_AreaInfoList_r9_t *)NULL, (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA , 0, 0 #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,CONFIG_ACTION_ADD, &sourceL2Id, &destinationL2Id #endif ); LOG_I(RRC,"Send DirectCommunicationEstablishResp to ProSe App\n"); memset(send_buf, 0, BUFSIZE); sl_ctrl_msg_send = calloc(1, sizeof(struct sidelink_ctrl_element)); sl_ctrl_msg_send->type = DIRECT_COMMUNICATION_ESTABLISH_RSP; sl_ctrl_msg_send->sidelinkPrimitive.slrb_id = 3; //slrb_id memcpy((void *)send_buf, (void *)sl_ctrl_msg_send, sizeof(struct sidelink_ctrl_element)); free(sl_ctrl_msg_send); prose_addr_len = sizeof(prose_app_addr); n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, (struct sockaddr *)&prose_app_addr, prose_addr_len); if (n < 0) { LOG_E(RRC, "ERROR: Failed to send to ProSe App\n"); exit(EXIT_FAILURE); } if (LOG_DEBUGFLAG(DEBUG_CTRLSOCKET)) { struct sidelink_ctrl_element *ptr_ctrl_msg = NULL; ptr_ctrl_msg = (struct sidelink_ctrl_element *) send_buf; LOG_UI(RRC,"[DirectCommunicationEstablishResponse] msg type: %d\n",ptr_ctrl_msg->type); LOG_UI(RRC,"[DirectCommunicationEstablishResponse] slrb_id: %d\n",ptr_ctrl_msg->sidelinkPrimitive.slrb_id); } break; case PC5S_ESTABLISH_REQ: type = sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.type; sourceL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.sourceL2Id; if (LOG_DEBUGFLAG(DEBUG_CTRLSOCKET)) { LOG_UI(RRC,"[PC5EstablishReq] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); LOG_UI(RRC,"[PC5EstablishReq] type: %d\n",sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.type); //RX/TX LOG_UI(RRC,"[PC5EstablishReq] source Id: 0x%08x \n",sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.sourceL2Id); } if (type > 0) { destinationL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.destinationL2Id; if (LOG_DEBUGFLAG(DEBUG_CTRLSOCKET)) { LOG_UI(RRC,"[PC5EstablishReq] destination Id: 0x%08x \n",sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.destinationL2Id); } } //store sourceL2Id/destinationL2Id if (type > 0) { //TX UE_rrc_inst[module_id].sourceL2Id = sourceL2Id; j = 0; i = 0; for (i=0; i< MAX_NUM_DEST; i++) { if ((UE_rrc_inst[module_id].destinationList[i] == 0) && (j == 0)) j = i+1; if (UE_rrc_inst[module_id].destinationList[i] == destinationL2Id) break; //group already exists! } if ((i == MAX_NUM_DEST) && (j > 0)) UE_mac_inst[module_id].destinationList[j-1] = destinationL2Id; } else {//RX UE_rrc_inst[module_id].sourceL2Id = sourceL2Id; } // configure lower layers PDCP/MAC/PHY for this communication //Establish a new RBID/LCID for this communication // Establish a SLRB (using DRB 10 for now) UE = &UE_rrc_inst[module_id]; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0); UE->DRB_config[0][0] = CALLOC(1,sizeof(struct LTE_DRB_ToAddMod)); UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); UE->DRB_config[0][0]->drb_Identity = 10; UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); // allowed value 5..15, value : x+4 *(UE->DRB_config[0][0]->eps_BearerIdentity) = 10; UE->DRB_config[0][0]->logicalChannelIdentity = CALLOC(1, sizeof(long)); *(UE->DRB_config[0][0]->logicalChannelIdentity) = UE->DRB_config[0][0]->drb_Identity; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2 DRB_rlc_config = CALLOC(1,sizeof(struct LTE_RLC_Config)); DRB_pdcp_config = CALLOC(1,sizeof(struct LTE_PDCP_Config)); PDCP_rlc_UM = CALLOC(1,sizeof(struct LTE_PDCP_Config__rlc_UM)); DRB_lchan_config = CALLOC(1,sizeof(struct LTE_LogicalChannelConfig)); DRB_ul_SpecificParameters = CALLOC(1, sizeof(struct LTE_LogicalChannelConfig__ul_SpecificParameters)); logicalchannelgroup_drb = CALLOC(1, sizeof(long)); DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional; DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; UE->DRB_config[0][0]->rlc_Config = DRB_rlc_config; DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); UE->DRB_config[0][0]->pdcp_Config = DRB_pdcp_config; DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity; DRB_pdcp_config->rlc_AM = NULL; DRB_pdcp_config->rlc_UM = NULL; /* avoid gcc warnings */ (void)PDCP_rlc_UM; DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed; UE->DRB_config[0][0]->logicalChannelConfig = DRB_lchan_config; DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters)); DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; DRB_ul_SpecificParameters->priority = 12; // lower priority than srb1, srb2 and other dedicated bearer DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; DRB_ul_SpecificParameters->bucketSizeDuration = LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM) *logicalchannelgroup_drb = 1; DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; UE->DRB_configList = CALLOC(1,sizeof(LTE_DRB_ToAddModList_t)); ASN_SEQUENCE_ADD(&UE->DRB_configList->list,UE->DRB_config[0][0]); rrc_pdcp_config_asn1_req(&ctxt, (LTE_SRB_ToAddModList_t *) NULL, UE->DRB_configList, (LTE_DRB_ToReleaseList_t *) NULL, 0xff, NULL, NULL, NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) , (LTE_PMCH_InfoList_r9_t *) NULL #endif ,NULL); rrc_rlc_config_asn1_req(&ctxt, (LTE_SRB_ToAddModList_t *)NULL, UE->DRB_configList, (LTE_DRB_ToReleaseList_t *)NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,(LTE_PMCH_InfoList_r9_t *)NULL , 0, 0 #endif ); //TX if (type > 0) { rrc_rlc_config_asn1_req(&ctxt, (LTE_SRB_ToAddModList_t *)NULL, UE->DRB_configList, (LTE_DRB_ToReleaseList_t *)NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,(LTE_PMCH_InfoList_r9_t *)NULL , sourceL2Id, destinationL2Id #endif ); //configure MAC with sourceL2Id/groupL2ID rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0 (LTE_RadioResourceConfigCommonSIB_t *)NULL, (struct LTE_PhysicalConfigDedicated *)NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (LTE_SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif (LTE_MeasObjectToAddMod_t **)NULL, (LTE_MAC_MainConfig_t *)NULL, 10, //LCID (struct LTE_LogicalChannelConfig *)NULL, (LTE_MeasGapConfig_t *)NULL, (LTE_TDD_Config_t *)NULL, (LTE_MobilityControlInfo_t *)NULL, NULL, NULL, NULL, NULL, NULL, NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,0, (LTE_MBSFN_AreaInfoList_r9_t *)NULL, (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA , 0, 0 #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,CONFIG_ACTION_ADD, &sourceL2Id, &destinationL2Id #endif ); } else {//RX //configure MAC with sourceL2Id/groupL2ID rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0 (LTE_RadioResourceConfigCommonSIB_t *)NULL, (struct LTE_PhysicalConfigDedicated *)NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (LTE_SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif (LTE_MeasObjectToAddMod_t **)NULL, (LTE_MAC_MainConfig_t *)NULL, 10, //LCID (struct LTE_LogicalChannelConfig *)NULL, (LTE_MeasGapConfig_t *)NULL, (LTE_TDD_Config_t *)NULL, (LTE_MobilityControlInfo_t *)NULL, NULL, NULL, NULL, NULL, NULL, NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,0, (LTE_MBSFN_AreaInfoList_r9_t *)NULL, (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA , 0, 0 #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,CONFIG_ACTION_ADD, &sourceL2Id, NULL #endif ); } LOG_I(RRC,"Send PC5EstablishRsp to ProSe App\n"); memset(send_buf, 0, BUFSIZE); sl_ctrl_msg_send = calloc(1, sizeof(struct sidelink_ctrl_element)); sl_ctrl_msg_send->type = PC5S_ESTABLISH_RSP; sl_ctrl_msg_send->sidelinkPrimitive.pc5s_establish_rsp.slrbid_lcid28 = 10; sl_ctrl_msg_send->sidelinkPrimitive.pc5s_establish_rsp.slrbid_lcid29 = 10; sl_ctrl_msg_send->sidelinkPrimitive.pc5s_establish_rsp.slrbid_lcid30 = 10; memcpy((void *)send_buf, (void *)sl_ctrl_msg_send, sizeof(struct sidelink_ctrl_element)); prose_addr_len = sizeof(prose_app_addr); n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, (struct sockaddr *)&prose_app_addr, prose_addr_len); // free(sl_ctrl_msg_send); if (n < 0) { LOG_E(RRC, "ERROR: Failed to send to ProSe App\n"); exit(EXIT_FAILURE); } break; case PC5_DISCOVERY_MESSAGE: if (LOG_DEBUGFLAG(DEBUG_CTRLSOCKET)) { LOG_UI(RRC,"[PC5DiscoveryMessage] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); } //prepare SL_Discovery buffer if (UE_rrc_inst) { memcpy((void *)&UE_rrc_inst[module_id].SL_Discovery[0].Tx_buffer.Payload[0], (void *)&sl_ctrl_msg_recv->sidelinkPrimitive.pc5_discovery_message.payload[0], PC5_DISCOVERY_PAYLOAD_SIZE); UE_rrc_inst[module_id].SL_Discovery[0].Tx_buffer.payload_size = PC5_DISCOVERY_PAYLOAD_SIZE; LOG_I(RRC,"[PC5DiscoveryMessage] Copied %d bytes\n",PC5_DISCOVERY_PAYLOAD_SIZE); } break; default: break; } } free (sl_ctrl_msg_recv); return 0; } //----------------------------------------------------------------------------- int decode_SL_Discovery_Message( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t *Sdu, const uint8_t Sdu_len) { int prose_addr_len; char send_buf[BUFSIZE]; int n; struct sidelink_ctrl_element *sl_ctrl_msg_send = NULL; //from the main program, listen for the incoming messages from control socket (ProSe App) prose_addr_len = sizeof(prose_app_addr); //Store in Rx_buffer memcpy((void *)&UE_rrc_inst[ctxt_pP->module_id].SL_Discovery[0].Rx_buffer.Payload[0], (void *)Sdu, Sdu_len); UE_rrc_inst[ctxt_pP->module_id].SL_Discovery[0].Rx_buffer.payload_size = Sdu_len; memset(send_buf, 0, BUFSIZE); //send to ProSeApp memcpy((void *)send_buf, (void *)Sdu, Sdu_len); prose_addr_len = sizeof(prose_app_addr); sl_ctrl_msg_send = calloc(1, sizeof(struct sidelink_ctrl_element)); sl_ctrl_msg_send->type = PC5_DISCOVERY_MESSAGE; // TODO: Add a check for the SDU size. memcpy((void *)&sl_ctrl_msg_send->sidelinkPrimitive.pc5_discovery_message.payload[0], (void *) Sdu, PC5_DISCOVERY_PAYLOAD_SIZE); memcpy((void *)send_buf, (void *)sl_ctrl_msg_send, sizeof(struct sidelink_ctrl_element)); free(sl_ctrl_msg_send); prose_addr_len = sizeof(prose_app_addr); n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, (struct sockaddr *)&prose_app_addr, prose_addr_len); if (n < 0) { // TODO: We should not just exit if the Prose App has not yet attached. It creates a race condition. LOG_I(RRC, "ERROR: Failed to send to ProSe App\n"); //exit(EXIT_FAILURE); } return(0); } #endif //----------------------------------------------------------------------------- RRC_status_t rrc_rx_tx_ue( protocol_ctxt_t *const ctxt_pP, const uint8_t enb_indexP, const int CC_id ) //----------------------------------------------------------------------------- { #ifdef LOCALIZATION double estimated_distance; protocol_ctxt_t ctxt; #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_IN); // check timers if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T300_active == 1) { if ((UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T300_cnt % 10) == 0) LOG_D(RRC, "[UE %d][RAPROC] Frame %d T300 Count %d ms\n", ctxt_pP->module_id, ctxt_pP->frame, UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T300_cnt); if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T300_cnt == T300[UE_rrc_inst[ctxt_pP->module_id].sib2[enb_indexP]->ue_TimersAndConstants.t300]) { UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T300_active = 0; // ALLOW CCCH to be used UE_rrc_inst[ctxt_pP->module_id].Srb0[enb_indexP].Tx_buffer.payload_size = 0; rrc_ue_generate_RRCConnectionRequest (ctxt_pP, enb_indexP); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT); return (RRC_ConnSetup_failed); } UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T300_cnt++; } if ((UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].SIStatus&2)>0) { if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].N310_cnt == N310[UE_rrc_inst[ctxt_pP->module_id].sib2[enb_indexP]->ue_TimersAndConstants.n310]) { LOG_I(RRC,"Activating T310\n"); UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_active = 1; } } else { // in case we have not received SIB2 yet /* if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].N310_cnt == 100) { UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].N310_cnt = 0; }*/ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT); return RRC_OK; } if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_active == 1) { if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].N311_cnt == N311[UE_rrc_inst[ctxt_pP->module_id].sib2[enb_indexP]->ue_TimersAndConstants.n311]) { UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_active = 0; UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].N311_cnt = 0; } if ((UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_cnt % 10) == 0) { LOG_D(RRC, "[UE %d] Frame %d T310 Count %d ms\n", ctxt_pP->module_id, ctxt_pP->frame, UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_cnt); } if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_cnt == T310[UE_rrc_inst[ctxt_pP->module_id].sib2[enb_indexP]->ue_TimersAndConstants.t310]) { UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_active = 0; rrc_t310_expiration (ctxt_pP, enb_indexP); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT); LOG_I(RRC,"Returning RRC_PHY_RESYNCH: T310 expired\n"); return RRC_PHY_RESYNCH; } UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_cnt++; } if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T304_active==1) { if ((UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T304_cnt % 10) == 0) LOG_D(RRC,"[UE %d][RAPROC] Frame %d T304 Count %d ms\n",ctxt_pP->module_id,ctxt_pP->frame, UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T304_cnt); if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T304_cnt == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T304_active = 0; UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.measFlag = 1; LOG_E(RRC,"[UE %d] Handover failure..initiating connection re-establishment procedure... \n", ctxt_pP->module_id); //Implement 36.331, section 5.3.5.6 here VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT); return(RRC_Handover_failed); } UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T304_cnt--; } // Layer 3 filtering of RRC measurements if (UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[0] != NULL) { ue_meas_filtering(ctxt_pP,enb_indexP); } ue_measurement_report_triggering(ctxt_pP,enb_indexP); if (UE_rrc_inst[ctxt_pP->module_id].Info[0].handoverTarget > 0) { LOG_I(RRC,"[UE %d] Frame %d : RRC handover initiated\n", ctxt_pP->module_id, ctxt_pP->frame); } if((UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].State == RRC_HO_EXECUTION) && (UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.targetCellId != 0xFF)) { UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].State= RRC_IDLE; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT); return(RRC_HO_STARTED); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT); return (RRC_OK); }