rrc_UE.c 188 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 "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
78
#if ENABLE_RAL
gauthier's avatar
gauthier committed
79
80
#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

// 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
144
#ifdef Rel10
145
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
146
#endif
147
148
149
150
151
152
153
154








winckel's avatar
winckel committed
155
/*------------------------------------------------------------------------------*/
Cedric Roux's avatar
Cedric Roux committed
156
157
/* to avoid gcc warnings when compiling with certain options */
#if defined(ENABLE_USE_MME) || ENABLE_RAL
158
159
static Rrc_State_t rrc_get_state (module_id_t ue_mod_idP)
{
gauthier's avatar
   
gauthier committed
160
  return UE_rrc_inst[ue_mod_idP].RrcState;
winckel's avatar
winckel committed
161
}
Cedric Roux's avatar
Cedric Roux committed
162
#endif
winckel's avatar
winckel committed
163

164
165
static Rrc_Sub_State_t rrc_get_sub_state (module_id_t ue_mod_idP)
{
gauthier's avatar
   
gauthier committed
166
  return UE_rrc_inst[ue_mod_idP].RrcSubState;
winckel's avatar
winckel committed
167
168
}

169
170
static int rrc_set_state (module_id_t ue_mod_idP, Rrc_State_t state)
{
winckel's avatar
winckel committed
171
  AssertFatal ((RRC_STATE_FIRST <= state) && (state <= RRC_STATE_LAST),
172
               "Invalid state %d!\n", state);
winckel's avatar
winckel committed
173

gauthier's avatar
   
gauthier committed
174
  if (UE_rrc_inst[ue_mod_idP].RrcState != state) {
175
    UE_rrc_inst[ue_mod_idP].RrcState = state;
winckel's avatar
winckel committed
176

177
#if defined(ENABLE_ITTI)
178
179
    {
      MessageDef *msg_p;
180

181
182
183
      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
184

185
      itti_send_msg_to_task(TASK_UNKNOWN, UE_MODULE_ID_TO_INSTANCE(ue_mod_idP), msg_p);
186
    }
187
#endif
188
    return (1);
winckel's avatar
winckel committed
189
190
191
192
193
  }

  return (0);
}

194
//-----------------------------------------------------------------------------
195
static int rrc_set_sub_state( module_id_t ue_mod_idP, Rrc_Sub_State_t subState )
196
{
197
#if (defined(ENABLE_ITTI) && (defined(ENABLE_USE_MME) || ENABLE_RAL))
198

gauthier's avatar
   
gauthier committed
199
  switch (UE_rrc_inst[ue_mod_idP].RrcState) {
gauthier's avatar
gauthier committed
200
201
  case RRC_STATE_INACTIVE:
    AssertFatal ((RRC_SUB_STATE_INACTIVE_FIRST <= subState) && (subState <= RRC_SUB_STATE_INACTIVE_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_IDLE:
    AssertFatal ((RRC_SUB_STATE_IDLE_FIRST <= subState) && (subState <= RRC_SUB_STATE_IDLE_LAST),
207
                 "Invalid sub state %d for state %d!\n", subState, UE_rrc_inst[ue_mod_idP].RrcState);
gauthier's avatar
gauthier committed
208
209
210
211
    break;

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

216
#endif
winckel's avatar
winckel committed
217

gauthier's avatar
   
gauthier committed
218
  if (UE_rrc_inst[ue_mod_idP].RrcSubState != subState) {
219
    UE_rrc_inst[ue_mod_idP].RrcSubState = subState;
winckel's avatar
winckel committed
220

221
#if defined(ENABLE_ITTI)
222
223
    {
      MessageDef *msg_p;
winckel's avatar
winckel committed
224

225
226
227
      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;
228

229
      itti_send_msg_to_task(TASK_UNKNOWN, UE_MODULE_ID_TO_INSTANCE(ue_mod_idP), msg_p);
230
    }
231
#endif
232
    return (1);
winckel's avatar
winckel committed
233
234
235
236
237
  }

  return (0);
}

238
//-----------------------------------------------------------------------------
239
static void init_SI_UE( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index )
240
{
241
242
  UE_rrc_inst[ctxt_pP->module_id].sizeof_SIB1[eNB_index] = 0;
  UE_rrc_inst[ctxt_pP->module_id].sizeof_SI[eNB_index] = 0;
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
  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 );
260

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

263
  UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus = 0;
264
  UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt    = 0;
265
266
267
}

#ifdef Rel10
268
//-----------------------------------------------------------------------------
269
#if 0
270
static void init_MCCH_UE(module_id_t ue_mod_idP, uint8_t eNB_index)
271
{
272
  int i;
gauthier's avatar
   
gauthier committed
273
274
275
  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));
276

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

280
  }
281
282
}
#endif
283
#endif
284

285
286
//-----------------------------------------------------------------------------
static void openair_rrc_lite_ue_init_security( const protocol_ctxt_t* const ctxt_pP )
287
288
{
#if defined(ENABLE_SECURITY)
gauthier's avatar
gauthier committed
289
290
291
292
  //    uint8_t *kRRCenc;
  //    uint8_t *kRRCint;
  char ascii_buffer[65];
  uint8_t i;
293

294
  memset(UE_rrc_inst[ctxt_pP->module_id].kenb, ctxt_pP->module_id, 32);
295

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

300
301
302
  LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT"[OSA] kenb    = %s\n",
        PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
        ascii_buffer);
303
#endif
304
}
305

306
//-----------------------------------------------------------------------------
307
char openair_rrc_lite_ue_init( const module_id_t ue_mod_idP, const unsigned char eNB_index )
308
{
309
  protocol_ctxt_t ctxt;
310
  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_idP, ENB_FLAG_NO, NOT_A_RNTI, 0, 0,eNB_index);
311
312
313
  LOG_I(RRC,
        PROTOCOL_RRC_CTXT_FMT" Init...\n",
        PROTOCOL_RRC_CTXT_ARGS(&ctxt));
gauthier's avatar
   
gauthier committed
314
315
316
  rrc_set_state (ue_mod_idP, RRC_STATE_INACTIVE);
  rrc_set_sub_state (ue_mod_idP, RRC_SUB_STATE_INACTIVE);

317
318
319
320
321
322
323
324
325
326
327
  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;
328
#ifdef Rel10
329
  UE_rrc_inst[ctxt.module_id].integrity_algorithm = SecurityAlgorithmConfig__integrityProtAlgorithm_eia0_v920;
330
#else
331
  UE_rrc_inst[ctxt.module_id].integrity_algorithm = SecurityAlgorithmConfig__integrityProtAlgorithm_reserved;
332
333
#endif

334
335
336
337
  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));
338
339

#ifndef NO_RRM
340
  send_msg(&S_rrc,msg_rrc_phy_synch_to_CH_ind(ctxt.module_id,eNB_index,UE_rrc_inst[ctxt.module_id].Mac_id));
341
342
343
#endif

#ifdef NO_RRM //init ch SRB0, SRB1 & BDTCH
344
  openair_rrc_on(&ctxt);
345
#endif
346
#ifdef CBA
347
  int j;
348

349
  for(j=0; j<NUM_MAX_CBA_GROUP; j++) {
gauthier's avatar
   
gauthier committed
350
    UE_rrc_inst[ue_mod_idP].cba_rnti[j] = 0x0000;
351
  }
352

gauthier's avatar
   
gauthier committed
353
  UE_rrc_inst[ue_mod_idP].num_active_cba_groups = 0;
354
355
356
357
358
#endif

  return 0;
}

359
//-----------------------------------------------------------------------------
360
void rrc_ue_generate_RRCConnectionRequest( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index )
361
{
362

gauthier's avatar
gauthier committed
363
  uint8_t i=0,rv[6];
gauthier's avatar
gauthier committed
364

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

367
368
369
370
371
372
    // 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;
373
#else
374
      rv[i]=taus()&0xff;
375
#endif
376
377
      LOG_T(RRC,"%x.",rv[i]);
    }
378

379
    LOG_T(RRC,"\n");
380
381
382
383
384
    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);
385
386

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

389
390
    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]);
391
392
393
    }

    LOG_T(RRC,"\n");
394
395
    /*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; */
396
397
398
399
400
401
402

  }
}


mui_t rrc_mui=0;

403
/* NAS Attach request with IMSI */
404
static const char const nas_attach_req_imsi[] = {
405
406
407
408
409
410
411
412
413
414
415
  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,
};
416
417

/* NAS Attach request with GUTI */
418
static const char const nas_attach_req_guti[] = {
419
420
421
422
423
424
425
426
427
428
429
  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,
};
430

431
//-----------------------------------------------------------------------------
432
static void rrc_ue_generate_RRCConnectionSetupComplete( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, const uint8_t Transaction_id )
433
{
434

gauthier's avatar
gauthier committed
435
436
  uint8_t    buffer[100];
  uint8_t    size;
437
  const char * nas_msg;
winckel's avatar
winckel committed
438
  int   nas_msg_length;
439

winckel's avatar
winckel committed
440
#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
441
442
  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
443
444
445
446
447
#else
  nas_msg         = nas_attach_req_imsi;
  nas_msg_length  = sizeof(nas_attach_req_imsi);
#endif

448
  size = do_RRCConnectionSetupComplete(ctxt_pP->module_id, buffer, Transaction_id, nas_msg_length, nas_msg);
449
450

  LOG_I(RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCConnectionSetupComplete (bytes%d, eNB %d)\n",
451
452
        ctxt_pP->module_id,ctxt_pP->frame, size, eNB_index);
  LOG_D(RLC,
gauthier's avatar
gauthier committed
453
        "[FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCConnectionSetupComplete to eNB %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n",
454
455
456
457
458
459
460
461
462
        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);
463
464
}

465
//-----------------------------------------------------------------------------
466
static void rrc_ue_generate_RRCConnectionReconfigurationComplete( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, const uint8_t Transaction_id )
467
{
468

gauthier's avatar
gauthier committed
469
  uint8_t buffer[32], size;
470
471
472
473
  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
474
        "[FRAME %05d][RRC_UE][INST %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCConnectionReconfigurationComplete to eNB %d MUI %d) --->][PDCP][INST %02d][RB %02d]\n",
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
        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);
490
491
492
}


493
494
//-----------------------------------------------------------------------------
// Called by L2 interface (MAC)
495
int rrc_ue_decode_ccch( const protocol_ctxt_t* const ctxt_pP, const SRB_INFO* const Srb_info, const uint8_t eNB_index )
496
497
{
  DL_CCCH_Message_t* dl_ccch_msg=NULL;
498
  asn_dec_rval_t dec_rval;
499
  int rval=0;
500

gauthier's avatar
gauthier committed
501
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN);
gauthier's avatar
   
gauthier committed
502
503
  //  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);
504
505

  dec_rval = uper_decode(NULL,
506
507
508
509
                         &asn_DEF_DL_CCCH_Message,
                         (void**)&dl_ccch_msg,
                         (uint8_t*)Srb_info->Rx_buffer.Payload,
                         100,0,0);
510
511
512
513
514

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

515
#if defined(ENABLE_ITTI)
516
# if defined(DISABLE_ITTI_XER_PRINT)
517
  {
winckel's avatar
winckel committed
518
    MessageDef *msg_p;
519

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

523
    itti_send_msg_to_task (TASK_UNKNOWN, ctxt_pP->instance, msg_p);
524
  }
525
526
# else
  {
527
528
    char        message_string[10000];
    size_t      message_string_size;
529

530
531
    if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message, (void *)dl_ccch_msg)) > 0) {
      MessageDef *msg_p;
532

533
534
535
      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);
536

537
      itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p);
538
    }
539
540
  }
# endif
541
542
#endif

543
  if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) {
544
    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
545
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
546
    return -1;
547
548
549
550
  }

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

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

553
      switch (dl_ccch_msg->message.choice.c1.present) {
554

555
      case DL_CCCH_MessageType__c1_PR_NOTHING:
556
557
558
        LOG_I(RRC, "[UE%d] Frame %d : Received PR_NOTHING on DL-CCCH-Message\n",
              ctxt_pP->module_id,
              ctxt_pP->frame);
559
560
        rval = 0;
        break;
561

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

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

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

586
587
      case DL_CCCH_MessageType__c1_PR_rrcConnectionSetup:
        LOG_I(RRC,
588
589
590
591
              "[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);
592
        // Get configuration
593

594
        // Release T300 timer
595
596
597
598
        UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].T300_active = 0;
        rrc_ue_process_radioResourceConfigDedicated(
          ctxt_pP,
          eNB_index,
599
          &dl_ccch_msg->message.choice.c1.choice.rrcConnectionSetup.criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated);
600

601
602
603
604
605
606
607
        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);
608

609
610
        rval = 0;
        break;
611

612
      default:
613
614
615
        LOG_E(RRC, "[UE%d] Frame %d : Unknown message\n",
              ctxt_pP->module_id,
              ctxt_pP->frame);
616
617
        rval = -1;
        break;
618
      }
619
    }
620
621
  }

gauthier's avatar
gauthier committed
622
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
623
624
625
  return rval;
}

626
627
628
629
630
631
632
633
634
//-----------------------------------------------------------------------------
int32_t
rrc_ue_establish_srb1(
  module_id_t ue_mod_idP,
  frame_t frameP,
  uint8_t eNB_index,
  struct SRB_ToAddMod* SRB_config
)
//-----------------------------------------------------------------------------
635
{
636
  // add descriptor from RRC PDU
637

gauthier's avatar
gauthier committed
638
  uint8_t lchan_id = DCCH;
639

gauthier's avatar
   
gauthier committed
640
641
642
  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;
643

gauthier's avatar
gauthier committed
644
  // copy default configuration for now
gauthier's avatar
   
gauthier committed
645
646
  //  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);
647
648


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

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

gauthier's avatar
   
gauthier committed
654
  //  UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Srb_info.Tx_buffer.payload_size=DEFAULT_MEAS_IND_SIZE+1;
655
656
657
658
659


  return(0);
}

660
661
662
663
664
665
666
667
668
//-----------------------------------------------------------------------------
int32_t
rrc_ue_establish_srb2(
  module_id_t ue_mod_idP,
  frame_t frameP,
  uint8_t eNB_index,
  struct SRB_ToAddMod* SRB_config
)
//-----------------------------------------------------------------------------
669
{
670
  // add descriptor from RRC PDU
671

gauthier's avatar
gauthier committed
672
  uint8_t lchan_id = DCCH1;
673

gauthier's avatar
   
gauthier committed
674
675
676
  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;
677

gauthier's avatar
gauthier committed
678
  // copy default configuration for now
gauthier's avatar
   
gauthier committed
679
680
  //  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);
681
682


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

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

gauthier's avatar
   
gauthier committed
688
  //  UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Srb_info.Tx_buffer.payload_size=DEFAULT_MEAS_IND_SIZE+1;
689
690
691
692
693


  return(0);
}

694
695
696
697
698
699
700
701
702
//-----------------------------------------------------------------------------
int32_t
rrc_ue_establish_drb(
  module_id_t ue_mod_idP,
  frame_t frameP,
  uint8_t eNB_index,
  struct DRB_ToAddMod* DRB_config
)
//-----------------------------------------------------------------------------
703
{
704
705
  // add descriptor from RRC PDU
#ifdef PDCP_USE_NETLINK
706
  int oip_ifup=0,ip_addr_offset3=0,ip_addr_offset4=0;
707
#endif
708

709
  LOG_I(RRC,"[UE %d] Frame %d: processing RRCConnectionReconfiguration: reconfiguring DRB %ld/LCID %d\n",
710
        ue_mod_idP, frameP, DRB_config->drb_Identity, (int)*DRB_config->logicalChannelIdentity);
711
  /*
gauthier's avatar
   
gauthier committed
712
  rrc_pdcp_config_req (ue_mod_idP+NB_eNB_INST, frameP, 0, CONFIG_ACTION_ADD,
713
                             (eNB_index * NB_RB_MAX) + *DRB_config->logicalChannelIdentity, UNDEF_SECURITY_MODE);
gauthier's avatar
gauthier committed
714

715
  rrc_rlc_config_req(ue_mod_idP+NB_eNB_INST,frameP,0,CONFIG_ACTION_ADD,
716
717
                    (eNB_index * NB_RB_MAX) + *DRB_config->logicalChannelIdentity,
                    RADIO_ACCESS_BEARER,Rlc_info_um);
gauthier's avatar
gauthier committed
718
   */
719
#ifdef PDCP_USE_NETLINK
720
#   if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(ETHERNET) && !defined(LINK_ENB_PDCP_TO_GTPV1U)
721
#    ifdef OAI_EMU
gauthier's avatar
gauthier committed
722
723
  ip_addr_offset3 = oai_emulation.info.nb_enb_local;
  ip_addr_offset4 = NB_eNB_INST;
724
#    else
gauthier's avatar
gauthier committed
725
726
  ip_addr_offset3 = 0;
  ip_addr_offset4 = 8;
727
#    endif
gauthier's avatar
   
gauthier committed
728
  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,
729
        ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1);
gauthier's avatar
   
gauthier committed
730
  oip_ifup=nas_config(ip_addr_offset3+ue_mod_idP,   // interface_id
731
732
733
734
                      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
735
#        ifdef OAI_EMU
736
    oai_emulation.info.oai_ifup[ue_mod_idP]=1;
737
#        endif
738
    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
739
740
          ue_mod_idP,
          ip_addr_offset3+ue_mod_idP,
741
          (eNB_index * maxDRB) + DRB_config->drb_Identity);
742

743
744
745
746
747
748
749
750
    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
751
  }
752

753
754
#    else
#        ifdef OAI_EMU
gauthier's avatar
   
gauthier committed
755
  oai_emulation.info.oai_ifup[ue_mod_idP]=1;
756
757
758
759
760
761
762
763
#        endif
#    endif
#endif

  return(0);
}


764
765
766
767
768
769
770
771
//-----------------------------------------------------------------------------
void
rrc_ue_process_measConfig(
  const protocol_ctxt_t* const       ctxt_pP,
  const uint8_t                      eNB_index,
  MeasConfig_t* const               measConfig
)
//-----------------------------------------------------------------------------
772
{
773
774
775
776
777
778
779

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

  if (measConfig->measObjectToRemoveList != NULL) {
780
781
    for (i=0; i<measConfig->measObjectToRemoveList->list.count; i++) {
      ind   = *measConfig->measObjectToRemoveList->list.array[i];
782
      free(UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index][ind-1]);
783
    }
784
  }
785

786
  if (measConfig->measObjectToAddModList != NULL) {
787
788
789
790
791
792
    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;

793
      if (UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index][ind-1]) {
794
        LOG_D(RRC,"Modifying measurement object %d\n",ind);
795
        memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index][ind-1],
796
797
798
799
800
801
802
803
804
805
806
               (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]);
807
          UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index][ind-1]=measObj;
808
        }
809
      }
810
811
    }

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

846
  if (measConfig->reportConfigToRemoveList != NULL) {
847
848
    for (i=0; i<measConfig->reportConfigToRemoveList->list.count; i++) {
      ind   = *measConfig->reportConfigToRemoveList->list.array[i];
849
      free(UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1]);
850
    }
851
  }
852

853
  if (measConfig->reportConfigToAddModList != NULL) {
854
855
856
857
858
    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;

859
      if (UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1]) {
860
        LOG_I(RRC,"Modifying Report Configuration %d\n",ind-1);
861
        memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1],
862
863
864
865
               (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]);
866
        UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1] = measConfig->reportConfigToAddModList->list.array[i];
867
      }
868
    }
869
870
871
  }

  if (measConfig->quantityConfig != NULL) {
872
    if (UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index]) {
873
      LOG_D(RRC,"Modifying Quantity Configuration \n");
874
      memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index],
875
876
877
878
             (char*)measConfig->quantityConfig,
             sizeof(QuantityConfig_t));
    } else {
      LOG_D(RRC,"Adding Quantity configuration\n");
879
      UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index] = measConfig->quantityConfig;
880
    }
881
882
883
  }

  if (measConfig->measIdToRemoveList != NULL) {
884
885
    for (i=0; i<measConfig->measIdToRemoveList->list.count; i++) {
      ind   = *measConfig->measIdToRemoveList->list.array[i];
886
      free(UE_rrc_inst[ctxt_pP->module_id].MeasId[eNB_index][ind-1]);
887
    }
888
889
890
  }

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

894
      if (UE_rrc_inst[ctxt_pP->module_id].MeasId[eNB_index][ind-1]) {
895
        LOG_D(RRC,"Modifying Measurement ID %d\n",ind-1);
896
        memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].MeasId[eNB_index][ind-1],
897
898
899
900
               (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]);
901
        UE_rrc_inst[ctxt_pP->module_id].MeasId[eNB_index][ind-1] = measConfig->measIdToAddModList->list.array[i];
902
      }
903
    }
904
905
906
  }

  if (measConfig->measGapConfig !=NULL) {
907
908
    if (UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index]) {
      memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index],
909
910
911
             (char*)measConfig->measGapConfig,
             sizeof(MeasGapConfig_t));
    } else {
912
      UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index] = measConfig->measGapConfig;
913
    }
914
915
  }

916
  if (measConfig->quantityConfig != NULL) {
917
    if (UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index]) {
918
      LOG_I(RRC,"Modifying Quantity Configuration \n");
919
      memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index],
920
921
922
923
             (char*)measConfig->quantityConfig,
             sizeof(QuantityConfig_t));
    } else {
      LOG_I(RRC,"Adding Quantity configuration\n");
924
      UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index] = measConfig->quantityConfig;
925
    }
gauthier's avatar
gauthier committed
926

927
928
929
930
    UE_rrc_inst[ctxt_pP->module_id].filter_coeff_rsrp = 1./pow(2,
        (*UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRP)/4);
    UE_rrc_inst[ctxt_pP->module_id].filter_coeff_rsrq = 1./pow(2,
        (*UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRQ)/4);
gauthier's avatar
gauthier committed
931

932
    LOG_I(RRC,"[UE %d] set rsrp-coeff for eNB %d: %d rsrq-coeff: %d rsrp_factor: %f rsrq_factor: %f \n",
933
934
935
936
937
938
939
          ctxt_pP->module_id, eNB_index, // UE_rrc_inst[ue_mod_idP].Info[eNB_index].UE_index,
          *UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRP,
          *UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRQ,
          UE_rrc_inst[ctxt_pP->module_id].filter_coeff_rsrp,
          UE_rrc_inst[ctxt_pP->module_id].filter_coeff_rsrp,
          UE_rrc_inst[ctxt_pP->module_id].filter_coeff_rsrp,
          UE_rrc_inst[ctxt_pP->module_id].filter_coeff_rsrq);
940
941
  }

942
  if (measConfig->s_Measure != NULL) {
943
    UE_rrc_inst[ctxt_pP->module_id].s_measure = *measConfig->s_Measure;
944
  }
gauthier's avatar
gauthier committed
945

946
  if (measConfig->speedStatePars != NULL) {
947
948
949
950
951
    if (UE_rrc_inst[ctxt_pP->module_id].speedStatePars) {
      memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].speedStatePars,(char*)measConfig->speedStatePars,sizeof(struct MeasConfig__speedStatePars));
    } else {
      UE_rrc_inst[ctxt_pP->module_id].speedStatePars = measConfig->speedStatePars;
    }