rrc_UE.c 187 KB
Newer Older
1
/*******************************************************************************
nikaeinn's avatar
nikaeinn committed
2 3
    OpenAirInterface
    Copyright(c) 1999 - 2014 Eurecom
4

nikaeinn's avatar
nikaeinn committed
5 6 7 8
    OpenAirInterface is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
9 10


nikaeinn's avatar
nikaeinn committed
11 12 13 14
    OpenAirInterface is distributed in the hope that 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.
15

nikaeinn's avatar
nikaeinn committed
16 17 18 19
    You should have received a copy of the GNU General Public License
    along with OpenAirInterface.The full GNU General Public License is
    included in this distribution in the file called "COPYING". If not,
    see <http://www.gnu.org/licenses/>.
20 21

  Contact Information
nikaeinn's avatar
nikaeinn committed
22 23 24
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
  OpenAirInterface Dev  : openair4g-devel@eurecom.fr
25

ghaddab's avatar
ghaddab committed
26
  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
27

nikaeinn's avatar
nikaeinn committed
28
*******************************************************************************/
29
/*! \file rrc_UE.c
gauthier's avatar
gauthier committed
30
 * \brief rrc procedures for UE
nikaeinn's avatar
nikaeinn committed
31 32
 * \author Navid Nikaein and Raymond Knopp
 * \date 2011 - 2014
gauthier's avatar
gauthier committed
33 34
 * \version 1.0
 * \company Eurecom
nikaeinn's avatar
nikaeinn committed
35
 * \email: navid.nikaein@eurecom.fr and raymond.knopp@eurecom.fr
gauthier's avatar
gauthier committed
36
 */
37

gauthier's avatar
gauthier committed
38 39
#define RRC_UE
#define RRC_UE_C
40

41
#include "assertions.h"
42
#include "asn1_conversions.h"
43
#include "defs.h"
44
#include "PHY/TOOLS/dB_routines.h"
45 46 47 48 49 50
#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"
51 52 53
#ifndef CELLULAR
#include "RRC/LITE/MESSAGES/asn1_msg.h"
#endif
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
#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
gauthier's avatar
gauthier committed
78 79 80
#ifdef ENABLE_RAL
#include "rrc_UE_ral.h"
#endif
81 82 83 84 85

#if defined(ENABLE_SECURITY)
# include "UTIL/OSA/osa_defs.h"
#endif

86
#include "pdcp.h"
87
#include "plmn_data.h"
gauthier's avatar
gauthier committed
88
#include "msc.h"
89

90 91 92 93
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#endif

94 95 96
#include "SIMULATION/TOOLS/defs.h" // for taus


97 98 99 100 101 102 103 104 105 106 107
#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

gauthier's avatar
gauthier committed
108
extern int8_t dB_fixed2(uint32_t x,uint32_t y);
109

110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152

// internal prototypes

void rrc_ue_process_securityModeCommand( const protocol_ctxt_t* const ctxt_pP, SecurityModeCommand_t* const securityModeCommand, const uint8_t eNB_index );

static int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index );

static int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, const uint8_t rsrq, const uint8_t rsrp );

/** \brief Generates/Encodes RRCConnnectionSetupComplete message at UE
 *  \param ctxt_pP Running context
 *  \param eNB_index Index of corresponding eNB/CH
 *  \param Transaction_id Transaction identifier
 */
static void rrc_ue_generate_RRCConnectionSetupComplete( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, const uint8_t Transaction_id );

/** \brief Generates/Encodes RRCConnectionReconfigurationComplete message at UE
 *  \param ctxt_pP Running context
 *  \param eNB_index Index of corresponding eNB/CH
 *  \param Transaction_id RRC transaction identifier
 */
static void rrc_ue_generate_RRCConnectionReconfigurationComplete( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, const uint8_t Transaction_id );

static void rrc_ue_generate_MeasurementReport( const protocol_ctxt_t* const ctxt_pP, uint8_t eNB_index );

static uint8_t check_trigger_meas_event(
  uint8_t module_idP,
  frame_t frameP,
  uint8_t eNB_index,
  uint8_t ue_cnx_index,
  uint8_t 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);

static void decode_MBSFNAreaConfiguration(module_id_t module_idP, uint8_t eNB_index, frame_t frameP,uint8_t mbsfn_sync_area);








winckel's avatar
winckel committed
153
/*------------------------------------------------------------------------------*/
154 155
static Rrc_State_t rrc_get_state (module_id_t ue_mod_idP)
{
gauthier's avatar
 
gauthier committed
156
  return UE_rrc_inst[ue_mod_idP].RrcState;
winckel's avatar
winckel committed
157 158
}

159 160
static Rrc_Sub_State_t rrc_get_sub_state (module_id_t ue_mod_idP)
{
gauthier's avatar
 
gauthier committed
161
  return UE_rrc_inst[ue_mod_idP].RrcSubState;
winckel's avatar
winckel committed
162 163
}

164 165
static int rrc_set_state (module_id_t ue_mod_idP, Rrc_State_t state)
{
winckel's avatar
winckel committed
166
  AssertFatal ((RRC_STATE_FIRST <= state) && (state <= RRC_STATE_LAST),
167
               "Invalid state %d!\n", state);
winckel's avatar
winckel committed
168

gauthier's avatar
 
gauthier committed
169
  if (UE_rrc_inst[ue_mod_idP].RrcState != state) {
170
    UE_rrc_inst[ue_mod_idP].RrcState = state;
winckel's avatar
winckel committed
171

172
#if defined(ENABLE_ITTI)
173 174
    {
      MessageDef *msg_p;
175

176 177 178
      msg_p = itti_alloc_new_message(TASK_RRC_UE, RRC_STATE_IND);
      RRC_STATE_IND(msg_p).state = UE_rrc_inst[ue_mod_idP].RrcState;
      RRC_STATE_IND(msg_p).sub_state = UE_rrc_inst[ue_mod_idP].RrcSubState;
winckel's avatar
winckel committed
179

180
      itti_send_msg_to_task(TASK_UNKNOWN, UE_MODULE_ID_TO_INSTANCE(ue_mod_idP), msg_p);
181
    }
182
#endif
183
    return (1);
winckel's avatar
winckel committed
184 185 186 187 188
  }

  return (0);
}

189
//-----------------------------------------------------------------------------
190
static int rrc_set_sub_state( module_id_t ue_mod_idP, Rrc_Sub_State_t subState )
191
{
192
#if (defined(ENABLE_ITTI) && (defined(ENABLE_USE_MME) || defined(ENABLE_RAL)))
193

gauthier's avatar
 
gauthier committed
194
  switch (UE_rrc_inst[ue_mod_idP].RrcState) {
gauthier's avatar
gauthier committed
195 196
  case RRC_STATE_INACTIVE:
    AssertFatal ((RRC_SUB_STATE_INACTIVE_FIRST <= subState) && (subState <= RRC_SUB_STATE_INACTIVE_LAST),
197
                 "Invalid sub state %d for state %d!\n", subState, UE_rrc_inst[ue_mod_idP].RrcState);
gauthier's avatar
gauthier committed
198 199 200 201
    break;

  case RRC_STATE_IDLE:
    AssertFatal ((RRC_SUB_STATE_IDLE_FIRST <= subState) && (subState <= RRC_SUB_STATE_IDLE_LAST),
202
                 "Invalid sub state %d for state %d!\n", subState, UE_rrc_inst[ue_mod_idP].RrcState);
gauthier's avatar
gauthier committed
203 204 205 206
    break;

  case RRC_STATE_CONNECTED:
    AssertFatal ((RRC_SUB_STATE_CONNECTED_FIRST <= subState) && (subState <= RRC_SUB_STATE_CONNECTED_LAST),
207
                 "Invalid sub state %d for state %d!\n", subState, UE_rrc_inst[ue_mod_idP].RrcState);
gauthier's avatar
gauthier committed
208
    break;
winckel's avatar
winckel committed
209
  }
210

211
#endif
winckel's avatar
winckel committed
212

gauthier's avatar
 
gauthier committed
213
  if (UE_rrc_inst[ue_mod_idP].RrcSubState != subState) {
214
    UE_rrc_inst[ue_mod_idP].RrcSubState = subState;
winckel's avatar
winckel committed
215

216
#if defined(ENABLE_ITTI)
217 218
    {
      MessageDef *msg_p;
winckel's avatar
winckel committed
219

220 221 222
      msg_p = itti_alloc_new_message(TASK_RRC_UE, RRC_STATE_IND);
      RRC_STATE_IND(msg_p).state = UE_rrc_inst[ue_mod_idP].RrcState;
      RRC_STATE_IND(msg_p).sub_state = UE_rrc_inst[ue_mod_idP].RrcSubState;
223

224
      itti_send_msg_to_task(TASK_UNKNOWN, UE_MODULE_ID_TO_INSTANCE(ue_mod_idP), msg_p);
225
    }
226
#endif
227
    return (1);
winckel's avatar
winckel committed
228 229 230 231 232
  }

  return (0);
}

233
//-----------------------------------------------------------------------------
234
static void init_SI_UE( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index )
235
{
236 237
  UE_rrc_inst[ctxt_pP->module_id].sizeof_SIB1[eNB_index] = 0;
  UE_rrc_inst[ctxt_pP->module_id].sizeof_SI[eNB_index] = 0;
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
  UE_rrc_inst[ctxt_pP->module_id].SIB1[eNB_index] = (uint8_t*)malloc16_clear( 32 );
  UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType1_t) );
  UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType2_t) );
  UE_rrc_inst[ctxt_pP->module_id].sib3[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType3_t) );
  UE_rrc_inst[ctxt_pP->module_id].sib4[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType4_t) );
  UE_rrc_inst[ctxt_pP->module_id].sib5[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType5_t) );
  UE_rrc_inst[ctxt_pP->module_id].sib6[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType6_t) );
  UE_rrc_inst[ctxt_pP->module_id].sib7[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType7_t) );
  UE_rrc_inst[ctxt_pP->module_id].sib8[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType8_t) );
  UE_rrc_inst[ctxt_pP->module_id].sib9[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType9_t) );
  UE_rrc_inst[ctxt_pP->module_id].sib10[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType10_t) );
  UE_rrc_inst[ctxt_pP->module_id].sib11[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType11_t) );
#ifdef Rel10
  UE_rrc_inst[ctxt_pP->module_id].sib12[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType12_r9_t) );
  UE_rrc_inst[ctxt_pP->module_id].sib13[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType13_r9_t) );
#endif
  UE_rrc_inst[ctxt_pP->module_id].SI[eNB_index] = (uint8_t*)malloc16_clear( 64 );
255

256
  UE_rrc_inst[ctxt_pP->module_id].si[eNB_index] = (SystemInformation_t*)malloc16_clear( sizeof(SystemInformation_t) );
257

258
  UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus = 0;
259
  UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt    = 0;
260 261 262
}

#ifdef Rel10
263 264
//-----------------------------------------------------------------------------
static void init_MCCH_UE(module_id_t ue_mod_idP, uint8_t eNB_index)
265
{
266
  int i;
gauthier's avatar
 
gauthier committed
267 268 269
  UE_rrc_inst[ue_mod_idP].sizeof_MCCH_MESSAGE[eNB_index] = 0;
  UE_rrc_inst[ue_mod_idP].MCCH_MESSAGE[eNB_index] = (uint8_t *)malloc16(32);
  UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index] = (MBSFNAreaConfiguration_r9_t *)malloc16(sizeof(MBSFNAreaConfiguration_r9_t));
270

271
  for (i=0; i<8; i++) { // MAX MBSFN Area
gauthier's avatar
 
gauthier committed
272
    UE_rrc_inst[ue_mod_idP].Info[eNB_index].MCCHStatus[i] = 0;
273

274
  }
275 276 277
}
#endif

278 279
//-----------------------------------------------------------------------------
static void openair_rrc_lite_ue_init_security( const protocol_ctxt_t* const ctxt_pP )
280 281
{
#if defined(ENABLE_SECURITY)
gauthier's avatar
gauthier committed
282 283 284 285
  //    uint8_t *kRRCenc;
  //    uint8_t *kRRCint;
  char ascii_buffer[65];
  uint8_t i;
286

287
  memset(UE_rrc_inst[ctxt_pP->module_id].kenb, ctxt_pP->module_id, 32);
288

gauthier's avatar
gauthier committed
289
  for (i = 0; i < 32; i++) {
290
    sprintf(&ascii_buffer[2 * i], "%02X", UE_rrc_inst[ctxt_pP->module_id].kenb[i]);
gauthier's avatar
gauthier committed
291
  }
292

293 294 295
  LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT"[OSA] kenb    = %s\n",
        PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
        ascii_buffer);
296
#endif
297
}
298

299
//-----------------------------------------------------------------------------
300
char openair_rrc_lite_ue_init( const module_id_t ue_mod_idP, const unsigned char eNB_index )
301
{
302
  protocol_ctxt_t ctxt;
303
  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_idP, ENB_FLAG_NO, NOT_A_RNTI, 0, 0,eNB_index);
304 305 306
  LOG_I(RRC,
        PROTOCOL_RRC_CTXT_FMT" Init...\n",
        PROTOCOL_RRC_CTXT_ARGS(&ctxt));
gauthier's avatar
 
gauthier committed
307 308 309
  rrc_set_state (ue_mod_idP, RRC_STATE_INACTIVE);
  rrc_set_sub_state (ue_mod_idP, RRC_SUB_STATE_INACTIVE);

310 311 312 313 314 315 316 317 318 319 320
  LOG_D(RRC,"[UE %d] INIT State = RRC_IDLE (eNB %d)\n",ctxt.module_id,eNB_index);
  UE_rrc_inst[ctxt.module_id].Info[eNB_index].State=RRC_IDLE;
  UE_rrc_inst[ctxt.module_id].Info[eNB_index].T300_active = 0;
  UE_rrc_inst[ctxt.module_id].Info[eNB_index].T304_active = 0;
  UE_rrc_inst[ctxt.module_id].Info[eNB_index].T310_active = 0;
  UE_rrc_inst[ctxt.module_id].Info[eNB_index].UE_index=0xffff;
  UE_rrc_inst[ctxt.module_id].Srb0[eNB_index].Active=0;
  UE_rrc_inst[ctxt.module_id].Srb1[eNB_index].Active=0;
  UE_rrc_inst[ctxt.module_id].Srb2[eNB_index].Active=0;
  UE_rrc_inst[ctxt.module_id].HandoverInfoUe.measFlag=1;
  UE_rrc_inst[ctxt.module_id].ciphering_algorithm = SecurityAlgorithmConfig__cipheringAlgorithm_eea0;
321
#ifdef Rel10
322
  UE_rrc_inst[ctxt.module_id].integrity_algorithm = SecurityAlgorithmConfig__integrityProtAlgorithm_eia0_v920;
323
#else
324
  UE_rrc_inst[ctxt.module_id].integrity_algorithm = SecurityAlgorithmConfig__integrityProtAlgorithm_reserved;
325 326
#endif

327 328 329 330
  openair_rrc_lite_ue_init_security(&ctxt);
  init_SI_UE(&ctxt,eNB_index);
  LOG_D(RRC,PROTOCOL_RRC_CTXT_FMT"  INIT: phy_sync_2_ch_ind\n",
        PROTOCOL_RRC_CTXT_ARGS(&ctxt));
331 332

#ifndef NO_RRM
333
  send_msg(&S_rrc,msg_rrc_phy_synch_to_CH_ind(ctxt.module_id,eNB_index,UE_rrc_inst[ctxt.module_id].Mac_id));
334 335 336
#endif

#ifdef NO_RRM //init ch SRB0, SRB1 & BDTCH
337
  openair_rrc_on(&ctxt);
338
#endif
339
#ifdef CBA
340
  int j;
341

342
  for(j=0; j<NUM_MAX_CBA_GROUP; j++) {
gauthier's avatar
 
gauthier committed
343
    UE_rrc_inst[ue_mod_idP].cba_rnti[j] = 0x0000;
344
  }
345

gauthier's avatar
 
gauthier committed
346
  UE_rrc_inst[ue_mod_idP].num_active_cba_groups = 0;
347 348 349 350 351
#endif

  return 0;
}

352
//-----------------------------------------------------------------------------
353
void rrc_ue_generate_RRCConnectionRequest( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index )
354
{
355

gauthier's avatar
gauthier committed
356
  uint8_t i=0,rv[6];
gauthier's avatar
gauthier committed
357

358
  if(UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Tx_buffer.payload_size ==0) {
359

360 361 362 363 364 365
    // 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;
366
#else
367
      rv[i]=taus()&0xff;
368
#endif
369 370
      LOG_T(RRC,"%x.",rv[i]);
    }
371

372
    LOG_T(RRC,"\n");
373 374 375 376 377
    UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Tx_buffer.payload_size =
      do_RRCConnectionRequest(
        ctxt_pP->module_id,
        (uint8_t*)UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Tx_buffer.Payload,
        rv);
378 379

    LOG_I(RRC,"[UE %d] : Frame %d, Logical Channel UL-CCCH (SRB0), Generating RRCConnectionRequest (bytes %d, eNB %d)\n",
380
          ctxt_pP->module_id, ctxt_pP->frame, UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Tx_buffer.payload_size, eNB_index);
381

382 383
    for (i=0; i<UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Tx_buffer.payload_size; i++) {
      LOG_T(RRC,"%x.",UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Tx_buffer.Payload[i]);
384 385 386
    }

    LOG_T(RRC,"\n");
387 388
    /*UE_rrc_inst[ue_mod_idP].Srb0[Idx].Tx_buffer.Payload[i] = taus()&0xff;
    UE_rrc_inst[ue_mod_idP].Srb0[Idx].Tx_buffer.payload_size =i; */
389 390 391 392 393 394 395

  }
}


mui_t rrc_mui=0;

396
/* NAS Attach request with IMSI */
397
static const char const nas_attach_req_imsi[] = {
398 399 400 401 402 403 404 405 406 407 408
  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,
};
409 410

/* NAS Attach request with GUTI */
411
static const char const nas_attach_req_guti[] = {
412 413 414 415 416 417 418 419 420 421 422
  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,
};
423

424
//-----------------------------------------------------------------------------
425
static void rrc_ue_generate_RRCConnectionSetupComplete( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, const uint8_t Transaction_id )
426
{
427

gauthier's avatar
gauthier committed
428 429
  uint8_t    buffer[100];
  uint8_t    size;
430
  const char * nas_msg;
winckel's avatar
winckel committed
431
  int   nas_msg_length;
432

winckel's avatar
winckel committed
433
#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
434 435
  nas_msg         = (char*) UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data;
  nas_msg_length  = UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.length;
winckel's avatar
winckel committed
436 437 438 439 440
#else
  nas_msg         = nas_attach_req_imsi;
  nas_msg_length  = sizeof(nas_attach_req_imsi);
#endif

441
  size = do_RRCConnectionSetupComplete(ctxt_pP->module_id, buffer, Transaction_id, nas_msg_length, nas_msg);
442 443

  LOG_I(RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCConnectionSetupComplete (bytes%d, eNB %d)\n",
444 445
        ctxt_pP->module_id,ctxt_pP->frame, size, eNB_index);
  LOG_D(RLC,
gauthier's avatar
gauthier committed
446
        "[FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCConnectionSetupComplete to eNB %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n",
447 448 449 450 451 452 453 454 455
        ctxt_pP->frame, ctxt_pP->module_id+NB_eNB_INST, size, eNB_index, rrc_mui, ctxt_pP->module_id+NB_eNB_INST, DCCH);
  pdcp_rrc_data_req (
    ctxt_pP,
    DCCH,
    rrc_mui++,
    SDU_CONFIRM_NO,
    size,
    buffer,
    PDCP_TRANSMISSION_MODE_CONTROL);
456 457
}

458
//-----------------------------------------------------------------------------
459
static void rrc_ue_generate_RRCConnectionReconfigurationComplete( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, const uint8_t Transaction_id )
460
{
461

gauthier's avatar
gauthier committed
462
  uint8_t buffer[32], size;
463 464 465 466
  size = do_RRCConnectionReconfigurationComplete(ctxt_pP, buffer, Transaction_id);
  LOG_I(RRC,PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel UL-DCCH (SRB1), Generating RRCConnectionReconfigurationComplete (bytes %d, eNB_index %d)\n",
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), size, eNB_index);
  LOG_D(RLC,
gauthier's avatar
gauthier committed
467
        "[FRAME %05d][RRC_UE][INST %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCConnectionReconfigurationComplete to eNB %d MUI %d) --->][PDCP][INST %02d][RB %02d]\n",
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482
        ctxt_pP->frame,
        UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id),
        size,
        eNB_index,
        rrc_mui,
        UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id),
        DCCH);
  pdcp_rrc_data_req (
    ctxt_pP,
    DCCH,
    rrc_mui++,
    SDU_CONFIRM_NO,
    size,
    buffer,
    PDCP_TRANSMISSION_MODE_CONTROL);
483 484 485
}


486 487
//-----------------------------------------------------------------------------
// Called by L2 interface (MAC)
488
int rrc_ue_decode_ccch( const protocol_ctxt_t* const ctxt_pP, const SRB_INFO* const Srb_info, const uint8_t eNB_index )
489 490
{
  DL_CCCH_Message_t* dl_ccch_msg=NULL;
491
  asn_dec_rval_t dec_rval;
492
  int rval=0;
493

gauthier's avatar
gauthier committed
494
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN);
gauthier's avatar
 
gauthier committed
495 496
  //  LOG_D(RRC,"[UE %d] Decoding DL-CCCH message (%d bytes), State %d\n",ue_mod_idP,Srb_info->Rx_buffer.payload_size,
  //  UE_rrc_inst[ue_mod_idP].Info[eNB_index].State);
497 498

  dec_rval = uper_decode(NULL,
499 500 501 502
                         &asn_DEF_DL_CCCH_Message,
                         (void**)&dl_ccch_msg,
                         (uint8_t*)Srb_info->Rx_buffer.Payload,
                         100,0,0);
503 504 505 506 507

#ifdef XER_PRINT
  xer_fprint(stdout,&asn_DEF_DL_CCCH_Message,(void*)dl_ccch_msg);
#endif

508
#if defined(ENABLE_ITTI)
509
# if defined(DISABLE_ITTI_XER_PRINT)
510
  {
winckel's avatar
winckel committed
511
    MessageDef *msg_p;
512

winckel's avatar
winckel committed
513 514
    msg_p = itti_alloc_new_message (TASK_RRC_UE, RRC_DL_CCCH_MESSAGE);
    memcpy (&msg_p->ittiMsg, (void *) dl_ccch_msg, sizeof(RrcDlCcchMessage));
515

516
    itti_send_msg_to_task (TASK_UNKNOWN, ctxt_pP->instance, msg_p);
517
  }
518 519
# else
  {
520 521
    char        message_string[10000];
    size_t      message_string_size;
522

523 524
    if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message, (void *)dl_ccch_msg)) > 0) {
      MessageDef *msg_p;
525

526 527 528
      msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText));
      msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size;
      memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size);
529

530
      itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p);
531
    }
532 533
  }
# endif
534 535
#endif

536
  if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) {
537
    LOG_E(RRC,"[UE %d] Frame %d : Failed to decode DL-CCCH-Message (%d bytes)\n",ctxt_pP->module_id,dec_rval.consumed);
gauthier's avatar
gauthier committed
538
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
539
    return -1;
540 541 542 543
  }

  if (dl_ccch_msg->message.present == DL_CCCH_MessageType_PR_c1) {

544
    if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State == RRC_SI_RECEIVED) {
545

546
      switch (dl_ccch_msg->message.choice.c1.present) {
547

548
      case DL_CCCH_MessageType__c1_PR_NOTHING:
549 550 551
        LOG_I(RRC, "[UE%d] Frame %d : Received PR_NOTHING on DL-CCCH-Message\n",
              ctxt_pP->module_id,
              ctxt_pP->frame);
552 553
        rval = 0;
        break;
554

555 556
      case DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishment:
        LOG_I(RRC,
557 558 559
              "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReestablishment\n",
              ctxt_pP->module_id,
              ctxt_pP->frame);
560 561
        rval = 0;
        break;
562

563 564
      case DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentReject:
        LOG_I(RRC,
565 566 567
              "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReestablishmentReject\n",
              ctxt_pP->module_id,
              ctxt_pP->frame);
568 569
        rval = 0;
        break;
570

571 572
      case DL_CCCH_MessageType__c1_PR_rrcConnectionReject:
        LOG_I(RRC,
573 574 575
              "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReject \n",
              ctxt_pP->module_id,
              ctxt_pP->frame);
576 577
        rval = 0;
        break;
578

579 580
      case DL_CCCH_MessageType__c1_PR_rrcConnectionSetup:
        LOG_I(RRC,
581 582 583 584
              "[UE%d][RAPROC] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionSetup RNTI %x\n",
              ctxt_pP->module_id,
              ctxt_pP->frame,
              ctxt_pP->rnti);
585
        // Get configuration
586

587
        // Release T300 timer
588 589 590 591
        UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].T300_active = 0;
        rrc_ue_process_radioResourceConfigDedicated(
          ctxt_pP,
          eNB_index,
592
          &dl_ccch_msg->message.choice.c1.choice.rrcConnectionSetup.criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated);
593

594 595 596 597 598 599 600
        rrc_set_state (ctxt_pP->module_id, RRC_STATE_CONNECTED);
        rrc_set_sub_state (ctxt_pP->module_id, RRC_SUB_STATE_CONNECTED);
        UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].rnti = ctxt_pP->rnti;
        rrc_ue_generate_RRCConnectionSetupComplete(
          ctxt_pP,
          eNB_index,
          dl_ccch_msg->message.choice.c1.choice.rrcConnectionSetup.rrc_TransactionIdentifier);
601

602 603
        rval = 0;
        break;
604

605
      default:
606 607 608
        LOG_E(RRC, "[UE%d] Frame %d : Unknown message\n",
              ctxt_pP->module_id,
              ctxt_pP->frame);
609 610
        rval = -1;
        break;
611
      }
612
    }
613 614
  }

gauthier's avatar
gauthier committed
615
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
616 617 618
  return rval;
}

619 620 621 622 623 624 625 626 627
//-----------------------------------------------------------------------------
int32_t
rrc_ue_establish_srb1(
  module_id_t ue_mod_idP,
  frame_t frameP,
  uint8_t eNB_index,
  struct SRB_ToAddMod* SRB_config
)
//-----------------------------------------------------------------------------
628
{
629
  // add descriptor from RRC PDU
630

gauthier's avatar
gauthier committed
631
  uint8_t lchan_id = DCCH;
632

gauthier's avatar
 
gauthier committed
633 634 635
  UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Active = 1;
  UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Status = RADIO_CONFIG_OK;//RADIO CFG
  UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Srb_info.Srb_id = 1;
636

gauthier's avatar
gauthier committed
637
  // copy default configuration for now
gauthier's avatar
 
gauthier committed
638 639
  //  memcpy(&UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Srb_info.Lchan_desc[0],&DCCH_LCHAN_DESC,LCHAN_DESC_SIZE);
  //  memcpy(&UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Srb_info.Lchan_desc[1],&DCCH_LCHAN_DESC,LCHAN_DESC_SIZE);
640 641


gauthier's avatar
 
gauthier committed
642
  LOG_I(RRC,"[UE %d], CONFIG_SRB1 %d corresponding to eNB_index %d\n", ue_mod_idP,lchan_id,eNB_index);
643

gauthier's avatar
 
gauthier committed
644 645
  //rrc_pdcp_config_req (ue_mod_idP+NB_eNB_INST, frameP, 0, CONFIG_ACTION_ADD, lchan_id,UNDEF_SECURITY_MODE);
  //  rrc_rlc_config_req(ue_mod_idP+NB_eNB_INST,frameP,0,CONFIG_ACTION_ADD,lchan_id,SIGNALLING_RADIO_BEARER,Rlc_info_am_config);
646

gauthier's avatar
 
gauthier committed
647
  //  UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Srb_info.Tx_buffer.payload_size=DEFAULT_MEAS_IND_SIZE+1;
648 649 650 651 652


  return(0);
}

653 654 655 656 657 658 659 660 661
//-----------------------------------------------------------------------------
int32_t
rrc_ue_establish_srb2(
  module_id_t ue_mod_idP,
  frame_t frameP,
  uint8_t eNB_index,
  struct SRB_ToAddMod* SRB_config
)
//-----------------------------------------------------------------------------
662
{
663
  // add descriptor from RRC PDU
664

gauthier's avatar
gauthier committed
665
  uint8_t lchan_id = DCCH1;
666

gauthier's avatar
 
gauthier committed
667 668 669
  UE_rrc_inst[ue_mod_idP].Srb2[eNB_index].Active = 1;
  UE_rrc_inst[ue_mod_idP].Srb2[eNB_index].Status = RADIO_CONFIG_OK;//RADIO CFG
  UE_rrc_inst[ue_mod_idP].Srb2[eNB_index].Srb_info.Srb_id = 2;
670

gauthier's avatar
gauthier committed
671
  // copy default configuration for now
gauthier's avatar
 
gauthier committed
672 673
  //  memcpy(&UE_rrc_inst[ue_mod_idP].Srb2[eNB_index].Srb_info.Lchan_desc[0],&DCCH_LCHAN_DESC,LCHAN_DESC_SIZE);
  //  memcpy(&UE_rrc_inst[ue_mod_idP].Srb2[eNB_index].Srb_info.Lchan_desc[1],&DCCH_LCHAN_DESC,LCHAN_DESC_SIZE);
674 675


gauthier's avatar
 
gauthier committed
676
  LOG_I(RRC,"[UE %d], CONFIG_SRB2 %d corresponding to eNB_index %d\n",ue_mod_idP,lchan_id,eNB_index);
677

gauthier's avatar
 
gauthier committed
678 679
  //rrc_pdcp_config_req (ue_mod_idP+NB_eNB_INST, frameP, 0, CONFIG_ACTION_ADD, lchan_id, UNDEF_SECURITY_MODE);
  //  rrc_rlc_config_req(ue_mod_idP+NB_eNB_INST,frameP,0,CONFIG_ACTION_ADD,lchan_id,SIGNALLING_RADIO_BEARER,Rlc_info_am_config);
680

gauthier's avatar
 
gauthier committed
681
  //  UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Srb_info.Tx_buffer.payload_size=DEFAULT_MEAS_IND_SIZE+1;
682 683 684 685 686


  return(0);
}

687 688 689 690 691 692 693 694 695
//-----------------------------------------------------------------------------
int32_t
rrc_ue_establish_drb(
  module_id_t ue_mod_idP,
  frame_t frameP,
  uint8_t eNB_index,
  struct DRB_ToAddMod* DRB_config
)
//-----------------------------------------------------------------------------
696
{
697 698
  // add descriptor from RRC PDU
#ifdef PDCP_USE_NETLINK
699
  int oip_ifup=0,ip_addr_offset3=0,ip_addr_offset4=0;
700
#endif
701

702
  LOG_I(RRC,"[UE %d] Frame %d: processing RRCConnectionReconfiguration: reconfiguring DRB %ld/LCID %d\n",
703
        ue_mod_idP, frameP, DRB_config->drb_Identity, (int)*DRB_config->logicalChannelIdentity);
704
  /*
gauthier's avatar
 
gauthier committed
705
  rrc_pdcp_config_req (ue_mod_idP+NB_eNB_INST, frameP, 0, CONFIG_ACTION_ADD,
706
                             (eNB_index * NB_RB_MAX) + *DRB_config->logicalChannelIdentity, UNDEF_SECURITY_MODE);
gauthier's avatar
gauthier committed
707

708
  rrc_rlc_config_req(ue_mod_idP+NB_eNB_INST,frameP,0,CONFIG_ACTION_ADD,
709 710
                    (eNB_index * NB_RB_MAX) + *DRB_config->logicalChannelIdentity,
                    RADIO_ACCESS_BEARER,Rlc_info_um);
gauthier's avatar
gauthier committed
711
   */
712
#ifdef PDCP_USE_NETLINK
713
#   if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(LINK_ENB_PDCP_TO_GTPV1U)
714
#    ifdef OAI_EMU
gauthier's avatar
gauthier committed
715 716
  ip_addr_offset3 = oai_emulation.info.nb_enb_local;
  ip_addr_offset4 = NB_eNB_INST;
717
#    else
gauthier's avatar
gauthier committed
718 719
  ip_addr_offset3 = 0;
  ip_addr_offset4 = 8;
720
#    endif
gauthier's avatar
 
gauthier committed
721
  LOG_I(OIP,"[UE %d] trying to bring up the OAI interface oai%d, IP 10.0.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP,
722
        ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1);
gauthier's avatar
 
gauthier committed
723
  oip_ifup=nas_config(ip_addr_offset3+ue_mod_idP,   // interface_id
724 725 726 727
                      ip_addr_offset3+ue_mod_idP+1, // third_octet
                      ip_addr_offset4+ue_mod_idP+1); // fourth_octet

  if (oip_ifup == 0 ) { // interface is up --> send a config the DRB
728
#        ifdef OAI_EMU
729
    oai_emulation.info.oai_ifup[ue_mod_idP]=1;
730
#        endif
731
    LOG_I(OIP,"[UE %d] Config the oai%d to send/receive pkt on DRB %d to/from the protocol stack\n",
gauthier's avatar
 
gauthier committed
732 733
          ue_mod_idP,
          ip_addr_offset3+ue_mod_idP,
734
          (eNB_index * maxDRB) + DRB_config->drb_Identity);
735

736 737 738 739 740 741 742 743
    rb_conf_ipv4(0,//add
                 ue_mod_idP,//cx align with the UE index
                 ip_addr_offset3+ue_mod_idP,//inst num_enb+ue_index
                 (eNB_index * maxDRB) + DRB_config->drb_Identity,//rb
                 0,//dscp
                 ipv4_address(ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1),//saddr
                 ipv4_address(ip_addr_offset3+ue_mod_idP+1,eNB_index+1));//daddr
    LOG_D(RRC,"[UE %d] State = Attached (eNB %d)\n",ue_mod_idP,eNB_index);
gauthier's avatar
gauthier committed
744
  }
745

746 747
#    else
#        ifdef OAI_EMU
gauthier's avatar
 
gauthier committed
748
  oai_emulation.info.oai_ifup[ue_mod_idP]=1;
749 750 751 752 753 754 755 756
#        endif
#    endif
#endif

  return(0);
}


757 758 759 760 761 762 763 764
//-----------------------------------------------------------------------------
void
rrc_ue_process_measConfig(
  const protocol_ctxt_t* const       ctxt_pP,
  const uint8_t                      eNB_index,
  MeasConfig_t* const               measConfig
)
//-----------------------------------------------------------------------------
765
{
766 767 768 769 770 771 772

  // This is the procedure described in 36.331 Section 5.5.2.1
  int i;
  long ind;
  MeasObjectToAddMod_t *measObj;

  if (measConfig->measObjectToRemoveList != NULL) {
773 774
    for (i=0; i<measConfig->measObjectToRemoveList->list.count; i++) {
      ind   = *measConfig->measObjectToRemoveList->list.array[i];
775
      free(UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index][ind-1]);
776
    }
777
  }
778

779
  if (measConfig->measObjectToAddModList != NULL) {
780 781 782 783 784 785
    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;

786
      if (UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index][ind-1]) {
787
        LOG_D(RRC,"Modifying measurement object %d\n",ind);
788
        memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index][ind-1],
789 790 791 792 793 794 795 796 797 798 799
               (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]);
800
          UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index][ind-1]=measObj;
801
        }
802
      }
803 804
    }

805
    rrc_mac_config_req(ctxt_pP->module_id,0,ENB_FLAG_NO,0,eNB_index,
806 807
                       (RadioResourceConfigCommonSIB_t *)NULL,
                       (struct PhysicalConfigDedicated *)NULL,
808
#ifdef Rel10
809 810 811
                       (SCellToAddMod_r10_t *)NULL,
                       //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
#endif
812
                       UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index],
813 814 815 816 817 818 819 820 821 822 823 824
                       (MAC_MainConfig_t *)NULL,
                       0,
                       (struct LogicalChannelConfig *)NULL,
                       (MeasGapConfig_t *)NULL,
                       (TDD_Config_t *)NULL,
                       (MobilityControlInfo_t *)NULL,
                       NULL,
                       NULL,
                       NULL,
                       NULL,
                       NULL,
                       NULL
825
#ifdef Rel10
826 827 828 829
                       ,
                       0,
                       (MBSFN_AreaInfoList_r9_t *)NULL,
                       (PMCH_InfoList_r9_t *)NULL
830 831
#endif
#ifdef CBA
832 833 834
                       ,
                       0,
                       0
835
#endif
836
                      );
837
  }
838

839
  if (measConfig->reportConfigToRemoveList != NULL) {
840 841
    for (i=0; i<measConfig->reportConfigToRemoveList->list.count; i++) {
      ind   = *measConfig->reportConfigToRemoveList->list.array[i];
842
      free(UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1]);
843
    }
844
  }
845

846
  if (measConfig->reportConfigToAddModList != NULL) {
847 848 849 850 851
    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;

852
      if (UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1]) {
853
        LOG_I(RRC,"Modifying Report Configuration %d\n",ind-1);
854
        memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1],
855 856 857 858
               (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]);
859
        UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1] = measConfig->reportConfigToAddModList->list.array[i];