Files
openairinterface5g/openair2/RRC/LTE/rrc_UE.c
T

5996 lines
306 KiB
C

/*
* 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 / rrc procedures for FeMBMS UE
* \author Navid Nikaein, Raymond Knopp and Javier Morgade
* \date 2011 - 2014 / FeMBMS 2019
* \version 1.0
* \company Eurecom, Vicomtech
* \email: navid.nikaein@eurecom.fr, raymond.knopp@eurecom.fr and javier.morgade@ieee.org
*/
#define RRC_UE
#define RRC_UE_C
#define _GNU_SOURCE
#include <arpa/inet.h>
#include "assertions.h"
#include "hashtable.h"
#include "oai_asn1.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"
#include "LTE_MCCH-Message.h"
#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 "common/utils/tun_if.h"
#if ENABLE_RAL
#include "rrc_UE_ral.h"
#endif
#include "openair3/SECU/key_nas_deriver.h"
#include "pdcp.h"
#include "plmn_data.h"
#include <common/utils/system.h>
#include "intertask_interface.h"
#include "executables/lte-softmodem.h"
#include "SIMULATION/TOOLS/sim.h" // for taus
#include "openair2/LAYER2/MAC/mac_extern.h"
#include "LTE_BCCH-BCH-Message-MBMS.h"
#include "LTE_BCCH-DL-SCH-Message-MBMS.h"
#include "LTE_SystemInformation-MBMS-r14.h"
#include "LTE_SystemInformationBlockType1-MBMS-r14.h"
#include "LTE_NonMBSFN-SubframeConfig-r14.h"
#include "LTE_SL-Preconfiguration-r12.h"
//for D2D
int ctrl_sock_fd;
struct sockaddr_in prose_app_addr;
int slrb_id;
int send_ue_information = 0;
// TimeToTrigger enum mapping table (36.331 TimeToTrigger IE)
static const uint32_t timeToTrigger_ms[16] = {0, 40, 64, 80, 100, 128, 160, 256, 320, 480, 512, 640, 1024, 1280, 2560, 5120};
/* 36.133 Section 9.1.4 RSRP Measurement Report Mapping, Table: 9.1.4-1 */
static const float RSRP_meas_mapping[98] = {-140, -139, -138, -137, -136, -135, -134, -133, -132, -131, -130, -129, -128, -127, -126, -125, -124, -123, -122, -121, -120, -119, -118, -117, -116,
-115, -114, -113, -112, -111, -110, -109, -108, -107, -106, -105, -104, -103, -102, -101, -100, -99, -98, -97, -96, -95, -94, -93, -92, -91,
-90, -89, -88, -87, -86, -85, -84, -83, -82, -81, -80, -79, -78, -77, -76, -75, -74, -73, -72, -71, -70, -69, -68, -67, -66,
-65, -64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54, -53, -52, -51, -50, -49, -48, -47, -46, -45, -44, -43};
static const float RSRQ_meas_mapping[35] = {-19, -18.5, -18, -17.5, -17, -16.5, -16, -15.5, -15, -14.5, -14, -13.5, -13, -12.5, -12, -11.5, -11, -10.5,
-10, -9.5, -9, -8.5, -8, -7.5, -7, -6.5, -6, -5.5, -5, -4.5, -4, -3.5, -3, -2.5, -2};
// 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_SI_MBMS( 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 );
static int decode_SIB1_MBMS( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t rsrq, const uint8_t rsrp );
typedef struct rrc_dcch_data_copy_t
{
LTE_DL_DCCH_Message_t *dl_dcch_msg;
} rrc_dcch_data_copy_t;
static void rrc_ue_process_ueCapabilityEnquiry(const protocol_ctxt_t *const ctxt_pP,
LTE_UECapabilityEnquiry_t *UECapabilityEnquiry,
uint8_t eNB_index);
/** \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
* \param sel_plmn_id selected PLMN Identity
*/
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 sel_plmn_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,
OCTET_STRING_t *str);
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);
static void decode_MBSFNAreaConfiguration(module_id_t module_idP, uint8_t eNB_index, frame_t frameP,uint8_t mbsfn_sync_area);
static void decode_MBMSCountingRequest(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);
void
rrc_ue_process_MBMSCountingRequest(
const protocol_ctxt_t *const ctxt_pP,
LTE_MBMSCountingRequest_r10_t *MBMSCountingRequest,
uint8_t eNB_index
);
protocol_ctxt_t ctxt_pP_local;
/*------------------------------------------------------------------------------*/
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 (!IS_SOFTMODEM_NOS1) {
switch (UE_rrc_inst[ue_mod_idP].RrcState) {
case RRC_STATE_INACTIVE:
AssertFatal(RRC_SUB_STATE_INACTIVE <= subState,
"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_SEARCHING <= subState) && (subState <= RRC_SUB_STATE_IDLE),
"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 <= subState,
"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].sizeof_SIB1_MBMS[eNB_index] = 0;
UE_rrc_inst[ctxt_pP->module_id].sizeof_SI_MBMS[eNB_index] = 0;
UE_rrc_inst[ctxt_pP->module_id].SIB1_MBMS[eNB_index] = (uint8_t *)malloc16_clear( 32 );
UE_rrc_inst[ctxt_pP->module_id].sib1_MBMS[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType1_MBMS_r14_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) );
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) );
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;
UE_rrc_inst[ctxt_pP->module_id].SI_MBMS[eNB_index] = (uint8_t *)malloc16_clear( 64 );
UE_rrc_inst[ctxt_pP->module_id].si_MBMS[eNB_index] = (LTE_SystemInformation_MBMS_r14_t *)malloc16_clear( sizeof(LTE_SystemInformation_MBMS_r14_t) );
UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus_MBMS = 0;
UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt_MBMS = 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(5,1);
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[4] = 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;
asn1cSeqAdd(&UE->SL_Preconfiguration[eNB_index]->preconfigComm_r12.list,preconfigpool);
// Rel13 extensions
UE->SL_Preconfiguration[eNB_index]->ext1 = NULL;
}
//-----------------------------------------------------------------------------
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].selected_plmn_identity = 1;
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;
UE_rrc_inst[ctxt.module_id].integrity_algorithm = LTE_SecurityAlgorithmConfig__integrityProtAlgorithm_eia0_v920;
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));
openair_rrc_on_ue(&ctxt);
return 0;
}
//-----------------------------------------------------------------------------
void rrc_ue_generate_RRCConnectionRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) {
uint8_t 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 (int 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,
sizeof(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 (int i=0; i<UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Tx_buffer.payload_size; i++) {
LOG_T(RRC,"%x.\n",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);
UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Active = 0;
UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].StatusSrb = 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 sel_plmn_id)
{
uint8_t buffer[100];
uint8_t size;
const char *nas_msg;
int nas_msg_length;
if (!IS_SOFTMODEM_NOS1) {
nas_msg = (char *)UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.nas_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, sel_plmn_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);
ctxt_pP_local.rntiMaybeUEid = ctxt_pP->rntiMaybeUEid;
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,
OCTET_STRING_t *str) {
uint8_t buffer[RRC_BUF_SIZE];
size_t size = do_RRCConnectionReconfigurationComplete(ctxt_pP, buffer, sizeof(buffer), Transaction_id, str);
LOG_I(RRC,PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel UL-DCCH (SRB1), Generating RRCConnectionReconfigurationComplete (bytes %zu, 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/%zu 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_A(RRC, "[UE%d][RAPROC] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionSetup RNTI %lx\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rntiMaybeUEid);
// 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->rntiMaybeUEid;
rrc_ue_generate_RRCConnectionSetupComplete(
ctxt_pP,
eNB_index,
dl_ccch_msg->message.choice.c1.choice.rrcConnectionSetup.rrc_TransactionIdentifier,
UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity);
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].StatusSrb = 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);
// 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].StatusSrb = 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);
// 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);
if (IS_SOFTMODEM_NOS1) {
ip_addr_offset3 = 0;
ip_addr_offset4 = 1;
LOG_I(OIP,"[UE %d] trying to bring up the OAI interface %d, IP X.Y.%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);
char ip[20];
snprintf(ip,
sizeof(ip),
"10.0.%d.%d",
UE_NAS_USE_TUN ? 1 : (ip_addr_offset3 + ue_mod_idP + 1),
ip_addr_offset4 + ue_mod_idP + 1);
char ifname[IFNAMSIZ];
tun_generate_ifname(ifname, "oaitun_ue", ip_addr_offset3 + ue_mod_idP);
oip_ifup = tun_config(ifname, ip, NULL);
if (oip_ifup == 0 && (!UE_NAS_USE_TUN)) { // interface is up --> send a config the DRB
LOG_I(OIP,"[UE %d] Config the ue net interface %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 * LTE_maxDRB) + DRB_config->drb_Identity));
AssertFatal(false, "not implemented\n");
LOG_D(RRC,"[UE %d] State = Attached (eNB %d)\n",ue_mod_idP,eNB_index);
}
}
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;
UE_RRC_INST *ue = &UE_rrc_inst[ctxt_pP->module_id];
if (measConfig->measObjectToRemoveList != NULL) {
for (i = 0; i < measConfig->measObjectToRemoveList->list.count; i++) {
ind = *measConfig->measObjectToRemoveList->list.array[i];
free(ue->MeasObj[eNB_index][ind-1]);
ue->MeasObj[eNB_index][ind-1] = NULL;
}
}
if (measConfig->measObjectToAddModList != NULL) {
LOG_I(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;
AssertFatal(ind > 0 && ind <= MAX_MEAS_OBJ && eNB_index >= 0 && eNB_index < NB_CNX_UE,
"measObjectId is out of bounds. ind = %ld, eNB_index = %d, i = %d.\n", ind, eNB_index, i);
if (ue->MeasObj[eNB_index][ind-1]) {
LOG_D(RRC, "Modifying measurement object [%d][%ld]\n", eNB_index, ind);
memcpy((char *)ue->MeasObj[eNB_index][ind-1],
(char *)measObj,
sizeof(LTE_MeasObjectToAddMod_t));
} else {
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]);
}
LOG_D(RRC, "Adding measurement object [%d][%ld]\n", eNB_index, ind);
ue->MeasObj[eNB_index][ind-1]=measObj;
}
measConfig->measObjectToAddModList->list.array[i] = NULL;
}
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,
(LTE_SCellToAddMod_r10_t *)NULL,
ue->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,
0,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL,
(LTE_PMCH_InfoList_r9_t *)NULL,
0,
NULL,
NULL,
0,
(struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL
);
}
if (measConfig->reportConfigToRemoveList != NULL) {
for (i=0; i<measConfig->reportConfigToRemoveList->list.count; i++) {
ind = *measConfig->reportConfigToRemoveList->list.array[i];
free(ue->ReportConfig[eNB_index][ind-1]);
ue->ReportConfig[eNB_index][ind-1] = NULL;
}
}
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;
AssertFatal(ind > 0 && ind <= MAX_MEAS_CONFIG && eNB_index >= 0 && eNB_index < NB_CNX_UE,
"ReportConfigId is out of bounds. ind = %ld, eNB_index = %d, i = %d.\n", ind, eNB_index, i);
if (ue->ReportConfig[eNB_index][ind-1]) {
LOG_D(RRC,"Modifying ReportConfig [%d][%ld]\n", eNB_index, ind-1);
memcpy((char *)ue->ReportConfig[eNB_index][ind-1],
(char *)measConfig->reportConfigToAddModList->list.array[i],
sizeof(LTE_ReportConfigToAddMod_t));
} else {
LOG_D(RRC,"Adding ReportConfig [%d][%ld]\n", eNB_index, ind-1);
ue->ReportConfig[eNB_index][ind-1] = measConfig->reportConfigToAddModList->list.array[i];
}
measConfig->reportConfigToAddModList->list.array[i] = NULL;
}
}
if (measConfig->quantityConfig != NULL) {
if (ue->QuantityConfig[eNB_index]) {
LOG_D(RRC,"Modifying Quantity Configuration \n");
memcpy((char *)ue->QuantityConfig[eNB_index],
(char *)measConfig->quantityConfig,
sizeof(LTE_QuantityConfig_t));
} else {
LOG_D(RRC,"Adding Quantity configuration\n");
ue->QuantityConfig[eNB_index] = measConfig->quantityConfig;
}
measConfig->quantityConfig = NULL;
}
if (measConfig->measIdToRemoveList != NULL) {
for (i=0; i<measConfig->measIdToRemoveList->list.count; i++) {
ind = *measConfig->measIdToRemoveList->list.array[i];
free(ue->MeasId[eNB_index][ind-1]);
ue->MeasId[eNB_index][ind-1] = NULL;
}
}
if (measConfig->measIdToAddModList != NULL) {
for (i=0; i<measConfig->measIdToAddModList->list.count; i++) {
ind = measConfig->measIdToAddModList->list.array[i]->measId;
AssertFatal(ind > 0 && ind <= MAX_MEAS_ID && eNB_index >= 0 && eNB_index < NB_CNX_UE,
"measId is out of bounds. ind = %ld, eNB_index = %d, i = %d.\n", ind, eNB_index, i);
if (ue->MeasId[eNB_index][ind-1]) {
LOG_I(RRC,"Modifying Measurement ID [%d][%ld]\n", eNB_index, ind-1);
memcpy((char *)ue->MeasId[eNB_index][ind-1],
(char *)measConfig->measIdToAddModList->list.array[i],
sizeof(LTE_MeasIdToAddMod_t));
} else {
LOG_I(RRC,"Adding Measurement ID [%d][%ld]\n", eNB_index, ind-1);
ue->MeasId[eNB_index][ind-1] = measConfig->measIdToAddModList->list.array[i];
}
measConfig->measIdToAddModList->list.array[i] = NULL;
}
}
if (measConfig->measGapConfig !=NULL) {
if (ue->measGapConfig[eNB_index]) {
memcpy((char *)ue->measGapConfig[eNB_index],
(char *)measConfig->measGapConfig,
sizeof(LTE_MeasGapConfig_t));
} else {
ue->measGapConfig[eNB_index] = measConfig->measGapConfig;
}
measConfig->measGapConfig = NULL;
}
if (measConfig->quantityConfig != NULL) {
if (ue->QuantityConfig[eNB_index]) {
LOG_I(RRC,"Modifying Quantity Configuration \n");
memcpy((char *)ue->QuantityConfig[eNB_index],
(char *)measConfig->quantityConfig,
sizeof(LTE_QuantityConfig_t));
} else {
LOG_I(RRC,"Adding Quantity configuration\n");
ue->QuantityConfig[eNB_index] = measConfig->quantityConfig;
}
measConfig->quantityConfig = NULL;
ue->filter_coeff_rsrp = 1./pow(2,
(*ue->QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRP)/4);
ue->filter_coeff_rsrq = 1./pow(2,
(*ue->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->QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRP,
*ue->QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRQ,
ue->filter_coeff_rsrp,
ue->filter_coeff_rsrq);
}
if (measConfig->s_Measure != NULL) {
ue->s_measure = *measConfig->s_Measure;
}
measConfig->s_Measure = NULL;
if (measConfig->speedStatePars != NULL) {
if (ue->speedStatePars) {
memcpy((char *)ue->speedStatePars,(char *)measConfig->speedStatePars,sizeof(struct LTE_MeasConfig__speedStatePars));
} else {
ue->speedStatePars = measConfig->speedStatePars;
}
measConfig->speedStatePars = NULL;
LOG_I(RRC,"[UE %d] Configuring mobility optimization params for UE %d \n",
ctxt_pP->module_id,ue->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;
// 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;
}
radioResourceConfigDedicated->physicalConfigDedicated = NULL;
}
// 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;
}
radioResourceConfigDedicated->sps_Config = NULL;
}
// Establish SRBs if present
// loop through SRBToAddModList
if (radioResourceConfigDedicated->srb_ToAddModList) {
uint8_t kRRCenc[32] = {0};
uint8_t kRRCint[32] = {0};
derive_key_nas(RRC_ENC_ALG, UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, kRRCenc);
derive_key_nas(RRC_INT_ALG, 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,
(LTE_PMCH_InfoList_r9_t *)NULL,
NULL);
// Refresh SRBs
rrc_rlc_config_asn1_req(ctxt_pP,
radioResourceConfigDedicated->srb_ToAddModList,
(LTE_DRB_ToAddModList_t *)NULL,
(LTE_DRB_ToReleaseList_t *)NULL,
(LTE_PMCH_InfoList_r9_t *)NULL,
0, 0
);
#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]);
radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt] = NULL;
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],
(LTE_SCellToAddMod_r10_t *)NULL,
(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,
0,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL,
(LTE_PMCH_InfoList_r9_t *)NULL,
0,
NULL,
NULL,
0,
(struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL
);
}
} 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]);
radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt] = NULL;
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],
(LTE_SCellToAddMod_r10_t *)NULL,
(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,
0,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL,
(LTE_PMCH_InfoList_r9_t *)NULL,
0,
NULL,
NULL,
0,
(struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL
);
}
}
}
}
// 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 = %ld\n",ctxt_pP->module_id, *UE_rrc_inst[ctxt_pP->module_id].defaultDRB);
}
uint8_t kUPenc[32] = {0};
derive_key_nas(UP_ENC_ALG, UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, kUPenc);
// 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,
(LTE_PMCH_InfoList_r9_t *)NULL,
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,
(LTE_PMCH_InfoList_r9_t *)NULL, 0, 0
);
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);
radioResourceConfigDedicated->drb_ToAddModList->list.array[i] = NULL;
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],
(LTE_SCellToAddMod_r10_t *)NULL,
(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,
0,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL,
(LTE_PMCH_InfoList_r9_t *)NULL,
0,
NULL,
NULL,
0,
(struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL
);
}
}
}
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[32] = {0};
uint8_t kUPenc[32] = {0};
uint8_t kRRCint[32] = {0};
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->rntiMaybeUEid, 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_nas(RRC_ENC_ALG, UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, kRRCenc);
derive_key_nas(RRC_INT_ALG, UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, kRRCint);
derive_key_nas(UP_ENC_ALG, 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_SecurityModeComplete__criticalExtensions_PR_securityModeComplete_r8;
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_MBMSCountingRequest(
const protocol_ctxt_t *const ctxt_pP,
LTE_MBMSCountingRequest_r10_t *MBMSCountingRequest,
uint8_t eNB_index
)
{
asn_enc_rval_t enc_rval;
LTE_UL_DCCH_Message_t ul_dcch_msg;
struct LTE_CountingResponseInfo_r10 CountingResponse;
uint8_t buffer[200];
//int i;
LOG_I(RRC,"[UE %d] Frame %d: Receiving from (MCCH), Processing MBMSCoutingRequest (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 *)&CountingResponse,0,sizeof(struct LTE_CountingResponseInfo_r10));
ul_dcch_msg.message.present = LTE_UL_DCCH_MessageType_PR_c1;
ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10;
LTE_MBMSCountingResponse_r10_t *MBMSCountingResponse = &ul_dcch_msg.message.choice.c1.choice.mbmsCountingResponse_r10;
MBMSCountingResponse->criticalExtensions.present = LTE_MBMSCountingResponse_r10__criticalExtensions_PR_c1;
MBMSCountingResponse->criticalExtensions.choice.c1.present = LTE_MBMSCountingResponse_r10__criticalExtensions__c1_PR_countingResponse_r10;
LTE_MBMSCountingResponse_r10_IEs_t *MBMSCountingResponse_r10_IEs = &MBMSCountingResponse->criticalExtensions.choice.c1.choice.countingResponse_r10;
MBMSCountingResponse_r10_IEs->mbsfn_AreaIndex_r10 = calloc(1,sizeof(long));
// MBMSCountingResponse_r10_IEs->countingResponseList_r10 = calloc(1,sizeof(struct LTE_CountingResponseList_r10));
//
// asn1cSeqAdd(
// &MBMSCountingResponse->criticalExtensions.choice.c1.choice.countingResponse_r10.countingResponseList_r10.list,
// &CountingResponse);
//
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);
}
xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)&ul_dcch_msg);
LOG_I(RRC,"MBMSCountingResponse Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
rrc_data_req_ue (
&ctxt_pP_local,
DCCH,
rrc_mui++,
SDU_CONFIRM_NO,
(enc_rval.encoded + 7) / 8,
buffer,
PDCP_TRANSMISSION_MODE_CONTROL);
}
//-----------------------------------------------------------------------------
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].UECap->sdu,
UE_rrc_inst[ctxt_pP->module_id].UECap->sdu_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) {
asn1cSeqAdd(
&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_A(RRC, "%s: UECapabilityInformation Encoded %zd bits (%zd bytes)\n",
__FUNCTION__, 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);
}
}
}
/** \brief process the received rrcConnectionReconfiguration message at UE
\param ctxt_pP Running context
\param *rrcConnectionReconfiguration pointer to the sturcture
\param eNB_index Index of corresponding eNB/CH*/
static 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 *r_r8 = &rrcConnectionReconfiguration->
criticalExtensions.choice.c1.
choice.rrcConnectionReconfiguration_r8;
if (r_r8->mobilityControlInfo) {
LOG_I(RRC,"Mobility Control Information is present\n");
rrc_ue_process_mobilityControlInfo(
ctxt_pP,
eNB_index,
r_r8->mobilityControlInfo);
}
if (r_r8->measConfig != NULL) {
LOG_I(RRC,"Measurement Configuration is present\n");
rrc_ue_process_measConfig(ctxt_pP,
eNB_index,
r_r8->measConfig);
r_r8->measConfig = NULL;
}
if (r_r8->radioResourceConfigDedicated) {
LOG_I(RRC,"Radio Resource Configuration is present\n");
rrc_ue_process_radioResourceConfigDedicated(ctxt_pP,
eNB_index,
r_r8->radioResourceConfigDedicated);
r_r8->radioResourceConfigDedicated = NULL;
}
//TTN for D2D
//if RRCConnectionReconfiguration message includes the sl-CommConfig
if ((r_r8->nonCriticalExtension != NULL)
&& (r_r8->nonCriticalExtension->nonCriticalExtension != NULL)
&& (r_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension != NULL)
&& (r_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension != NULL)
&& (r_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension
!= NULL)
&& (r_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12
!= NULL)) {
if (r_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,
r_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12,
(LTE_SL_DiscConfig_r12_t *)NULL
);
}
}
/*
//if RRCConnectionReconfiguration message includes the sl-DiscConfig
if (r_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,
r_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_DiscConfig_r12
);
}
*/
/* Check if there is dedicated NAS information to forward to NAS */
if (r_r8->dedicatedInfoNASList != NULL) {
int list_count;
uint32_t pdu_length;
uint8_t *pdu_buffer;
MessageDef *msg_p;
for (list_count = 0; list_count < r_r8->dedicatedInfoNASList->list.count; list_count++) {
pdu_length = r_r8->dedicatedInfoNASList->list.array[list_count]->size;
pdu_buffer = r_r8->dedicatedInfoNASList->list.array[list_count]->buf;
msg_p = itti_alloc_new_message(TASK_RRC_UE, 0, 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.nas_data = pdu_buffer;
itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p);
}
LOG_D(RRC, "Sent NAS_CONN_ESTABLI_CNF to NAS layer via itti!\n");
free (r_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, 0, 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->rntiMaybeUEid;
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 < LTE_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++)
{
asn1cSeqAdd (&(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);
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);
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);
//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,
(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,
mobilityControlInfo,
(uint8_t *)NULL,
(uint16_t *)NULL,
NULL,
NULL,
NULL,
NULL,
0,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL,
(LTE_PMCH_InfoList_r9_t *)NULL,
0,
NULL,
NULL,
0,
(struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL
);
// 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);
// rrc_rlc_config_req(ue_mod_idP+NB_eNB_INST,frameP,0,CONFIG_ACTION_ADD,ue_mod_idP+DCCH1,SIGNALLING_RADIO_BEARER);
// rrc_rlc_config_req(ue_mod_idP+NB_eNB_INST,frameP,0,CONFIG_ACTION_ADD,ue_mod_idP+DTCH,RADIO_ACCESS_BEARER);
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]
}
//-----------------------------------------------------------------------------
/** \brief Decodes a DL-DCCH message and invokes appropriate routine to handle the message
\param ctxt_pP Running context
\param Srb_id Index of Srb (1,2)
\param Buffer Pointer to received SDU
\param Buffer_size
\param eNB_indexP Index of corresponding eNB/CH*/
static void rrc_ue_decode_dcch(const protocol_ctxt_t *const ctxt_pP,
const rb_id_t Srb_id,
const uint8_t *const Buffer,
const uint32_t Buffer_size,
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%ld), should not have ...\n",
ctxt_pP->module_id, ctxt_pP->frame, Srb_id);
return;
}
asn_dec_rval_t dec_rval = uper_decode(NULL,
&asn_DEF_LTE_DL_DCCH_Message,
(void **)&dl_dcch_msg,
(uint8_t *)Buffer,
Buffer_size, 0, 0);
if (dec_rval.code != RC_OK && dec_rval.consumed == 0)
{
LOG_E(RRC, "%s: Failed to decode LTE_DL_DCC_Msg\n", __FUNCTION__);
SEQUENCE_free(&asn_DEF_LTE_DL_DCCH_Message, dl_dcch_msg, ASFM_FREE_EVERYTHING);
return;
}
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;
MessageDef *msg_p;
uint32_t pdu_length = dedicatedInfoType->choice.dedicatedInfoNAS.size;
uint8_t *pdu_buffer = malloc(pdu_length);
memcpy(pdu_buffer, dedicatedInfoType->choice.dedicatedInfoNAS.buf, pdu_length);
msg_p = itti_alloc_new_message(TASK_RRC_UE, 0, 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.nas_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,
NULL);
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, 0, 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 < LTE_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,
NULL);
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, 0, 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 < LTE_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;
asn1cSeqAdd(&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 ++;
}
UE_RRC_INFO *info = &UE_rrc_inst[ctxt_pP->module_id].Info[eNB_indexP];
if (info->dl_dcch_msg != NULL) {
SEQUENCE_free(&asn_DEF_LTE_DL_DCCH_Message, info->dl_dcch_msg, ASFM_FREE_EVERYTHING);
}
info->dl_dcch_msg = dl_dcch_msg;
dl_dcch_msg = NULL;
break;
case LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionRelease:
msg_p = itti_alloc_new_message(TASK_RRC_UE, 0, 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, 0, 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;
case LTE_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r9:
break;
case LTE_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r10:
break;
case LTE_DL_DCCH_MessageType__c1_PR_rnReconfiguration_r10:
break;
case LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionResume_r13:
break;
case LTE_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16:
break;
case LTE_DL_DCCH_MessageType__c1_PR_spare1:
case LTE_DL_DCCH_MessageType__c1_PR_spare2:
break;
default:
break;
}
}
}
}
const char siWindowLength[9][5] = {"1ms","2ms","5ms","10ms","15ms","20ms","40ms","80ms","ERR"};
const char siWindowLength_int[8] = {1,2,5,10,15,20,40,80};
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_MBMS_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_MBMS_t *bcch_message = NULL;
//LTE_SystemInformationBlockType1_MBMS_r14_t *sib1_mbms = UE_rrc_inst[ctxt_pP->module_id].sib1_MBMS[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_MBMS&1) == 1) && // SIB1 received
(UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt_MBMS == sib1->schedulingInfoList_MBMS_r14.list.count)) {
// Avoid decoding SystemInformationBlockType1_t* sib1_MBMS = UE_rrc_inst[ctxt_pP->module_id].sib1_MBMS[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_MBMS,(void *)bcch_message );
//}
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
&asn_DEF_LTE_BCCH_DL_SCH_Message_MBMS,
(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_MBMS_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_MBMS, (void *)bcch_message, 1 );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT );
return -1;
}
//if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
//xer_fprint(stdout, &asn_DEF_LTE_BCCH_DL_SCH_Message_MBMS,(void *)bcch_message );
//}
if (bcch_message->message.present == LTE_BCCH_DL_SCH_MessageType_MBMS_r14_PR_c1) {
switch (bcch_message->message.choice.c1.present) {
case LTE_BCCH_DL_SCH_MessageType_MBMS_r14__c1_PR_systemInformationBlockType1_MBMS_r14:
if ((ctxt_pP->frame % 4) == 0) {
// every 4 frame
if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus_MBMS&1) == 0) {
LTE_SystemInformationBlockType1_MBMS_r14_t *sib1_mbms = UE_rrc_inst[ctxt_pP->module_id].sib1_MBMS[eNB_index];
memcpy( (void *)sib1_mbms,
(void *)&bcch_message->message.choice.c1.choice.systemInformationBlockType1_MBMS_r14,
sizeof(LTE_SystemInformationBlockType1_MBMS_r14_t) );
LOG_D( RRC, "[UE %"PRIu8"] Decoding \"First\" SIB1-MBMS\n", ctxt_pP->module_id );
decode_SIB1_MBMS( ctxt_pP, eNB_index, rsrq, rsrp );
}
}
break;
case LTE_BCCH_DL_SCH_MessageType_MBMS_r14__c1_PR_systemInformation_MBMS_r14:
if ((ctxt_pP->frame % 4) == 0) {
//if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&1) == 1) {
// SIB1 with schedulingInfoList is available
// you miss this on the eNB!!!!
LTE_SystemInformation_MBMS_r14_t *si_mbms = UE_rrc_inst[ctxt_pP->module_id].si_MBMS[eNB_index];
memcpy( si_mbms,
&bcch_message->message.choice.c1.choice.systemInformation_MBMS_r14,
sizeof(LTE_SystemInformation_MBMS_r14_t) );
LOG_W( RRC, "[UE %"PRIu8"] Decoding MBMS SI for frameP %"PRIu32"\n",
ctxt_pP->module_id,
ctxt_pP->frame );
decode_SI_MBMS( ctxt_pP, eNB_index ); //TODO
//UE_mac_inst[ctxt_pP->module_id].SI_Decoded = 1;
//}
}
break;
case LTE_BCCH_DL_SCH_MessageType__c1_PR_NOTHING:
default:
break;
}
}
/*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;
}
}*/
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT );
return 0;
}
//-----------------------------------------------------------------------------
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) {
if (!UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]) {
LOG_E(PHY,"UE_rrc_inst[%d].sib1[%d] is null, allocating\n", ctxt_pP->module_id, eNB_index);
openair_rrc_ue_init(ctxt_pP->module_id, eNB_index);
}
LTE_SystemInformationBlockType1_t *sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index];
memcpy( sib1,
&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 ((UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.nas_data != NULL) || IS_SOFTMODEM_NOS1) {
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_MBMS( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t rsrq, const uint8_t rsrp ) {
LTE_SystemInformationBlockType1_MBMS_r14_t *sib1_MBMS = UE_rrc_inst[ctxt_pP->module_id].sib1_MBMS[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 SIB1-MBMS\n", ctxt_pP->module_id );
//cannot parse ! ... TODO
/*LTE_PLMN_Identity_t *PLMN_identity = ((LTE_PLMN_Identity_t*)(&sib1_MBMS->cellAccessRelatedInfo_r14.plmn_IdentityList_r14.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_MBMS->cellAccessRelatedInfo_r14.trackingAreaCode_r14.size == 2)?((sib1_MBMS->cellAccessRelatedInfo_r14.trackingAreaCode_r14.buf[0]<<8) + sib1_MBMS->cellAccessRelatedInfo_r14.trackingAreaCode_r14.buf[1]):0));
LOG_I( RRC, "cellReservedForOperatorUse : raw:%ld decoded:%s\n", ((LTE_PLMN_IndentityInfo_t*)sib1_MBMS->cellAccessRelatedInfo_r14.plmn_IdentityList_r14.list.array[0])->cellReservedForOperatorUse,
SIBreserved(((LTE_PLMN_IdentityInfo_t*)sib1_MBMS->cellAccessRelatedInfo_r14.plmn_IdentityList_r14.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_MBMS->cellAccessRelatedInfo_r14.cellIdentity_r14 ),
sib1_MBMS->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[0],
sib1_MBMS->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[1],
sib1_MBMS->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[2],
sib1_MBMS->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[3] >> sib1_MBMS->cellAccessRelatedInfo_r14.cellIdentity_r14.bits_unused);
//LOG_I( RRC, "cellAccessRelatedInfo.cellBarred : raw:%ld decoded:%s\n", sib1_MBMS->cellAccessRelatedInfo_r14.cellBarred, SIBbarred(sib1_MBMS->cellAccessRelatedInfo_r14.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_MBMS->freqBandIndicator_r14 );
if (sib1_MBMS->schedulingInfoList_MBMS_r14.list.count > 0) {
for (int i=0; i<sib1_MBMS->schedulingInfoList_MBMS_r14.list.count; i++) {
LOG_I( RRC, "si_Periodicity[%d] : %s\n", i, SIBPeriod[min(sib1_MBMS->schedulingInfoList_MBMS_r14.list.array[i]->si_Periodicity_r14,7)]);
if (sib1_MBMS->schedulingInfoList_MBMS_r14.list.array[i]->sib_MappingInfo_r14.list.count > 0) {
char temp[32 * sizeof(SIBType[0])] = {0}; // maxSIB==32
for (int j=0; j<sib1_MBMS->schedulingInfoList_MBMS_r14.list.array[i]->sib_MappingInfo_r14.list.count; j++) {
sprintf( temp + j*sizeof(SIBType[0]), "%*s ", (int)sizeof(SIBType[0])-1, SIBType[min(*sib1_MBMS->schedulingInfoList_MBMS_r14.list.array[i]->sib_MappingInfo_r14.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_MBMS->tdd_Config) {
//LOG_I( RRC, "TDD subframeAssignment : %ld\n", sib1_MBMS->tdd_Config->subframeAssignment );
//LOG_I( RRC, "TDD specialSubframePatterns : %ld\n", sib1_MBMS->tdd_Config->specialSubframePatterns );
//}
LOG_I( RRC, "siWindowLength : %s\n", siWindowLength[min(sib1_MBMS->si_WindowLength_r14,8)] );
LOG_I( RRC, "systemInfoValueTag : %ld\n", sib1_MBMS->systemInfoValueTag_r14 );
UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod_MBMS = siPeriod_int[sib1_MBMS->schedulingInfoList_MBMS_r14.list.array[0]->si_Periodicity_r14];
UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIwindowsize_MBMS = siWindowLength_int[sib1_MBMS->si_WindowLength_r14];
LOG_I( RRC, "[FRAME unknown][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB1-MBMS 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,
(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,//UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->tdd_Config,
(LTE_MobilityControlInfo_t *) NULL,
NULL,//&UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIwindowsize,
NULL,//&UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod,
NULL,
NULL,
NULL,
(LTE_MBSFN_SubframeConfigList_t *)NULL,0,
(sib1_MBMS->systemInformationBlockType13_r14==NULL?(LTE_MBSFN_AreaInfoList_r9_t *)NULL:&(sib1_MBMS->systemInformationBlockType13_r14)->mbsfn_AreaInfoList_r9),//(LTE_MBSFN_AreaInfoList_r9_t *)NULL,
(LTE_PMCH_InfoList_r9_t *)NULL,
0,
NULL,
NULL,
0,
(sib1_MBMS->nonMBSFN_SubframeConfig_r14==NULL?(struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL:sib1_MBMS->nonMBSFN_SubframeConfig_r14),//(struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL
);
LOG_I(RRC,"Setting SIStatus bit 0 to 1\n");
UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus_MBMS = 1;
UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIB1systemInfoValueTag_MBMS = sib1_MBMS->systemInfoValueTag_r14;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_OUT );
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 );
const int n = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.count;
for (int i = 0; i < n; ++i) {
LTE_PLMN_Identity_t *PLMN_identity = &sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[i]->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 %d MCC %0*d, MNC %0*d\n", i + 1, mccdigits, mcc, mncdigits, mnc);
// search internal table for provider name
const size_t num_plmn_data = sizeof(plmn_data) / sizeof(plmn_data[0]);
for (size_t plmn_ind = 0;; ++plmn_ind) {
if (plmn_ind == num_plmn_data) {
LOG_W( RRC, "Did not find operator name from internal table for MCC %0*d, MNC %0*d\n",
mccdigits, mcc, mncdigits, mnc);
break;
}
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;
}
}
}
LOG_I( RRC, "TAC 0x%04x\n",
((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) );
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,8)] );
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 );
/* pointers to SIperiod inthe Info struct points to a packed structure
* Using these possibly unaligned pointers in a function call may trigger alignment errors at run time and
* gcc, from v9, now warns about it. fix these warnings by removing the indirection on data
* Not sure if SiPeriod can be modified, reassign after function call for security
*/
uint16_t Aligned_SIperiod = UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod;
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,
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,
&Aligned_SIperiod,
NULL,
NULL,
NULL,
(LTE_MBSFN_SubframeConfigList_t *)NULL,0,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL,
(LTE_PMCH_InfoList_r9_t *)NULL,
0,
NULL,
NULL,
0,
(struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL
);
UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod=Aligned_SIperiod;
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 (!IS_SOFTMODEM_NOS1) {
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, 0, 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;
UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity = plmn + 1;
break;
}
}
}
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, 0, 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 "
"(selected_plmn_identity %d), the message PHY_FIND_NEXT_CELL_REQ "
"is sent but lost in current UE implementation!\n",
UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity);
}
}
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 );
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 (sib2->lateNonCriticalExtension) {
LOG_I( RRC, "lateNonCriticalExtension : %p\n", sib2->lateNonCriticalExtension );
} else
LOG_I( RRC, "lateNonCriticalExtension : not defined\n" );
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" );
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" );
}
//-----------------------------------------------------------------------------
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 (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);
}
}
}
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
}
}
}
//-----------------------------------------------------------------------------
int decode_SI_MBMS( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) {
return 0;
}
//-----------------------------------------------------------------------------
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 ||
(*si)->criticalExtensions.present == LTE_SystemInformation__criticalExtensions_PR_criticalExtensionsFuture_r15) {
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,
(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,
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,0,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL,
(LTE_PMCH_InfoList_r9_t *)NULL,
0,
NULL,
NULL,
0,
(struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL
);
// After SI is received, prepare RRCConnectionRequest
if (UE_rrc_inst[ctxt_pP->module_id].MBMS_flag < 3) // see -Q option
if (!IS_SOFTMODEM_NOS1) {
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, 0, 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
}
}else{
//LOG_W( RRC, "[UE %d] Received new SIB1/SIB2/SIB3 with MBMSs %d\n", ctxt_pP->module_id, ((&typeandinfo->choice.sib2)->mbsfn_SubframeConfigList == NULL ? 0:1) );
if((&typeandinfo->choice.sib2)->mbsfn_SubframeConfigList != NULL && (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&4096) == 0){
LOG_W( RRC, "[UE %d] Received SIB2 with MBSFN SF Config\n", ctxt_pP->module_id );
memcpy( UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index], &typeandinfo->choice.sib2, sizeof(LTE_SystemInformationBlockType2_t) );
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,
(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,
UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->mbsfn_SubframeConfigList
,0,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL,
(LTE_PMCH_InfoList_r9_t *)NULL,
#ifdef CBA
0,0,
#endif
0,
NULL,
NULL,
0,
(struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL
);
}
}
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;
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,
0,
NULL,
NULL,
0,
(struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL
);
}
break;
//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;
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);
}
}
//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[RRC_BUF_SIZE];
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;
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 (int 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_I(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_I(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_I(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);
ssize_t size = do_MeasurementReport(ctxt_pP->module_id, buffer, sizeof(buffer),
measId, targetCellId, rsrp_s, rsrq_s, rsrp_t, rsrq_t);
AssertFatal(size >= 0, "do_MeasurementReport failed \n");
LOG_I(RRC, "[UE %d] Frame %d : Generating Measurement Report for eNB %d. Size is %zu\n",
ctxt_pP->module_id, ctxt_pP->frame, eNB_index, size);
const bool result = pdcp_data_req(ctxt_pP, SRB_FLAG_YES, DCCH, rrc_mui++, 0, size, buffer, PDCP_TRANSMISSION_MODE_DATA,NULL, NULL);
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;
UE_RRC_INST *ue = &UE_rrc_inst[ctxt_pP->module_id];
for(i=0 ; i<NB_CNX_UE ; i++) {
for(j=0 ; j<MAX_MEAS_ID ; j++) {
if(ue->MeasId[i][j] != NULL) {
measObjId = ue->MeasId[i][j]->measObjectId;
reportConfigId = ue->MeasId[i][j]->reportConfigId;
if(ue->MeasObj[i][measObjId-1] != NULL) {
if(ue->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->ReportConfig[i][reportConfigId-1]);
if((ue->ReportConfig[i][reportConfigId-1] != NULL) &&
(ue->ReportConfig[i][reportConfigId-1]->reportConfig.present == LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA) &&
(ue->ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.present ==
LTE_ReportConfigEUTRA__triggerType_PR_event)) {
hys = ue->ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis;
ttt_ms = timeToTrigger_ms[ue->ReportConfig[i][reportConfigId
-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger];
// Freq specific offset of neighbor cell freq
ofn = 5;//((ue->MeasObj[i][measObjId-1]->measObject.choice.measObjectEUTRA.offsetFreq != NULL) ?
// *ue->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->ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset;
switch (ue->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->Info[0].State >= RRC_CONNECTED) &&
(ue->Info[0].T304_active == 0 ) &&
(ue->HandoverInfoUe.measFlag == 1)) {
//trigger measurement reporting procedure (36.331, section 5.5.5)
if (ue->measReportList[i][j] == NULL) {
ue->measReportList[i][j] = malloc(sizeof(MEAS_REPORT_LIST));
}
ue->measReportList[i][j]->measId = ue->MeasId[i][j]->measId;
ue->measReportList[i][j]->numberOfReportsSent = 0;
rrc_ue_generate_MeasurementReport(
ctxt_pP,
eNB_index);
ue->HandoverInfoUe.measFlag = 1;
} else {
if(ue->measReportList[i][j] != NULL) {
free(ue->measReportList[i][j]);
}
ue->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->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) ttt(%ld) rssi %3.1f\n",
ue_mod_idP,
ofn,ocn,hys,ofs,ocs,ttt,
10*log10(get_RSSI(ue_mod_idP,0))-get_rx_total_gain_dB(ue_mod_idP,0));
LOG_D(RRC, "[UE %d] Frame %d: num_adj: %d eNB_idx: %d, NB_eNB_INST: %d\n",
ue_mod_idP, frameP, get_n_adj_cells(ue_mod_idP,0), eNB_index, NB_eNB_INST);
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;
}
//-----------------------------------------------------------------------------
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 if(1/*UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State >= RRC_CONNECTED*/ /*|| UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State == RRC_RECONFIGURED*/){
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);
}
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);
}
}else if(mcch->message.present == LTE_MCCH_MessageType_PR_later){
LOG_D(RRC,"[UE %d] Found mcch message \n",
ctxt_pP->module_id);
if(mcch->message.choice.later.present == LTE_MCCH_MessageType__later_PR_c2){
if(mcch->message.choice.later.choice.c2.present == LTE_MCCH_MessageType__later__c2_PR_mbmsCountingRequest_r10){
LOG_I(RRC,"[UE %d] Frame %d : Found MBMSCountingRequest from eNB %d %p\n",
ctxt_pP->module_id,
ctxt_pP->frame,
eNB_index,&mcch->message.choice.later.choice.c2.choice.mbmsCountingRequest_r10);
rrc_ue_process_MBMSCountingRequest(ctxt_pP,&mcch->message.choice.later.choice.c2.choice.mbmsCountingRequest_r10,eNB_index);
decode_MBMSCountingRequest(
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)\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_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,
(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,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL,
&UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->pmch_InfoList_r9,
0,
NULL,
NULL,
0,
(struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL
);
if(1/*UE_rrc_inst[ue_mod_idP].Info[eNB_index].State >= RRC_CONNECTED*/ /*|| UE_rrc_inst[ue_mod_idP].Info[eNB_index].State == RRC_RECONFIGURED*/)
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
&(UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->pmch_InfoList_r9),
NULL
);
rrc_rlc_config_asn1_req(&ctxt,
NULL,// SRB_ToAddModList
NULL,// DRB_ToAddModList
NULL,// DRB_ToReleaseList
&(UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->pmch_InfoList_r9), 0, 0
);
// */
}
void decode_MBMSCountingRequest( 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;
}
//-----------------------------------------------------------------------------
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_DESTINATION_INSTANCE (msg_p);
ue_mod_id = UE_INSTANCE_TO_MODULE_ID(instance);
/* TODO: Add case to handle nr-UE messages we want from nrUE RRC layer */
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_BCCH_MBMS_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_MBMS_DATA_IND (msg_p).frame, RRC_MAC_BCCH_MBMS_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_MBMS_DATA_IND (msg_p).frame, 0,RRC_MAC_BCCH_MBMS_DATA_IND (msg_p).enb_index);
decode_BCCH_MBMS_DLSCH_Message (&ctxt,
RRC_MAC_BCCH_MBMS_DATA_IND (msg_p).enb_index,
RRC_MAC_BCCH_MBMS_DATA_IND (msg_p).sdu,
RRC_MAC_BCCH_MBMS_DATA_IND (msg_p).sdu_size,
RRC_MAC_BCCH_MBMS_DATA_IND (msg_p).rsrq,
RRC_MAC_BCCH_MBMS_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;
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;
*/
/* 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).sdu_size,
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 RRC_DCCH_DATA_COPY_IND:
{
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, RRC_DCCH_DATA_COPY_IND (msg_p).module_id,
ENB_FLAG_NO, RRC_DCCH_DATA_COPY_IND (msg_p).rnti,
RRC_DCCH_DATA_COPY_IND (msg_p).frame,
0,
RRC_DCCH_DATA_COPY_IND (msg_p).eNB_index);
LOG_I(RRC, "[UE %d] Received %s. Now calling rrc_ue_process_ueCapabilityEnquiry\n",
ue_mod_id, ITTI_MSG_NAME (msg_p));
rrc_dcch_data_copy_t *dl_dcch_buffer = (void *)RRC_DCCH_DATA_COPY_IND (msg_p).sdu_p;
AssertFatal(RRC_DCCH_DATA_COPY_IND (msg_p).sdu_size == sizeof(*dl_dcch_buffer), "Size of dl_dcch_buffer incorrect\n");
rrc_ue_process_ueCapabilityEnquiry(
&ctxt,
&dl_dcch_buffer->dl_dcch_msg->message.choice.c1.choice.ueCapabilityEnquiry,
RRC_DCCH_DATA_COPY_IND (msg_p).eNB_index);
SEQUENCE_free(&asn_DEF_LTE_DL_DCCH_Message, dl_dcch_buffer->dl_dcch_msg, ASFM_FREE_EVERYTHING);
result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), RRC_DCCH_DATA_COPY_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, 0, 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.nas_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, 0, 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, 0, 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, 0, 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;
}
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;
}
/* 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);
} 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;
}
}
}
}
//-----------------------------------------------------------
void rrc_control_socket_init() {
struct sockaddr_in rrc_ctrl_socket_addr;
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);
}
pthread_t rrc_control_socket_thread;
threadCreate(&rrc_control_socket_thread, rrc_control_socket_thread_fct, NULL, "RRC/ProSeApp", -1, OAI_PRIORITY_RT);
}
//--------------------------------------------------------
void *rrc_control_socket_thread_fct(void *arg) {
//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)
//int enable_notification = 1;
while (1) {
LOG_I(RRC,"Listening to incoming connection from ProSe App \n");
// receive a message from ProSe App
char receive_buf[MAX_MESSAGE_SIZE];
memset(receive_buf, 0, sizeof(receive_buf));
socklen_t prose_addr_len = sizeof(prose_app_addr);
n = recvfrom(ctrl_sock_fd, receive_buf, sizeof(receive_buf), MSG_TRUNC,
(struct sockaddr *) &prose_app_addr, &prose_addr_len);
if (n < 0) {
LOG_E(RRC, "ERROR: Failed to receive from ProSe App\n");
exit(EXIT_FAILURE);
}
if (n == 0) {
LOG_E(RRC, "%s(%d). EOF for ctrl_sock_fd\n", __FUNCTION__, __LINE__);
}
if (n > MAX_MESSAGE_SIZE) {
LOG_E(RRC, "%s(%d). Message truncated. %d\n", __FUNCTION__, __LINE__, 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
char send_buf[MAX_MESSAGE_SIZE];
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, MAX_MESSAGE_SIZE);
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);
n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0,
(struct sockaddr *)&prose_app_addr, sizeof(prose_app_addr));
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( &notification_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));
asn1cSeqAdd(&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,
(LTE_PMCH_InfoList_r9_t *) NULL
,NULL);
rrc_rlc_config_asn1_req(&ctxt,
(LTE_SRB_ToAddModList_t *)NULL,
UE->DRB_configList,
(LTE_DRB_ToReleaseList_t *)NULL,
(LTE_PMCH_InfoList_r9_t *)NULL
, 0, 0
);
rrc_rlc_config_asn1_req(&ctxt,
(LTE_SRB_ToAddModList_t *)NULL,
UE->DRB_configList,
(LTE_DRB_ToReleaseList_t *)NULL,
(LTE_PMCH_InfoList_r9_t *)NULL,
sourceL2Id, groupL2Id
);
//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,
(LTE_SCellToAddMod_r10_t *)NULL,
(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,0,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL,
(LTE_PMCH_InfoList_r9_t *)NULL,
CONFIG_ACTION_ADD,
&sourceL2Id,
&groupL2Id,
0,
(struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL
);
LOG_I(RRC,"Send GroupCommunicationEstablishResp to ProSe App\n");
memset(send_buf, 0, MAX_MESSAGE_SIZE);
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);
n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0,
(struct sockaddr *)&prose_app_addr, sizeof(prose_app_addr));
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,
(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,
NULL,0,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL,
(LTE_PMCH_InfoList_r9_t *)NULL
,CONFIG_ACTION_REMOVE,
&sourceL2Id,
&destinationL2Id,
0,
(struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL
);
LOG_I(RRC,"Send GroupCommunicationReleaseResponse to ProSe App \n");
memset(send_buf, 0, MAX_MESSAGE_SIZE);
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);
n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0,
(struct sockaddr *)&prose_app_addr, sizeof(prose_app_addr));
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));
asn1cSeqAdd(&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,
(LTE_PMCH_InfoList_r9_t *) NULL,NULL);
rrc_rlc_config_asn1_req(&ctxt,
(LTE_SRB_ToAddModList_t *)NULL,
UE->DRB_configList,
(LTE_DRB_ToReleaseList_t *)NULL,
(LTE_PMCH_InfoList_r9_t *)NULL
, 0, 0
);
rrc_rlc_config_asn1_req(&ctxt,
(LTE_SRB_ToAddModList_t *)NULL,
UE->DRB_configList,
(LTE_DRB_ToReleaseList_t *)NULL,
(LTE_PMCH_InfoList_r9_t *)NULL
, sourceL2Id, destinationL2Id
);
//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,
(LTE_SCellToAddMod_r10_t *)NULL,
(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,0,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL,
(LTE_PMCH_InfoList_r9_t *)NULL,
CONFIG_ACTION_ADD,
&sourceL2Id,
&destinationL2Id,
0,
(struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL
);
LOG_I(RRC,"Send DirectCommunicationEstablishResp to ProSe App\n");
memset(send_buf, 0, MAX_MESSAGE_SIZE);
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);
n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0,
(struct sockaddr *)&prose_app_addr, sizeof(prose_app_addr));
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));
asn1cSeqAdd(&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,
(LTE_PMCH_InfoList_r9_t *) NULL,NULL);
rrc_rlc_config_asn1_req(&ctxt,
(LTE_SRB_ToAddModList_t *)NULL,
UE->DRB_configList,
(LTE_DRB_ToReleaseList_t *)NULL,
(LTE_PMCH_InfoList_r9_t *)NULL, 0, 0
);
//TX
if (type > 0) {
rrc_rlc_config_asn1_req(&ctxt,
(LTE_SRB_ToAddModList_t *)NULL,
UE->DRB_configList,
(LTE_DRB_ToReleaseList_t *)NULL,
(LTE_PMCH_InfoList_r9_t *)NULL,
sourceL2Id, destinationL2Id
);
//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,
(LTE_SCellToAddMod_r10_t *)NULL,
(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,
0,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL,
(LTE_PMCH_InfoList_r9_t *)NULL,
CONFIG_ACTION_ADD,
&sourceL2Id,
&destinationL2Id,
0,
(struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL
);
} 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,
(LTE_SCellToAddMod_r10_t *)NULL,
(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,0,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL,
(LTE_PMCH_InfoList_r9_t *)NULL,
CONFIG_ACTION_ADD,
&sourceL2Id,
NULL,
0,
(struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL
);
}
LOG_I(RRC,"Send PC5EstablishRsp to ProSe App\n");
memset(send_buf, 0, MAX_MESSAGE_SIZE);
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));
n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0,
(struct sockaddr *)&prose_app_addr, sizeof(prose_app_addr));
// 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) {
char send_buf[MAX_MESSAGE_SIZE];
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)
//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, MAX_MESSAGE_SIZE);
//send to ProSeApp
memcpy((void *)send_buf, (void *)Sdu, Sdu_len);
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);
n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0,
(struct sockaddr *)&prose_app_addr, sizeof(prose_app_addr));
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);
}
//-----------------------------------------------------------------------------
RRC_status_t
rrc_rx_tx_ue(
protocol_ctxt_t *const ctxt_pP,
const uint8_t enb_indexP,
const int CC_id
)
//-----------------------------------------------------------------------------
{
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);
}