rrc_UE.c 193 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
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
24
  OpenAirInterface Dev  : openair4g-devel@lists.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 "hashtable.h"
43
#include "asn1_conversions.h"
44
#include "defs.h"
45
#include "PHY/TOOLS/dB_routines.h"
46
47
48
49
50
51
#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"
52
53
54
#ifndef CELLULAR
#include "RRC/LITE/MESSAGES/asn1_msg.h"
#endif
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#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
79
#if ENABLE_RAL
gauthier's avatar
gauthier committed
80
81
#include "rrc_UE_ral.h"
#endif
82
83
84
85
86

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

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

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

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


98
99
100
101
102
103
104
105
106
107
108
#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
109
extern int8_t dB_fixed2(uint32_t x,uint32_t y);
110

111
112
113
114
115
116
117
118
119
extern void pdcp_config_set_security(
  const protocol_ctxt_t* const  ctxt_pP,
  pdcp_t         * const pdcp_pP,
  const rb_id_t         rb_idP,
  const uint16_t        lc_idP,
  const uint8_t         security_modeP,
  uint8_t        * const kRRCenc,
  uint8_t        * const kRRCint,
  uint8_t        * const  kUPenc);
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
153

// 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);

Cedric Roux's avatar
Cedric Roux committed
154
#ifdef Rel10
155
static void decode_MBSFNAreaConfiguration(module_id_t module_idP, uint8_t eNB_index, frame_t frameP,uint8_t mbsfn_sync_area);
Cedric Roux's avatar
Cedric Roux committed
156
#endif
157
158
159
160
161
162
163
164








winckel's avatar
winckel committed
165
/*------------------------------------------------------------------------------*/
Cedric Roux's avatar
Cedric Roux committed
166
167
/* to avoid gcc warnings when compiling with certain options */
#if defined(ENABLE_USE_MME) || ENABLE_RAL
168
169
static Rrc_State_t rrc_get_state (module_id_t ue_mod_idP)
{
gauthier's avatar
   
gauthier committed
170
  return UE_rrc_inst[ue_mod_idP].RrcState;
winckel's avatar
winckel committed
171
}
Cedric Roux's avatar
Cedric Roux committed
172
#endif
winckel's avatar
winckel committed
173

174
175
static Rrc_Sub_State_t rrc_get_sub_state (module_id_t ue_mod_idP)
{
gauthier's avatar
   
gauthier committed
176
  return UE_rrc_inst[ue_mod_idP].RrcSubState;
winckel's avatar
winckel committed
177
178
}

179
180
static int rrc_set_state (module_id_t ue_mod_idP, Rrc_State_t state)
{
winckel's avatar
winckel committed
181
  AssertFatal ((RRC_STATE_FIRST <= state) && (state <= RRC_STATE_LAST),
182
               "Invalid state %d!\n", state);
winckel's avatar
winckel committed
183

gauthier's avatar
   
gauthier committed
184
  if (UE_rrc_inst[ue_mod_idP].RrcState != state) {
185
    UE_rrc_inst[ue_mod_idP].RrcState = state;
winckel's avatar
winckel committed
186

187
#if defined(ENABLE_ITTI)
188
189
    {
      MessageDef *msg_p;
190

191
192
193
      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
194

195
      itti_send_msg_to_task(TASK_UNKNOWN, UE_MODULE_ID_TO_INSTANCE(ue_mod_idP), msg_p);
196
    }
197
#endif
198
    return (1);
winckel's avatar
winckel committed
199
200
201
202
203
  }

  return (0);
}

204
//-----------------------------------------------------------------------------
205
static int rrc_set_sub_state( module_id_t ue_mod_idP, Rrc_Sub_State_t subState )
206
{
207
#if (defined(ENABLE_ITTI) && (defined(ENABLE_USE_MME) || ENABLE_RAL))
208

gauthier's avatar
   
gauthier committed
209
  switch (UE_rrc_inst[ue_mod_idP].RrcState) {
gauthier's avatar
gauthier committed
210
211
  case RRC_STATE_INACTIVE:
    AssertFatal ((RRC_SUB_STATE_INACTIVE_FIRST <= subState) && (subState <= RRC_SUB_STATE_INACTIVE_LAST),
212
                 "Invalid sub state %d for state %d!\n", subState, UE_rrc_inst[ue_mod_idP].RrcState);
gauthier's avatar
gauthier committed
213
214
215
216
    break;

  case RRC_STATE_IDLE:
    AssertFatal ((RRC_SUB_STATE_IDLE_FIRST <= subState) && (subState <= RRC_SUB_STATE_IDLE_LAST),
217
                 "Invalid sub state %d for state %d!\n", subState, UE_rrc_inst[ue_mod_idP].RrcState);
gauthier's avatar
gauthier committed
218
219
220
221
    break;

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

226
#endif
winckel's avatar
winckel committed
227

gauthier's avatar
   
gauthier committed
228
  if (UE_rrc_inst[ue_mod_idP].RrcSubState != subState) {
229
    UE_rrc_inst[ue_mod_idP].RrcSubState = subState;
winckel's avatar
winckel committed
230

231
#if defined(ENABLE_ITTI)
232
233
    {
      MessageDef *msg_p;
winckel's avatar
winckel committed
234

235
236
237
      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;
238

239
      itti_send_msg_to_task(TASK_UNKNOWN, UE_MODULE_ID_TO_INSTANCE(ue_mod_idP), msg_p);
240
    }
241
#endif
242
    return (1);
winckel's avatar
winckel committed
243
244
245
246
247
  }

  return (0);
}

248
//-----------------------------------------------------------------------------
249
static void init_SI_UE( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index )
250
{
251
252
  UE_rrc_inst[ctxt_pP->module_id].sizeof_SIB1[eNB_index] = 0;
  UE_rrc_inst[ctxt_pP->module_id].sizeof_SI[eNB_index] = 0;
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
  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 );
270

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

273
  UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus = 0;
274
  UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt    = 0;
275
276
277
}

#ifdef Rel10
278
//-----------------------------------------------------------------------------
279
#if 0
280
static void init_MCCH_UE(module_id_t ue_mod_idP, uint8_t eNB_index)
281
{
282
  int i;
gauthier's avatar
   
gauthier committed
283
284
285
  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));
286

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

290
  }
291
292
}
#endif
293
#endif
294

295
//-----------------------------------------------------------------------------
296
static void openair_rrc_ue_init_security( const protocol_ctxt_t* const ctxt_pP )
297
298
{
#if defined(ENABLE_SECURITY)
gauthier's avatar
gauthier committed
299
300
301
302
  //    uint8_t *kRRCenc;
  //    uint8_t *kRRCint;
  char ascii_buffer[65];
  uint8_t i;
303

304
  memset(UE_rrc_inst[ctxt_pP->module_id].kenb, ctxt_pP->module_id, 32);
305

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

310
311
312
  LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT"[OSA] kenb    = %s\n",
        PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
        ascii_buffer);
313
#endif
314
}
315

316
//-----------------------------------------------------------------------------
317
char openair_rrc_ue_init( const module_id_t ue_mod_idP, const unsigned char eNB_index )
318
{
319
  protocol_ctxt_t ctxt;
320
  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_idP, ENB_FLAG_NO, NOT_A_RNTI, 0, 0,eNB_index);
321
322
323
  LOG_I(RRC,
        PROTOCOL_RRC_CTXT_FMT" Init...\n",
        PROTOCOL_RRC_CTXT_ARGS(&ctxt));
gauthier's avatar
   
gauthier committed
324
325
326
  rrc_set_state (ue_mod_idP, RRC_STATE_INACTIVE);
  rrc_set_sub_state (ue_mod_idP, RRC_SUB_STATE_INACTIVE);

327
328
329
330
331
332
333
334
335
336
337
  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;
338
#ifdef Rel10
339
  UE_rrc_inst[ctxt.module_id].integrity_algorithm = SecurityAlgorithmConfig__integrityProtAlgorithm_eia0_v920;
340
#else
341
  UE_rrc_inst[ctxt.module_id].integrity_algorithm = SecurityAlgorithmConfig__integrityProtAlgorithm_reserved;
342
343
#endif

344
  openair_rrc_ue_init_security(&ctxt);
345
346
347
  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));
348
349

#ifndef NO_RRM
350
  send_msg(&S_rrc,msg_rrc_phy_synch_to_CH_ind(ctxt.module_id,eNB_index,UE_rrc_inst[ctxt.module_id].Mac_id));
351
352
353
#endif

#ifdef NO_RRM //init ch SRB0, SRB1 & BDTCH
354
  openair_rrc_on(&ctxt);
355
#endif
356
#ifdef CBA
357
  int j;
358

359
  for(j=0; j<NUM_MAX_CBA_GROUP; j++) {
gauthier's avatar
   
gauthier committed
360
    UE_rrc_inst[ue_mod_idP].cba_rnti[j] = 0x0000;
361
  }
362

gauthier's avatar
   
gauthier committed
363
  UE_rrc_inst[ue_mod_idP].num_active_cba_groups = 0;
364
365
366
367
368
#endif

  return 0;
}

369
//-----------------------------------------------------------------------------
370
void rrc_ue_generate_RRCConnectionRequest( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index )
371
{
372

gauthier's avatar
gauthier committed
373
  uint8_t i=0,rv[6];
gauthier's avatar
gauthier committed
374

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

377
378
379
380
381
382
    // 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;
383
#else
384
      rv[i]=taus()&0xff;
385
#endif
386
387
      LOG_T(RRC,"%x.",rv[i]);
    }
388

389
    LOG_T(RRC,"\n");
390
391
392
393
394
    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);
395
396

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

399
400
    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]);
401
402
403
    }

    LOG_T(RRC,"\n");
404
405
    /*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; */
406
407
408
409
410
411
412

  }
}


mui_t rrc_mui=0;

413
/* NAS Attach request with IMSI */
414
static const char const nas_attach_req_imsi[] = {
415
416
417
418
419
420
421
422
423
424
425
  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,
};
426
427

/* NAS Attach request with GUTI */
428
static const char const nas_attach_req_guti[] = {
429
430
431
432
433
434
435
436
437
438
439
  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,
};
440

441
//-----------------------------------------------------------------------------
442
static void rrc_ue_generate_RRCConnectionSetupComplete( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, const uint8_t Transaction_id )
443
{
444

gauthier's avatar
gauthier committed
445
446
  uint8_t    buffer[100];
  uint8_t    size;
447
  const char * nas_msg;
winckel's avatar
winckel committed
448
  int   nas_msg_length;
449

winckel's avatar
winckel committed
450
#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
451
452
  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
453
454
455
456
457
#else
  nas_msg         = nas_attach_req_imsi;
  nas_msg_length  = sizeof(nas_attach_req_imsi);
#endif

458
  size = do_RRCConnectionSetupComplete(ctxt_pP->module_id, buffer, Transaction_id, nas_msg_length, nas_msg);
459
460

  LOG_I(RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCConnectionSetupComplete (bytes%d, eNB %d)\n",
461
462
        ctxt_pP->module_id,ctxt_pP->frame, size, eNB_index);
  LOG_D(RLC,
gauthier's avatar
gauthier committed
463
        "[FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCConnectionSetupComplete to eNB %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n",
464
        ctxt_pP->frame, ctxt_pP->module_id+NB_eNB_INST, size, eNB_index, rrc_mui, ctxt_pP->module_id+NB_eNB_INST, DCCH);
465
466
467
468
469
470
471
472
  rrc_data_req (
		ctxt_pP,
		DCCH,
		rrc_mui++,
		SDU_CONFIRM_NO,
		size,
		buffer,
		PDCP_TRANSMISSION_MODE_CONTROL);
473
474
}

475
//-----------------------------------------------------------------------------
476
static void rrc_ue_generate_RRCConnectionReconfigurationComplete( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, const uint8_t Transaction_id )
477
{
478

gauthier's avatar
gauthier committed
479
  uint8_t buffer[32], size;
480
481
482
483
  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
484
        "[FRAME %05d][RRC_UE][INST %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCConnectionReconfigurationComplete to eNB %d MUI %d) --->][PDCP][INST %02d][RB %02d]\n",
485
486
487
488
489
490
491
        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);
492
493
494
495
496
497
498
499
  rrc_data_req (
		ctxt_pP,
		DCCH,
		rrc_mui++,
		SDU_CONFIRM_NO,
		size,
		buffer,
		PDCP_TRANSMISSION_MODE_CONTROL);
500
501
502
}


503
504
//-----------------------------------------------------------------------------
// Called by L2 interface (MAC)
505
int rrc_ue_decode_ccch( const protocol_ctxt_t* const ctxt_pP, const SRB_INFO* const Srb_info, const uint8_t eNB_index )
506
507
{
  DL_CCCH_Message_t* dl_ccch_msg=NULL;
508
  asn_dec_rval_t dec_rval;
509
  int rval=0;
510

gauthier's avatar
gauthier committed
511
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN);
gauthier's avatar
   
gauthier committed
512
513
  //  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);
514
515

  dec_rval = uper_decode(NULL,
516
517
518
519
                         &asn_DEF_DL_CCCH_Message,
                         (void**)&dl_ccch_msg,
                         (uint8_t*)Srb_info->Rx_buffer.Payload,
                         100,0,0);
520
521
522
523
524

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

525
#if defined(ENABLE_ITTI)
526
# if defined(DISABLE_ITTI_XER_PRINT)
527
  {
winckel's avatar
winckel committed
528
    MessageDef *msg_p;
529

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

533
    itti_send_msg_to_task (TASK_UNKNOWN, ctxt_pP->instance, msg_p);
534
  }
535
536
# else
  {
537
538
    char        message_string[10000];
    size_t      message_string_size;
539

540
541
    if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message, (void *)dl_ccch_msg)) > 0) {
      MessageDef *msg_p;
542

543
544
545
      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);
546

547
      itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p);
548
    }
549
550
  }
# endif
551
552
#endif

553
  if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) {
554
    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
555
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
556
    return -1;
557
558
559
560
  }

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

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

563
      switch (dl_ccch_msg->message.choice.c1.present) {
564

565
      case DL_CCCH_MessageType__c1_PR_NOTHING:
566
567
568
        LOG_I(RRC, "[UE%d] Frame %d : Received PR_NOTHING on DL-CCCH-Message\n",
              ctxt_pP->module_id,
              ctxt_pP->frame);
569
570
        rval = 0;
        break;
571

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

580
581
      case DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentReject:
        LOG_I(RRC,
582
583
584
              "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReestablishmentReject\n",
              ctxt_pP->module_id,
              ctxt_pP->frame);
585
586
        rval = 0;
        break;
587

588
589
      case DL_CCCH_MessageType__c1_PR_rrcConnectionReject:
        LOG_I(RRC,
590
591
592
              "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReject \n",
              ctxt_pP->module_id,
              ctxt_pP->frame);
593
594
        rval = 0;
        break;
595

596
597
      case DL_CCCH_MessageType__c1_PR_rrcConnectionSetup:
        LOG_I(RRC,
598
599
600
601
              "[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);
602
        // Get configuration
603

604
        // Release T300 timer
605
606
607
608
        UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].T300_active = 0;
        rrc_ue_process_radioResourceConfigDedicated(
          ctxt_pP,
          eNB_index,
609
          &dl_ccch_msg->message.choice.c1.choice.rrcConnectionSetup.criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated);
610

611
612
613
614
615
616
617
        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);
618

619
620
        rval = 0;
        break;
621

622
      default:
623
624
625
        LOG_E(RRC, "[UE%d] Frame %d : Unknown message\n",
              ctxt_pP->module_id,
              ctxt_pP->frame);
626
627
        rval = -1;
        break;
628
      }
629
    }
630
631
  }

gauthier's avatar
gauthier committed
632
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
633
634
635
  return rval;
}

636
637
638
639
640
641
642
643
644
//-----------------------------------------------------------------------------
int32_t
rrc_ue_establish_srb1(
  module_id_t ue_mod_idP,
  frame_t frameP,
  uint8_t eNB_index,
  struct SRB_ToAddMod* SRB_config
)
//-----------------------------------------------------------------------------
645
{
646
  // add descriptor from RRC PDU
647

gauthier's avatar
gauthier committed
648
  uint8_t lchan_id = DCCH;
649

gauthier's avatar
   
gauthier committed
650
651
652
  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;
653

gauthier's avatar
gauthier committed
654
  // copy default configuration for now
gauthier's avatar
   
gauthier committed
655
656
  //  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);
657
658


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

gauthier's avatar
   
gauthier committed
661
662
  //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);
663

gauthier's avatar
   
gauthier committed
664
  //  UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Srb_info.Tx_buffer.payload_size=DEFAULT_MEAS_IND_SIZE+1;
665
666
667
668
669


  return(0);
}

670
671
672
673
674
675
676
677
678
//-----------------------------------------------------------------------------
int32_t
rrc_ue_establish_srb2(
  module_id_t ue_mod_idP,
  frame_t frameP,
  uint8_t eNB_index,
  struct SRB_ToAddMod* SRB_config
)
//-----------------------------------------------------------------------------
679
{
680
  // add descriptor from RRC PDU
681

gauthier's avatar
gauthier committed
682
  uint8_t lchan_id = DCCH1;
683

gauthier's avatar
   
gauthier committed
684
685
686
  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;
687

gauthier's avatar
gauthier committed
688
  // copy default configuration for now
gauthier's avatar
   
gauthier committed
689
690
  //  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);
691
692


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

gauthier's avatar
   
gauthier committed
695
696
  //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);
697

gauthier's avatar
   
gauthier committed
698
  //  UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Srb_info.Tx_buffer.payload_size=DEFAULT_MEAS_IND_SIZE+1;
699
700
701
702
703


  return(0);
}

704
705
706
707
708
709
710
711
712
//-----------------------------------------------------------------------------
int32_t
rrc_ue_establish_drb(
  module_id_t ue_mod_idP,
  frame_t frameP,
  uint8_t eNB_index,
  struct DRB_ToAddMod* DRB_config
)
//-----------------------------------------------------------------------------
713
{
714
715
  // add descriptor from RRC PDU
#ifdef PDCP_USE_NETLINK
716
  int oip_ifup=0,ip_addr_offset3=0,ip_addr_offset4=0;
Cedric Roux's avatar
Cedric Roux committed
717
718
719
720
  /* avoid gcc warnings */
  (void)oip_ifup;
  (void)ip_addr_offset3;
  (void)ip_addr_offset4;
721
#endif
722

723
  LOG_I(RRC,"[UE %d] Frame %d: processing RRCConnectionReconfiguration: reconfiguring DRB %ld/LCID %d\n",
724
        ue_mod_idP, frameP, DRB_config->drb_Identity, (int)*DRB_config->logicalChannelIdentity);
725
  /*
gauthier's avatar
   
gauthier committed
726
  rrc_pdcp_config_req (ue_mod_idP+NB_eNB_INST, frameP, 0, CONFIG_ACTION_ADD,
727
                             (eNB_index * NB_RB_MAX) + *DRB_config->logicalChannelIdentity, UNDEF_SECURITY_MODE);
gauthier's avatar
gauthier committed
728

729
  rrc_rlc_config_req(ue_mod_idP+NB_eNB_INST,frameP,0,CONFIG_ACTION_ADD,
730
731
                    (eNB_index * NB_RB_MAX) + *DRB_config->logicalChannelIdentity,
                    RADIO_ACCESS_BEARER,Rlc_info_um);
gauthier's avatar
gauthier committed
732
   */
733
#ifdef PDCP_USE_NETLINK
734
#   if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(ETHERNET) && !defined(LINK_ENB_PDCP_TO_GTPV1U)
735
#    ifdef OAI_EMU
gauthier's avatar
gauthier committed
736
737
  ip_addr_offset3 = oai_emulation.info.nb_enb_local;
  ip_addr_offset4 = NB_eNB_INST;
738
#    else
gauthier's avatar
gauthier committed
739
740
  ip_addr_offset3 = 0;
  ip_addr_offset4 = 8;
741
#    endif
gauthier's avatar
   
gauthier committed
742
  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,
743
        ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1);
gauthier's avatar
   
gauthier committed
744
  oip_ifup=nas_config(ip_addr_offset3+ue_mod_idP,   // interface_id
745
746
747
748
                      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
749
#        ifdef OAI_EMU
750
    oai_emulation.info.oai_ifup[ue_mod_idP]=1;
751
#        endif
752
    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
753
754
          ue_mod_idP,
          ip_addr_offset3+ue_mod_idP,
755
          (eNB_index * maxDRB) + DRB_config->drb_Identity);
756

757
758
759
760
761
762
763
764
    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
765
  }
766

767
768
#    else
#        ifdef OAI_EMU
gauthier's avatar
   
gauthier committed
769
  oai_emulation.info.oai_ifup[ue_mod_idP]=1;
770
771
772
773
774
775
776
777
#        endif
#    endif
#endif

  return(0);
}


778
779
780
781
782
783
784
785
//-----------------------------------------------------------------------------
void
rrc_ue_process_measConfig(
  const protocol_ctxt_t* const       ctxt_pP,
  const uint8_t                      eNB_index,
  MeasConfig_t* const               measConfig
)
//-----------------------------------------------------------------------------
786
{
787
788
789
790
791
792
793

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

  if (measConfig->measObjectToRemoveList != NULL) {
794
795
    for (i=0; i<measConfig->measObjectToRemoveList->list.count; i++) {
      ind   = *measConfig->measObjectToRemoveList->list.array[i];
796
      free(UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index][ind-1]);
797
    }
798
  }
799

800
  if (measConfig->measObjectToAddModList != NULL) {
801
802
803
804
805
806
    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;

807
      if (UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index][ind-1]) {
808
        LOG_D(RRC,"Modifying measurement object %d\n",ind);
809
        memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index][ind-1],
810
811
812
813
814
815
816
817
818
819
820
               (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]);
821
          UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index][ind-1]=measObj;
822
        }
823
      }
824
825
    }

826
    rrc_mac_config_req(ctxt_pP->module_id,0,ENB_FLAG_NO,0,eNB_index,
827
828
                       (RadioResourceConfigCommonSIB_t *)NULL,
                       (struct PhysicalConfigDedicated *)NULL,
829
#ifdef Rel10
830
831
832
                       (SCellToAddMod_r10_t *)NULL,
                       //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
#endif
833
                       UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index],
834
835
836
837
838
839
840
841
842
843
844
845
                       (MAC_MainConfig_t *)NULL,
                       0,
                       (struct LogicalChannelConfig *)NULL,
                       (MeasGapConfig_t *)NULL,
                       (TDD_Config_t *)NULL,
                       (MobilityControlInfo_t *)NULL,
                       NULL,
                       NULL,
                       NULL,
                       NULL,
                       NULL,
                       NULL
846
#ifdef Rel10
847
848
849
850
                       ,
                       0,
                       (MBSFN_AreaInfoList_r9_t *)NULL,
                       (PMCH_InfoList_r9_t *)NULL
851
852
#endif
#ifdef CBA
853
854
855
                       ,
                       0,
                       0
856
#endif
857
                      );
858
  }
859

860
  if (measConfig->reportConfigToRemoveList != NULL) {
861
862
    for (i=0; i<measConfig->reportConfigToRemoveList->list.count; i++) {
      ind   = *measConfig->reportConfigToRemoveList->list.array[i];
863
      free(UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1]);
864
    }
865
  }
866

867
  if (measConfig->reportConfigToAddModList != NULL) {
868
869
870
871
872
    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;

873
      if (UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1]) {
874
        LOG_I(RRC,"Modifying Report Configuration %d\n",ind-1);
875
        memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1],
876
877
878
879
               (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]);
880
        UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1] = measConfig->reportConfigToAddModList->list.array[i];
881
      }
882
    }
883
884
885
  }

  if (measConfig->quantityConfig != NULL) {
886
    if (UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index]) {
887
      LOG_D(RRC,"Modifying Quantity Configuration \n");
888
      memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index],
889
890
891
892
             (char*)measConfig->quantityConfig,
             sizeof(QuantityConfig_t));
    } else {
      LOG_D(RRC,"Adding Quantity configuration\n");
893
      UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index] = measConfig->quantityConfig;
894
    }
895
896
897
  }

  if (measConfig->measIdToRemoveList != NULL) {
898
899
    for (i=0; i<measConfig->measIdToRemoveList->list.count; i++) {
      ind   = *measConfig->measIdToRemoveList->list.array[i];
900
      free(UE_rrc_inst[ctxt_pP->module_id].MeasId[eNB_index][ind-1]);
901
    }
902
903
904
  }

  if (measConfig->measIdToAddModList != NULL) {
905
906
907
    for (i=0; i<measConfig->measIdToAddModList->list.count; i++) {
      ind   = measConfig->measIdToAddModList->list.array[i]->measId;

908
      if (UE_rrc_inst[ctxt_pP->module_id].MeasId[eNB_index][ind-1]) {
909
        LOG_D(RRC,"Modifying Measurement ID %d\n",ind-1);
910
        memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].MeasId[eNB_index][ind-1],
911
912
913
914
               (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]);
915
        UE_rrc_inst[ctxt_pP->module_id].MeasId[eNB_index][ind-1] = measConfig->measIdToAddModList->list.array[i];
916
      }
917
    }
918
919
920
  }

  if (measConfig->measGapConfig !=NULL) {
921
922
    if (UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index]) {
      memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index],
923
924
925
             (char*)measConfig->measGapConfig,
             sizeof(MeasGapConfig_t));
    } else {