- Reorganized ITTI messages definition by groups (MAC, PDCP and RRC). - Added support for some NAS / S1AP messages. S1AP: - Corrected MME selection in handle NAS first request. - Modified some messages definition. git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4429 818b1a75-f10b-46b9-bf7c-635c3b92a50f
2380 lines
102 KiB
C
2380 lines
102 KiB
C
/*******************************************************************************
|
|
|
|
Eurecom OpenAirInterface 2
|
|
Copyright(c) 1999 - 2010 Eurecom
|
|
|
|
This program is free software; you can redistribute it and/or modify it
|
|
under the terms and conditions of the GNU General Public License,
|
|
version 2, as published by the Free Software Foundation.
|
|
|
|
This program is distributed in the hope it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
more details.
|
|
You should have received a copy of the GNU General Public License along with
|
|
this program; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
The full GNU General Public License is included in this distribution in
|
|
the file called "COPYING".
|
|
|
|
Contact Information
|
|
Openair Admin: openair_admin@eurecom.fr
|
|
Openair Tech : openair_tech@eurecom.fr
|
|
Forums : http://forums.eurecom.fsr/openairinterface
|
|
Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
|
|
|
|
*******************************************************************************/
|
|
|
|
/*! \file rrc_UE.c
|
|
* \brief rrc procedures for UE
|
|
* \author Raymond Knopp and Navid Nikaein
|
|
* \date 2011
|
|
* \version 1.0
|
|
* \company Eurecom
|
|
* \email: raymond.knopp@eurecom.fr and navid.nikaein@eurecom.fr
|
|
*/
|
|
|
|
|
|
#include "defs.h"
|
|
#include "PHY/TOOLS/dB_routines.h"
|
|
#include "extern.h"
|
|
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
|
|
#include "LAYER2/RLC/rlc.h"
|
|
#include "COMMON/mac_rrc_primitives.h"
|
|
#include "UTIL/LOG/log.h"
|
|
#include "UTIL/LOG/vcd_signal_dumper.h"
|
|
#ifndef CELLULAR
|
|
#include "RRC/LITE/MESSAGES/asn1_msg.h"
|
|
#endif
|
|
#include "RRCConnectionRequest.h"
|
|
#include "RRCConnectionReconfiguration.h"
|
|
#include "UL-CCCH-Message.h"
|
|
#include "DL-CCCH-Message.h"
|
|
#include "UL-DCCH-Message.h"
|
|
#include "DL-DCCH-Message.h"
|
|
#include "BCCH-DL-SCH-Message.h"
|
|
#ifdef Rel10
|
|
#include "MCCH-Message.h"
|
|
#endif
|
|
#include "MeasConfig.h"
|
|
#include "MeasGapConfig.h"
|
|
#include "MeasObjectEUTRA.h"
|
|
#include "TDD-Config.h"
|
|
#include "UECapabilityEnquiry.h"
|
|
#include "UE-CapabilityRequest.h"
|
|
#ifdef PHY_ABSTRACTION
|
|
#include "OCG.h"
|
|
#include "OCG_extern.h"
|
|
#endif
|
|
#ifdef USER_MODE
|
|
#include "RRC/NAS/nas_config.h"
|
|
#include "RRC/NAS/rb_config.h"
|
|
#endif
|
|
|
|
#if defined(ENABLE_SECURITY)
|
|
# include "UTIL/OSA/osa_defs.h"
|
|
#endif
|
|
|
|
#include "pdcp.h"
|
|
|
|
#if defined(ENABLE_ITTI)
|
|
# include "intertask_interface.h"
|
|
#endif
|
|
|
|
#ifdef PHY_EMUL
|
|
extern EMULATION_VARS *Emul_vars;
|
|
#endif
|
|
extern eNB_MAC_INST *eNB_mac_inst;
|
|
extern UE_MAC_INST *UE_mac_inst;
|
|
#ifdef BIGPHYSAREA
|
|
extern void *bigphys_malloc(int);
|
|
#endif
|
|
|
|
//#define XER_PRINT
|
|
|
|
extern inline unsigned int taus(void);
|
|
extern s8 dB_fixed2(u32 x,u32 y);
|
|
|
|
void init_SI_UE(u8 Mod_id,u8 eNB_index) {
|
|
|
|
int i;
|
|
|
|
|
|
UE_rrc_inst[Mod_id].sizeof_SIB1[eNB_index] = 0;
|
|
UE_rrc_inst[Mod_id].sizeof_SI[eNB_index] = 0;
|
|
|
|
UE_rrc_inst[Mod_id].SIB1[eNB_index] = (u8 *)malloc16(32);
|
|
UE_rrc_inst[Mod_id].sib1[eNB_index] = (SystemInformationBlockType1_t *)malloc16(sizeof(SystemInformationBlockType1_t));
|
|
UE_rrc_inst[Mod_id].SI[eNB_index] = (u8 *)malloc16(64);
|
|
|
|
for (i=0;i<NB_CNX_UE;i++) {
|
|
UE_rrc_inst[Mod_id].si[eNB_index][i] = (SystemInformation_t *)malloc16(sizeof(SystemInformation_t));
|
|
}
|
|
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].SIB1Status = 0;
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].SIStatus = 0;
|
|
|
|
|
|
}
|
|
|
|
#ifdef Rel10
|
|
void init_MCCH_UE(u8 Mod_id, u8 eNB_index) {
|
|
int i;
|
|
UE_rrc_inst[Mod_id].sizeof_MCCH_MESSAGE[eNB_index] = 0;
|
|
UE_rrc_inst[Mod_id].MCCH_MESSAGE[eNB_index] = (u8 *)malloc16(32);
|
|
UE_rrc_inst[Mod_id].mcch_message[eNB_index] = (MBSFNAreaConfiguration_r9_t *)malloc16(sizeof(MBSFNAreaConfiguration_r9_t));
|
|
for (i=0; i<8;i++) // MAX MBSFN Area
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].MCCHStatus[i] = 0;
|
|
|
|
}
|
|
#endif
|
|
|
|
static
|
|
void openair_rrc_lite_ue_init_security(u8 Mod_id)
|
|
{
|
|
#if defined(ENABLE_SECURITY)
|
|
uint8_t *kRRCenc;
|
|
uint8_t *kRRCint;
|
|
char ascii_buffer[65];
|
|
uint8_t i;
|
|
|
|
memset(UE_rrc_inst[Mod_id].kenb, Mod_id, 32);
|
|
|
|
for (i = 0; i < 32; i++) {
|
|
sprintf(&ascii_buffer[2 * i], "%02X", UE_rrc_inst[Mod_id].kenb[i]);
|
|
}
|
|
|
|
LOG_T(RRC, "[OSA][UE %02d] kenb = %s\n",
|
|
Mod_id, ascii_buffer);
|
|
#endif
|
|
}
|
|
|
|
/*------------------------------------------------------------------------------*/
|
|
char openair_rrc_lite_ue_init(u8 Mod_id, unsigned char eNB_index){
|
|
/*-----------------------------------------------------------------------------*/
|
|
LOG_D(RRC,"[UE %d] INIT State = RRC_IDLE (eNB %d)\n",Mod_id,eNB_index);
|
|
LOG_D(RRC,"[MSC_NEW][FRAME 00000][RRC_UE][MOD %02d][]\n", Mod_id+NB_eNB_INST);
|
|
LOG_D(RRC, "[MSC_NEW][FRAME 00000][IP][MOD %02d][]\n", Mod_id+NB_eNB_INST);
|
|
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].State=RRC_IDLE;
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].T300_active = 0;
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].T304_active = 0;
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].T310_active = 0;
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].UE_index=0xffff;
|
|
UE_rrc_inst[Mod_id].Srb0[eNB_index].Active=0;
|
|
UE_rrc_inst[Mod_id].Srb1[eNB_index].Active=0;
|
|
UE_rrc_inst[Mod_id].Srb2[eNB_index].Active=0;
|
|
UE_rrc_inst[Mod_id].HandoverInfoUe.measFlag=1;
|
|
|
|
UE_rrc_inst[Mod_id].ciphering_algorithm = SecurityAlgorithmConfig__cipheringAlgorithm_eea0;
|
|
#ifdef Rel10
|
|
UE_rrc_inst[Mod_id].integrity_algorithm = SecurityAlgorithmConfig__integrityProtAlgorithm_eia0_v920;
|
|
#else
|
|
UE_rrc_inst[Mod_id].integrity_algorithm = SecurityAlgorithmConfig__integrityProtAlgorithm_reserved;
|
|
#endif
|
|
|
|
openair_rrc_lite_ue_init_security(Mod_id);
|
|
|
|
init_SI_UE(Mod_id,eNB_index);
|
|
LOG_D(RRC,"[UE %d] INIT: phy_sync_2_ch_ind\n", Mod_id);
|
|
|
|
#ifndef NO_RRM
|
|
send_msg(&S_rrc,msg_rrc_phy_synch_to_CH_ind(Mod_id,eNB_index,UE_rrc_inst[Mod_id].Mac_id));
|
|
#endif
|
|
|
|
#ifdef NO_RRM //init ch SRB0, SRB1 & BDTCH
|
|
openair_rrc_on(Mod_id,0);
|
|
#endif
|
|
#ifdef CBA
|
|
int j;
|
|
for(j=0; j<NUM_MAX_CBA_GROUP; j++)
|
|
UE_rrc_inst[Mod_id].cba_rnti[j] = 0x0000;
|
|
UE_rrc_inst[Mod_id].num_active_cba_groups = 0;
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*------------------------------------------------------------------------------*/
|
|
void rrc_ue_generate_RRCConnectionRequest(u8 Mod_id, u32 frame, u8 eNB_index){
|
|
/*------------------------------------------------------------------------------*/
|
|
|
|
u8 i=0,rv[6];
|
|
|
|
if(UE_rrc_inst[Mod_id].Srb0[eNB_index].Tx_buffer.payload_size ==0){
|
|
|
|
// Get RRCConnectionRequest, fill random for now
|
|
// Generate random byte stream for contention resolution
|
|
for (i=0;i<6;i++) {
|
|
#ifdef SMBV
|
|
// if SMBV is configured the contention resolution needs to be fix for the connection procedure to succeed
|
|
rv[i]=i;
|
|
#else
|
|
rv[i]=taus()&0xff;
|
|
#endif
|
|
LOG_T(RRC,"%x.",rv[i]);
|
|
}
|
|
LOG_T(RRC,"\n");
|
|
UE_rrc_inst[Mod_id].Srb0[eNB_index].Tx_buffer.payload_size = do_RRCConnectionRequest((u8 *)UE_rrc_inst[Mod_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",
|
|
Mod_id, frame, UE_rrc_inst[Mod_id].Srb0[eNB_index].Tx_buffer.payload_size, eNB_index);
|
|
|
|
for (i=0;i<UE_rrc_inst[Mod_id].Srb0[eNB_index].Tx_buffer.payload_size;i++) {
|
|
LOG_T(RRC,"%x.",UE_rrc_inst[Mod_id].Srb0[eNB_index].Tx_buffer.Payload[i]);
|
|
}
|
|
LOG_T(RRC,"\n");
|
|
/*
|
|
UE_rrc_inst[Mod_id].Srb0[Idx].Tx_buffer.Payload[i] = taus()&0xff;
|
|
|
|
UE_rrc_inst[Mod_id].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,
|
|
};
|
|
|
|
/* NAS Attach request with GUTI */
|
|
static const char nas_attach_req_guti[] =
|
|
{
|
|
0x07, 0x41,
|
|
/* EPS Mobile identity = GUTI */
|
|
0x71, 0x0B, 0xF6, 0x12, 0xF2, 0x01, 0x80, 0x00, 0x01, 0xE0, 0x00,
|
|
0xDA, 0x1F,
|
|
/* 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_ue_generate_RRCConnectionSetupComplete(u8 Mod_id, u32 frame, u8 eNB_index){
|
|
/*------------------------------------------------------------------------------*/
|
|
|
|
u8 buffer[100];
|
|
u8 size;
|
|
|
|
size = do_RRCConnectionSetupComplete(buffer, sizeof(nas_attach_req_guti), nas_attach_req_guti);
|
|
|
|
LOG_I(RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCConnectionSetupComplete (bytes%d, eNB %d)\n",
|
|
Mod_id,frame, size, eNB_index);
|
|
|
|
LOG_D(RLC, "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCConnectionSetupComplete to eNB %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n",
|
|
frame, Mod_id+NB_eNB_INST, size, eNB_index, rrc_mui, Mod_id+NB_eNB_INST, DCCH);
|
|
|
|
// rrc_rlc_data_req(Mod_id+NB_eNB_INST,frame, 0 ,DCCH,rrc_mui++,0,size,(char*)buffer);
|
|
pdcp_rrc_data_req (Mod_id + NB_eNB_INST, frame, 0, DCCH, rrc_mui++, 0, size, buffer, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void rrc_ue_generate_RRCConnectionReconfigurationComplete(u8 Mod_id, u32 frame, u8 eNB_index) {
|
|
|
|
u8 buffer[32], size;
|
|
|
|
size = do_RRCConnectionReconfigurationComplete(buffer);
|
|
|
|
LOG_I(RRC,"[UE %d] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCConnectionReconfigurationComplete (bytes %d, eNB_index %d)\n",
|
|
Mod_id,frame, size, eNB_index);
|
|
LOG_D(RLC, "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCConnectionReconfigurationComplete to eNB %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n",
|
|
frame, Mod_id+NB_eNB_INST, size, eNB_index, rrc_mui, Mod_id+NB_eNB_INST, DCCH);
|
|
|
|
//rrc_rlc_data_req(Mod_id+NB_eNB_INST,frame, 0 ,DCCH,rrc_mui++,0,size,(char*)buffer);
|
|
pdcp_rrc_data_req (Mod_id + NB_eNB_INST, frame, 0, DCCH, rrc_mui++, 0, size, buffer, 1);
|
|
}
|
|
|
|
/*------------------------------------------------------------------------------*/
|
|
int rrc_ue_decode_ccch(u8 Mod_id, u32 frame, SRB_INFO *Srb_info, u8 eNB_index){
|
|
/*------------------------------------------------------------------------------*/
|
|
|
|
//DL_CCCH_Message_t dlccchmsg;
|
|
DL_CCCH_Message_t *dl_ccch_msg=NULL;//&dlccchmsg;
|
|
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);
|
|
|
|
//memset(dl_ccch_msg,0,sizeof(DL_CCCH_Message_t));
|
|
|
|
// LOG_D(RRC,"[UE %d] Decoding DL-CCCH message (%d bytes), State %d\n",Mod_id,Srb_info->Rx_buffer.payload_size,
|
|
// UE_rrc_inst[Mod_id].Info[eNB_index].State);
|
|
|
|
dec_rval = uper_decode(NULL,
|
|
&asn_DEF_DL_CCCH_Message,
|
|
(void**)&dl_ccch_msg,
|
|
(uint8_t*)Srb_info->Rx_buffer.Payload,
|
|
100,0,0);
|
|
|
|
#ifdef XER_PRINT
|
|
xer_fprint(stdout,&asn_DEF_DL_CCCH_Message,(void*)dl_ccch_msg);
|
|
#endif
|
|
|
|
#if defined(ENABLE_ITTI)
|
|
{
|
|
MessageDef *message_p;
|
|
|
|
message_p = itti_alloc_new_message (TASK_RRC_UE, RRC_DL_CCCH_MESSAGE);
|
|
memcpy (&message_p->msg, (void *) dl_ccch_msg, sizeof(RrcDlCcchMessage));
|
|
|
|
itti_send_msg_to_task (TASK_UNKNOWN, Mod_id + NB_eNB_INST, message_p);
|
|
}
|
|
#endif
|
|
|
|
if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) {
|
|
LOG_E(RRC,"[UE %d] Frame %d : Failed to decode DL-CCCH-Message (%d bytes)\n",Mod_id,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 == DL_CCCH_MessageType_PR_c1) {
|
|
|
|
if (UE_rrc_inst[Mod_id].Info[eNB_index].State == RRC_SI_RECEIVED) {
|
|
|
|
switch (dl_ccch_msg->message.choice.c1.present) {
|
|
|
|
case DL_CCCH_MessageType__c1_PR_NOTHING :
|
|
|
|
LOG_I(RRC,"[UE%d] Frame %d : Received PR_NOTHING on DL-CCCH-Message\n",Mod_id,frame);
|
|
rval= 0;
|
|
break;
|
|
case DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishment:
|
|
LOG_D(RRC, "[MSC_MSG][FRAME %05d][MAC_UE][MOD %02d][][--- MAC_DATA_IND (rrcConnectionReestablishment ENB %d) --->][RRC_UE][MOD %02d][]\n",
|
|
frame, Mod_id+NB_eNB_INST, eNB_index, Mod_id+NB_eNB_INST);
|
|
|
|
LOG_I(RRC,"[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReestablishment\n",Mod_id,frame);
|
|
rval= 0;
|
|
break;
|
|
case DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentReject:
|
|
LOG_D(RRC, "[MSC_MSG][FRAME %05d][MAC_UE][MOD %02d][][--- MAC_DATA_IND (RRCConnectionReestablishmentReject ENB %d) --->][RRC_UE][MOD %02d][]\n",
|
|
frame, Mod_id+NB_eNB_INST, eNB_index, Mod_id+NB_eNB_INST);
|
|
LOG_I(RRC,"[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReestablishmentReject\n",Mod_id,frame);
|
|
rval= 0;
|
|
break;
|
|
case DL_CCCH_MessageType__c1_PR_rrcConnectionReject:
|
|
LOG_D(RRC, "[MSC_MSG][FRAME %05d][MAC_UE][MOD %02d][][--- MAC_DATA_IND (rrcConnectionReject ENB %d) --->][RRC_UE][MOD %02d][]\n",
|
|
frame, Mod_id+NB_eNB_INST, eNB_index, Mod_id+NB_eNB_INST);
|
|
|
|
LOG_I(RRC,"[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReject \n",Mod_id,frame);
|
|
rval= 0;
|
|
break;
|
|
case DL_CCCH_MessageType__c1_PR_rrcConnectionSetup:
|
|
LOG_D(RRC, "[MSC_MSG][FRAME %05d][MAC_UE][MOD %02d][][--- MAC_DATA_IND (rrcConnectionSetup ENB %d) --->][RRC_UE][MOD %02d][]\n",
|
|
frame, Mod_id+NB_eNB_INST, eNB_index, Mod_id+NB_eNB_INST);
|
|
|
|
LOG_I(RRC,"[UE%d][RAPROC] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionSetup \n",Mod_id,frame);
|
|
// Get configuration
|
|
|
|
// Release T300 timer
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].T300_active=0;
|
|
rrc_ue_process_radioResourceConfigDedicated(Mod_id,frame,eNB_index,
|
|
&dl_ccch_msg->message.choice.c1.choice.rrcConnectionSetup.criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated);
|
|
|
|
rrc_ue_generate_RRCConnectionSetupComplete(Mod_id,frame, eNB_index);
|
|
|
|
rval= 0;
|
|
break;
|
|
default:
|
|
LOG_E(RRC,"[UE%d] Frame %d : Unknown message\n",Mod_id,frame);
|
|
rval= -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
|
|
return rval;
|
|
}
|
|
|
|
|
|
s32 rrc_ue_establish_srb1(u8 Mod_id,u32 frame,u8 eNB_index,
|
|
struct SRB_ToAddMod *SRB_config) { // add descriptor from RRC PDU
|
|
|
|
u8 lchan_id = DCCH;
|
|
|
|
UE_rrc_inst[Mod_id].Srb1[eNB_index].Active = 1;
|
|
UE_rrc_inst[Mod_id].Srb1[eNB_index].Status = RADIO_CONFIG_OK;//RADIO CFG
|
|
UE_rrc_inst[Mod_id].Srb1[eNB_index].Srb_info.Srb_id = 1;
|
|
|
|
// copy default configuration for now
|
|
// memcpy(&UE_rrc_inst[Mod_id].Srb1[eNB_index].Srb_info.Lchan_desc[0],&DCCH_LCHAN_DESC,LCHAN_DESC_SIZE);
|
|
// memcpy(&UE_rrc_inst[Mod_id].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", Mod_id,lchan_id,eNB_index);
|
|
|
|
//rrc_pdcp_config_req (Mod_id+NB_eNB_INST, frame, 0, ACTION_ADD, lchan_id,UNDEF_SECURITY_MODE);
|
|
// rrc_rlc_config_req(Mod_id+NB_eNB_INST,frame,0,ACTION_ADD,lchan_id,SIGNALLING_RADIO_BEARER,Rlc_info_am_config);
|
|
|
|
// UE_rrc_inst[Mod_id].Srb1[eNB_index].Srb_info.Tx_buffer.payload_size=DEFAULT_MEAS_IND_SIZE+1;
|
|
|
|
|
|
return(0);
|
|
}
|
|
|
|
s32 rrc_ue_establish_srb2(u8 Mod_id,u32 frame,u8 eNB_index,
|
|
struct SRB_ToAddMod *SRB_config) { // add descriptor from RRC PDU
|
|
|
|
u8 lchan_id = DCCH1;
|
|
|
|
UE_rrc_inst[Mod_id].Srb2[eNB_index].Active = 1;
|
|
UE_rrc_inst[Mod_id].Srb2[eNB_index].Status = RADIO_CONFIG_OK;//RADIO CFG
|
|
UE_rrc_inst[Mod_id].Srb2[eNB_index].Srb_info.Srb_id = 2;
|
|
|
|
// copy default configuration for now
|
|
// memcpy(&UE_rrc_inst[Mod_id].Srb2[eNB_index].Srb_info.Lchan_desc[0],&DCCH_LCHAN_DESC,LCHAN_DESC_SIZE);
|
|
// memcpy(&UE_rrc_inst[Mod_id].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",Mod_id,lchan_id,eNB_index);
|
|
|
|
//rrc_pdcp_config_req (Mod_id+NB_eNB_INST, frame, 0, ACTION_ADD, lchan_id, UNDEF_SECURITY_MODE);
|
|
// rrc_rlc_config_req(Mod_id+NB_eNB_INST,frame,0,ACTION_ADD,lchan_id,SIGNALLING_RADIO_BEARER,Rlc_info_am_config);
|
|
|
|
// UE_rrc_inst[Mod_id].Srb1[eNB_index].Srb_info.Tx_buffer.payload_size=DEFAULT_MEAS_IND_SIZE+1;
|
|
|
|
|
|
return(0);
|
|
}
|
|
|
|
s32 rrc_ue_establish_drb(u8 Mod_id,u32 frame,u8 eNB_index,
|
|
struct DRB_ToAddMod *DRB_config) { // add descriptor from RRC PDU
|
|
#ifdef NAS_NETLINK
|
|
int oip_ifup=0,ip_addr_offset3=0,ip_addr_offset4=0;
|
|
#endif
|
|
|
|
LOG_I(RRC,"[UE] Frame %d: processing RRCConnectionReconfiguration: reconfiguring DRB %ld/LCID %d\n",
|
|
frame,DRB_config->drb_Identity,(int)*DRB_config->logicalChannelIdentity);
|
|
/*
|
|
rrc_pdcp_config_req (Mod_id+NB_eNB_INST, frame, 0, ACTION_ADD,
|
|
(eNB_index * NB_RB_MAX) + *DRB_config->logicalChannelIdentity, UNDEF_SECURITY_MODE);
|
|
|
|
rrc_rlc_config_req(Mod_id+NB_eNB_INST,frame,0,ACTION_ADD,
|
|
(eNB_index * NB_RB_MAX) + *DRB_config->logicalChannelIdentity,
|
|
RADIO_ACCESS_BEARER,Rlc_info_um);
|
|
*/
|
|
#ifdef NAS_NETLINK
|
|
# ifdef OAI_EMU
|
|
ip_addr_offset3 = oai_emulation.info.nb_enb_local;
|
|
ip_addr_offset4 = NB_eNB_INST;
|
|
# else
|
|
ip_addr_offset3 = 0;
|
|
ip_addr_offset4 = 8;
|
|
# endif
|
|
# if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO)
|
|
LOG_I(OIP,"[UE %d] trying to bring up the OAI interface oai%d, IP 10.0.%d.%d\n", Mod_id, ip_addr_offset3+Mod_id,
|
|
ip_addr_offset3+Mod_id+1,ip_addr_offset4+Mod_id+1);
|
|
oip_ifup=nas_config(ip_addr_offset3+Mod_id, // interface_id
|
|
ip_addr_offset3+Mod_id+1, // third_octet
|
|
ip_addr_offset4+Mod_id+1); // fourth_octet
|
|
if (oip_ifup == 0 ){ // interface is up --> send a config the DRB
|
|
# ifdef OAI_EMU
|
|
oai_emulation.info.oai_ifup[Mod_id]=1;
|
|
# endif
|
|
LOG_I(OIP,"[UE %d] Config the oai%d to send/receive pkt on DRB %d to/from the protocol stack\n",
|
|
Mod_id,
|
|
ip_addr_offset3+Mod_id,
|
|
(eNB_index * NB_RB_MAX) + *DRB_config->logicalChannelIdentity);
|
|
|
|
rb_conf_ipv4(0,//add
|
|
Mod_id,//cx align with the UE index
|
|
ip_addr_offset3+Mod_id,//inst num_enb+ue_index
|
|
(eNB_index * NB_RB_MAX) + *DRB_config->logicalChannelIdentity,//rb
|
|
0,//dscp
|
|
ipv4_address(ip_addr_offset3+Mod_id+1,ip_addr_offset4+Mod_id+1),//saddr
|
|
ipv4_address(ip_addr_offset3+Mod_id+1,eNB_index+1));//daddr
|
|
LOG_D(RRC,"[UE %d] State = Attached (eNB %d)\n",Mod_id,eNB_index);
|
|
}
|
|
# else
|
|
# ifdef OAI_EMU
|
|
oai_emulation.info.oai_ifup[Mod_id]=1;
|
|
# endif
|
|
# endif
|
|
#endif
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
void rrc_ue_process_measConfig(u8 Mod_id,u32 frame, u8 eNB_index,MeasConfig_t *measConfig){
|
|
|
|
// This is the procedure described in 36.331 Section 5.5.2.1
|
|
int i;
|
|
long ind;
|
|
MeasObjectToAddMod_t *measObj;
|
|
|
|
if (measConfig->measObjectToRemoveList != NULL) {
|
|
for (i=0;i<measConfig->measObjectToRemoveList->list.count;i++) {
|
|
ind = *measConfig->measObjectToRemoveList->list.array[i];
|
|
free(UE_rrc_inst[Mod_id].MeasObj[eNB_index][ind-1]);
|
|
}
|
|
}
|
|
if (measConfig->measObjectToAddModList != NULL) {
|
|
LOG_D(RRC,"Measurement Object List is present\n");
|
|
for (i=0;i<measConfig->measObjectToAddModList->list.count;i++) {
|
|
measObj = measConfig->measObjectToAddModList->list.array[i];
|
|
ind = measConfig->measObjectToAddModList->list.array[i]->measObjectId;
|
|
|
|
if (UE_rrc_inst[Mod_id].MeasObj[eNB_index][ind-1]) {
|
|
LOG_D(RRC,"Modifying measurement object %d\n",ind);
|
|
memcpy((char*)UE_rrc_inst[Mod_id].MeasObj[eNB_index][ind-1],
|
|
(char*)measObj,
|
|
sizeof(MeasObjectToAddMod_t));
|
|
}
|
|
else {
|
|
LOG_I(RRC,"Adding measurement object %d\n",ind);
|
|
if (measObj->measObject.present == MeasObjectToAddMod__measObject_PR_measObjectEUTRA) {
|
|
LOG_I(RRC,"EUTRA Measurement : carrierFreq %d, allowedMeasBandwidth %d,presenceAntennaPort1 %d, neighCellConfig %d\n",
|
|
measObj->measObject.choice.measObjectEUTRA.carrierFreq,
|
|
measObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth,
|
|
measObj->measObject.choice.measObjectEUTRA.presenceAntennaPort1,
|
|
measObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf[0]);
|
|
UE_rrc_inst[Mod_id].MeasObj[eNB_index][ind-1]=measObj;
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
rrc_mac_config_req(Mod_id,0,0,eNB_index,
|
|
(RadioResourceConfigCommonSIB_t *)NULL,
|
|
(struct PhysicalConfigDedicated *)NULL,
|
|
UE_rrc_inst[Mod_id].MeasObj[eNB_index],
|
|
(MAC_MainConfig_t *)NULL,
|
|
0,
|
|
(struct LogicalChannelConfig *)NULL,
|
|
(MeasGapConfig_t *)NULL,
|
|
(TDD_Config_t *)NULL,
|
|
(MobilityControlInfo_t *)NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL
|
|
#ifdef Rel10
|
|
,
|
|
0,
|
|
(MBSFN_AreaInfoList_r9_t *)NULL,
|
|
(PMCH_InfoList_r9_t *)NULL
|
|
#endif
|
|
#ifdef CBA
|
|
,
|
|
0,
|
|
0
|
|
#endif
|
|
);
|
|
}
|
|
if (measConfig->reportConfigToRemoveList != NULL) {
|
|
for (i=0;i<measConfig->reportConfigToRemoveList->list.count;i++) {
|
|
ind = *measConfig->reportConfigToRemoveList->list.array[i];
|
|
free(UE_rrc_inst[Mod_id].ReportConfig[eNB_index][ind-1]);
|
|
}
|
|
}
|
|
if (measConfig->reportConfigToAddModList != NULL) {
|
|
LOG_I(RRC,"Report Configuration List is present\n");
|
|
for (i=0;i<measConfig->reportConfigToAddModList->list.count;i++) {
|
|
ind = measConfig->reportConfigToAddModList->list.array[i]->reportConfigId;
|
|
if (UE_rrc_inst[Mod_id].ReportConfig[eNB_index][ind-1]) {
|
|
LOG_I(RRC,"Modifying Report Configuration %d\n",ind-1);
|
|
memcpy((char*)UE_rrc_inst[Mod_id].ReportConfig[eNB_index][ind-1],
|
|
(char*)measConfig->reportConfigToAddModList->list.array[i],
|
|
sizeof(ReportConfigToAddMod_t));
|
|
}
|
|
else {
|
|
LOG_D(RRC,"Adding Report Configuration %d %p \n",ind-1,measConfig->reportConfigToAddModList->list.array[i]);
|
|
UE_rrc_inst[Mod_id].ReportConfig[eNB_index][ind-1] = measConfig->reportConfigToAddModList->list.array[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (measConfig->quantityConfig != NULL) {
|
|
if (UE_rrc_inst[Mod_id].QuantityConfig[eNB_index]) {
|
|
LOG_D(RRC,"Modifying Quantity Configuration \n");
|
|
memcpy((char*)UE_rrc_inst[Mod_id].QuantityConfig[eNB_index],
|
|
(char*)measConfig->quantityConfig,
|
|
sizeof(QuantityConfig_t));
|
|
}
|
|
else {
|
|
LOG_D(RRC,"Adding Quantity configuration\n");
|
|
UE_rrc_inst[Mod_id].QuantityConfig[eNB_index] = measConfig->quantityConfig;
|
|
}
|
|
}
|
|
|
|
if (measConfig->measIdToRemoveList != NULL) {
|
|
for (i=0;i<measConfig->measIdToRemoveList->list.count;i++) {
|
|
ind = *measConfig->measIdToRemoveList->list.array[i];
|
|
free(UE_rrc_inst[Mod_id].MeasId[eNB_index][ind-1]);
|
|
}
|
|
}
|
|
|
|
if (measConfig->measIdToAddModList != NULL) {
|
|
for (i=0;i<measConfig->measIdToAddModList->list.count;i++) {
|
|
ind = measConfig->measIdToAddModList->list.array[i]->measId;
|
|
if (UE_rrc_inst[Mod_id].MeasId[eNB_index][ind-1]) {
|
|
LOG_D(RRC,"Modifying Measurement ID %d\n",ind-1);
|
|
memcpy((char*)UE_rrc_inst[Mod_id].MeasId[eNB_index][ind-1],
|
|
(char*)measConfig->measIdToAddModList->list.array[i],
|
|
sizeof(MeasIdToAddMod_t));
|
|
}
|
|
else {
|
|
LOG_D(RRC,"Adding Measurement ID %d %p\n",ind-1,measConfig->measIdToAddModList->list.array[i]);
|
|
UE_rrc_inst[Mod_id].MeasId[eNB_index][ind-1] = measConfig->measIdToAddModList->list.array[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (measConfig->measGapConfig !=NULL) {
|
|
if (UE_rrc_inst[Mod_id].measGapConfig[eNB_index]) {
|
|
memcpy((char*)UE_rrc_inst[Mod_id].measGapConfig[eNB_index],
|
|
(char*)measConfig->measGapConfig,
|
|
sizeof(MeasGapConfig_t));
|
|
}
|
|
else {
|
|
UE_rrc_inst[Mod_id].measGapConfig[eNB_index] = measConfig->measGapConfig;
|
|
}
|
|
}
|
|
|
|
if (measConfig->quantityConfig != NULL) {
|
|
if (UE_rrc_inst[Mod_id].QuantityConfig[eNB_index]) {
|
|
LOG_I(RRC,"Modifying Quantity Configuration \n");
|
|
memcpy((char*)UE_rrc_inst[Mod_id].QuantityConfig[eNB_index],
|
|
(char*)measConfig->quantityConfig,
|
|
sizeof(QuantityConfig_t));
|
|
}
|
|
else {
|
|
LOG_I(RRC,"Adding Quantity configuration\n");
|
|
UE_rrc_inst[Mod_id].QuantityConfig[eNB_index] = measConfig->quantityConfig;
|
|
}
|
|
|
|
UE_rrc_inst[Mod_id].filter_coeff_rsrp = 1./pow(2,(*UE_rrc_inst[Mod_id].QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRP)/4);
|
|
UE_rrc_inst[Mod_id].filter_coeff_rsrq = 1./pow(2,(*UE_rrc_inst[Mod_id].QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRQ)/4);
|
|
|
|
LOG_I(RRC,"[UE %d] set rsrp-coeff for eNB %d: %d rsrq-coeff: %d rsrp_factor: %f rsrq_factor: %f \n",
|
|
Mod_id, eNB_index, // UE_rrc_inst[Mod_id].Info[eNB_index].UE_index,
|
|
*UE_rrc_inst[Mod_id].QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRP,
|
|
*UE_rrc_inst[Mod_id].QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRQ,
|
|
UE_rrc_inst[Mod_id].filter_coeff_rsrp, UE_rrc_inst[Mod_id].filter_coeff_rsrp,
|
|
UE_rrc_inst[Mod_id].filter_coeff_rsrp, UE_rrc_inst[Mod_id].filter_coeff_rsrq);
|
|
}
|
|
|
|
if (measConfig->s_Measure != NULL) {
|
|
UE_rrc_inst[Mod_id].s_measure = *measConfig->s_Measure;
|
|
}
|
|
|
|
if (measConfig->speedStatePars != NULL) {
|
|
if (UE_rrc_inst[Mod_id].speedStatePars)
|
|
memcpy((char*)UE_rrc_inst[Mod_id].speedStatePars,(char*)measConfig->speedStatePars,sizeof(struct MeasConfig__speedStatePars));
|
|
else
|
|
UE_rrc_inst[Mod_id].speedStatePars = measConfig->speedStatePars;
|
|
LOG_I(RRC,"[UE %d] Configuring mobility optimization params for UE %d \n",
|
|
Mod_id,UE_rrc_inst[Mod_id].Info[0].UE_index);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
rrc_ue_process_radioResourceConfigDedicated(u8 Mod_id,u32 frame, u8 eNB_index,
|
|
RadioResourceConfigDedicated_t *radioResourceConfigDedicated) {
|
|
|
|
long SRB_id,DRB_id;
|
|
int i,cnt;
|
|
LogicalChannelConfig_t *SRB1_logicalChannelConfig,*SRB2_logicalChannelConfig;
|
|
#ifdef CBA
|
|
uint8_t cba_found = 0;
|
|
uint16_t cba_RNTI;
|
|
#endif
|
|
|
|
// Save physicalConfigDedicated if present
|
|
if (radioResourceConfigDedicated->physicalConfigDedicated) {
|
|
if (UE_rrc_inst[Mod_id].physicalConfigDedicated[eNB_index]) {
|
|
memcpy((char*)UE_rrc_inst[Mod_id].physicalConfigDedicated[eNB_index],(char*)radioResourceConfigDedicated->physicalConfigDedicated,
|
|
sizeof(struct PhysicalConfigDedicated));
|
|
|
|
}
|
|
else {
|
|
UE_rrc_inst[Mod_id].physicalConfigDedicated[eNB_index] = radioResourceConfigDedicated->physicalConfigDedicated;
|
|
}
|
|
}
|
|
// Apply macMainConfig if present
|
|
if (radioResourceConfigDedicated->mac_MainConfig) {
|
|
if (radioResourceConfigDedicated->mac_MainConfig->present == RadioResourceConfigDedicated__mac_MainConfig_PR_explicitValue) {
|
|
if (UE_rrc_inst[Mod_id].mac_MainConfig[eNB_index]) {
|
|
memcpy((char*)UE_rrc_inst[Mod_id].mac_MainConfig[eNB_index],(char*)&radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue,
|
|
sizeof(MAC_MainConfig_t));
|
|
}
|
|
else
|
|
UE_rrc_inst[Mod_id].mac_MainConfig[eNB_index] = &radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue;
|
|
}
|
|
}
|
|
|
|
// Apply spsConfig if present
|
|
if (radioResourceConfigDedicated->sps_Config) {
|
|
if (UE_rrc_inst[Mod_id].sps_Config[eNB_index]) {
|
|
memcpy(UE_rrc_inst[Mod_id].sps_Config[eNB_index],radioResourceConfigDedicated->sps_Config,
|
|
sizeof(struct SPS_Config));
|
|
}
|
|
else {
|
|
UE_rrc_inst[Mod_id].sps_Config[eNB_index] = radioResourceConfigDedicated->sps_Config;
|
|
}
|
|
}
|
|
#ifdef CBA
|
|
if (radioResourceConfigDedicated->cba_RNTI_vlola) {
|
|
cba_RNTI = (uint16_t) (((radioResourceConfigDedicated->cba_RNTI_vlola->buf[1]&0xff) << 8) |
|
|
(radioResourceConfigDedicated->cba_RNTI_vlola->buf[0]&0xff));
|
|
for (i=0 ; i< NUM_MAX_CBA_GROUP; i++) {
|
|
if (UE_rrc_inst[Mod_id].cba_rnti[i] == cba_RNTI ) {
|
|
cba_found=1;
|
|
break;
|
|
} else if (UE_rrc_inst[Mod_id].cba_rnti[i] == 0 )
|
|
break;
|
|
}
|
|
if (cba_found==0) {
|
|
UE_rrc_inst[Mod_id].num_active_cba_groups++;
|
|
UE_rrc_inst[Mod_id].cba_rnti[i]=cba_RNTI;
|
|
LOG_D(RRC, "[UE %d] Frame %d: radioResourceConfigDedicated reveived CBA_RNTI = %x for group %d from eNB %d \n",
|
|
Mod_id,frame, UE_rrc_inst[Mod_id].cba_rnti[i], i, eNB_index);
|
|
}
|
|
}
|
|
#endif
|
|
// Establish SRBs if present
|
|
// loop through SRBToAddModList
|
|
if (radioResourceConfigDedicated->srb_ToAddModList) {
|
|
uint8_t *kRRCenc = NULL;
|
|
uint8_t *kRRCint = NULL;
|
|
|
|
#if defined(ENABLE_SECURITY)
|
|
derive_key_rrc_enc(UE_rrc_inst[Mod_id].ciphering_algorithm,
|
|
UE_rrc_inst[Mod_id].kenb, &kRRCenc);
|
|
derive_key_rrc_int(UE_rrc_inst[Mod_id].integrity_algorithm,
|
|
UE_rrc_inst[Mod_id].kenb, &kRRCint);
|
|
#endif
|
|
|
|
// Refresh SRBs
|
|
rrc_pdcp_config_asn1_req(NB_eNB_INST+Mod_id,frame,0,eNB_index,
|
|
radioResourceConfigDedicated->srb_ToAddModList,
|
|
(DRB_ToAddModList_t*)NULL,
|
|
(DRB_ToReleaseList_t*)NULL,
|
|
UE_rrc_inst[Mod_id].ciphering_algorithm |
|
|
(UE_rrc_inst[Mod_id].integrity_algorithm << 4),
|
|
kRRCenc,
|
|
kRRCint,
|
|
NULL
|
|
#ifdef Rel10
|
|
,(PMCH_InfoList_r9_t *)NULL
|
|
#endif
|
|
);
|
|
|
|
// Refresh SRBs
|
|
rrc_rlc_config_asn1_req(NB_eNB_INST+Mod_id,frame,0,eNB_index,
|
|
radioResourceConfigDedicated->srb_ToAddModList,
|
|
(DRB_ToAddModList_t*)NULL,
|
|
(DRB_ToReleaseList_t*)NULL
|
|
#ifdef Rel10
|
|
,(PMCH_InfoList_r9_t *)NULL
|
|
#endif
|
|
);
|
|
|
|
for (cnt=0;cnt<radioResourceConfigDedicated->srb_ToAddModList->list.count;cnt++) {
|
|
|
|
SRB_id = radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]->srb_Identity;
|
|
LOG_D(RRC,"[UE %d]: Frame %d SRB config cnt %d (SRB%ld)\n",Mod_id,frame,cnt,SRB_id);
|
|
if (SRB_id == 1) {
|
|
if (UE_rrc_inst[Mod_id].SRB1_config[eNB_index]) {
|
|
memcpy(UE_rrc_inst[Mod_id].SRB1_config[eNB_index],radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt],
|
|
sizeof(struct SRB_ToAddMod));
|
|
}
|
|
else {
|
|
UE_rrc_inst[Mod_id].SRB1_config[eNB_index] = radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt];
|
|
|
|
rrc_ue_establish_srb1(Mod_id,frame,eNB_index,radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]);
|
|
if (UE_rrc_inst[Mod_id].SRB1_config[eNB_index]->logicalChannelConfig) {
|
|
if (UE_rrc_inst[Mod_id].SRB1_config[eNB_index]->logicalChannelConfig->present == SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) {
|
|
SRB1_logicalChannelConfig = &UE_rrc_inst[Mod_id].SRB1_config[eNB_index]->logicalChannelConfig->choice.explicitValue;
|
|
}
|
|
else {
|
|
SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue;
|
|
}
|
|
}
|
|
else {
|
|
SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue;
|
|
}
|
|
|
|
|
|
LOG_D(RRC, "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB1 eNB %d) --->][MAC_UE][MOD %02d][]\n",
|
|
frame, Mod_id, eNB_index, Mod_id);
|
|
rrc_mac_config_req(Mod_id,0,0,eNB_index,
|
|
(RadioResourceConfigCommonSIB_t *)NULL,
|
|
UE_rrc_inst[Mod_id].physicalConfigDedicated[eNB_index],
|
|
(MeasObjectToAddMod_t **)NULL,
|
|
UE_rrc_inst[Mod_id].mac_MainConfig[eNB_index],
|
|
1,
|
|
SRB1_logicalChannelConfig,
|
|
(MeasGapConfig_t *)NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL
|
|
#ifdef Rel10
|
|
,
|
|
0,
|
|
(MBSFN_AreaInfoList_r9_t *)NULL,
|
|
(PMCH_InfoList_r9_t *)NULL
|
|
#endif
|
|
#ifdef CBA
|
|
,
|
|
0,
|
|
0
|
|
#endif
|
|
);
|
|
}
|
|
}
|
|
else {
|
|
if (UE_rrc_inst[Mod_id].SRB2_config[eNB_index]) {
|
|
memcpy(UE_rrc_inst[Mod_id].SRB2_config[eNB_index],radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt],
|
|
sizeof(struct SRB_ToAddMod));
|
|
}
|
|
else {
|
|
|
|
UE_rrc_inst[Mod_id].SRB2_config[eNB_index] = radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt];
|
|
|
|
rrc_ue_establish_srb2(Mod_id,frame,eNB_index,radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]);
|
|
if (UE_rrc_inst[Mod_id].SRB2_config[eNB_index]->logicalChannelConfig) {
|
|
if (UE_rrc_inst[Mod_id].SRB2_config[eNB_index]->logicalChannelConfig->present == SRB_ToAddMod__logicalChannelConfig_PR_explicitValue){
|
|
LOG_I(RRC,"Applying Explicit SRB2 logicalChannelConfig\n");
|
|
SRB2_logicalChannelConfig = &UE_rrc_inst[Mod_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_D(RRC, "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB2 eNB %d) --->][MAC_UE][MOD %02d][]\n",
|
|
frame, Mod_id, eNB_index, Mod_id);
|
|
rrc_mac_config_req(Mod_id,0,0,eNB_index,
|
|
(RadioResourceConfigCommonSIB_t *)NULL,
|
|
UE_rrc_inst[Mod_id].physicalConfigDedicated[eNB_index],
|
|
(MeasObjectToAddMod_t **)NULL,
|
|
UE_rrc_inst[Mod_id].mac_MainConfig[eNB_index],
|
|
2,
|
|
SRB2_logicalChannelConfig,
|
|
UE_rrc_inst[Mod_id].measGapConfig[eNB_index],
|
|
(TDD_Config_t *)NULL,
|
|
(MobilityControlInfo_t *)NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL
|
|
#ifdef Rel10
|
|
,
|
|
0,
|
|
(MBSFN_AreaInfoList_r9_t *)NULL,
|
|
(PMCH_InfoList_r9_t *)NULL
|
|
#endif
|
|
#ifdef CBA
|
|
,
|
|
0,
|
|
0
|
|
#endif
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Establish DRBs if present
|
|
if (radioResourceConfigDedicated->drb_ToAddModList) {
|
|
uint8_t *kUPenc = NULL;
|
|
|
|
#if defined(ENABLE_SECURITY)
|
|
derive_key_up_enc(UE_rrc_inst[Mod_id].integrity_algorithm,
|
|
UE_rrc_inst[Mod_id].kenb, &kUPenc);
|
|
#endif
|
|
|
|
// Refresh DRBs
|
|
rrc_pdcp_config_asn1_req(NB_eNB_INST+Mod_id,frame,0,eNB_index,
|
|
(SRB_ToAddModList_t*)NULL,
|
|
radioResourceConfigDedicated->drb_ToAddModList,
|
|
(DRB_ToReleaseList_t*)NULL,
|
|
UE_rrc_inst[Mod_id].ciphering_algorithm |
|
|
(UE_rrc_inst[Mod_id].integrity_algorithm << 4),
|
|
NULL,
|
|
NULL,
|
|
kUPenc
|
|
#ifdef Rel10
|
|
,(PMCH_InfoList_r9_t *)NULL
|
|
#endif
|
|
);
|
|
|
|
// Refresh DRBs
|
|
rrc_rlc_config_asn1_req(NB_eNB_INST+Mod_id,frame,0,eNB_index,
|
|
(SRB_ToAddModList_t*)NULL,
|
|
radioResourceConfigDedicated->drb_ToAddModList,
|
|
(DRB_ToReleaseList_t*)NULL
|
|
#ifdef Rel10
|
|
,(PMCH_InfoList_r9_t *)NULL
|
|
#endif
|
|
);
|
|
for (i=0;i<radioResourceConfigDedicated->drb_ToAddModList->list.count;i++) {
|
|
DRB_id = radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity-1;
|
|
if (UE_rrc_inst[Mod_id].DRB_config[eNB_index][DRB_id]) {
|
|
memcpy(UE_rrc_inst[Mod_id].DRB_config[eNB_index][DRB_id],radioResourceConfigDedicated->drb_ToAddModList->list.array[i],
|
|
sizeof(struct DRB_ToAddMod));
|
|
}
|
|
else {
|
|
UE_rrc_inst[Mod_id].DRB_config[eNB_index][DRB_id] = radioResourceConfigDedicated->drb_ToAddModList->list.array[i];
|
|
|
|
rrc_ue_establish_drb(Mod_id,frame,eNB_index,radioResourceConfigDedicated->drb_ToAddModList->list.array[i]);
|
|
// MAC/PHY Configuration
|
|
LOG_D(RRC, "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (DRB %d eNB %d) --->][MAC_UE][MOD %02d][]\n",
|
|
frame, Mod_id, radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity, eNB_index, Mod_id);
|
|
rrc_mac_config_req(Mod_id,0,0,eNB_index,
|
|
(RadioResourceConfigCommonSIB_t *)NULL,
|
|
UE_rrc_inst[Mod_id].physicalConfigDedicated[eNB_index],
|
|
(MeasObjectToAddMod_t **)NULL,
|
|
UE_rrc_inst[Mod_id].mac_MainConfig[eNB_index],
|
|
*UE_rrc_inst[Mod_id].DRB_config[eNB_index][DRB_id]->logicalChannelIdentity,
|
|
UE_rrc_inst[Mod_id].DRB_config[eNB_index][DRB_id]->logicalChannelConfig,
|
|
UE_rrc_inst[Mod_id].measGapConfig[eNB_index],
|
|
(TDD_Config_t*)NULL,
|
|
(MobilityControlInfo_t *)NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL
|
|
#ifdef Rel10
|
|
,
|
|
0,
|
|
(MBSFN_AreaInfoList_r9_t *)NULL,
|
|
(PMCH_InfoList_r9_t *)NULL
|
|
#endif
|
|
#ifdef CBA
|
|
,
|
|
UE_rrc_inst[Mod_id].num_active_cba_groups, //
|
|
UE_rrc_inst[Mod_id].cba_rnti[0]
|
|
#endif
|
|
);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].State = RRC_CONNECTED;
|
|
LOG_I(RRC,"[UE %d] State = RRC_CONNECTED (eNB %d)\n",Mod_id,eNB_index);
|
|
|
|
|
|
}
|
|
|
|
void rrc_ue_process_securityModeCommand(uint8_t Mod_id,uint32_t frame,SecurityModeCommand_t *securityModeCommand,uint8_t eNB_index) {
|
|
|
|
asn_enc_rval_t enc_rval;
|
|
|
|
UL_DCCH_Message_t ul_dcch_msg;
|
|
// SecurityModeCommand_t SecurityModeCommand;
|
|
uint8_t buffer[200];
|
|
int i, securityMode;
|
|
|
|
LOG_I(RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing securityModeCommand (eNB %d)\n",
|
|
Mod_id,frame,eNB_index);
|
|
|
|
switch (securityModeCommand->criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm){
|
|
case SecurityAlgorithmConfig__cipheringAlgorithm_eea0:
|
|
LOG_I(RRC,"[UE %d] Security algorithm is set to eea0\n",Mod_id);
|
|
securityMode= SecurityAlgorithmConfig__cipheringAlgorithm_eea0;
|
|
break;
|
|
case SecurityAlgorithmConfig__cipheringAlgorithm_eea1:
|
|
LOG_I(RRC,"[UE %d] Security algorithm is set to eea1\n",Mod_id);
|
|
securityMode= SecurityAlgorithmConfig__cipheringAlgorithm_eea1;
|
|
break;
|
|
case SecurityAlgorithmConfig__cipheringAlgorithm_eea2:
|
|
LOG_I(RRC,"[UE %d] Security algorithm is set to eea2\n",Mod_id);
|
|
securityMode = SecurityAlgorithmConfig__cipheringAlgorithm_eea2;
|
|
break;
|
|
default:
|
|
LOG_I(RRC,"[UE %d] Security algorithm is set to none\n",Mod_id);
|
|
securityMode = SecurityAlgorithmConfig__cipheringAlgorithm_spare1;
|
|
break;
|
|
}
|
|
switch (securityModeCommand->criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm){
|
|
case SecurityAlgorithmConfig__integrityProtAlgorithm_eia1:
|
|
LOG_I(RRC,"[UE %d] Integrity protection algorithm is set to eia1\n",Mod_id);
|
|
securityMode |= 1 << 5;
|
|
break;
|
|
case SecurityAlgorithmConfig__integrityProtAlgorithm_eia2:
|
|
LOG_I(RRC,"[UE %d] Integrity protection algorithm is set to eia2\n",Mod_id);
|
|
securityMode |= 1 << 6;
|
|
break;
|
|
default:
|
|
LOG_I(RRC,"[UE %d] Integrity protection algorithm is set to none\n",Mod_id);
|
|
securityMode |= 0x70 ;
|
|
break;
|
|
}
|
|
LOG_D(RRC,"[UE %d] security mode is %x \n",Mod_id, securityMode);
|
|
|
|
/* Store the parameters received */
|
|
UE_rrc_inst[Mod_id].ciphering_algorithm = securityModeCommand->criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm;
|
|
UE_rrc_inst[Mod_id].integrity_algorithm = securityModeCommand->criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm;
|
|
|
|
memset((void *)&ul_dcch_msg,0,sizeof(UL_DCCH_Message_t));
|
|
//memset((void *)&SecurityModeCommand,0,sizeof(SecurityModeCommand_t));
|
|
|
|
ul_dcch_msg.message.present = UL_DCCH_MessageType_PR_c1;
|
|
if (securityMode >= NO_SECURITY_MODE)
|
|
ul_dcch_msg.message.choice.c1.present = UL_DCCH_MessageType__c1_PR_securityModeComplete;
|
|
else
|
|
ul_dcch_msg.message.choice.c1.present = UL_DCCH_MessageType__c1_PR_securityModeFailure;
|
|
|
|
if (securityModeCommand->criticalExtensions.present == SecurityModeCommand__criticalExtensions_PR_c1) {
|
|
if (securityModeCommand->criticalExtensions.choice.c1.present == SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8) {
|
|
|
|
ul_dcch_msg.message.choice.c1.choice.securityModeComplete.rrc_TransactionIdentifier = securityModeCommand->rrc_TransactionIdentifier;
|
|
ul_dcch_msg.message.choice.c1.choice.securityModeComplete.criticalExtensions.present = SecurityModeCommand__criticalExtensions_PR_c1;
|
|
ul_dcch_msg.message.choice.c1.choice.securityModeComplete.criticalExtensions.choice.securityModeComplete_r8.nonCriticalExtension =NULL;
|
|
|
|
LOG_I(RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), encoding securityModeComplete (eNB %d)\n",
|
|
Mod_id,frame,eNB_index);
|
|
|
|
enc_rval = uper_encode_to_buffer(&asn_DEF_UL_DCCH_Message,
|
|
(void*)&ul_dcch_msg,
|
|
buffer,
|
|
100);
|
|
|
|
#ifdef XER_PRINT
|
|
xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void*)&ul_dcch_msg);
|
|
#endif
|
|
|
|
#ifdef USER_MODE
|
|
LOG_D(RRC, "securityModeComplete Encoded %d bits (%d bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8);
|
|
#endif
|
|
for (i = 0; i < (enc_rval.encoded + 7) / 8; i++)
|
|
LOG_T(RRC, "%02x.", buffer[i]);
|
|
LOG_T(RRC, "\n");
|
|
pdcp_rrc_data_req (Mod_id + NB_eNB_INST, frame, 0, DCCH, rrc_mui++, 0, (enc_rval.encoded + 7) / 8, buffer, 1);
|
|
}
|
|
}
|
|
|
|
}
|
|
void rrc_ue_process_ueCapabilityEnquiry(uint8_t Mod_id,uint32_t frame,UECapabilityEnquiry_t *UECapabilityEnquiry,uint8_t eNB_index) {
|
|
|
|
asn_enc_rval_t enc_rval;
|
|
|
|
UL_DCCH_Message_t ul_dcch_msg;
|
|
|
|
|
|
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",
|
|
Mod_id,frame,eNB_index);
|
|
|
|
|
|
memset((void *)&ul_dcch_msg,0,sizeof(UL_DCCH_Message_t));
|
|
memset((void *)&ue_CapabilityRAT_Container,0,sizeof(UE_CapabilityRAT_Container_t));
|
|
|
|
ul_dcch_msg.message.present = UL_DCCH_MessageType_PR_c1;
|
|
ul_dcch_msg.message.choice.c1.present = UL_DCCH_MessageType__c1_PR_ueCapabilityInformation;
|
|
|
|
ue_CapabilityRAT_Container.rat_Type = RAT_Type_eutra;
|
|
OCTET_STRING_fromBuf(&ue_CapabilityRAT_Container.ueCapabilityRAT_Container,
|
|
(const char*)UE_rrc_inst[Mod_id].UECapability,
|
|
UE_rrc_inst[Mod_id].UECapability_size);
|
|
// ue_CapabilityRAT_Container.ueCapabilityRAT_Container.buf = UE_rrc_inst[Mod_id].UECapability;
|
|
// ue_CapabilityRAT_Container.ueCapabilityRAT_Container.size = UE_rrc_inst[Mod_id].UECapability_size;
|
|
|
|
|
|
if (UECapabilityEnquiry->criticalExtensions.present == UECapabilityEnquiry__criticalExtensions_PR_c1) {
|
|
if (UECapabilityEnquiry->criticalExtensions.choice.c1.present == UECapabilityEnquiry__criticalExtensions__c1_PR_ueCapabilityEnquiry_r8) {
|
|
ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.present = UECapabilityInformation__criticalExtensions_PR_c1;
|
|
ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.present = 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]==RAT_Type_eutra) {
|
|
// ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.rrc_TransactionIdentifier = UECapabilityEnquiry->rrc_TransactionIdentifier;
|
|
ASN_SEQUENCE_ADD(&ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list,
|
|
&ue_CapabilityRAT_Container);
|
|
|
|
enc_rval = uper_encode_to_buffer(&asn_DEF_UL_DCCH_Message,
|
|
(void*)&ul_dcch_msg,
|
|
buffer,
|
|
100);
|
|
|
|
#ifdef XER_PRINT
|
|
xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void*)&ul_dcch_msg);
|
|
#endif
|
|
|
|
#ifdef USER_MODE
|
|
LOG_D(RRC,"UECapabilityInformation Encoded %d bits (%d bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
|
|
#endif
|
|
for (i = 0; i < (enc_rval.encoded + 7) / 8; i++)
|
|
LOG_T(RRC, "%02x.", buffer[i]);
|
|
LOG_T(RRC, "\n");
|
|
pdcp_rrc_data_req (Mod_id + NB_eNB_INST, frame, 0, DCCH, rrc_mui++, 0, (enc_rval.encoded + 7) / 8, buffer, 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void rrc_ue_process_rrcConnectionReconfiguration(u8 Mod_id, u32 frame,
|
|
RRCConnectionReconfiguration_t *rrcConnectionReconfiguration,
|
|
u8 eNB_index) {
|
|
|
|
LOG_I(RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing RRCConnectionReconfiguration (eNB %d)\n",
|
|
Mod_id,frame,eNB_index);
|
|
if (rrcConnectionReconfiguration->criticalExtensions.present == RRCConnectionReconfiguration__criticalExtensions_PR_c1) {
|
|
if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.present == RRCConnectionReconfiguration__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r8) {
|
|
|
|
if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo) {
|
|
LOG_I(RRC,"Mobility Control Information is present\n");
|
|
rrc_ue_process_mobilityControlInfo(Mod_id,frame, eNB_index,
|
|
rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo);
|
|
|
|
}
|
|
if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig != NULL) {
|
|
LOG_I(RRC,"Measurement Configuration is present\n");
|
|
rrc_ue_process_measConfig(Mod_id,frame, eNB_index,
|
|
rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig);
|
|
}
|
|
if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated) {
|
|
LOG_I(RRC,"Radio Resource Configuration is present\n");
|
|
rrc_ue_process_radioResourceConfigDedicated(Mod_id,frame,eNB_index,
|
|
rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated);
|
|
}
|
|
} // 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(u8 Mod_id,u32 frame, u8 eNB_index,struct MobilityControlInfo *mobilityControlInfo) {
|
|
/*
|
|
DRB_ToReleaseList_t* drb2release_list;
|
|
DRB_Identity_t *lcid;
|
|
*/
|
|
LOG_N(RRC,"Note: This function needs some updates\n");
|
|
if(UE_rrc_inst[Mod_id].Info[eNB_index].T310_active == 1)
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].T310_active = 0;
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].T304_active = 1;
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].T304_cnt = T304[mobilityControlInfo->t304];
|
|
|
|
/*
|
|
drb2release_list = CALLOC (1, sizeof (*drb2release_list));
|
|
lcid= CALLOC (1, sizeof (DRB_Identity_t)); // long
|
|
for (*lcid=0;*lcid<NB_RB_MAX;*lcid++)
|
|
{
|
|
ASN_SEQUENCE_ADD (&(drb2release_list)->list,lcid);
|
|
}
|
|
*/
|
|
|
|
//Removing SRB1 and SRB2 and DRB0
|
|
LOG_N(RRC,"[UE %d] : Update needed for rrc_pdcp_config_req (deprecated) and rrc_rlc_config_req commands(deprecated)\n",Mod_id);
|
|
rrc_pdcp_config_req (Mod_id+NB_eNB_INST, frame, 0, ACTION_REMOVE, Mod_id+DCCH,UNDEF_SECURITY_MODE);
|
|
rrc_rlc_config_req(Mod_id+NB_eNB_INST,frame,0,ACTION_REMOVE,Mod_id+DCCH,SIGNALLING_RADIO_BEARER,Rlc_info_am_config);
|
|
|
|
rrc_pdcp_config_req (Mod_id+NB_eNB_INST, frame, 0, ACTION_REMOVE, Mod_id+DCCH1,UNDEF_SECURITY_MODE);
|
|
rrc_rlc_config_req(Mod_id+NB_eNB_INST,frame,0,ACTION_REMOVE,Mod_id+DCCH1,SIGNALLING_RADIO_BEARER,Rlc_info_am_config);
|
|
|
|
rrc_pdcp_config_req (Mod_id+NB_eNB_INST, frame, 0, ACTION_REMOVE, Mod_id+DTCH,UNDEF_SECURITY_MODE);
|
|
rrc_rlc_config_req(Mod_id+NB_eNB_INST,frame,0,ACTION_REMOVE,Mod_id+DTCH,RADIO_ACCESS_BEARER,Rlc_info_um);
|
|
/*
|
|
rrc_pdcp_config_asn1_req(NB_eNB_INST+Mod_id,frame, 0,eNB_index,
|
|
NULL, // SRB_ToAddModList
|
|
NULL, // DRB_ToAddModList
|
|
drb2release_list,
|
|
0, // security mode
|
|
NULL, // key rrc encryption
|
|
NULL, // key rrc integrity
|
|
NULL // key encryption
|
|
#ifdef Rel10
|
|
,NULL
|
|
#endif
|
|
);
|
|
|
|
rrc_rlc_config_asn1_req(NB_eNB_INST+Mod_id, frame,0,eNB_index,
|
|
NULL,// SRB_ToAddModList
|
|
NULL,// DRB_ToAddModList
|
|
drb2release_list // DRB_ToReleaseList
|
|
#ifdef Rel10
|
|
,NULL
|
|
#endif
|
|
);
|
|
*/
|
|
|
|
|
|
//A little cleanup at RRC...
|
|
//Copying current queue config to free RRC index
|
|
/*
|
|
memcpy((void *)UE_rrc_inst[Mod_id].SRB1_config[~(7<<eNB_index)],(void *)UE_rrc_inst[Mod_id].SRB1_config[7<<eNB_index],sizeof(SRB_ToAddMod_t));
|
|
memcpy((void *)UE_rrc_inst[Mod_id].SRB2_config[~(7<<eNB_index)],(void *)UE_rrc_inst[Mod_id].SRB2_config[7<<eNB_index],sizeof(SRB_ToAddMod_t));
|
|
memcpy((void *)UE_rrc_inst[Mod_id].DRB_config[~(7<<eNB_index)][0],(void *)UE_rrc_inst[Mod_id].DRB_config[7<<eNB_index][0],sizeof(DRB_ToAddMod_t));
|
|
*/
|
|
/*
|
|
LOG_N(RRC,"Not sure if Freeing the current queue config works properly: Fix me\n");
|
|
free((void *)&UE_rrc_inst[Mod_id].SRB1_config[eNB_index]);
|
|
free((void *)&UE_rrc_inst[Mod_id].SRB2_config[eNB_index]);
|
|
free((void *)&UE_rrc_inst[Mod_id].DRB_config[eNB_index][0]);
|
|
|
|
UE_rrc_inst[Mod_id].SRB1_config[eNB_index] = NULL;
|
|
UE_rrc_inst[Mod_id].SRB2_config[eNB_index] = NULL;
|
|
UE_rrc_inst[Mod_id].DRB_config[eNB_index][0] = NULL;
|
|
*/
|
|
//Synchronisation to DL of target cell
|
|
LOG_D(RRC,"HO: Reset PDCP and RLC for configured RBs.. \n[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB2 eNB %d) --->][MAC_UE][MOD %02d][]\n",
|
|
frame, Mod_id, eNB_index, Mod_id);
|
|
|
|
// Reset MAC and configure PHY
|
|
rrc_mac_config_req(Mod_id,0,0,eNB_index,
|
|
(RadioResourceConfigCommonSIB_t *)NULL,
|
|
(struct PhysicalConfigDedicated *)NULL,
|
|
(MeasObjectToAddMod_t **)NULL,
|
|
(MAC_MainConfig_t *)NULL,
|
|
0,
|
|
(struct LogicalChannelConfig *)NULL,
|
|
(MeasGapConfig_t *)NULL,
|
|
(TDD_Config_t *)NULL,
|
|
mobilityControlInfo,
|
|
(u8 *)NULL,
|
|
(u16 *)NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL
|
|
#ifdef Rel10
|
|
,0,
|
|
(MBSFN_AreaInfoList_r9_t *)NULL,
|
|
(PMCH_InfoList_r9_t *)NULL
|
|
#endif
|
|
#ifdef CBA
|
|
,0,
|
|
0
|
|
#endif
|
|
);
|
|
|
|
// Re-establish PDCP for all RBs that are established
|
|
// rrc_pdcp_config_req (Mod_id+NB_eNB_INST, frame, 0, ACTION_ADD, Mod_id+DCCH);
|
|
// rrc_pdcp_config_req (Mod_id+NB_eNB_INST, frame, 0, ACTION_ADD, Mod_id+DCCH1);
|
|
// rrc_pdcp_config_req (Mod_id+NB_eNB_INST, frame, 0, ACTION_ADD, Mod_id+DTCH);
|
|
|
|
|
|
// Re-establish RLC for all RBs that are established
|
|
// rrc_rlc_config_req(Mod_id+NB_eNB_INST,frame,0,ACTION_ADD,Mod_id+DCCH,SIGNALLING_RADIO_BEARER,Rlc_info_am_config);
|
|
// rrc_rlc_config_req(Mod_id+NB_eNB_INST,frame,0,ACTION_ADD,Mod_id+DCCH1,SIGNALLING_RADIO_BEARER,Rlc_info_am_config);
|
|
// rrc_rlc_config_req(Mod_id+NB_eNB_INST,frame,0,ACTION_ADD,Mod_id+DTCH,RADIO_ACCESS_BEARER,Rlc_info_um);
|
|
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].State = RRC_SI_RECEIVED;
|
|
|
|
}
|
|
void rrc_detach_from_eNB(u8 Mod_id,u8 eNB_index) {
|
|
//UE_rrc_inst[Mod_id].DRB_config[eNB_index]
|
|
}
|
|
|
|
/*------------------------------------------------------------------------------------------*/
|
|
void rrc_ue_decode_dcch(u8 Mod_id,u32 frame,u8 Srb_id, u8 *Buffer,u8 eNB_index){
|
|
/*------------------------------------------------------------------------------------------*/
|
|
|
|
//DL_DCCH_Message_t dldcchmsg;
|
|
DL_DCCH_Message_t *dl_dcch_msg=NULL;//&dldcchmsg;
|
|
// asn_dec_rval_t dec_rval;
|
|
// int i;
|
|
u8 target_eNB_index=0xFF;
|
|
if (Srb_id != 1) {
|
|
LOG_E(RRC,"[UE %d] Frame %d: Received message on DL-DCCH (SRB1), should not have ...\n",Mod_id,frame);
|
|
return;
|
|
}
|
|
|
|
//memset(dl_dcch_msg,0,sizeof(DL_DCCH_Message_t));
|
|
|
|
// decode messages
|
|
// LOG_D(RRC,"[UE %d] Decoding DL-DCCH message\n",Mod_id);
|
|
/*
|
|
for (i=0;i<30;i++)
|
|
LOG_T(RRC,"%x.",Buffer[i]);
|
|
LOG_T(RRC, "\n");
|
|
*/
|
|
uper_decode(NULL,
|
|
&asn_DEF_DL_DCCH_Message,
|
|
(void**)&dl_dcch_msg,
|
|
(uint8_t*)Buffer,
|
|
RRC_BUF_SIZE,0,0);
|
|
|
|
#ifdef XER_PRINT
|
|
xer_fprint(stdout,&asn_DEF_DL_DCCH_Message,(void*)dl_dcch_msg);
|
|
#endif
|
|
|
|
#if defined(ENABLE_ITTI)
|
|
{
|
|
MessageDef *message_p;
|
|
|
|
message_p = itti_alloc_new_message (TASK_RRC_UE, RRC_DL_DCCH_MESSAGE);
|
|
memcpy (&message_p->msg, (void *) dl_dcch_msg, sizeof(RrcDlDcchMessage));
|
|
|
|
itti_send_msg_to_task (TASK_UNKNOWN, Mod_id + NB_eNB_INST, message_p);
|
|
}
|
|
#endif
|
|
|
|
if (dl_dcch_msg->message.present == DL_DCCH_MessageType_PR_c1) {
|
|
|
|
if (UE_rrc_inst[Mod_id].Info[eNB_index].State >= RRC_CONNECTED) {
|
|
|
|
switch (dl_dcch_msg->message.choice.c1.present) {
|
|
|
|
case DL_DCCH_MessageType__c1_PR_NOTHING :
|
|
LOG_I(RRC,"[UE %d] Frame %d : Received PR_NOTHING on DL-DCCH-Message\n",Mod_id,frame);
|
|
return;
|
|
|
|
case DL_DCCH_MessageType__c1_PR_csfbParametersResponseCDMA2000:
|
|
break;
|
|
case DL_DCCH_MessageType__c1_PR_dlInformationTransfer:
|
|
{
|
|
#if defined(ENABLE_ITTI)
|
|
DLInformationTransfer_t *dlInformationTransfer = &dl_dcch_msg->message.choice.c1.choice.dlInformationTransfer;
|
|
|
|
if ((dlInformationTransfer->criticalExtensions.present == DLInformationTransfer__criticalExtensions_PR_c1)
|
|
&& (dlInformationTransfer->criticalExtensions.choice.c1.present == DLInformationTransfer__criticalExtensions__c1_PR_dlInformationTransfer_r8)
|
|
&& (dlInformationTransfer->criticalExtensions.choice.c1.choice.dlInformationTransfer_r8.dedicatedInfoType.present == DLInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS))
|
|
{
|
|
/* This message hold a dedicated info NAS payload, forward it to NAS */
|
|
struct DLInformationTransfer_r8_IEs__dedicatedInfoType *dedicatedInfoType =
|
|
&dlInformationTransfer->criticalExtensions.choice.c1.choice.dlInformationTransfer_r8.dedicatedInfoType;
|
|
uint32_t pdu_length;
|
|
uint8_t *pdu_buffer;
|
|
MessageDef *msg_p;
|
|
|
|
pdu_length = dedicatedInfoType->choice.dedicatedInfoNAS.size;
|
|
pdu_buffer = dedicatedInfoType->choice.dedicatedInfoNAS.buf;
|
|
|
|
msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_DOWNLINK_DATA_IND);
|
|
NAS_DOWNLINK_DATA_IND (msg_p).UEid = Mod_id; // TODO set the UEid to something else ?
|
|
NAS_DOWNLINK_DATA_IND (msg_p).nasMsg.length = pdu_length;
|
|
NAS_DOWNLINK_DATA_IND (msg_p).nasMsg.data = pdu_buffer;
|
|
|
|
itti_send_msg_to_task(TASK_NAS_UE, Mod_id + NB_eNB_INST, msg_p);
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
case DL_DCCH_MessageType__c1_PR_handoverFromEUTRAPreparationRequest:
|
|
break;
|
|
case DL_DCCH_MessageType__c1_PR_mobilityFromEUTRACommand:
|
|
break;
|
|
case 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[Mod_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 (%d) is different from RSRP measured target (%d)..\n",Mod_id, frame,
|
|
dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo->targetPhysCellId,UE_rrc_inst[Mod_id].HandoverInfoUe.targetCellId);
|
|
return;
|
|
} else if ((target_eNB_index=get_adjacent_cell_mod_id(UE_rrc_inst[Mod_id].HandoverInfoUe.targetCellId)) == 0xFF ){
|
|
LOG_W(RRC,"[UE %d] Frame %d: Mod_id of the target eNB not found, check the network topology\n",Mod_id, frame);
|
|
return;
|
|
} else {
|
|
LOG_I(RRC,"[UE% d] Frame %d: Received rrcConnectionReconfiguration with mobilityControlInfo \n", Mod_id, frame);
|
|
UE_rrc_inst[Mod_id].HandoverInfoUe.measFlag = 1; // Ready to send more MeasReports if required
|
|
}
|
|
}
|
|
rrc_ue_process_rrcConnectionReconfiguration(Mod_id,frame,&dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration,eNB_index);
|
|
if (target_eNB_index!=0xFF){
|
|
rrc_ue_generate_RRCConnectionReconfigurationComplete(Mod_id,frame,target_eNB_index);
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].State = RRC_HO_EXECUTION;
|
|
UE_rrc_inst[Mod_id].Info[target_eNB_index].State = RRC_RECONFIGURED;
|
|
LOG_I(RRC,"[UE %d] State = RRC_RECONFIGURED during HO (eNB %d)\n",Mod_id,target_eNB_index);
|
|
}else {
|
|
rrc_ue_generate_RRCConnectionReconfigurationComplete(Mod_id,frame,eNB_index);
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].State = RRC_RECONFIGURED;
|
|
LOG_I(RRC,"[UE %d] State = RRC_RECONFIGURED (eNB %d)\n",Mod_id,eNB_index);
|
|
}
|
|
break;
|
|
case DL_DCCH_MessageType__c1_PR_rrcConnectionRelease:
|
|
break;
|
|
case DL_DCCH_MessageType__c1_PR_securityModeCommand:
|
|
LOG_I(RRC,"[UE %d] Received securityModeCommand (eNB %d)\n",Mod_id,eNB_index);
|
|
rrc_ue_process_securityModeCommand(Mod_id,frame,&dl_dcch_msg->message.choice.c1.choice.securityModeCommand,eNB_index);
|
|
break;
|
|
case DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry:
|
|
LOG_I(RRC,"[UE %d] Received Capability Enquiry (eNB %d)\n",Mod_id,eNB_index);
|
|
rrc_ue_process_ueCapabilityEnquiry(Mod_id,frame,&dl_dcch_msg->message.choice.c1.choice.ueCapabilityEnquiry,eNB_index);
|
|
break;
|
|
case DL_DCCH_MessageType__c1_PR_counterCheck:
|
|
break;
|
|
#ifdef Rel10
|
|
case DL_DCCH_MessageType__c1_PR_ueInformationRequest_r9:
|
|
break;
|
|
case DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r10:
|
|
break;
|
|
case DL_DCCH_MessageType__c1_PR_rnReconfiguration_r10:
|
|
break;
|
|
#endif
|
|
case DL_DCCH_MessageType__c1_PR_spare1:
|
|
case DL_DCCH_MessageType__c1_PR_spare2:
|
|
case DL_DCCH_MessageType__c1_PR_spare3:
|
|
case DL_DCCH_MessageType__c1_PR_spare4:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
#ifndef NO_RRM
|
|
send_msg(&S_rrc,msg_rrc_end_scan_req(Mod_id,eNB_index));
|
|
#endif
|
|
}
|
|
|
|
const char siWindowLength[7][5] = {"1ms\0","2ms\0","5ms\0","10ms\0","15ms\0","20ms\0","40ms\0"};
|
|
const char siWindowLength_int[7] = {1,2,5,10,15,20,40};
|
|
|
|
const char SIBType[16][6] ={"SIB3\0","SIB4\0","SIB5\0","SIB6\0","SIB7\0","SIB8\0","SIB9\0","SIB10\0","SIB11\0","SIB12\0","SIB13\0","Sp2\0","Sp3\0","Sp4\0"};
|
|
const char SIBPeriod[7][7]= {"80ms\0","160ms\0","320ms\0","640ms\0","1280ms\0","2560ms\0","5120ms\0"};
|
|
int siPeriod_int[7] = {80,160,320,640,1280,2560,5120};
|
|
|
|
int decode_BCCH_DLSCH_Message(u8 Mod_id,u32 frame,u8 eNB_index,u8 *Sdu,u8 Sdu_len) {
|
|
|
|
//BCCH_DL_SCH_Message_t bcch_message;
|
|
BCCH_DL_SCH_Message_t *bcch_message=NULL;//_ptr=&bcch_message;
|
|
SystemInformationBlockType1_t **sib1=&UE_rrc_inst[Mod_id].sib1[eNB_index];
|
|
SystemInformation_t **si=UE_rrc_inst[Mod_id].si[eNB_index];
|
|
asn_dec_rval_t dec_rval;
|
|
uint32_t si_window;//, sib1_decoded=0, si_decoded=0;
|
|
// int i;
|
|
|
|
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_IN);
|
|
|
|
|
|
if ((UE_rrc_inst[Mod_id].Info[eNB_index].SIB1Status == 1) &&
|
|
(UE_rrc_inst[Mod_id].Info[eNB_index].SIStatus == 1)) {
|
|
// Avoid decoding to prevent memory bloating
|
|
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT);
|
|
return 0;
|
|
}
|
|
else {
|
|
|
|
//memset(&bcch_message,0,sizeof(BCCH_DL_SCH_Message_t));
|
|
// LOG_D(RRC,"[UE %d] Decoding DL_BCCH_DLSCH_Message\n",Mod_id)
|
|
/*
|
|
for (i=0;i<Sdu_len;i++)
|
|
printf("%x.",Sdu[i]);
|
|
printf("\n");*/
|
|
dec_rval = uper_decode_complete(NULL,
|
|
&asn_DEF_BCCH_DL_SCH_Message,
|
|
(void **)&bcch_message,
|
|
(const void *)Sdu,
|
|
Sdu_len);//,0,0);
|
|
|
|
if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) {
|
|
LOG_E(RRC,"[UE %d] Failed to decode BCCH_DLSCH_MESSAGE (%d bits)\n",Mod_id,dec_rval.consumed);
|
|
//free the memory
|
|
SEQUENCE_free(&asn_DEF_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;
|
|
}
|
|
// xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message, (void*)&bcch_message);
|
|
|
|
#if defined(ENABLE_ITTI)
|
|
{
|
|
MessageDef *message_p;
|
|
|
|
message_p = itti_alloc_new_message (TASK_RRC_UE, RRC_DL_BCCH_MESSAGE);
|
|
memcpy (&message_p->msg, (void *) bcch_message, sizeof(RrcDlBcchMessage));
|
|
|
|
itti_send_msg_to_task (TASK_UNKNOWN, Mod_id + NB_eNB_INST, message_p);
|
|
}
|
|
#endif
|
|
|
|
if (bcch_message->message.present == BCCH_DL_SCH_MessageType_PR_c1) {
|
|
switch (bcch_message->message.choice.c1.present) {
|
|
case BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1:
|
|
if ((frame %2) == 0) {
|
|
if (UE_rrc_inst[Mod_id].Info[eNB_index].SIB1Status == 0) {
|
|
memcpy((void*)*sib1,
|
|
(void*)&bcch_message->message.choice.c1.choice.systemInformationBlockType1,
|
|
sizeof(SystemInformationBlockType1_t));
|
|
LOG_D(RRC,"[UE %d] Decoding First SIB1\n",Mod_id);
|
|
decode_SIB1(Mod_id,eNB_index);
|
|
//mac_xface->macphy_exit("after decode_SIB1");
|
|
|
|
}
|
|
}
|
|
break;
|
|
case BCCH_DL_SCH_MessageType__c1_PR_systemInformation:
|
|
if ((UE_rrc_inst[Mod_id].Info[eNB_index].SIB1Status == 1) &&
|
|
(UE_rrc_inst[Mod_id].Info[eNB_index].SIStatus == 0)) {
|
|
// if ((frame %8) == 1) { // check only in odd frames for SI
|
|
si_window = (frame%(UE_rrc_inst[Mod_id].Info[eNB_index].SIperiod/10))/(UE_rrc_inst[Mod_id].Info[eNB_index].SIwindowsize/10);
|
|
memcpy((void*)si[si_window],
|
|
(void*)&bcch_message->message.choice.c1.choice.systemInformation,
|
|
sizeof(SystemInformation_t));
|
|
LOG_D(RRC,"[UE %d] Decoding SI for frame %d, si_window %d\n",Mod_id,frame,si_window);
|
|
decode_SI(Mod_id,frame,eNB_index,si_window);
|
|
//mac_xface->macphy_exit("after decode_SI");
|
|
|
|
// }
|
|
}
|
|
break;
|
|
case BCCH_DL_SCH_MessageType__c1_PR_NOTHING:
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
/* if ((UE_rrc_inst[Mod_id].Info[eNB_index].SIB1Status == 1) &&
|
|
(UE_rrc_inst[Mod_id].Info[eNB_index].SIStatus == 1) && (frame >= Mod_id * 20 + 10))
|
|
SEQUENCE_free(&asn_DEF_BCCH_DL_SCH_Message, (void*)bcch_message, 0);*/
|
|
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int decode_SIB1(u8 Mod_id,u8 eNB_index) {
|
|
SystemInformationBlockType1_t **sib1=&UE_rrc_inst[Mod_id].sib1[eNB_index];
|
|
int i;
|
|
|
|
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_IN);
|
|
|
|
LOG_D(RRC,"[UE %d] : Dumping SIB 1\n",Mod_id);
|
|
|
|
// xer_fprint(stdout,&asn_DEF_SystemInformationBlockType1, (void*)*sib1);
|
|
|
|
LOG_D(RRC,"cellAccessRelatedInfo.cellIdentity : %x.%x.%x.%x\n",
|
|
(*sib1)->cellAccessRelatedInfo.cellIdentity.buf[0],
|
|
(*sib1)->cellAccessRelatedInfo.cellIdentity.buf[1],
|
|
(*sib1)->cellAccessRelatedInfo.cellIdentity.buf[2],
|
|
(*sib1)->cellAccessRelatedInfo.cellIdentity.buf[3]);
|
|
|
|
LOG_D(RRC,"cellSelectionInfo.q_RxLevMin : %d\n",(int)(*sib1)->cellSelectionInfo.q_RxLevMin);
|
|
LOG_D(RRC,"freqBandIndicator : %d\n",(int)(*sib1)->freqBandIndicator);
|
|
LOG_D(RRC,"siWindowLength : %s\n",siWindowLength[(*sib1)->si_WindowLength]);
|
|
if ((*sib1)->schedulingInfoList.list.count>0) {
|
|
for (i=0;i<(*sib1)->schedulingInfoList.list.count;i++) {
|
|
LOG_D(RRC,"siSchedulingInfoPeriod[%d] : %s\n",i,SIBPeriod[(int)(*sib1)->schedulingInfoList.list.array[i]->si_Periodicity]);
|
|
if ((*sib1)->schedulingInfoList.list.array[i]->sib_MappingInfo.list.count>0)
|
|
LOG_D(RRC,"siSchedulingInfoSIBType[%d] : %s\n",i,SIBType[(int)(*(*sib1)->schedulingInfoList.list.array[i]->sib_MappingInfo.list.array[0])]);
|
|
else {
|
|
LOG_W(RRC,"mapping list %d is null\n",i);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
LOG_E(RRC,"siSchedulingInfoPeriod[0] : PROBLEM!!!\n");
|
|
return -1;
|
|
}
|
|
|
|
if ((*sib1)->tdd_Config) {
|
|
LOG_D(RRC,"TDD subframe assignment : %d\n",(int)(*sib1)->tdd_Config->subframeAssignment);
|
|
LOG_D(RRC,"S-Subframe Config : %d\n",(int)(*sib1)->tdd_Config->specialSubframePatterns);
|
|
}
|
|
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].SIperiod = siPeriod_int[(*sib1)->schedulingInfoList.list.array[0]->si_Periodicity];
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].SIwindowsize = siWindowLength_int[(*sib1)->si_WindowLength];
|
|
LOG_D(RRC, "[MSC_MSG][FRAME unknown][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SIB1 params eNB %d) --->][MAC_UE][MOD %02d][]\n",
|
|
Mod_id, eNB_index, Mod_id);
|
|
|
|
rrc_mac_config_req(Mod_id,0,0,eNB_index,
|
|
(RadioResourceConfigCommonSIB_t *)NULL,
|
|
(struct PhysicalConfigDedicated *)NULL,
|
|
(MeasObjectToAddMod_t **)NULL,
|
|
(MAC_MainConfig_t *)NULL,
|
|
0,
|
|
(struct LogicalChannelConfig *)NULL,
|
|
(MeasGapConfig_t *)NULL,
|
|
UE_rrc_inst[Mod_id].sib1[eNB_index]->tdd_Config,
|
|
(MobilityControlInfo_t *) NULL,
|
|
&UE_rrc_inst[Mod_id].Info[eNB_index].SIwindowsize,
|
|
&UE_rrc_inst[Mod_id].Info[eNB_index].SIperiod,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
(MBSFN_SubframeConfigList_t *)NULL
|
|
#ifdef Rel10
|
|
,0,
|
|
(MBSFN_AreaInfoList_r9_t *)NULL,
|
|
(PMCH_InfoList_r9_t *)NULL
|
|
#endif
|
|
#ifdef CBA
|
|
,
|
|
0,
|
|
0
|
|
#endif
|
|
);
|
|
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].SIB1Status = 1;
|
|
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_OUT);
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
void dump_sib2(SystemInformationBlockType2_t *sib2) {
|
|
|
|
LOG_D(RRC,"radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.numberOfRA_Preambles : %ld\n",
|
|
sib2->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.numberOfRA_Preambles);
|
|
|
|
// if (radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig)
|
|
//msg("radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig ",sib2->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig = NULL;
|
|
|
|
LOG_D(RRC,"[UE]radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.powerRampingStep : %ld\n",sib2->radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.powerRampingStep);
|
|
|
|
LOG_D(RRC,"[UE]radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.preambleInitialReceivedTargetPower : %ld\n",sib2->radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.preambleInitialReceivedTargetPower);
|
|
|
|
LOG_D(RRC,"radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.preambleTransMax : %ld\n",sib2->radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.preambleTransMax);
|
|
|
|
LOG_D(RRC,"radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.ra_ResponseWindowSize : %ld\n",sib2->radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.ra_ResponseWindowSize);
|
|
|
|
LOG_D(RRC,"radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.mac_ContentionResolutionTimer : %ld\n",sib2->radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.mac_ContentionResolutionTimer);
|
|
|
|
LOG_D(RRC,"radioResourceConfigCommon.rach_ConfigCommon.maxHARQ_Msg3Tx : %ld\n",
|
|
sib2->radioResourceConfigCommon.rach_ConfigCommon.maxHARQ_Msg3Tx);
|
|
|
|
LOG_D(RRC,"radioResourceConfigCommon.prach_Config.rootSequenceIndex : %ld\n",sib2->radioResourceConfigCommon.prach_Config.rootSequenceIndex);
|
|
LOG_D(RRC,"radioResourceConfigCommon.prach_Config.prach_ConfigInfo.prach_ConfigIndex : %ld\n",sib2->radioResourceConfigCommon.prach_Config.prach_ConfigInfo.prach_ConfigIndex);
|
|
LOG_D(RRC,"radioResourceConfigCommon.prach_Config.prach_ConfigInfo.highSpeedFlag : %d\n", (int)sib2->radioResourceConfigCommon.prach_Config.prach_ConfigInfo.highSpeedFlag);
|
|
LOG_D(RRC,"radioResourceConfigCommon.prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig : %ld\n", sib2->radioResourceConfigCommon.prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig);
|
|
LOG_D(RRC,"radioResourceConfigCommon.prach_Config.prach_ConfigInfo.prach_FreqOffset %ld\n", sib2->radioResourceConfigCommon.prach_Config.prach_ConfigInfo.prach_FreqOffset);
|
|
|
|
// PDSCH-Config
|
|
LOG_D(RRC,"radioResourceConfigCommon.pdsch_ConfigCommon.referenceSignalPower : %ld\n",sib2->radioResourceConfigCommon.pdsch_ConfigCommon.referenceSignalPower);
|
|
LOG_D(RRC,"radioResourceConfigCommon.pdsch_ConfigCommon.p_b : %ld\n",sib2->radioResourceConfigCommon.pdsch_ConfigCommon.p_b);
|
|
|
|
// PUSCH-Config
|
|
LOG_D(RRC,"radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.n_SB : %ld\n",sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.n_SB);
|
|
LOG_D(RRC,"radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode : %ld\n",sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode);
|
|
LOG_D(RRC,"radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset : %ld\n",sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset);
|
|
LOG_D(RRC,"radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM : %d\n",(int)sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM);
|
|
LOG_D(RRC,"radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled : %d\n",(int)sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled);
|
|
LOG_D(RRC,"radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH : %ld\n",sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH);
|
|
LOG_D(RRC,"radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled : %d\n",(int)sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled);
|
|
LOG_D(RRC,"radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift : %ld\n",sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift);
|
|
|
|
// PUCCH-Config
|
|
|
|
LOG_D(RRC,"radioResourceConfigCommon.pucch_ConfigCommon.deltaPUCCH_Shift : %ld\n",sib2->radioResourceConfigCommon.pucch_ConfigCommon.deltaPUCCH_Shift);
|
|
LOG_D(RRC,"radioResourceConfigCommon.pucch_ConfigCommon.nRB_CQI : %ld\n",sib2->radioResourceConfigCommon.pucch_ConfigCommon.nRB_CQI);
|
|
LOG_D(RRC,"radioResourceConfigCommon.pucch_ConfigCommon.nCS_AN : %ld\n",sib2->radioResourceConfigCommon.pucch_ConfigCommon.nCS_AN);
|
|
LOG_D(RRC,"radioResourceConfigCommon.pucch_ConfigCommon.n1PUCCH_AN : %ld\n",sib2->radioResourceConfigCommon.pucch_ConfigCommon.n1PUCCH_AN);
|
|
|
|
LOG_D(RRC,"radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present : %d\n",sib2-> radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present);
|
|
|
|
|
|
// uplinkPowerControlCommon
|
|
|
|
LOG_D(RRC,"radioResourceConfigCommon.uplinkPowerControlCommon.p0_NominalPUSCH : %ld\n",sib2->radioResourceConfigCommon.uplinkPowerControlCommon.p0_NominalPUSCH);
|
|
LOG_D(RRC,"radioResourceConfigCommon.uplinkPowerControlCommon.alpha : %ld\n",sib2->radioResourceConfigCommon.uplinkPowerControlCommon.alpha);
|
|
|
|
LOG_D(RRC,"radioResourceConfigCommon.uplinkPowerControlCommon.p0_NominalPUCCH : %ld\n",sib2->radioResourceConfigCommon.uplinkPowerControlCommon.p0_NominalPUCCH);
|
|
LOG_D(RRC,"radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1 : %ld\n",sib2->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1);
|
|
LOG_D(RRC,"radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1b :%ld\n",sib2->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1b);
|
|
LOG_D(RRC,"radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2 :%ld\n",sib2->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2);
|
|
LOG_D(RRC,"radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2a :%ld\n",sib2->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2a);
|
|
LOG_D(RRC,"radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2b :%ld\n",sib2->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2b);
|
|
|
|
LOG_D(RRC,"radioResourceConfigCommon.uplinkPowerControlCommon.deltaPreambleMsg3 : %ld\n",sib2->radioResourceConfigCommon.uplinkPowerControlCommon.deltaPreambleMsg3);
|
|
|
|
LOG_D(RRC,"radioResourceConfigCommon.ul_CyclicPrefixLength : %ld\n", sib2->radioResourceConfigCommon.ul_CyclicPrefixLength);
|
|
|
|
LOG_D(RRC,"ue_TimersAndConstants.t300 : %ld\n", sib2->ue_TimersAndConstants.t300);
|
|
LOG_D(RRC,"ue_TimersAndConstants.t301 : %ld\n", sib2->ue_TimersAndConstants.t301);
|
|
LOG_D(RRC,"ue_TimersAndConstants.t310 : %ld\n", sib2->ue_TimersAndConstants.t310);
|
|
LOG_D(RRC,"ue_TimersAndConstants.n310 : %ld\n", sib2->ue_TimersAndConstants.n310);
|
|
LOG_D(RRC,"ue_TimersAndConstants.t311 : %ld\n", sib2->ue_TimersAndConstants.t311);
|
|
LOG_D(RRC,"ue_TimersAndConstants.n311 : %ld\n", sib2->ue_TimersAndConstants.n311);
|
|
|
|
LOG_D(RRC,"freqInfo.additionalSpectrumEmission : %ld\n",sib2->freqInfo.additionalSpectrumEmission);
|
|
LOG_D(RRC,"freqInfo.ul_CarrierFreq : %p\n", sib2->freqInfo.ul_CarrierFreq);
|
|
LOG_D(RRC,"freqInfo.ul_Bandwidth : %p\n", sib2->freqInfo.ul_Bandwidth);
|
|
LOG_D(RRC,"mbsfn_SubframeConfigList : %p\n", sib2->mbsfn_SubframeConfigList);
|
|
LOG_D(RRC,"timeAlignmentTimerCommon : %ld\n", sib2->timeAlignmentTimerCommon);
|
|
|
|
|
|
|
|
}
|
|
|
|
void dump_sib3(SystemInformationBlockType3_t *sib3) {
|
|
|
|
}
|
|
|
|
#ifdef Rel10
|
|
void dump_sib13(SystemInformationBlockType13_r9_t *sib13) {
|
|
|
|
LOG_D(RRC,"[RRC][UE] Dumping SIB13\n");
|
|
LOG_D(RRC,"[RRC][UE] dumping sib13 second time\n");
|
|
LOG_D(RRC,"[RRC][UE] NotificationRepetitionCoeff-r9 : %ld\n", sib13->notificationConfig_r9.notificationRepetitionCoeff_r9);
|
|
LOG_D(RRC,"[RRC][UE] NotificationOffset-r9 : %d\n", (int)sib13->notificationConfig_r9.notificationOffset_r9);
|
|
LOG_D(RRC,"[RRC][UE] NotificationSF-Index-r9 : %d\n", (int)sib13->notificationConfig_r9.notificationSF_Index_r9);
|
|
|
|
}
|
|
#endif
|
|
//const char SIBPeriod[7][7]= {"80ms\0","160ms\0","320ms\0","640ms\0","1280ms\0","2560ms\0","5120ms\0"};
|
|
int decode_SI(u8 Mod_id,u32 frame,u8 eNB_index,u8 si_window) {
|
|
|
|
SystemInformation_t **si=&UE_rrc_inst[Mod_id].si[eNB_index][si_window];
|
|
int i;
|
|
struct SystemInformation_r8_IEs_sib_TypeAndInfo_Member *typeandinfo;
|
|
|
|
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI , VCD_FUNCTION_IN);
|
|
|
|
// Dump contents
|
|
if ((*si)->criticalExtensions.present==SystemInformation__criticalExtensions_PR_systemInformation_r8) {
|
|
LOG_D(RRC,"(*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 (i=0;i<(*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count;i++) {
|
|
LOG_D(RRC,"SI count %d\n",i);
|
|
typeandinfo=(*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.array[i];
|
|
|
|
switch(typeandinfo->present) {
|
|
case SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib2:
|
|
UE_rrc_inst[Mod_id].sib2[eNB_index] = &typeandinfo->choice.sib2;
|
|
LOG_D(RRC,"[UE %d] Frame %d Found SIB2 from eNB %d\n",Mod_id,frame,eNB_index);
|
|
dump_sib2(UE_rrc_inst[Mod_id].sib2[eNB_index]);
|
|
LOG_D(RRC, "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SIB2 params eNB %d) --->][MAC_UE][MOD %02d][]\n",
|
|
frame, Mod_id, eNB_index, Mod_id);
|
|
rrc_mac_config_req(Mod_id,0,0,eNB_index,
|
|
&UE_rrc_inst[Mod_id].sib2[eNB_index]->radioResourceConfigCommon,
|
|
(struct PhysicalConfigDedicated *)NULL,
|
|
(MeasObjectToAddMod_t **)NULL,
|
|
(MAC_MainConfig_t *)NULL,
|
|
0,
|
|
(struct LogicalChannelConfig *)NULL,
|
|
(MeasGapConfig_t *)NULL,
|
|
(TDD_Config_t *)NULL,
|
|
(MobilityControlInfo_t *)NULL,
|
|
NULL,
|
|
NULL,
|
|
UE_rrc_inst[Mod_id].sib2[eNB_index]->freqInfo.ul_CarrierFreq,
|
|
UE_rrc_inst[Mod_id].sib2[eNB_index]->freqInfo.ul_Bandwidth,
|
|
&UE_rrc_inst[Mod_id].sib2[eNB_index]->freqInfo.additionalSpectrumEmission,
|
|
UE_rrc_inst[Mod_id].sib2[eNB_index]->mbsfn_SubframeConfigList
|
|
#ifdef Rel10
|
|
,0,
|
|
(MBSFN_AreaInfoList_r9_t *)NULL,
|
|
(PMCH_InfoList_r9_t *)NULL
|
|
#endif
|
|
#ifdef CBA
|
|
,0,
|
|
0
|
|
#endif
|
|
);
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].SIStatus = 1;
|
|
// After SI is received, prepare RRCConnectionRequest
|
|
#ifdef Rel10
|
|
if (UE_rrc_inst[Mod_id].MBMS_flag < 3) // see -Q option
|
|
#endif
|
|
rrc_ue_generate_RRCConnectionRequest(Mod_id,frame,eNB_index);
|
|
LOG_I(RRC, "not sending connection request\n");
|
|
|
|
if (UE_rrc_inst[Mod_id].Info[eNB_index].State == RRC_IDLE) {
|
|
LOG_I(RRC,"[UE %d] Received SIB1/SIB2/SIB3 Switching to RRC_SI_RECEIVED\n",Mod_id);
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].State = RRC_SI_RECEIVED;
|
|
}
|
|
break;
|
|
case SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib3:
|
|
UE_rrc_inst[Mod_id].sib3[eNB_index] = &typeandinfo->choice.sib3;
|
|
LOG_I(RRC,"[UE %d] Frame %d Found SIB3 from eNB %d\n",Mod_id,frame,eNB_index);
|
|
dump_sib3(UE_rrc_inst[Mod_id].sib3[eNB_index]);
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].SIStatus = 1;
|
|
break;
|
|
case SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib4:
|
|
UE_rrc_inst[Mod_id].sib4[eNB_index] = &typeandinfo->choice.sib4;
|
|
LOG_I(RRC,"[UE %d] Frame %d Found SIB4 from eNB %d\n",Mod_id,frame,eNB_index);
|
|
break;
|
|
case SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib5:
|
|
UE_rrc_inst[Mod_id].sib5[eNB_index] = &typeandinfo->choice.sib5;
|
|
LOG_I(RRC,"[UE %d] Found SIB5 from eNB %d\n",Mod_id,eNB_index);
|
|
break;
|
|
case SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib6:
|
|
UE_rrc_inst[Mod_id].sib6[eNB_index] = &typeandinfo->choice.sib6;
|
|
LOG_I(RRC,"[UE %d] Found SIB6 from eNB %d\n",Mod_id,eNB_index);
|
|
break;
|
|
case SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib7:
|
|
UE_rrc_inst[Mod_id].sib7[eNB_index] = &typeandinfo->choice.sib7;
|
|
LOG_I(RRC,"[UE %d] Found SIB7 from eNB %d\n",Mod_id,eNB_index);
|
|
break;
|
|
case SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib8:
|
|
UE_rrc_inst[Mod_id].sib8[eNB_index] = &typeandinfo->choice.sib8;
|
|
LOG_I(RRC,"[UE %d] Found SIB8 from eNB %d\n",Mod_id,eNB_index);
|
|
break;
|
|
case SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib9:
|
|
UE_rrc_inst[Mod_id].sib9[eNB_index] = &typeandinfo->choice.sib9;
|
|
LOG_I(RRC,"[UE %d] Found SIB9 from eNB %d\n",Mod_id,eNB_index);
|
|
break;
|
|
case SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib10:
|
|
UE_rrc_inst[Mod_id].sib10[eNB_index] = &typeandinfo->choice.sib10;
|
|
LOG_I(RRC,"[UE %d] Found SIB10 from eNB %d\n",Mod_id,eNB_index);
|
|
break;
|
|
case SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib11:
|
|
UE_rrc_inst[Mod_id].sib11[eNB_index] = &typeandinfo->choice.sib11;
|
|
LOG_I(RRC,"[UE %d] Found SIB11 from eNB %d\n",Mod_id,eNB_index);
|
|
break;
|
|
#ifdef Rel10
|
|
case SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib12_v920:
|
|
UE_rrc_inst[Mod_id].sib12[eNB_index] = &typeandinfo->choice.sib12_v920;
|
|
LOG_I(RRC,"[RRC][UE %d] Found SIB12 from eNB %d\n",Mod_id,eNB_index);
|
|
|
|
break;
|
|
case SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib13_v920:
|
|
UE_rrc_inst[Mod_id].sib13[eNB_index] = &typeandinfo->choice.sib13_v920;
|
|
LOG_I(RRC,"[RRC][UE %d] Found SIB13 from eNB %d\n",Mod_id,eNB_index);
|
|
dump_sib13(UE_rrc_inst[Mod_id].sib13[eNB_index]);
|
|
// adding here function to store necessary parameters for using in decode_MCCH_Message + maybe transfer to PHY layer
|
|
LOG_D(RRC, "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SIB13 params eNB %d) --->][MAC_UE][MOD %02d][]\n",
|
|
frame, Mod_id, eNB_index, Mod_id);
|
|
rrc_mac_config_req(Mod_id,0,0,eNB_index,
|
|
(RadioResourceConfigCommonSIB_t *)NULL,
|
|
(struct PhysicalConfigDedicated *)NULL,
|
|
(MeasObjectToAddMod_t **)NULL,
|
|
(MAC_MainConfig_t *)NULL,
|
|
0,
|
|
(struct LogicalChannelConfig *)NULL,
|
|
(MeasGapConfig_t *)NULL,
|
|
(TDD_Config_t *)NULL,
|
|
(MobilityControlInfo_t *)NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
(MBSFN_SubframeConfigList_t *)NULL
|
|
#ifdef Rel10
|
|
,0,
|
|
&UE_rrc_inst[Mod_id].sib13[eNB_index]->mbsfn_AreaInfoList_r9,
|
|
(PMCH_InfoList_r9_t *)NULL
|
|
#endif
|
|
#ifdef CBA
|
|
,0,
|
|
0
|
|
#endif
|
|
);
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].SIStatus = 1;
|
|
break;
|
|
#endif
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
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(u8 Mod_id,u32 frame,u8 eNB_index){
|
|
float a = UE_rrc_inst[Mod_id].filter_coeff_rsrp; // 'a' in 36.331 Sec. 5.5.3.2
|
|
float a1 = UE_rrc_inst[Mod_id].filter_coeff_rsrq;
|
|
//float rsrp_db, rsrq_db;
|
|
u8 eNB_offset;
|
|
|
|
if(UE_rrc_inst[Mod_id].QuantityConfig[0] != NULL) { // Only consider 1 serving cell (index: 0)
|
|
if (UE_rrc_inst[Mod_id].QuantityConfig[0]->quantityConfigEUTRA != NULL) {
|
|
if(UE_rrc_inst[Mod_id].QuantityConfig[0]->quantityConfigEUTRA->filterCoefficientRSRP != NULL) {
|
|
for (eNB_offset = 0;eNB_offset<1+mac_xface->get_n_adj_cells(Mod_id);eNB_offset++) {
|
|
//filter_factor = 1/power(2,*UE_rrc_inst[Mod_id].QuantityConfig[0]->quantityConfigEUTRA->filterCoefficientRSRP/4);
|
|
// LOG_N(RRC,"[UE %d] Frame %d : check proper operation in abstraction mode rsrp (%d), rx gain (%d) N_RB_DL (%d)\n",
|
|
// Mod_id,frame,mac_xface->get_RSRP(Mod_id,eNB_offset),mac_xface->get_rx_total_gain_dB(Mod_id),mac_xface->lte_frame_parms->N_RB_DL);
|
|
UE_rrc_inst[Mod_id].rsrp_db[eNB_offset] = (dB_fixed_times10(mac_xface->get_RSRP(Mod_id,eNB_offset))/10.0)-mac_xface->get_rx_total_gain_dB(Mod_id)-dB_fixed(mac_xface->lte_frame_parms->N_RB_DL*12);
|
|
UE_rrc_inst[Mod_id].rsrp_db_filtered[eNB_offset] = (1.0-a)*UE_rrc_inst[Mod_id].rsrp_db_filtered[eNB_offset] + a*UE_rrc_inst[Mod_id].rsrp_db[eNB_offset];
|
|
//mac_xface->set_RSRP_filtered(Mod_id,eNB_offset,UE_rrc_inst[Mod_id].rsrp_db_filtered[eNB_offset]);
|
|
|
|
LOG_D(RRC,"[UE %d] Frame %d: Meas RSRP: eNB_offset: %d rsrp_coef: %3.2f filter_coef: %d before L3 filtering: rsrp: %3.1f after L3 filtering: rsrp: %3.1f \n ",
|
|
Mod_id, frame, eNB_offset,a,
|
|
*UE_rrc_inst->QuantityConfig[0]->quantityConfigEUTRA->filterCoefficientRSRP,
|
|
UE_rrc_inst[Mod_id].rsrp_db[eNB_offset],
|
|
UE_rrc_inst[Mod_id].rsrp_db_filtered[eNB_offset]);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
for (eNB_offset = 0;eNB_offset<1+mac_xface->get_n_adj_cells(Mod_id);eNB_offset++) {
|
|
UE_rrc_inst[Mod_id].rsrp_db_filtered[eNB_offset]= mac_xface->get_RSRP(Mod_id,eNB_offset);
|
|
// phy_vars_ue->PHY_measurements.rsrp_filtered[eNB_offset]=UE_rrc_inst[Mod_id].rsrp_db_filtered[eNB_offset];
|
|
//mac_xface->set_RSRP_filtered(Mod_id,eNB_offset,UE_rrc_inst[Mod_id].rsrp_db_filtered[eNB_offset]);
|
|
}
|
|
}
|
|
if (UE_rrc_inst[Mod_id].QuantityConfig[0]->quantityConfigEUTRA != NULL) {
|
|
if(UE_rrc_inst[Mod_id].QuantityConfig[0]->quantityConfigEUTRA->filterCoefficientRSRQ != NULL) {
|
|
for (eNB_offset = 0;eNB_offset<1+mac_xface->get_n_adj_cells(Mod_id);eNB_offset++) {
|
|
// LOG_N(RRC,"[UE %d] Frame %d : check if this operation workes properly in abstraction mode\n",Mod_id,frame);
|
|
UE_rrc_inst[Mod_id].rsrq_db[eNB_offset] = (10*log10(mac_xface->get_RSRQ(Mod_id,eNB_offset)))-20;
|
|
UE_rrc_inst[Mod_id].rsrq_db_filtered[eNB_offset]=(1-a1)*UE_rrc_inst[Mod_id].rsrq_db_filtered[eNB_offset] + a1 *UE_rrc_inst[Mod_id].rsrq_db[eNB_offset];
|
|
//mac_xface->set_RSRP_filtered(Mod_id,eNB_offset,UE_rrc_inst[Mod_id].rsrp_db_filtered[eNB_offset]);
|
|
/*
|
|
LOG_D(RRC,"[UE %d] meas RSRQ: eNB_offset: %d rsrq_coef: %3.2f filter_coef: %d before L3 filtering: rsrq: %3.1f after L3 filtering: rsrq: %3.1f \n ",
|
|
Mod_id, eNB_offset,
|
|
a1,
|
|
*UE_rrc_inst->QuantityConfig[0]->quantityConfigEUTRA->filterCoefficientRSRQ,
|
|
mac_xface->get_RSRQ(Mod_id,eNB_offset),
|
|
UE_rrc_inst[Mod_id].rsrq_db[eNB_offset],
|
|
UE_rrc_inst[Mod_id].rsrq_db_filtered[eNB_offset]);
|
|
*/
|
|
}
|
|
}
|
|
}
|
|
else{
|
|
for (eNB_offset = 0;eNB_offset<1+mac_xface->get_n_adj_cells(Mod_id);eNB_offset++) {
|
|
UE_rrc_inst[Mod_id].rsrq_db_filtered[eNB_offset]= mac_xface->get_RSRQ(Mod_id,eNB_offset);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//Below routine implements Measurement Reporting procedure from 36.331 Section 5.5.5
|
|
void rrc_ue_generate_MeasurementReport(u8 Mod_id, u32 frame,u8 eNB_index) {
|
|
|
|
u8 buffer[32], size;
|
|
u8 i;
|
|
u8 target_eNB_offset;
|
|
MeasId_t measId;
|
|
PhysCellId_t cellId, targetCellId;
|
|
long rsrq_s,rsrp_t,rsrq_t;
|
|
long rsrp_s, nElem, nElem1;
|
|
float rsrp_filtered, rsrq_filtered;
|
|
nElem = 100;
|
|
nElem1 = 33;
|
|
static u32 pframe=0;
|
|
target_eNB_offset = UE_rrc_inst[Mod_id].Info[0].handoverTarget; // eNB_offset of target eNB: used to obtain the mod_id of target eNB
|
|
|
|
for (i=0;i<MAX_MEAS_ID;i++) {
|
|
if (UE_rrc_inst[Mod_id].measReportList[0][i] != NULL) {
|
|
measId = UE_rrc_inst[Mod_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[Mod_id].rsrp_db_filtered[eNB_index];//nid_cell];
|
|
rsrp_s = binary_search_float(RSRP_meas_mapping,nElem, rsrp_filtered); //mapped RSRP of serving cell
|
|
|
|
rsrq_filtered = UE_rrc_inst[Mod_id].rsrq_db_filtered[eNB_index];//nid_cell]; //RSRQ of serving cell
|
|
rsrq_s = binary_search_float(RSRQ_meas_mapping,nElem1,rsrp_filtered);//mapped RSRQ of serving cell
|
|
|
|
LOG_D(RRC,"[UE %d] Frame %d: source eNB %d :rsrp_s: %d rsrq_s: %d tmp: %f tmp1: %f \n",
|
|
Mod_id,frame,eNB_index, rsrp_s,rsrq_s,rsrp_filtered,rsrq_filtered);
|
|
|
|
rsrp_t = binary_search_float(RSRP_meas_mapping,nElem,UE_rrc_inst[Mod_id].rsrp_db_filtered[target_eNB_offset]); //RSRP of target cell
|
|
rsrq_t = binary_search_float(RSRQ_meas_mapping,nElem1,UE_rrc_inst[Mod_id].rsrq_db_filtered[target_eNB_offset]); //RSRQ of target cell
|
|
|
|
// if (measFlag == 1) {
|
|
cellId = get_adjacent_cell_id(Mod_id,eNB_index); //PhycellId of serving cell
|
|
targetCellId = UE_rrc_inst[Mod_id].HandoverInfoUe.targetCellId ;//get_adjacent_cell_id(Mod_id,target_eNB_offset); //PhycellId of target cell
|
|
|
|
if (pframe!=frame){
|
|
pframe=frame;
|
|
size = do_MeasurementReport(buffer,measId,targetCellId,rsrp_s,rsrq_s,rsrp_t,rsrq_t);
|
|
LOG_D(RRC,"[UE %d] Frame %d: Sending MeasReport: servingCell(%d) targetCell(%d) rsrp_s(%d) rsrq_s(%d) rsrp_t(%d) rsrq_t(%d) \n",
|
|
Mod_id, frame, cellId,targetCellId,rsrp_s,rsrq_s,rsrp_t,rsrq_t);
|
|
LOG_I(RRC,"[UE %d] Frame %d : Generating Measurement Report for eNB %d\n",Mod_id,frame,eNB_index);
|
|
LOG_D(RLC,"[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (MeasurementReport to eNB %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n",
|
|
frame, Mod_id+NB_eNB_INST, size, eNB_index, rrc_mui, Mod_id+NB_eNB_INST, DCCH);
|
|
pdcp_data_req(Mod_id+NB_eNB_INST,frame,0,DCCH,rrc_mui++,0,size,buffer,1);
|
|
//LOG_D(RRC, "[UE %d] Frame %d Sending MeasReport (%d bytes) through DCCH%d to PDCP \n",Mod_id,frame, size, DCCH);
|
|
}
|
|
// measFlag = 0; //re-setting measFlag so that no more MeasReports are sent in this frame
|
|
// }
|
|
}
|
|
}
|
|
}
|
|
|
|
// Measurement report triggering, described in 36.331 Section 5.5.4.1: called periodically
|
|
void ue_measurement_report_triggering(u8 Mod_id, u32 frame,u8 eNB_index) {
|
|
u8 i,j;
|
|
Hysteresis_t hys;
|
|
TimeToTrigger_t ttt_ms;
|
|
Q_OffsetRange_t ofn;
|
|
Q_OffsetRange_t ocn;
|
|
Q_OffsetRange_t ofs = 0;
|
|
Q_OffsetRange_t ocs = 0;
|
|
long a3_offset;
|
|
MeasObjectId_t measObjId;
|
|
ReportConfigId_t reportConfigId;
|
|
|
|
for(i=0 ; i<NB_CNX_UE ; i++) {
|
|
for(j=0 ; j<MAX_MEAS_ID ; j++) {
|
|
if(UE_rrc_inst[Mod_id].MeasId[i][j] != NULL) {
|
|
measObjId = UE_rrc_inst[Mod_id].MeasId[i][j]->measObjectId;
|
|
reportConfigId = UE_rrc_inst[Mod_id].MeasId[i][j]->reportConfigId;
|
|
if( /*UE_rrc_inst[Mod_id].MeasId[i][j] != NULL && */ UE_rrc_inst[Mod_id].MeasObj[i][measObjId-1] != NULL) {
|
|
if(UE_rrc_inst[Mod_id].MeasObj[i][measObjId-1]->measObject.present == MeasObjectToAddMod__measObject_PR_measObjectEUTRA) {
|
|
/* consider any neighboring cell detected on the associated frequency to be
|
|
* applicable when the concerned cell is not included in the blackCellsToAddModList
|
|
* defined within the VarMeasConfig for this measId */
|
|
// LOG_I(RRC,"event %d %d %p \n", measObjId,reportConfigId, UE_rrc_inst[Mod_id].ReportConfig[i][reportConfigId-1]);
|
|
if((UE_rrc_inst[Mod_id].ReportConfig[i][reportConfigId-1] != NULL) &&
|
|
(UE_rrc_inst[Mod_id].ReportConfig[i][reportConfigId-1]->reportConfig.present==ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA) &&
|
|
(UE_rrc_inst[Mod_id].ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.present == ReportConfigEUTRA__triggerType_PR_event)) {
|
|
hys = UE_rrc_inst[Mod_id].ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis;
|
|
//LOG_N(RRC,"[UE%d] Frame %d Check below lines for segfault :), Fix me \n",Mod_id, frame);
|
|
ttt_ms = timeToTrigger_ms[UE_rrc_inst[Mod_id].ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger];
|
|
// Freq specific offset of neighbor cell freq
|
|
ofn = ((UE_rrc_inst[Mod_id].MeasObj[i][measObjId-1]->measObject.choice.measObjectEUTRA.offsetFreq != NULL) ?
|
|
*UE_rrc_inst[Mod_id].MeasObj[i][measObjId-1]->measObject.choice.measObjectEUTRA.offsetFreq : 15); // /* 15 is the Default */
|
|
// cellIndividualOffset of neighbor cell - not defined yet
|
|
ocn = 0;
|
|
a3_offset = UE_rrc_inst[Mod_id].ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset;
|
|
|
|
switch (UE_rrc_inst[Mod_id].ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present) {
|
|
case ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1:
|
|
LOG_D(RRC,"[UE %d] Frame %d : A1 event: check if serving becomes better than threshold\n",Mod_id, frame);
|
|
break;
|
|
case ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2:
|
|
LOG_D(RRC,"[UE %d] Frame %d : A2 event, check if serving becomes worse than a threshold\n",Mod_id, frame);
|
|
break;
|
|
case 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",Mod_id, frame);
|
|
if ((check_trigger_meas_event(Mod_id,frame,eNB_index,i,j,ofn,ocn,hys,ofs,ocs,a3_offset,ttt_ms)) &&
|
|
(UE_rrc_inst[Mod_id].Info[0].State >= RRC_CONNECTED) &&
|
|
(UE_rrc_inst[Mod_id].Info[0].T304_active == 0 ) &&
|
|
(UE_rrc_inst[Mod_id].HandoverInfoUe.measFlag == 1)) {
|
|
//trigger measurement reporting procedure (36.331, section 5.5.5)
|
|
if (UE_rrc_inst[Mod_id].measReportList[i][j] == NULL) {
|
|
UE_rrc_inst[Mod_id].measReportList[i][j] = malloc(sizeof(MEAS_REPORT_LIST));
|
|
}
|
|
UE_rrc_inst[Mod_id].measReportList[i][j]->measId = UE_rrc_inst[Mod_id].MeasId[i][j]->measId;
|
|
UE_rrc_inst[Mod_id].measReportList[i][j]->numberOfReportsSent = 0;
|
|
rrc_ue_generate_MeasurementReport(Mod_id,frame,eNB_index);
|
|
UE_rrc_inst[Mod_id].HandoverInfoUe.measFlag = 1;
|
|
LOG_I(RRC,"[UE %d] Frame %d: A3 event detected, state: %d \n", Mod_id, frame, UE_rrc_inst[Mod_id].Info[0].State);
|
|
}
|
|
else {
|
|
if(UE_rrc_inst[Mod_id].measReportList[i][j] != NULL){
|
|
free(UE_rrc_inst[Mod_id].measReportList[i][j]);
|
|
}
|
|
UE_rrc_inst[Mod_id].measReportList[i][j] = NULL;
|
|
}
|
|
break;
|
|
case 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",Mod_id, frame);
|
|
break;
|
|
case 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",Mod_id, frame);
|
|
break;
|
|
default:
|
|
LOG_D(RRC,"Invalid ReportConfigEUTRA__triggerType__event__eventId: %d",
|
|
UE_rrc_inst[Mod_id].ReportConfig[i][j]->reportConfig.choice.reportConfigEUTRA.triggerType.present);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//check_trigger_meas_event(Mod_id, frame, eNB_index, i,j,ofn,ocn,hys,ofs,ocs,a3_offset,ttt_ms)
|
|
u8 check_trigger_meas_event(u8 Mod_id,u32 frame, u8 eNB_index, u8 ue_cnx_index, u8 meas_index,
|
|
Q_OffsetRange_t ofn, Q_OffsetRange_t ocn, Hysteresis_t hys,
|
|
Q_OffsetRange_t ofs, Q_OffsetRange_t ocs, long a3_offset, TimeToTrigger_t ttt) {
|
|
u8 eNB_offset;
|
|
u8 currentCellIndex = mac_xface->lte_frame_parms->Nid_cell;
|
|
|
|
LOG_I(RRC,"ofn(%d) ocn(%d) hys(%d) ofs(%d) ocs(%d) a3_offset(%d) ttt(%d) rssi %3.1f\n", \
|
|
ofn,ocn,hys,ofs,ocs,a3_offset,ttt,10*log10(mac_xface->get_RSSI(Mod_id))-mac_xface->get_rx_total_gain_dB(Mod_id));
|
|
|
|
// for (eNB_offset = 0;(eNB_offset<1+mac_xface->get_n_adj_cells(Mod_id))&& (eNB_offset!=eNB_index);eNB_offset++) {
|
|
for (eNB_offset = 1;(eNB_offset<1+mac_xface->get_n_adj_cells(Mod_id));eNB_offset++) {
|
|
/* RHS: Verify that idx 0 corresponds to currentCellIndex in rsrp array */
|
|
if(UE_rrc_inst[Mod_id].rsrp_db_filtered[eNB_offset]+ofn+ocn-hys > UE_rrc_inst[Mod_id].rsrp_db_filtered[0/*eNB_index*/]+ofs+ocs - 1 /*+a3_offset*/) {
|
|
UE_rrc_inst->measTimer[ue_cnx_index][meas_index][eNB_offset-1] += 2; //Called every subframe = 2ms
|
|
LOG_D(RRC,"[UE %d] Frame %d: Entry measTimer[%d][%d]: %d currentCell: %d betterCell: %d \n",
|
|
Mod_id, frame, ue_cnx_index,meas_index,UE_rrc_inst->measTimer[ue_cnx_index][meas_index][eNB_offset-1],currentCellIndex,eNB_offset);
|
|
}
|
|
else {
|
|
UE_rrc_inst->measTimer[ue_cnx_index][meas_index][eNB_offset-1] = 0; //Exit condition: Resetting the measurement timer
|
|
LOG_D(RRC,"[UE %d] Frame %d: Exit measTimer[%d][%d]: %d currentCell: %d betterCell: %d \n",
|
|
Mod_id, frame, ue_cnx_index,meas_index,UE_rrc_inst->measTimer[ue_cnx_index][meas_index][eNB_offset-1],currentCellIndex,eNB_offset);
|
|
}
|
|
if (UE_rrc_inst->measTimer[ue_cnx_index][meas_index][eNB_offset-1] >= ttt) {
|
|
UE_rrc_inst->HandoverInfoUe.targetCellId = get_adjacent_cell_id(Mod_id,eNB_offset-1); //check this!
|
|
LOG_D(RRC,"[UE %d] Frame %d eNB %d: Handover triggered: targetCellId: %d currentCellId: %d eNB_offset: %d rsrp source: %3.1f rsrp target: %3.1f\n", \
|
|
Mod_id, frame, eNB_index,
|
|
UE_rrc_inst->HandoverInfoUe.targetCellId,ue_cnx_index,eNB_offset,
|
|
(dB_fixed_times10(UE_rrc_inst[Mod_id].rsrp_db[0])/10.0)-mac_xface->get_rx_total_gain_dB(Mod_id)-dB_fixed(mac_xface->lte_frame_parms->N_RB_DL*12),
|
|
(dB_fixed_times10(UE_rrc_inst[Mod_id].rsrp_db[eNB_offset])/10.0)-mac_xface->get_rx_total_gain_dB(Mod_id)-dB_fixed(mac_xface->lte_frame_parms->N_RB_DL*12));
|
|
UE_rrc_inst->Info[0].handoverTarget = eNB_offset;
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#ifdef Rel10
|
|
int decode_MCCH_Message(u8 Mod_id, u32 frame, u8 eNB_index, u8 *Sdu, u8 Sdu_len,u8 mbsfn_sync_area) {
|
|
|
|
MCCH_Message_t *mcch=NULL;
|
|
MBSFNAreaConfiguration_r9_t **mcch_message=&UE_rrc_inst[Mod_id].mcch_message[eNB_index];
|
|
asn_dec_rval_t dec_rval;
|
|
|
|
if (UE_rrc_inst[Mod_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",
|
|
Mod_id, frame, mbsfn_sync_area);
|
|
return 0; // avoid decoding to prevent memory bloating
|
|
}
|
|
else {
|
|
dec_rval = uper_decode_complete(NULL,
|
|
&asn_DEF_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 (%d bits)\n",Mod_id,dec_rval.consumed);
|
|
//free the memory
|
|
SEQUENCE_free(&asn_DEF_MCCH_Message, (void*)mcch, 1);
|
|
return -1;
|
|
}
|
|
#ifdef XER_PRINT
|
|
xer_fprint(stdout, &asn_DEF_MCCH_Message, (void*)mcch);
|
|
#endif
|
|
|
|
if (mcch->message.present == MCCH_MessageType_PR_c1) {
|
|
LOG_D(RRC,"[UE %d] Found mcch message \n",Mod_id);
|
|
if(mcch->message.choice.c1.present == 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",Mod_id, frame, eNB_index);
|
|
decode_MBSFNAreaConfiguration(Mod_id,eNB_index,frame, mbsfn_sync_area);
|
|
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void decode_MBSFNAreaConfiguration(u8 Mod_id, u8 eNB_index, u32 frame,u8 mbsfn_sync_area) {
|
|
LOG_D(RRC,"[UE %d] Frame %d : Number of MCH(s) in the MBSFN Sync Area %d is %d\n",
|
|
Mod_id, frame, mbsfn_sync_area, UE_rrc_inst[Mod_id].mcch_message[eNB_index]->pmch_InfoList_r9.list.count);
|
|
// store to MAC/PHY necessary parameters for receiving MTCHs
|
|
rrc_mac_config_req(Mod_id,0,0,eNB_index,
|
|
(RadioResourceConfigCommonSIB_t *)NULL,
|
|
(struct PhysicalConfigDedicated *)NULL,
|
|
(MeasObjectToAddMod_t **)NULL,
|
|
(MAC_MainConfig_t *)NULL,
|
|
0,
|
|
(struct LogicalChannelConfig *)NULL,
|
|
(MeasGapConfig_t *)NULL,
|
|
(TDD_Config_t *)NULL,
|
|
(MobilityControlInfo_t *)NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
(MBSFN_SubframeConfigList_t *)NULL
|
|
#ifdef Rel10
|
|
,
|
|
0,
|
|
(MBSFN_AreaInfoList_r9_t *)NULL,
|
|
&UE_rrc_inst[Mod_id].mcch_message[eNB_index]->pmch_InfoList_r9
|
|
#endif
|
|
#ifdef CBA
|
|
,
|
|
0,
|
|
0
|
|
#endif
|
|
);
|
|
|
|
UE_rrc_inst[Mod_id].Info[eNB_index].MCCHStatus[mbsfn_sync_area] = 1;
|
|
|
|
// Config Radio Bearer for MBMS user data (similar way to configure for eNB side in init_MBMS function)
|
|
rrc_pdcp_config_asn1_req(NB_eNB_INST+Mod_id,frame,0,eNB_index,
|
|
NULL, // SRB_ToAddModList
|
|
NULL, // DRB_ToAddModList
|
|
(DRB_ToReleaseList_t*)NULL,
|
|
0, // security mode
|
|
NULL, // key rrc encryption
|
|
NULL, // key rrc integrity
|
|
NULL // key encryption
|
|
#ifdef Rel10
|
|
,&(UE_rrc_inst[Mod_id].mcch_message[eNB_index]->pmch_InfoList_r9)
|
|
#endif
|
|
);
|
|
|
|
rrc_rlc_config_asn1_req(NB_eNB_INST+Mod_id, frame,0,eNB_index,
|
|
NULL,// SRB_ToAddModList
|
|
NULL,// DRB_ToAddModList
|
|
NULL,// DRB_ToReleaseList
|
|
#ifdef Rel10
|
|
&(UE_rrc_inst[Mod_id].mcch_message[eNB_index]->pmch_InfoList_r9)
|
|
#endif
|
|
);
|
|
// */
|
|
|
|
}
|
|
|
|
#endif // rel10
|
|
|
|
#ifndef USER_MODE
|
|
EXPORT_SYMBOL(Rlc_info_am_config);
|
|
#endif
|
|
|
|
#if defined(ENABLE_ITTI)
|
|
void *rrc_ue_task(void *args_p) {
|
|
MessageDef *msg_p;
|
|
const char *msg_name;
|
|
instance_t instance;
|
|
unsigned int Mod_id;
|
|
SRB_INFO *srb_info_p;
|
|
|
|
itti_mark_task_ready (TASK_RRC_UE);
|
|
|
|
while(1) {
|
|
// Wait for a message
|
|
itti_receive_msg (TASK_RRC_UE, &msg_p);
|
|
|
|
msg_name = ITTI_MSG_NAME (msg_p);
|
|
instance = ITTI_MSG_INSTANCE (msg_p);
|
|
Mod_id = instance - NB_eNB_INST;
|
|
|
|
switch (ITTI_MSG_ID(msg_p)) {
|
|
case TERMINATE_MESSAGE:
|
|
itti_exit_task ();
|
|
break;
|
|
|
|
case MESSAGE_TEST:
|
|
LOG_D(RRC, "Received %s\n", msg_name);
|
|
break;
|
|
|
|
/* MAC messages */
|
|
case RRC_MAC_IN_SYNC_IND:
|
|
LOG_D(RRC, "Received %s: instance %d, frame %d, eNB %d\n", msg_name, instance,
|
|
RRC_MAC_IN_SYNC_IND (msg_p).frame, RRC_MAC_IN_SYNC_IND (msg_p).enb_index);
|
|
|
|
UE_rrc_inst[Mod_id].Info[RRC_MAC_IN_SYNC_IND (msg_p).enb_index].N310_cnt = 0;
|
|
if (UE_rrc_inst[Mod_id].Info[RRC_MAC_IN_SYNC_IND (msg_p).enb_index].T310_active == 1)
|
|
UE_rrc_inst[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, "Received %s: instance %d, frame %d, eNB %d\n", msg_name, instance,
|
|
RRC_MAC_OUT_OF_SYNC_IND (msg_p).frame, RRC_MAC_OUT_OF_SYNC_IND (msg_p).enb_index);
|
|
|
|
UE_rrc_inst[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, "Received %s: instance %d, frame %d, eNB %d\n", msg_name, instance,
|
|
RRC_MAC_BCCH_DATA_IND (msg_p).frame, RRC_MAC_BCCH_DATA_IND (msg_p).enb_index);
|
|
|
|
decode_BCCH_DLSCH_Message (Mod_id, RRC_MAC_BCCH_DATA_IND (msg_p).frame,
|
|
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);
|
|
break;
|
|
|
|
case RRC_MAC_CCCH_DATA_CNF:
|
|
LOG_D(RRC, "Received %s: instance %d, eNB %d\n", msg_name, instance,
|
|
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[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, "Received %s: instance %d, frame %d, eNB %d\n", msg_name, instance,
|
|
RRC_MAC_CCCH_DATA_IND (msg_p).frame, RRC_MAC_CCCH_DATA_IND (msg_p).enb_index);
|
|
|
|
srb_info_p = &UE_rrc_inst[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;
|
|
rrc_ue_decode_ccch (Mod_id, RRC_MAC_CCCH_DATA_IND (msg_p).frame, srb_info_p,
|
|
RRC_MAC_CCCH_DATA_IND (msg_p).enb_index);
|
|
break;
|
|
|
|
#ifdef Rel10
|
|
case RRC_MAC_MCCH_DATA_IND:
|
|
LOG_D(RRC, "Received %s: instance %d, frame %d, eNB %d, mbsfn SA %d\n", msg_name, instance,
|
|
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);
|
|
|
|
decode_MCCH_Message (Mod_id, RRC_MAC_MCCH_DATA_IND (msg_p).frame, 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;
|
|
#endif
|
|
|
|
/* PDCP messages */
|
|
case RRC_DCCH_DATA_IND:
|
|
LOG_D(RRC, "Received %s: instance %d, frame %d, DCCH %d, UE %d\n", msg_name, instance,
|
|
RRC_DCCH_DATA_IND (msg_p).frame, RRC_DCCH_DATA_IND (msg_p).dcch_index, RRC_DCCH_DATA_IND (msg_p).ue_index);
|
|
|
|
rrc_ue_decode_dcch (Mod_id, RRC_DCCH_DATA_IND (msg_p).frame,
|
|
RRC_DCCH_DATA_IND (msg_p).dcch_index, RRC_DCCH_DATA_IND (msg_p).sdu_p,
|
|
RRC_DCCH_DATA_IND (msg_p).ue_index);
|
|
|
|
// Message buffer has been processed, free it now.
|
|
free (RRC_DCCH_DATA_IND (msg_p).sdu_p);
|
|
break;
|
|
|
|
/* NAS messages */
|
|
case NAS_UPLINK_DATA_REQ:
|
|
{
|
|
uint32_t length;
|
|
uint8_t *buffer;
|
|
|
|
LOG_D(RRC, "Received %s: instance %d, UEid %d\n", msg_name, instance, NAS_UPLINK_DATA_REQ (msg_p).UEid);
|
|
|
|
/* Allocate a buffer for the NAS PDU payload plus some space for the encapsulation */
|
|
length = NAS_UPLINK_DATA_REQ (msg_p).nasMsg.length + 20;
|
|
buffer = malloc (length);
|
|
|
|
/* Create message for PDCP (ULInformationTransfer_t) */
|
|
length = do_ULInformationTransfer(length, buffer,
|
|
NAS_UPLINK_DATA_REQ (msg_p).nasMsg.length, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.data);
|
|
|
|
/* Transfer data to PDCP */
|
|
pdcp_rrc_data_req (instance, 0 /* TODO put frame number ! */, 0, DCCH, rrc_mui++, 0, length, buffer, 1);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
LOG_E(RRC, "Received unexpected message %s\n", msg_name);
|
|
break;
|
|
}
|
|
|
|
free (msg_p);
|
|
msg_p = NULL;
|
|
}
|
|
}
|
|
#endif
|