rrc_UE.c 161 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
void
rrc_ue_process_securityModeCommand(
  const protocol_ctxt_t* const ctxt_pP,
  SecurityModeCommand_t* const securityModeCommand,
  const uint8_t                eNB_index
);
winckel's avatar
winckel committed
116
/*------------------------------------------------------------------------------*/
117
118
static Rrc_State_t rrc_get_state (module_id_t ue_mod_idP)
{
gauthier's avatar
   
gauthier committed
119
  return UE_rrc_inst[ue_mod_idP].RrcState;
winckel's avatar
winckel committed
120
121
}

122
123
static Rrc_Sub_State_t rrc_get_sub_state (module_id_t ue_mod_idP)
{
gauthier's avatar
   
gauthier committed
124
  return UE_rrc_inst[ue_mod_idP].RrcSubState;
winckel's avatar
winckel committed
125
126
}

127
128
static int rrc_set_state (module_id_t ue_mod_idP, Rrc_State_t state)
{
winckel's avatar
winckel committed
129
  AssertFatal ((RRC_STATE_FIRST <= state) && (state <= RRC_STATE_LAST),
130
               "Invalid state %d!\n", state);
winckel's avatar
winckel committed
131

gauthier's avatar
   
gauthier committed
132
  if (UE_rrc_inst[ue_mod_idP].RrcState != state) {
133
    UE_rrc_inst[ue_mod_idP].RrcState = state;
winckel's avatar
winckel committed
134

135
#if defined(ENABLE_ITTI)
136
137
    {
      MessageDef *msg_p;
138

139
140
141
      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
142

143
      itti_send_msg_to_task(TASK_UNKNOWN, UE_MODULE_ID_TO_INSTANCE(ue_mod_idP), msg_p);
144
    }
145
#endif
146
    return (1);
winckel's avatar
winckel committed
147
148
149
150
151
  }

  return (0);
}

152
153
154
155
156
157
158
//-----------------------------------------------------------------------------
static int
rrc_set_sub_state (
  module_id_t ue_mod_idP,
  Rrc_Sub_State_t subState
)
//-----------------------------------------------------------------------------
159
{
160
#if (defined(ENABLE_ITTI) && (defined(ENABLE_USE_MME) || defined(ENABLE_RAL)))
161

gauthier's avatar
   
gauthier committed
162
  switch (UE_rrc_inst[ue_mod_idP].RrcState) {
gauthier's avatar
gauthier committed
163
164
  case RRC_STATE_INACTIVE:
    AssertFatal ((RRC_SUB_STATE_INACTIVE_FIRST <= subState) && (subState <= RRC_SUB_STATE_INACTIVE_LAST),
165
                 "Invalid sub state %d for state %d!\n", subState, UE_rrc_inst[ue_mod_idP].RrcState);
gauthier's avatar
gauthier committed
166
167
168
169
    break;

  case RRC_STATE_IDLE:
    AssertFatal ((RRC_SUB_STATE_IDLE_FIRST <= subState) && (subState <= RRC_SUB_STATE_IDLE_LAST),
170
                 "Invalid sub state %d for state %d!\n", subState, UE_rrc_inst[ue_mod_idP].RrcState);
gauthier's avatar
gauthier committed
171
172
173
174
    break;

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

179
#endif
winckel's avatar
winckel committed
180

gauthier's avatar
   
gauthier committed
181
  if (UE_rrc_inst[ue_mod_idP].RrcSubState != subState) {
182
    UE_rrc_inst[ue_mod_idP].RrcSubState = subState;
winckel's avatar
winckel committed
183

184
#if defined(ENABLE_ITTI)
185
186
    {
      MessageDef *msg_p;
winckel's avatar
winckel committed
187

188
189
190
      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;
191

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

  return (0);
}

201
202
203
204
205
206
207
//-----------------------------------------------------------------------------
void
init_SI_UE(
  const protocol_ctxt_t* const ctxt_pP,
  const uint8_t eNB_index
)
//-----------------------------------------------------------------------------
208
{
209
210
211
212

  int i;


213
214
215
216
217
  UE_rrc_inst[ctxt_pP->module_id].sizeof_SIB1[eNB_index] = 0;
  UE_rrc_inst[ctxt_pP->module_id].sizeof_SI[eNB_index] = 0;
  UE_rrc_inst[ctxt_pP->module_id].SIB1[eNB_index] = (uint8_t*)malloc16(32);
  UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index] = (SystemInformationBlockType1_t*)malloc16(sizeof(SystemInformationBlockType1_t));
  UE_rrc_inst[ctxt_pP->module_id].SI[eNB_index] = (uint8_t*)malloc16(64);
218

219
  for (i=0; i<8; i++) {
220
    UE_rrc_inst[ctxt_pP->module_id].si[eNB_index][i] = (SystemInformation_t*)malloc16(sizeof(SystemInformation_t));
221
222
  }

223
224
  UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIB1Status = 0;
  UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus = 0;
225
226
227
}

#ifdef Rel10
228
229
void init_MCCH_UE(module_id_t ue_mod_idP, uint8_t eNB_index)
{
230
  int i;
gauthier's avatar
   
gauthier committed
231
232
233
  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));
234

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

238
  }
239
240
241
242
}
#endif

static
243
244
245
void openair_rrc_lite_ue_init_security(
  const protocol_ctxt_t* const ctxt_pP
)
246
247
{
#if defined(ENABLE_SECURITY)
gauthier's avatar
gauthier committed
248
249
250
251
  //    uint8_t *kRRCenc;
  //    uint8_t *kRRCint;
  char ascii_buffer[65];
  uint8_t i;
252

253
  memset(UE_rrc_inst[ctxt_pP->module_id].kenb, ctxt_pP->module_id, 32);
254

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

259
260
261
  LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT"[OSA] kenb    = %s\n",
        PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
        ascii_buffer);
262
#endif
263
}
264

265
266
267
268
269
270
271
//-----------------------------------------------------------------------------
char
openair_rrc_lite_ue_init(
  const module_id_t ue_mod_idP,
  const unsigned char eNB_index
)
//-----------------------------------------------------------------------------
272
{
273
  protocol_ctxt_t ctxt;
274
  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_idP, ENB_FLAG_NO, NOT_A_RNTI, 0, 0,eNB_index);
275
276
277
  LOG_I(RRC,
        PROTOCOL_RRC_CTXT_FMT" Init...\n",
        PROTOCOL_RRC_CTXT_ARGS(&ctxt));
gauthier's avatar
   
gauthier committed
278
279
280
  rrc_set_state (ue_mod_idP, RRC_STATE_INACTIVE);
  rrc_set_sub_state (ue_mod_idP, RRC_SUB_STATE_INACTIVE);

281
282
283
284
285
286
287
288
289
290
291
  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;
292
#ifdef Rel10
293
  UE_rrc_inst[ctxt.module_id].integrity_algorithm = SecurityAlgorithmConfig__integrityProtAlgorithm_eia0_v920;
294
#else
295
  UE_rrc_inst[ctxt.module_id].integrity_algorithm = SecurityAlgorithmConfig__integrityProtAlgorithm_reserved;
296
297
#endif

298
299
300
301
  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));
302
303

#ifndef NO_RRM
304
  send_msg(&S_rrc,msg_rrc_phy_synch_to_CH_ind(ctxt.module_id,eNB_index,UE_rrc_inst[ctxt.module_id].Mac_id));
305
306
307
#endif

#ifdef NO_RRM //init ch SRB0, SRB1 & BDTCH
308
  openair_rrc_on(&ctxt);
309
#endif
310
#ifdef CBA
311
  int j;
312

313
  for(j=0; j<NUM_MAX_CBA_GROUP; j++) {
gauthier's avatar
   
gauthier committed
314
    UE_rrc_inst[ue_mod_idP].cba_rnti[j] = 0x0000;
315
  }
316

gauthier's avatar
   
gauthier committed
317
  UE_rrc_inst[ue_mod_idP].num_active_cba_groups = 0;
318
319
320
321
322
#endif

  return 0;
}

323
324
325
326
327
328
329
//-----------------------------------------------------------------------------
void
rrc_ue_generate_RRCConnectionRequest(
  const protocol_ctxt_t* const ctxt_pP,
  const uint8_t                eNB_index
)
//-----------------------------------------------------------------------------
330
{
331

gauthier's avatar
gauthier committed
332
  uint8_t i=0,rv[6];
gauthier's avatar
gauthier committed
333

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

336
337
338
339
340
341
    // 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;
342
#else
343
      rv[i]=taus()&0xff;
344
#endif
345
346
      LOG_T(RRC,"%x.",rv[i]);
    }
347

348
    LOG_T(RRC,"\n");
349
350
351
352
353
    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);
354
355

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

358
359
    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]);
360
361
362
    }

    LOG_T(RRC,"\n");
363
364
    /*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; */
365
366
367
368
369
370
371

  }
}


mui_t rrc_mui=0;

372
/* NAS Attach request with IMSI */
373
static const char const nas_attach_req_imsi[] = {
374
375
376
377
378
379
380
381
382
383
384
  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,
};
385
386

/* NAS Attach request with GUTI */
387
static const char const nas_attach_req_guti[] = {
388
389
390
391
392
393
394
395
396
397
398
  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,
};
399

400
401
402
403
404
405
406
407
//-----------------------------------------------------------------------------
void
rrc_ue_generate_RRCConnectionSetupComplete(
  const protocol_ctxt_t* const ctxt_pP,
  const uint8_t                eNB_index,
  const uint8_t                Transaction_id
)
//-----------------------------------------------------------------------------
408
{
409

gauthier's avatar
gauthier committed
410
411
  uint8_t    buffer[100];
  uint8_t    size;
412
  const char * nas_msg;
winckel's avatar
winckel committed
413
  int   nas_msg_length;
414

winckel's avatar
winckel committed
415
#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
416
417
  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
418
419
420
421
422
#else
  nas_msg         = nas_attach_req_imsi;
  nas_msg_length  = sizeof(nas_attach_req_imsi);
#endif

423
  size = do_RRCConnectionSetupComplete(ctxt_pP->module_id, buffer, Transaction_id, nas_msg_length, nas_msg);
424
425

  LOG_I(RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCConnectionSetupComplete (bytes%d, eNB %d)\n",
426
427
        ctxt_pP->module_id,ctxt_pP->frame, size, eNB_index);
  LOG_D(RLC,
gauthier's avatar
gauthier committed
428
        "[FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCConnectionSetupComplete to eNB %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n",
429
430
431
432
433
434
435
436
437
        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);
438
439
}

440
441
442
443
444
445
446
447
//-----------------------------------------------------------------------------
void
rrc_ue_generate_RRCConnectionReconfigurationComplete(
  const protocol_ctxt_t* const ctxt_pP,
  const uint8_t                eNB_index,
  const uint8_t                Transaction_id
)
//-----------------------------------------------------------------------------
448
{
449

gauthier's avatar
gauthier committed
450
  uint8_t buffer[32], size;
451
452
453
454
  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
455
        "[FRAME %05d][RRC_UE][INST %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCConnectionReconfigurationComplete to eNB %d MUI %d) --->][PDCP][INST %02d][RB %02d]\n",
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
        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);
471
472
473
}


474
475
476
477
478
479
480
481
482
483
484
//-----------------------------------------------------------------------------
// Called by L2 interface (MAC)
int
rrc_ue_decode_ccch(
  const protocol_ctxt_t* const ctxt_pP,
  const SRB_INFO*        const Srb_info,
  const uint8_t                eNB_index
)
//-----------------------------------------------------------------------------
{
  DL_CCCH_Message_t* dl_ccch_msg=NULL;
485
  asn_dec_rval_t dec_rval;
486
  int rval=0;
487

gauthier's avatar
gauthier committed
488
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN);
gauthier's avatar
   
gauthier committed
489
490
  //  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);
491
492

  dec_rval = uper_decode(NULL,
493
494
495
496
                         &asn_DEF_DL_CCCH_Message,
                         (void**)&dl_ccch_msg,
                         (uint8_t*)Srb_info->Rx_buffer.Payload,
                         100,0,0);
497
498
499
500
501

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

502
#if defined(ENABLE_ITTI)
503
# if defined(DISABLE_ITTI_XER_PRINT)
504
  {
winckel's avatar
winckel committed
505
    MessageDef *msg_p;
506

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

510
    itti_send_msg_to_task (TASK_UNKNOWN, ctxt_pP->instance, msg_p);
511
  }
512
513
# else
  {
514
515
    char        message_string[10000];
    size_t      message_string_size;
516

517
518
    if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message, (void *)dl_ccch_msg)) > 0) {
      MessageDef *msg_p;
519

520
521
522
      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);
523

524
      itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p);
525
    }
526
527
  }
# endif
528
529
#endif

530
  if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) {
531
    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
532
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
533
    return -1;
534
535
536
537
  }

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

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

540
      switch (dl_ccch_msg->message.choice.c1.present) {
541

542
      case DL_CCCH_MessageType__c1_PR_NOTHING:
543
544
545
        LOG_I(RRC, "[UE%d] Frame %d : Received PR_NOTHING on DL-CCCH-Message\n",
              ctxt_pP->module_id,
              ctxt_pP->frame);
546
547
        rval = 0;
        break;
548

549
550
      case DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishment:
        LOG_I(RRC,
551
552
553
              "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReestablishment\n",
              ctxt_pP->module_id,
              ctxt_pP->frame);
554
555
        rval = 0;
        break;
556

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

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

573
574
      case DL_CCCH_MessageType__c1_PR_rrcConnectionSetup:
        LOG_I(RRC,
575
576
577
578
              "[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);
579
        // Get configuration
580

581
        // Release T300 timer
582
583
584
585
        UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].T300_active = 0;
        rrc_ue_process_radioResourceConfigDedicated(
          ctxt_pP,
          eNB_index,
586
          &dl_ccch_msg->message.choice.c1.choice.rrcConnectionSetup.criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated);
587

588
589
590
591
592
593
594
        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);
595

596
597
        rval = 0;
        break;
598

599
      default:
600
601
602
        LOG_E(RRC, "[UE%d] Frame %d : Unknown message\n",
              ctxt_pP->module_id,
              ctxt_pP->frame);
603
604
        rval = -1;
        break;
605
      }
606
    }
607
608
  }

gauthier's avatar
gauthier committed
609
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
610
611
612
  return rval;
}

613
614
615
616
617
618
619
620
621
//-----------------------------------------------------------------------------
int32_t
rrc_ue_establish_srb1(
  module_id_t ue_mod_idP,
  frame_t frameP,
  uint8_t eNB_index,
  struct SRB_ToAddMod* SRB_config
)
//-----------------------------------------------------------------------------
622
{
623
  // add descriptor from RRC PDU
624

gauthier's avatar
gauthier committed
625
  uint8_t lchan_id = DCCH;
626

gauthier's avatar
   
gauthier committed
627
628
629
  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;
630

gauthier's avatar
gauthier committed
631
  // copy default configuration for now
gauthier's avatar
   
gauthier committed
632
633
  //  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);
634
635


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

gauthier's avatar
   
gauthier committed
638
639
  //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);
640

gauthier's avatar
   
gauthier committed
641
  //  UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Srb_info.Tx_buffer.payload_size=DEFAULT_MEAS_IND_SIZE+1;
642
643
644
645
646


  return(0);
}

647
648
649
650
651
652
653
654
655
//-----------------------------------------------------------------------------
int32_t
rrc_ue_establish_srb2(
  module_id_t ue_mod_idP,
  frame_t frameP,
  uint8_t eNB_index,
  struct SRB_ToAddMod* SRB_config
)
//-----------------------------------------------------------------------------
656
{
657
  // add descriptor from RRC PDU
658

gauthier's avatar
gauthier committed
659
  uint8_t lchan_id = DCCH1;
660

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

gauthier's avatar
gauthier committed
665
  // copy default configuration for now
gauthier's avatar
   
gauthier committed
666
667
  //  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);
668
669


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

gauthier's avatar
   
gauthier committed
672
673
  //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);
674

gauthier's avatar
   
gauthier committed
675
  //  UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Srb_info.Tx_buffer.payload_size=DEFAULT_MEAS_IND_SIZE+1;
676
677
678
679
680


  return(0);
}

681
682
683
684
685
686
687
688
689
//-----------------------------------------------------------------------------
int32_t
rrc_ue_establish_drb(
  module_id_t ue_mod_idP,
  frame_t frameP,
  uint8_t eNB_index,
  struct DRB_ToAddMod* DRB_config
)
//-----------------------------------------------------------------------------
690
{
691
692
  // add descriptor from RRC PDU
#ifdef PDCP_USE_NETLINK
693
  int oip_ifup=0,ip_addr_offset3=0,ip_addr_offset4=0;
694
#endif
695

696
  LOG_I(RRC,"[UE %d] Frame %d: processing RRCConnectionReconfiguration: reconfiguring DRB %ld/LCID %d\n",
697
        ue_mod_idP, frameP, DRB_config->drb_Identity, (int)*DRB_config->logicalChannelIdentity);
698
  /*
gauthier's avatar
   
gauthier committed
699
  rrc_pdcp_config_req (ue_mod_idP+NB_eNB_INST, frameP, 0, CONFIG_ACTION_ADD,
700
                             (eNB_index * NB_RB_MAX) + *DRB_config->logicalChannelIdentity, UNDEF_SECURITY_MODE);
gauthier's avatar
gauthier committed
701

702
  rrc_rlc_config_req(ue_mod_idP+NB_eNB_INST,frameP,0,CONFIG_ACTION_ADD,
703
704
                    (eNB_index * NB_RB_MAX) + *DRB_config->logicalChannelIdentity,
                    RADIO_ACCESS_BEARER,Rlc_info_um);
gauthier's avatar
gauthier committed
705
   */
706
707
#ifdef PDCP_USE_NETLINK
#   if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(LINK_ENB_PDCP_TO_GTPV1U)
708
#    ifdef OAI_EMU
gauthier's avatar
gauthier committed
709
710
  ip_addr_offset3 = oai_emulation.info.nb_enb_local;
  ip_addr_offset4 = NB_eNB_INST;
711
#    else
gauthier's avatar
gauthier committed
712
713
  ip_addr_offset3 = 0;
  ip_addr_offset4 = 8;
714
#    endif
gauthier's avatar
   
gauthier committed
715
  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,
716
        ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1);
gauthier's avatar
   
gauthier committed
717
  oip_ifup=nas_config(ip_addr_offset3+ue_mod_idP,   // interface_id
718
719
720
721
                      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
722
#        ifdef OAI_EMU
723
    oai_emulation.info.oai_ifup[ue_mod_idP]=1;
724
#        endif
725
    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
726
727
          ue_mod_idP,
          ip_addr_offset3+ue_mod_idP,
728
          (eNB_index * maxDRB) + DRB_config->drb_Identity);
729

730
731
732
733
734
735
736
737
    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
738
  }
739

740
741
#    else
#        ifdef OAI_EMU
gauthier's avatar
   
gauthier committed
742
  oai_emulation.info.oai_ifup[ue_mod_idP]=1;
743
744
745
746
747
748
749
750
#        endif
#    endif
#endif

  return(0);
}


751
752
753
754
755
756
757
758
//-----------------------------------------------------------------------------
void
rrc_ue_process_measConfig(
  const protocol_ctxt_t* const       ctxt_pP,
  const uint8_t                      eNB_index,
  MeasConfig_t* const               measConfig
)
//-----------------------------------------------------------------------------
759
{
760
761
762
763
764
765
766

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

  if (measConfig->measObjectToRemoveList != NULL) {
767
768
    for (i=0; i<measConfig->measObjectToRemoveList->list.count; i++) {
      ind   = *measConfig->measObjectToRemoveList->list.array[i];
769
      free(UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index][ind-1]);
770
    }
771
  }
772

773
  if (measConfig->measObjectToAddModList != NULL) {
774
775
776
777
778
779
    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;

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

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

833
  if (measConfig->reportConfigToRemoveList != NULL) {
834
835
    for (i=0; i<measConfig->reportConfigToRemoveList->list.count; i++) {
      ind   = *measConfig->reportConfigToRemoveList->list.array[i];
836
      free(UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1]);
837
    }
838
  }
839

840
  if (measConfig->reportConfigToAddModList != NULL) {
841
842
843
844
845
    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;

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

  if (measConfig->quantityConfig != NULL) {
859
    if (UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index]) {
860
      LOG_D(RRC,"Modifying Quantity Configuration \n");
861
      memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index],
862
863
864
865
             (char*)measConfig->quantityConfig,
             sizeof(QuantityConfig_t));
    } else {
      LOG_D(RRC,"Adding Quantity configuration\n");
866
      UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index] = measConfig->quantityConfig;
867
    }
868
869
870
  }

  if (measConfig->measIdToRemoveList != NULL) {
871
872
    for (i=0; i<measConfig->measIdToRemoveList->list.count; i++) {
      ind   = *measConfig->measIdToRemoveList->list.array[i];
873
      free(UE_rrc_inst[ctxt_pP->module_id].MeasId[eNB_index][ind-1]);
874
    }
875
876
877
  }

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

881
      if (UE_rrc_inst[ctxt_pP->module_id].MeasId[eNB_index][ind-1]) {
882
        LOG_D(RRC,"Modifying Measurement ID %d\n",ind-1);
883
        memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].MeasId[eNB_index][ind-1],
884
885
886
887
               (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]);
888
        UE_rrc_inst[ctxt_pP->module_id].MeasId[eNB_index][ind-1] = measConfig->measIdToAddModList->list.array[i];
889
      }
890
    }
891
892
893
  }

  if (measConfig->measGapConfig !=NULL) {
894
895
    if (UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index]) {
      memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index],
896
897
898
             (char*)measConfig->measGapConfig,
             sizeof(MeasGapConfig_t));
    } else {
899
      UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index] = measConfig->measGapConfig;
900
    }
901
902
  }

903
  if (measConfig->quantityConfig != NULL) {
904
    if (UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index]) {
905
      LOG_I(RRC,"Modifying Quantity Configuration \n");
906
      memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index],
907
908
909
910
             (char*)measConfig->quantityConfig,
             sizeof(QuantityConfig_t));
    } else {
      LOG_I(RRC,"Adding Quantity configuration\n");
911
      UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index] = measConfig->quantityConfig;
912
    }
gauthier's avatar
gauthier committed
913

914
915
916
917
    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
918

919
    LOG_I(RRC,"[UE %d] set rsrp-coeff for eNB %d: %d rsrq-coeff: %d rsrp_factor: %f rsrq_factor: %f \n",
920
921
922
923
924
925
926
          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);
927
928
  }

929
  if (measConfig->s_Measure != NULL) {
930
    UE_rrc_inst[ctxt_pP->module_id].s_measure = *measConfig->s_Measure;
931
  }
gauthier's avatar
gauthier committed
932

933
  if (measConfig->speedStatePars != NULL) {
934
935
936
937
938
    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;
    }
939
940

    LOG_I(RRC,"[UE %d] Configuring mobility optimization params for UE %d \n",
941
          ctxt_pP->module_id,UE_rrc_inst[ctxt_pP->module_id].Info[0].UE_index);
942
  }
943
944
}

945
//-----------------------------------------------------------------------------
946
void
947
948
949
950