5996 lines
306 KiB
C
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( ¬ification_thread , NULL , send_UE_status_notification , (void*) &sockfd) < 0)
|
|
error("ERROR: could not create thread");
|
|
}
|
|
enable_notification = 0;
|
|
*/
|
|
break;
|
|
|
|
case GROUP_COMMUNICATION_ESTABLISH_REQ:
|
|
sourceL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.sourceL2Id;
|
|
groupL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupL2Id;
|
|
|
|
if (LOG_DEBUGFLAG(DEBUG_CTRLSOCKET)) {
|
|
LOG_UI(RRC,"[GroupCommunicationEstablishReq] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type);
|
|
LOG_UI(RRC,"[GroupCommunicationEstablishReq] source Id: 0x%08x\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.sourceL2Id);
|
|
LOG_UI(RRC,"[GroupCommunicationEstablishReq] group Id: 0x%08x\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupL2Id);
|
|
LOG_UI(RRC,"[GroupCommunicationEstablishReq] group IP Address: " IPV4_ADDR "\n",IPV4_ADDR_FORMAT(sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupIpAddress));
|
|
}
|
|
|
|
//store sourceL2Id/groupL2Id
|
|
UE_rrc_inst[module_id].sourceL2Id = sourceL2Id;
|
|
UE_rrc_inst[module_id].groupL2Id = groupL2Id;
|
|
j = 0;
|
|
i = 0;
|
|
|
|
for (i=0; i< MAX_NUM_DEST; i++) {
|
|
if ((UE_rrc_inst[module_id].destinationList[i] == 0) && (j == 0)) j = i+1;
|
|
|
|
if (UE_rrc_inst[module_id].destinationList[i] == groupL2Id) break; //group already exists!
|
|
}
|
|
|
|
if ((i == MAX_NUM_DEST) && (j > 0)) UE_mac_inst[module_id].destinationList[j-1] = groupL2Id;
|
|
|
|
// configure lower layers PDCP/MAC/PHY for this communication
|
|
//Establish a new RBID/LCID for this communication
|
|
// Establish a SLRB (using DRB 3 for now)
|
|
UE = &UE_rrc_inst[module_id];
|
|
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0);
|
|
UE->DRB_config[0][0] = CALLOC(1,sizeof(struct LTE_DRB_ToAddMod));
|
|
UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long));
|
|
UE->DRB_config[0][0]->drb_Identity = 3;
|
|
UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long));
|
|
// allowed value 5..15, value : x+4
|
|
*(UE->DRB_config[0][0]->eps_BearerIdentity) = 3;
|
|
UE->DRB_config[0][0]->logicalChannelIdentity = CALLOC(1, sizeof(long));
|
|
*(UE->DRB_config[0][0]->logicalChannelIdentity) = UE->DRB_config[0][0]->drb_Identity; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2
|
|
DRB_rlc_config = CALLOC(1,sizeof(struct LTE_RLC_Config));
|
|
DRB_pdcp_config = CALLOC(1,sizeof(struct LTE_PDCP_Config));
|
|
PDCP_rlc_UM = CALLOC(1,sizeof(struct LTE_PDCP_Config__rlc_UM));
|
|
DRB_lchan_config = CALLOC(1,sizeof(struct LTE_LogicalChannelConfig));
|
|
DRB_ul_SpecificParameters = CALLOC(1, sizeof(struct LTE_LogicalChannelConfig__ul_SpecificParameters));
|
|
logicalchannelgroup_drb = CALLOC(1, sizeof(long));
|
|
DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional;
|
|
DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10;
|
|
DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10;
|
|
DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35;
|
|
UE->DRB_config[0][0]->rlc_Config = DRB_rlc_config;
|
|
DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config));
|
|
UE->DRB_config[0][0]->pdcp_Config = DRB_pdcp_config;
|
|
DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long));
|
|
*DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity;
|
|
DRB_pdcp_config->rlc_AM = NULL;
|
|
DRB_pdcp_config->rlc_UM = NULL;
|
|
/* avoid gcc warnings */
|
|
(void)PDCP_rlc_UM;
|
|
DRB_pdcp_config->rlc_UM = PDCP_rlc_UM;
|
|
PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits;
|
|
DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed;
|
|
UE->DRB_config[0][0]->logicalChannelConfig = DRB_lchan_config;
|
|
DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters));
|
|
DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters;
|
|
DRB_ul_SpecificParameters->priority = 12; // lower priority than srb1, srb2 and other dedicated bearer
|
|
DRB_ul_SpecificParameters->prioritisedBitRate =LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ;
|
|
//LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
|
|
DRB_ul_SpecificParameters->bucketSizeDuration =
|
|
LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
|
|
// LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM)
|
|
*logicalchannelgroup_drb = 1;
|
|
DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb;
|
|
UE->DRB_configList = CALLOC(1,sizeof(LTE_DRB_ToAddModList_t));
|
|
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);
|
|
}
|