rrc_UE.c 160 KB
Newer Older
1
/*******************************************************************************
2 3
    OpenAirInterface
    Copyright(c) 1999 - 2014 Eurecom
4

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


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

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
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

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

Lionel Gauthier's avatar
Lionel 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
Lionel Gauthier's avatar
Lionel 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"
88

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

93 94 95 96 97 98 99 100 101 102 103 104
#ifdef PHY_EMUL
extern EMULATION_VARS *Emul_vars;
#endif
extern eNB_MAC_INST *eNB_mac_inst;
extern UE_MAC_INST *UE_mac_inst;
#ifdef BIGPHYSAREA
extern void *bigphys_malloc(int);
#endif

//#define XER_PRINT

extern inline unsigned int taus(void);
105
extern int8_t dB_fixed2(uint32_t x,uint32_t y);
106

107 108 109 110 111 112
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
113
/*------------------------------------------------------------------------------*/
114 115
static Rrc_State_t rrc_get_state (module_id_t ue_mod_idP)
{
Lionel Gauthier's avatar
 
Lionel Gauthier committed
116
  return UE_rrc_inst[ue_mod_idP].RrcState;
winckel's avatar
winckel committed
117 118
}

119 120
static Rrc_Sub_State_t rrc_get_sub_state (module_id_t ue_mod_idP)
{
Lionel Gauthier's avatar
 
Lionel Gauthier committed
121
  return UE_rrc_inst[ue_mod_idP].RrcSubState;
winckel's avatar
winckel committed
122 123
}

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

Lionel Gauthier's avatar
 
Lionel Gauthier committed
129
  if (UE_rrc_inst[ue_mod_idP].RrcState != state) {
130
    UE_rrc_inst[ue_mod_idP].RrcState = state;
winckel's avatar
winckel committed
131

132
#if defined(ENABLE_ITTI)
133 134
    {
      MessageDef *msg_p;
135

136 137 138
      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
139

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

  return (0);
}

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

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

  case RRC_STATE_IDLE:
    AssertFatal ((RRC_SUB_STATE_IDLE_FIRST <= subState) && (subState <= RRC_SUB_STATE_IDLE_LAST),
167
                 "Invalid sub state %d for state %d!\n", subState, UE_rrc_inst[ue_mod_idP].RrcState);
168 169 170 171
    break;

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

176
#endif
winckel's avatar
winckel committed
177

Lionel Gauthier's avatar
 
Lionel Gauthier committed
178
  if (UE_rrc_inst[ue_mod_idP].RrcSubState != subState) {
179
    UE_rrc_inst[ue_mod_idP].RrcSubState = subState;
winckel's avatar
winckel committed
180

181
#if defined(ENABLE_ITTI)
182 183
    {
      MessageDef *msg_p;
winckel's avatar
winckel committed
184

185 186 187
      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;
188

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

  return (0);
}

198 199 200 201 202 203 204
//-----------------------------------------------------------------------------
void
init_SI_UE(
  const protocol_ctxt_t* const ctxt_pP,
  const uint8_t eNB_index
)
//-----------------------------------------------------------------------------
205
{
206 207 208 209

  int i;


210 211 212 213 214
  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);
215

216 217 218
  // FIXME the structure member si is defined as si[NB_CNX_UE][8]
  // FIXME the code at rrc_UE.c:2250 indexes si like this: UE_rrc_inst[ctxt_pP->module_id].si[eNB_index][si_window]
  // FIXME for si_window = 2 (which can happen) this produces a SIGSEGV
219
  for (i=0; i<NB_CNX_UE; 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;
Lionel Gauthier's avatar
 
Lionel 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
Lionel Gauthier's avatar
 
Lionel 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)
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

255
  for (i = 0; i < 32; i++) {
256
    sprintf(&ascii_buffer[2 * i], "%02X", UE_rrc_inst[ctxt_pP->module_id].kenb[i]);
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 274 275 276 277
  protocol_ctxt_t ctxt;
  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_idP, ENB_FLAG_NO, NOT_A_RNTI, 0, 0);
  LOG_I(RRC,
        PROTOCOL_RRC_CTXT_FMT" Init...\n",
        PROTOCOL_RRC_CTXT_ARGS(&ctxt));
Lionel Gauthier's avatar
 
Lionel 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++) {
Lionel Gauthier's avatar
 
Lionel Gauthier committed
314
    UE_rrc_inst[ue_mod_idP].cba_rnti[j] = 0x0000;
315
  }
316

Lionel Gauthier's avatar
 
Lionel 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

332
  uint8_t i=0,rv[6];
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

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 428 429 430 431 432 433 434 435 436 437
        ctxt_pP->module_id,ctxt_pP->frame, size, eNB_index);
  LOG_D(RLC,
        "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCConnectionSetupComplete to eNB %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n",
        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

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

488
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN);
Lionel Gauthier's avatar
 
Lionel 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);
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
  }

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

625
  uint8_t lchan_id = DCCH;
626

Lionel Gauthier's avatar
 
Lionel 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

631
  // copy default configuration for now
Lionel Gauthier's avatar
 
Lionel 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


Lionel Gauthier's avatar
 
Lionel 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

Lionel Gauthier's avatar
 
Lionel 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

Lionel Gauthier's avatar
 
Lionel 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

659
  uint8_t lchan_id = DCCH1;
660

Lionel Gauthier's avatar
 
Lionel 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

665
  // copy default configuration for now
Lionel Gauthier's avatar
 
Lionel 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


Lionel Gauthier's avatar
 
Lionel 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

Lionel Gauthier's avatar
 
Lionel 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

Lionel Gauthier's avatar
 
Lionel 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
  /*
Lionel Gauthier's avatar
 
Lionel 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);
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);
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
709 710
  ip_addr_offset3 = oai_emulation.info.nb_enb_local;
  ip_addr_offset4 = NB_eNB_INST;
711
#    else
712 713
  ip_addr_offset3 = 0;
  ip_addr_offset4 = 8;
714
#    endif
Lionel Gauthier's avatar
 
Lionel 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);
Lionel Gauthier's avatar
 
Lionel 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",
Lionel Gauthier's avatar
 
Lionel 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);
738
  }
739

740 741
#    else
#        ifdef OAI_EMU
Lionel Gauthier's avatar
 
Lionel 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
    }
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);
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
  }
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 951 952
rrc_ue_process_radioResourceConfigDedicated(
  const protocol_ctxt_t* const ctxt_pP,
  uint8_t eNB_index,
  RadioResourceConfigDedicated_t* radioResourceConfigDedicated
)
//-----------------------------------------------------------------------------
953
{
954 955 956 957

  long SRB_id,DRB_id;
  int i,cnt;
  LogicalChannelConfig_t *SRB1_logicalChannelConfig,*SRB2_logicalChannelConfig;
958
#ifdef CBA
959 960
  uint8_t cba_found = 0;
  uint16_t cba_RNTI;
961
#endif
962 963 964

  // Save physicalConfigDedicated if present
  if (radioResourceConfigDedicated->physicalConfigDedicated) {
965 966
    if (UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]) {
      memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index],(char*)radioResourceConfigDedicated->physicalConfigDedicated,
967
             sizeof(struct PhysicalConfigDedicated));
968

969
    } else {
970
      UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index] = radioResourceConfigDedicated->physicalConfigDedicated;
971
    }
972
  }
973

974 975
  // Apply macMainConfig if present
  if (radioResourceConfigDedicated->mac_MainConfig) {
976
    if (radioResourceConfigDedicated->mac_MainConfig->present == RadioResourceConfigDedicated__mac_MainConfig_PR_explicitValue) {
977 978
      if (UE_rrc_inst[ctxt_pP->module_id].mac_MainConfig[eNB_index]) {
        memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].mac_MainConfig[eNB_index],(char*)&radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue,
979
               sizeof(MAC_MainConfig_t));
980 981 982
      } else {
        UE_rrc_inst[ctxt_pP->module_id].mac_MainConfig[eNB_index] = &radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue;
      }
983
    }
984 985 986 987
  }

  // Apply spsConfig if present
  if (radioResourceConfigDedicated->sps_Config) {
988 989
    if (UE_rrc_inst[ctxt_pP->module_id].sps_Config[eNB_index]) {
      memcpy(UE_rrc_inst[ctxt_pP->module_id].sps_Config[eNB_index],radioResourceConfigDedicated->sps_Config,
990 991
             sizeof(struct SPS_Config));
    } else {
992
      UE_rrc_inst[ctxt_pP->module_id].sps_Config[eNB_index] = radioResourceConfigDedicated->sps_Config;
993
    }
994
  }
995

996
#ifdef CBA
997

998
  if (radioResourceConfigDedicated->cba_RNTI_vlola) {
999 1000 1001 1002
    cba_RNTI = (uint16_t) (((radioResourceConfigDedicated->cba_RNTI_vlola->buf[1]&0xff) << 8) |
                           (radioResourceConfigDedicated->cba_RNTI_vlola->buf[0]&0xff));

    for (i=0 ; i< NUM_MAX_CBA_GROUP; i++) {
1003
      if (UE_rrc_inst[ctxt_pP->module_id].cba_rnti[i] == cba_RNTI ) {
1004 1005
        cba_found=1;
        break;
1006
      } else if (UE_rrc_inst[ctxt_pP->module_id].cba_rnti[i] == 0 ) {
1007
        break;
1008
      }
1009 1010 1011
    }

    if (cba_found==0) {
1012 1013
      UE_rrc_inst[ctxt_pP->module_id].num_active_cba_groups++;
      UE_rrc_inst[ctxt_pP->module_id].cba_rnti[i]=cba_RNTI;
1014
      LOG_D(RRC, "[UE %d] Frame %d: radioResourceConfigDedicated reveived CBA_RNTI = %x for group %d from eNB %d \n",
1015
            ctxt_pP->module_id,frameP, UE_rrc_inst[ctxt_pP->module_id].cba_rnti[i], i, eNB_index);
1016
    }
1017
  }
1018 1019 1020

#endif

1021 1022 1023
  // Establish SRBs if present
  // loop through SRBToAddModList
  if (radioResourceConfigDedicated->srb_ToAddModList) {
1024 1025
    uint8_t *kRRCenc = NULL;
    uint8_t *kRRCint = NULL;
1026 1027

#if defined(ENABLE_SECURITY)
1028 1029 1030 1031
    derive_key_rrc_enc(UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm,
                       UE_rrc_inst[ctxt_pP->module_id].kenb, &kRRCenc);
    derive_key_rrc_int(UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm,
                       UE_rrc_inst[ctxt_pP->module_id].kenb, &kRRCint);
1032 1033
#endif
    // Refresh SRBs
1034
    rrc_pdcp_config_asn1_req(ctxt_pP,
1035 1036 1037
                             radioResourceConfigDedicated->srb_ToAddModList,
                             (DRB_ToAddModList_t*)NULL,
                             (DRB_ToReleaseList_t*)NULL,
1038 1039
                             UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm |
                             (UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm << 4),
1040 1041 1042
                             kRRCenc,
                             kRRCint,
                             NULL
1043
#ifdef Rel10
1044
                             ,(PMCH_InfoList_r9_t *)NULL
1045
#endif
1046
                            );
1047

1048
    // Refresh SRBs
1049
    rrc_rlc_config_asn1_req(ctxt_pP,
1050 1051 1052
                            radioResourceConfigDedicated->srb_ToAddModList,
                            (DRB_ToAddModList_t*)NULL,
                            (DRB_ToReleaseList_t*)NULL
1053
#ifdef Rel10
1054
                            ,(PMCH_InfoList_r9_t *)NULL
1055
#endif
1056
                           );
1057

1058
#ifdef ENABLE_RAL
1059
    // first msg that includes srb config
1060
    UE_rrc_inst[ctxt_pP->module_id].num_srb=radioResourceConfigDedicated->srb_ToAddModList->list.count;
1061
#endif
1062

1063 1064 1065
    for (cnt=0; cnt<radioResourceConfigDedicated->srb_ToAddModList->list.count; cnt++) {
      //  connection_reestablishment_ind.num_srb+=1;
      SRB_id = radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]->srb_Identity;
1066
      LOG_D(RRC,"[UE %d]: Frame %d SRB config cnt %d (SRB%ld)\n",ctxt_pP->module_id,ctxt_pP->frame,cnt,SRB_id);
1067 1068

      if (SRB_id == 1) {
1069 1070
        if (UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index]) {
          memcpy(UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index],radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt],
1071 1072
                 sizeof(struct SRB_ToAddMod));
        } else {
1073 1074
          UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index] = radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt];
          rrc_ue_establish_srb1(ctxt_pP->module_id,ctxt_pP->frame,eNB_index,radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]);
1075

1076 1077 1078
          if (UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index]->logicalChannelConfig) {
            if (UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index]->logicalChannelConfig->present == SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) {
              SRB1_logicalChannelConfig = &UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index]->logicalChannelConfig->choice.explicitValue;
1079 1080 1081 1082 1083 1084 1085 1086 1087

            } else {
              SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue;
            }
          } else {
            SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue;
          }

          LOG_D(RRC, "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ  (SRB1 eNB %d) --->][MAC_UE][MOD %02d][]\n",
1088 1089
                ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id);
          rrc_mac_config_req(ctxt_pP->module_id,ENB_FLAG_NO,0,eNB_index,
1090
                             (RadioResourceConfigCommonSIB_t *)NULL,
1091
                             UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index],
1092 1093 1094 1095 1096
#ifdef Rel10
                             (SCellToAddMod_r10_t *)NULL,
                             //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
#endif
                             (MeasObjectToAddMod_t **)NULL,
1097
                             UE_rrc_inst[ctxt_pP->module_id].mac_MainConfig[eNB_index],
1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108
                             1,
                             SRB1_logicalChannelConfig,
                             (MeasGapConfig_t *)NULL,
                             NULL,
                             NULL,
                             NULL,
                             NULL,
                             NULL,
                             NULL,
                             NULL,
                             NULL
1109
#ifdef Rel10
1110 1111 1112 1113
                             ,
                             0,
                             (MBSFN_AreaInfoList_r9_t *)NULL,
                             (PMCH_InfoList_r9_t *)NULL
1114 1115
#endif
#ifdef CBA
1116 1117 1118
                             ,
                             0,
                             0
1119
#endif
1120 1121 1122
                            );
        }
      } else {
1123 1124
        if (UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index]) {
          memcpy(UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index],radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt],
1125 1126
                 sizeof(struct SRB_ToAddMod));
        } else {
1127 1128
          UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index] = radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt];
          rrc_ue_establish_srb2(ctxt_pP->module_id,ctxt_pP->frame,eNB_index,radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]);
1129

1130 1131
          if (UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index]->logicalChannelConfig) {
            if (UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index]->logicalChannelConfig->present == SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) {
1132
              LOG_I(RRC,"Applying Explicit SRB2 logicalChannelConfig\n");
1133
              SRB2_logicalChannelConfig = &UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index]->logicalChannelConfig->choice.explicitValue;
1134 1135 1136 1137 1138 1139
            } else {
              LOG_I(RRC,"Applying default SRB2 logicalChannelConfig\n");
              SRB2_logicalChannelConfig = &SRB2_logicalChannelConfig_defaultValue;
            }
          } else {
            SRB2_logicalChannelConfig = &SRB2_logicalChannelConfig_defaultValue;
1140
          }
1141

1142
          LOG_D(RRC, "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ  (SRB2 eNB %d) --->][MAC_UE][MOD %02d][]\n",
1143 1144 1145 1146 1147
                ctxt_pP->frame,
                ctxt_pP->module_id,
                eNB_index,
                ctxt_pP->module_id);
          rrc_mac_config_req(ctxt_pP->module_id,ENB_FLAG_NO,0,eNB_index,
1148
                             (RadioResourceConfigCommonSIB_t *)NULL,
1149
                             UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index],
1150
#ifdef Rel10
1151 1152 1153 1154
                             (SCellToAddMod_r10_t *)NULL,
                             //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
#endif
                             (MeasObjectToAddMod_t **)NULL,
1155
                             UE_rrc_inst[ctxt_pP->module_id].mac_MainConfig[eNB_index],
1156 1157
                             2,
                             SRB2_logicalChannelConfig,
1158
                             UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index],
1159 1160 1161 1162 1163 1164 1165 1166
                             (TDD_Config_t *)NULL,
                             (MobilityControlInfo_t *)NULL,
                             NULL,
                             NULL,
                             NULL,
                             NULL,
                             NULL,
                             NULL
1167
#ifdef Rel10
1168 1169 1170 1171
                             ,
                             0,
                             (MBSFN_AreaInfoList_r9_t *)NULL,
                             (PMCH_InfoList_r9_t *)NULL
1172 1173
#endif
#ifdef CBA
1174 1175 1176
                             ,
                             0,
                             0
1177
#endif
1178 1179
                            );
        }
1180
      }
1181
    }
1182 1183 1184 1185
  }

  // Establish DRBs if present
  if (radioResourceConfigDedicated->drb_ToAddModList) {
1186
    uint8_t *kUPenc = NULL;
1187 1188

#if defined(ENABLE_SECURITY)
1189 1190
    derive_key_up_enc(UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm,
                      UE_rrc_inst[ctxt_pP->module_id].kenb, &kUPenc);
1191 1192 1193
#endif

    // Refresh DRBs
1194
    rrc_pdcp_config_asn1_req(ctxt_pP,
1195 1196 1197
                             (SRB_ToAddModList_t*)NULL,
                             radioResourceConfigDedicated->drb_ToAddModList,
                             (DRB_ToReleaseList_t*)NULL,
1198 1199
                             UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm |
                             (UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm << 4),
1200 1201 1202
                             NULL,
                             NULL,
                             kUPenc
1203
#ifdef Rel10
1204
                             ,(PMCH_InfoList_r9_t *)NULL
1205
#endif
1206
                            );
1207

1208
    // Refresh DRBs
1209
    rrc_rlc_config_asn1_req(ctxt_pP,
1210 1211 1212
                            (SRB_ToAddModList_t*)NULL,
                            radioResourceConfigDedicated->drb_ToAddModList,
                            (DRB_ToReleaseList_t*)NULL
1213
#ifdef Rel10
1214 1215 1216 1217 1218 1219 1220
                            ,(PMCH_InfoList_r9_t *)NULL
#endif
                           );

    for (i=0; i<radioResourceConfigDedicated->drb_ToAddModList->list.count; i++) {
      DRB_id   = radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity-1;

1221 1222 1223
      if (UE_rrc_inst[ctxt_pP->module_id].DRB_config[eNB_index][DRB_id]) {
        memcpy(UE_rrc_inst[ctxt_pP->module_id].DRB_config[eNB_index][DRB_id],
               radioResourceConfigDedicated->drb_ToAddModList->list.array[i],
1224 1225
               sizeof(struct DRB_ToAddMod));
      } else {
1226 1227
        UE_rrc_inst[ctxt_pP->module_id].DRB_config[eNB_index][DRB_id] = radioResourceConfigDedicated->drb_ToAddModList->list.array[i];
        rrc_ue_establish_drb(ctxt_pP->module_id,ctxt_pP->frame,eNB_index,radioResourceConfigDedicated->drb_ToAddModList->list.array[i]);
1228 1229
        // MAC/PHY Configuration
        LOG_D(RRC, "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (DRB %d eNB %d) --->][MAC_UE][MOD %02d][]\n",
1230 1231 1232 1233 1234
              ctxt_pP->frame, ctxt_pP->module_id,
              radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity,
              eNB_index,
              ctxt_pP->module_id);
        rrc_mac_config_req(ctxt_pP->module_id,ENB_FLAG_NO,0,eNB_index,
1235
                           (RadioResourceConfigCommonSIB_t *)NULL,
1236
                           UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index],
1237
#ifdef Rel10
1238 1239 1240 1241
                           (SCellToAddMod_r10_t *)NULL,
                           //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
#endif
                           (MeasObjectToAddMod_t **)NULL,
1242 1243 1244 1245
                           UE_rrc_inst[ctxt_pP->module_id].mac_MainConfig[eNB_index],
                           *UE_rrc_inst[ctxt_pP->module_id].DRB_config[eNB_index][DRB_id]->logicalChannelIdentity,
                           UE_rrc_inst[ctxt_pP->module_id].DRB_config[eNB_index][DRB_id]->logicalChannelConfig,
                           UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index],
1246 1247 1248 1249 1250 1251 1252 1253
                           (TDD_Config_t*)NULL,
                           (MobilityControlInfo_t *)NULL,
                           NULL,
                           NULL,
                           NULL,
                           NULL,
                           NULL,
                           NULL
1254
#ifdef Rel10
1255 1256 1257 1258
                           ,
                           0,
                           (MBSFN_AreaInfoList_r9_t *)NULL,
                           (PMCH_InfoList_r9_t *)NULL
1259 1260
#endif
#ifdef CBA
1261 1262 1263
                           ,
                           UE_rrc_inst[ue_mod_idP].num_active_cba_groups, //
                           UE_rrc_inst[ue_mod_idP].cba_rnti[0]
1264
#endif
1265
                          );
1266 1267

      }
1268
    }
1269 1270
  }

1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281
  UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State = RRC_CONNECTED;
  LOG_I(RRC,"[UE %d] State = RRC_CONNECTED (eNB %d)\n",ctxt_pP->module_id,eNB_index);
#if !defined(ENABLE_USE_MME)
  rrc_eNB_emulation_notify_ue_module_id(
    ctxt_pP->module_id,
    ctxt_pP->rnti,
    UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->cellAccessRelatedInfo.cellIdentity.buf[0],
    UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->cellAccessRelatedInfo.cellIdentity.buf[1],
    UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->cellAccessRelatedInfo.cellIdentity.buf[2],
    UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->cellAccessRelatedInfo.cellIdentity.buf[3]);
#endif
1282 1283
}

1284 1285 1286 1287 1288 1289 1290 1291 1292

//-----------------------------------------------------------------------------
void
rrc_ue_process_securityModeCommand(
  const protocol_ctxt_t* const ctxt_pP,
  SecurityModeCommand_t* const securityModeCommand,
  const uint8_t                eNB_index
)
//-----------------------------------------------------------------------------
1293
{
1294 1295 1296 1297 1298 1299 1300

  asn_enc_rval_t enc_rval;

  UL_DCCH_Message_t ul_dcch_msg;
  // SecurityModeCommand_t SecurityModeCommand;
  uint8_t buffer[200];
  int i, securityMode;
1301

1302
  LOG_I(RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing securityModeCommand (eNB %d)\n",
1303
        ctxt_pP->module_id,ctxt_pP->frame,eNB_index);
1304

1305
  switch (securityModeCommand->criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm) {
1306
  case SecurityAlgorithmConfig__cipheringAlgorithm_eea0:
1307 1308
    LOG_I(RRC,"[UE %d] Security algorithm is set to eea0\n",
          ctxt_pP->module_id);
1309 1310
    securityMode= SecurityAlgorithmConfig__cipheringAlgorithm_eea0;
    break;
1311

1312
  case SecurityAlgorithmConfig__cipheringAlgorithm_eea1:
1313
    LOG_I(RRC,"[UE %d] Security algorithm is set to eea1\n",ctxt_pP->module_id);
1314 1315
    securityMode= SecurityAlgorithmConfig__cipheringAlgorithm_eea1;
    break;
1316

1317
  case SecurityAlgorithmConfig__cipheringAlgorithm_eea2:
1318 1319
    LOG_I(RRC,"[UE %d] Security algorithm is set to eea2\n",
          ctxt_pP->module_id);
1320 1321
    securityMode = SecurityAlgorithmConfig__cipheringAlgorithm_eea2;
    break;
1322

1323
  default:
1324
    LOG_I(RRC,"[UE %d] Security algorithm is set to none\n",ctxt_pP->module_id);
1325 1326 1327
    securityMode = SecurityAlgorithmConfig__cipheringAlgorithm_spare1;
    break;
  }
1328 1329

  switch (securityModeCommand->criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm) {
1330
  case SecurityAlgorithmConfig__integrityProtAlgorithm_eia1:
1331
    LOG_I(RRC,"[UE %d] Integrity protection algorithm is set to eia1\n",ctxt_pP->module_id);
1332 1333
    securityMode |= 1 << 5;
    break;
1334

1335
  case SecurityAlgorithmConfig__integrityProtAlgorithm_eia2:
1336
    LOG_I(RRC,"[UE %d] Integrity protection algorithm is set to eia2\n",ctxt_pP->module_id);
1337 1338
    securityMode |= 1 << 6;
    break;
1339

1340
  default:
1341
    LOG_I(RRC,"[UE %d] Integrity protection algorithm is set to none\n",ctxt_pP->module_id);
1342 1343 1344
    securityMode |= 0x70 ;
    break;
  }
1345

1346
  LOG_D(RRC,"[UE %d] security mode is %x \n",ctxt_pP->module_id, securityMode);
1347 1348

  /* Store the parameters received */
1349 1350 1351 1352
  UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm =
    securityModeCommand->criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm;
  UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm =
    securityModeCommand->criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm;
1353

1354 1355 1356 1357
  memset((void *)&ul_dcch_msg,0,sizeof(UL_DCCH_Message_t));
  //memset((void *)&SecurityModeCommand,0,sizeof(SecurityModeCommand_t));

  ul_dcch_msg.message.present           = UL_DCCH_MessageType_PR_c1;
1358

1359
  if (securityMode >= NO_SECURITY_MODE) {
1360
    ul_dcch_msg.message.choice.c1.present = UL_DCCH_MessageType__c1_PR_securityModeComplete;
1361
  } else {
1362
    ul_dcch_msg.message.choice.c1.present = UL_DCCH_MessageType__c1_PR_securityModeFailure;
1363
  }
1364

1365
  if (securityModeCommand->criticalExtensions.present == SecurityModeCommand__criticalExtensions_PR_c1) {
1366
    if (securityModeCommand->criticalExtensions.choice.c1.present == SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8) {
1367

1368
      ul_dcch_msg.message.choice.c1.choice.securityModeComplete.rrc_TransactionIdentifier = securityModeCommand->rrc_TransactionIdentifier;
1369
      ul_dcch_msg.message.choice.c1.choice.securityModeComplete.criticalExtensions.present = SecurityModeCommand__criticalExtensions_PR_c1;
1370
      ul_dcch_msg.message.choice.c1.choice.securityModeComplete.criticalExtensions.choice.securityModeComplete_r8.nonCriticalExtension =NULL;
1371

1372
      LOG_I(RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), encoding securityModeComplete (eNB %d)\n",
1373
            ctxt_pP->module_id,ctxt_pP->frame,eNB_index);
1374

1375 1376 1377 1378 1379 1380
      enc_rval = uper_encode_to_buffer(&asn_DEF_UL_DCCH_Message,
                                       (void*)&ul_dcch_msg,
                                       buffer,
                                       100);
      AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n",
                   enc_rval.failed_type->name, enc_rval.encoded);
1381 1382

#ifdef XER_PRINT
1383 1384
      xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void*)&ul_dcch_msg);
#endif
1385

1386 1387
#if defined(ENABLE_ITTI)
# if !defined(DISABLE_XER_SPRINT)
1388 1389 1390
      {
        char        message_string[20000];
        size_t      message_string_size;
1391

1392 1393
        if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) {
          MessageDef *msg_p;
1394

1395 1396 1397
          msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UL_DCCH, message_string_size + sizeof (IttiMsgText));
          msg_p->ittiMsg.rrc_ul_dcch.size = message_string_size;
          memcpy(&msg_p->ittiMsg.rrc_ul_dcch.text, message_string, message_string_size);
1398

1399
          itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p);
1400 1401
        }
      }
1402 1403 1404
# endif
#endif

1405
#ifdef USER_MODE
1406
      LOG_D(RRC, "securityModeComplete Encoded %d bits (%d bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8);
1407
#endif
1408

1409
      for (i = 0; i < (enc_rval.encoded + 7) / 8; i++) {
1410
        LOG_T(RRC, "%02x.", buffer[i]);
1411
      }
1412 1413

      LOG_T(RRC, "\n");
1414 1415 1416 1417 1418 1419 1420 1421 1422
      pdcp_rrc_data_req (
        ctxt_pP,
        DCCH,
        rrc_mui++,
        SDU_CONFIRM_NO,
        (enc_rval.encoded + 7) / 8,
        buffer,
        PDCP_TRANSMISSION_MODE_CONTROL);
    }
1423
    }
1424
  }
1425

1426 1427 1428 1429 1430 1431 1432 1433
//-----------------------------------------------------------------------------
void
rrc_ue_process_ueCapabilityEnquiry(
  const protocol_ctxt_t* const ctxt_pP,
  UECapabilityEnquiry_t* UECapabilityEnquiry,
  uint8_t eNB_index
)
//-----------------------------------------------------------------------------
1434
{
1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446

  asn_enc_rval_t enc_rval;

  UL_DCCH_Message_t ul_dcch_msg;


  UE_CapabilityRAT_Container_t ue_CapabilityRAT_Container;

  uint8_t buffer[200];
  int i;

  LOG_I(RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing UECapabilityEnquiry (eNB %d)\n",
1447 1448 1449
        ctxt_pP->module_id,
        ctxt_pP->frame,
        eNB_index);
1450 1451 1452 1453 1454 1455 1456


  memset((void *)&ul_dcch_msg,0,sizeof(UL_DCCH_Message_t));
  memset((void *)&ue_CapabilityRAT_Container,0,sizeof(UE_CapabilityRAT_Container_t));

  ul_dcch_msg.message.present           = UL_DCCH_MessageType_PR_c1;
  ul_dcch_msg.message.choice.c1.present = UL_DCCH_MessageType__c1_PR_ueCapabilityInformation;
1457
  ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.rrc_TransactionIdentifier = UECapabilityEnquiry->rrc_TransactionIdentifier;
1458 1459 1460

  ue_CapabilityRAT_Container.rat_Type = RAT_Type_eutra;
  OCTET_STRING_fromBuf(&ue_CapabilityRAT_Container.ueCapabilityRAT_Container,
1461 1462
                       (const char*)UE_rrc_inst[ctxt_pP->module_id].UECapability,
                       UE_rrc_inst[ctxt_pP->module_id].UECapability_size);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1463 1464
  //  ue_CapabilityRAT_Container.ueCapabilityRAT_Container.buf  = UE_rrc_inst[ue_mod_idP].UECapability;
  // ue_CapabilityRAT_Container.ueCapabilityRAT_Container.size = UE_rrc_inst[ue_mod_idP].UECapability_size;
1465

1466 1467

  if (UECapabilityEnquiry->criticalExtensions.present == UECapabilityEnquiry__criticalExtensions_PR_c1) {
1468 1469
    if (UECapabilityEnquiry->criticalExtensions.choice.c1.present == UECapabilityEnquiry__criticalExtensions__c1_PR_ueCapabilityEnquiry_r8) {
      ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.present           = UECapabilityInformation__criticalExtensions_PR_c1;
1470 1471 1472 1473
      ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.present =
        UECapabilityInformation__criticalExtensions__c1_PR_ueCapabilityInformation_r8;
      ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.count
        =0;
1474

1475
      for (i=0; i<UECapabilityEnquiry->criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list.count; i++) {
1476

1477 1478 1479 1480 1481
        if (*UECapabilityEnquiry->criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list.array[i]
            == RAT_Type_eutra) {
          ASN_SEQUENCE_ADD(
            &ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list,
            &ue_CapabilityRAT_Container);
1482

1483 1484 1485
          enc_rval = uper_encode_to_buffer(&asn_DEF_UL_DCCH_Message, (void*) &ul_dcch_msg, buffer, 100);
          AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n",
                       enc_rval.failed_type->name, enc_rval.encoded);
1486 1487

#ifdef XER_PRINT
1488
          xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void*)&ul_dcch_msg);
1489
#endif
1490

1491 1492
#if defined(ENABLE_ITTI)
# if !defined(DISABLE_XER_SPRINT)
1493 1494 1495
          {
            char        message_string[20000];
            size_t      message_string_size;
1496

1497 1498
            if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) {
              MessageDef *msg_p;
1499

1500 1501 1502
              msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UL_DCCH, message_string_size + sizeof (IttiMsgText));
              msg_p->ittiMsg.rrc_ul_dcch.size = message_string_size;
              memcpy(&msg_p->ittiMsg.rrc_ul_dcch.text, message_string, message_string_size);
1503

1504
              itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p);
1505 1506
            }
          }
1507 1508 1509
# endif
#endif

1510
#ifdef USER_MODE
1511
          LOG_D(RRC,"UECapabilityInformation Encoded %d bits (%d bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
1512
#endif
1513

1514
          for (i = 0; i < (enc_rval.encoded + 7) / 8; i++) {
1515
            LOG_T(RRC, "%02x.", buffer[i]);
1516
          }
1517 1518

          LOG_T(RRC, "\n");
1519 1520 1521 1522 1523 1524 1525 1526
          pdcp_rrc_data_req (
            ctxt_pP,
            DCCH,
            rrc_mui++,
            SDU_CONFIRM_NO,
            (enc_rval.encoded + 7) / 8,
            buffer,
            PDCP_TRANSMISSION_MODE_CONTROL);
1527
        }
1528
      }
1529
    }
1530 1531 1532
  }
}

1533

1534 1535 1536 1537
//-----------------------------------------------------------------------------
void
rrc_ue_process_rrcConnectionReconfiguration(
  const protocol_ctxt_t* const       ctxt_pP,
1538
    RRCConnectionReconfiguration_t *rrcConnectionReconfiguration,
1539 1540 1541
  uint8_t eNB_index
)
//-----------------------------------------------------------------------------
1542
{
1543

1544
  LOG_I(RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing RRCConnectionReconfiguration (eNB %d)\n",
1545
        ctxt_pP->module_id,ctxt_pP->frame,eNB_index);
1546

1547
  if (rrcConnectionReconfiguration->criticalExtensions.present == RRCConnectionReconfiguration__criticalExtensions_PR_c1) {
1548 1549
    if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.present ==
        RRCConnectionReconfiguration__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r8) {
1550 1551
      RRCConnectionReconfiguration_r8_IEs_t* rrcConnectionReconfiguration_r8 =
        &rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8;
Lionel Gauthier's avatar
Lionel Gauthier committed
1552

1553 1554
      if (rrcConnectionReconfiguration_r8->mobilityControlInfo) {
        LOG_I(RRC,"Mobility Control Information is present\n");
1555 1556 1557 1558
        rrc_ue_process_mobilityControlInfo(
          ctxt_pP,
          eNB_index,
          rrcConnectionReconfiguration_r8->mobilityControlInfo);
1559 1560 1561 1562
      }

      if (rrcConnectionReconfiguration_r8->measConfig != NULL) {
        LOG_I(RRC,"Measurement Configuration is present\n");
1563 1564
        rrc_ue_process_measConfig(ctxt_pP,
                                  eNB_index,
1565 1566 1567 1568 1569
                                  rrcConnectionReconfiguration_r8->measConfig);
      }

      if (rrcConnectionReconfiguration_r8->radioResourceConfigDedicated) {
        LOG_I(RRC,"Radio Resource Configuration is present\n");
1570
        rrc_ue_process_radioResourceConfigDedicated(ctxt_pP,eNB_index, rrcConnectionReconfiguration_r8->radioResourceConfigDedicated);
1571
      }
1572 1573 1574

#if defined(ENABLE_ITTI)

1575 1576 1577 1578 1579 1580
      /* Check if there is dedicated NAS information to forward to NAS */
      if (rrcConnectionReconfiguration_r8->dedicatedInfoNASList != NULL) {
        int list_count;
        uint32_t pdu_length;
        uint8_t *pdu_buffer;
        MessageDef *msg_p;
1581

1582 1583 1584
        for (list_count = 0; list_count < rrcConnectionReconfiguration_r8->dedicatedInfoNASList->list.count; list_count++) {
          pdu_length = rrcConnectionReconfiguration_r8->dedicatedInfoNASList->list.array[list_count]->size;
          pdu_buffer = rrcConnectionReconfiguration_r8->dedicatedInfoNASList->list.array[list_count]->buf;
1585

1586 1587 1588 1589
          msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_CONN_ESTABLI_CNF);
          NAS_CONN_ESTABLI_CNF(msg_p).errCode = AS_SUCCESS;
          NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length = pdu_length;
          NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data = pdu_buffer;
1590

1591
          itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p);
1592
        }
1593

1594 1595
        free (rrcConnectionReconfiguration_r8->dedicatedInfoNASList);
      }
1596

1597 1598 1599 1600 1601 1602 1603 1604 1605
#ifdef ENABLE_RAL
      {
        MessageDef                                 *message_ral_p = NULL;
        rrc_ral_connection_reestablishment_ind_t    connection_reestablishment_ind;
        int                                         i;

        message_ral_p = itti_alloc_new_message (TASK_RRC_UE, RRC_RAL_CONNECTION_REESTABLISHMENT_IND);
        memset(&connection_reestablishment_ind, 0, sizeof(rrc_ral_connection_reestablishment_ind_t));
        // TO DO ral_si_ind.plmn_id        = 0;
1606
        connection_reestablishment_ind.ue_id            = ctxt_pP->rnti;
1607 1608 1609 1610 1611

        if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList != NULL) {
          connection_reestablishment_ind.num_drb      =
            rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.count;

1612 1613 1614
          for (i=0; (
                 i<rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.count)
               && (i < maxDRB); i++) {
1615 1616 1617
            // why minus 1 in RRC code for drb_identity ?
            connection_reestablishment_ind.drb_id[i]   =
              rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity;
1618
          }
1619 1620 1621 1622 1623 1624
        } else {
          connection_reestablishment_ind.num_drb      = 0;
        }

        if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->srb_ToAddModList != NULL) {
          connection_reestablishment_ind.num_srb      =
1625 1626
            rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->srb_ToAddModList->list.count +
            UE_rrc_inst[ctxt_pP->module_id].num_srb;
1627 1628

        } else {
1629
          connection_reestablishment_ind.num_srb      += UE_rrc_inst[ctxt_pP->module_id].num_srb;
1630 1631
        }

1632
        if (connection_reestablishment_ind.num_srb > 2) { // fixme: only 2 srbs can exist, adjust the value
1633
          connection_reestablishment_ind.num_srb =2;
1634
        }
1635 1636 1637 1638

        memcpy (&message_ral_p->ittiMsg, (void *) &connection_reestablishment_ind, sizeof(rrc_ral_connection_reestablishment_ind_t));
        //#warning "ue_mod_idP ? for instance ? => YES"
        LOG_I(RRC, "Sending RRC_RAL_CONNECTION_REESTABLISHMENT_IND to mRAL\n");
1639
        itti_send_msg_to_task (TASK_RAL_UE, ctxt_pP->instance, message_ral_p);
1640
      }
Lionel Gauthier's avatar
Lionel Gauthier committed
1641
#endif
1642
#endif
1643
    } // c1 present
1644
  } // critical extensions present
1645 1646
}

1647
/* 36.331, 5.3.5.4      Reception of an RRCConnectionReconfiguration including the mobilityControlInfo by the UE (handover) */
1648 1649 1650 1651 1652 1653 1654 1655
//-----------------------------------------------------------------------------
void
rrc_ue_process_mobilityControlInfo(
  const protocol_ctxt_t* const       ctxt_pP,
  const uint8_t                      eNB_index,
  struct MobilityControlInfo* const mobilityControlInfo
)
//-----------------------------------------------------------------------------
1656
{
1657
  /*
1658 1659
  DRB_ToReleaseList_t*  drb2release_list;
  DRB_Identity_t *lcid;
1660
   */
1661
  LOG_N(RRC,"Note: This function needs some updates\n");
1662

1663 1664 1665
  if(UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].T310_active == 1) {
    UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].T310_active = 0;
  }
1666

1667 1668
  UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].T304_active = 1;
  UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].T304_cnt = T304[mobilityControlInfo->t304];
1669

1670
  /*
1671 1672 1673
  drb2release_list = CALLOC (1, sizeof (*drb2release_list));
  lcid= CALLOC (1, sizeof (DRB_Identity_t)); // long
  for (*lcid=0;*lcid<NB_RB_MAX;*lcid++)
1674
  {
1675
    ASN_SEQUENCE_ADD (&(drb2release_list)->list,lcid);
1676
  }
1677
   */
1678
  //Removing SRB1 and SRB2 and DRB0
1679 1680 1681 1682 1683 1684 1685
  LOG_N(RRC,"[UE %d] : Update needed for rrc_pdcp_config_req (deprecated) and rrc_rlc_config_req commands(deprecated)\n", ctxt_pP->module_id);
  rrc_pdcp_config_req (ctxt_pP, SRB_FLAG_YES, CONFIG_ACTION_REMOVE, DCCH,UNDEF_SECURITY_MODE);
  rrc_rlc_config_req(ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, CONFIG_ACTION_REMOVE,ctxt_pP->module_id+DCCH,Rlc_info_am_config);
  rrc_pdcp_config_req (ctxt_pP, SRB_FLAG_YES, CONFIG_ACTION_REMOVE, DCCH1,UNDEF_SECURITY_MODE);
  rrc_rlc_config_req(ctxt_pP, SRB_FLAG_YES,CONFIG_ACTION_REMOVE, MBMS_FLAG_NO,ctxt_pP->module_id+DCCH1,Rlc_info_am_config);
  rrc_pdcp_config_req (ctxt_pP, SRB_FLAG_NO, CONFIG_ACTION_REMOVE, DTCH,UNDEF_SECURITY_MODE);
  rrc_rlc_config_req(ctxt_pP, SRB_FLAG_NO,CONFIG_ACTION_REMOVE, MBMS_FLAG_NO,ctxt_pP->module_id+DTCH,Rlc_info_um);
1686
  /*
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1687
  rrc_pdcp_config_asn1_req(NB_eNB_INST+ue_mod_idP,frameP, 0,eNB_index,
1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698
         NULL, // SRB_ToAddModList
         NULL, // DRB_ToAddModList
         drb2release_list,
         0, // security mode
         NULL, // key rrc encryption
         NULL, // key rrc integrity
         NULL // key encryption
  #ifdef Rel10
         ,NULL
  #endif
         );
1699

Lionel Gauthier's avatar
 
Lionel Gauthier committed
1700
  rrc_rlc_config_asn1_req(NB_eNB_INST+ue_mod_idP, frameP,0,eNB_index,
1701 1702 1703 1704 1705 1706 1707
        NULL,// SRB_ToAddModList
        NULL,// DRB_ToAddModList
        drb2release_list // DRB_ToReleaseList
  #ifdef Rel10
        ,NULL
  #endif
        );
1708
   */
1709

1710 1711 1712 1713

  //A little cleanup at RRC...
  //Copying current queue config to free RRC index
  /*
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1714 1715 1716
    memcpy((void *)UE_rrc_inst[ue_mod_idP].SRB1_config[~(7<<eNB_index)],(void *)UE_rrc_inst[ue_mod_idP].SRB1_config[7<<eNB_index],sizeof(SRB_ToAddMod_t));
    memcpy((void *)UE_rrc_inst[ue_mod_idP].SRB2_config[~(7<<eNB_index)],(void *)UE_rrc_inst[ue_mod_idP].SRB2_config[7<<eNB_index],sizeof(SRB_ToAddMod_t));
    memcpy((void *)UE_rrc_inst[ue_mod_idP].DRB_config[~(7<<eNB_index)][0],(void *)UE_rrc_inst[ue_mod_idP].DRB_config[7<<eNB_index][0],sizeof(DRB_ToAddMod_t));
1717
   */
1718 1719
  /*
  LOG_N(RRC,"Not sure if Freeing the current queue config works properly: Fix me\n");
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1720 1721 1722
  free((void *)&UE_rrc_inst[ue_mod_idP].SRB1_config[eNB_index]);
  free((void *)&UE_rrc_inst[ue_mod_idP].SRB2_config[eNB_index]);
  free((void *)&UE_rrc_inst[ue_mod_idP].DRB_config[eNB_index][0]);
1723

Lionel Gauthier's avatar
 
Lionel Gauthier committed
1724 1725 1726
  UE_rrc_inst[ue_mod_idP].SRB1_config[eNB_index] = NULL;
  UE_rrc_inst[ue_mod_idP].SRB2_config[eNB_index] = NULL;
  UE_rrc_inst[ue_mod_idP].DRB_config[eNB_index][0] = NULL;
1727
   */
1728
  //Synchronisation to DL of target cell
1729 1730 1731
  LOG_D(RRC,
        "HO: Reset PDCP and RLC for configured RBs.. \n[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ  (SRB2 eNB %d) --->][MAC_UE][MOD %02d][]\n",
        ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id);
1732 1733

  // Reset MAC and configure PHY
1734 1735 1736 1737
  rrc_mac_config_req(ctxt_pP->module_id,
                     ENB_FLAG_NO,
                     0,
                     eNB_index,
1738 1739
                     (RadioResourceConfigCommonSIB_t *)NULL,
                     (struct PhysicalConfigDedicated *)NULL,
1740
#ifdef Rel10
1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756
                     (SCellToAddMod_r10_t *)NULL,
                     //(struct PhysicalConfigDedicatedSCell_r10 *)NULL,
#endif
                     (MeasObjectToAddMod_t **)NULL,
                     (MAC_MainConfig_t *)NULL,
                     0,
                     (struct LogicalChannelConfig *)NULL,
                     (MeasGapConfig_t *)NULL,
                     (TDD_Config_t *)NULL,
                     mobilityControlInfo,
                     (uint8_t *)NULL,
                     (uint16_t *)NULL,
                     NULL,
                     NULL,
                     NULL,
                     NULL
1757
#ifdef Rel10
1758 1759 1760
                     ,0,
                     (MBSFN_AreaInfoList_r9_t *)NULL,
                     (PMCH_InfoList_r9_t *)NULL
1761 1762
#endif
#ifdef CBA
1763 1764
                     ,0,
                     0
1765
#endif
1766
                    );
1767

1768
  // Re-establish PDCP for all RBs that are established
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1769 1770 1771
  // rrc_pdcp_config_req (ue_mod_idP+NB_eNB_INST, frameP, 0, CONFIG_ACTION_ADD, ue_mod_idP+DCCH);
  // rrc_pdcp_config_req (ue_mod_idP+NB_eNB_INST, frameP, 0, CONFIG_ACTION_ADD, ue_mod_idP+DCCH1);
  // rrc_pdcp_config_req (ue_mod_idP+NB_eNB_INST, frameP, 0, CONFIG_ACTION_ADD, ue_mod_idP+DTCH);
1772 1773


1774
  // Re-establish RLC for all RBs that are established
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1775 1776 1777
  // rrc_rlc_config_req(ue_mod_idP+NB_eNB_INST,frameP,0,CONFIG_ACTION_ADD,ue_mod_idP+DCCH,SIGNALLING_RADIO_BEARER,Rlc_info_am_config);
  // rrc_rlc_config_req(ue_mod_idP+NB_eNB_INST,frameP,0,CONFIG_ACTION_ADD,ue_mod_idP+DCCH1,SIGNALLING_RADIO_BEARER,Rlc_info_am_config);
  // rrc_rlc_config_req(ue_mod_idP+NB_eNB_INST,frameP,0,CONFIG_ACTION_ADD,ue_mod_idP+DTCH,RADIO_ACCESS_BEARER,Rlc_info_um);
1778
  UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State = RRC_SI_RECEIVED;
1779
}
1780 1781 1782 1783 1784 1785 1786 1787

//-----------------------------------------------------------------------------
void
rrc_detach_from_eNB(
  module_id_t ue_mod_idP,
  uint8_t eNB_index
)
//-----------------------------------------------------------------------------
1788
{
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1789
  //UE_rrc_inst[ue_mod_idP].DRB_config[eNB_index]
1790 1791
}

1792 1793 1794 1795 1796 1797 1798 1799 1800
//-----------------------------------------------------------------------------
void
rrc_ue_decode_dcch(
  const protocol_ctxt_t* const ctxt_pP,
  const rb_id_t                Srb_id,
  const uint8_t*         const Buffer,
  const uint8_t                eNB_indexP
)
//-----------------------------------------------------------------------------
1801
{
1802 1803 1804 1805

  //DL_DCCH_Message_t dldcchmsg;
  DL_DCCH_Message_t *dl_dcch_msg=NULL;//&dldcchmsg;
  //  asn_dec_rval_t dec_rval;
1806
  // int i;
1807
  uint8_t target_eNB_index=0xFF;
winckel's avatar
winckel committed
1808 1809 1810 1811
#if defined(ENABLE_ITTI)
  MessageDef *msg_p;
#endif

1812
  if (Srb_id != 1) {
1813
    LOG_E(RRC,"[UE %d] Frame %d: Received message on DL-DCCH (SRB%d), should not have ...\n",
1814
          ctxt_pP->module_id, ctxt_pP->frame, Srb_id);
1815
    return;
1816 1817 1818 1819 1820
  }

  //memset(dl_dcch_msg,0,sizeof(DL_DCCH_Message_t));

  // decode messages
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1821
  //  LOG_D(RRC,"[UE %d] Decoding DL-DCCH message\n",ue_mod_idP);
1822 1823 1824 1825
  /*
  for (i=0;i<30;i++)
    LOG_T(RRC,"%x.",Buffer[i]);
  LOG_T(RRC, "\n");
1826
   */
1827
  uper_decode(NULL,
1828 1829 1830 1831
              &asn_DEF_DL_DCCH_Message,
              (void**)&dl_dcch_msg,
              (uint8_t*)Buffer,
              RRC_BUF_SIZE,0,0);
1832 1833 1834 1835 1836

#ifdef XER_PRINT
  xer_fprint(stdout,&asn_DEF_DL_DCCH_Message,(void*)dl_dcch_msg);
#endif

1837
#if defined(ENABLE_ITTI)
1838
# if defined(DISABLE_ITTI_XER_PRINT)
1839
  {
winckel's avatar
winckel committed
1840 1841
    msg_p = itti_alloc_new_message (TASK_RRC_UE, RRC_DL_DCCH_MESSAGE);
    memcpy (&msg_p->ittiMsg, (void *) dl_dcch_msg, sizeof(RrcDlDcchMessage));
1842

1843
    itti_send_msg_to_task (TASK_UNKNOWN, ctxt_pP->instance, msg_p);
1844
  }
1845 1846
# else
  {
1847
    char        message_string[30000];
1848
    size_t      message_string_size;
1849

1850 1851 1852 1853
    if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_DCCH_Message, (void *)dl_dcch_msg)) > 0) {
      msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_DL_DCCH, message_string_size + sizeof (IttiMsgText));
      msg_p->ittiMsg.rrc_dl_dcch.size = message_string_size;
      memcpy(&msg_p->ittiMsg.rrc_dl_dcch.text, message_string, message_string_size);
1854

1855
      itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p);
1856
    }
1857 1858
  }
# endif
1859 1860
#endif

1861 1862
  if (dl_dcch_msg->message.present == DL_DCCH_MessageType_PR_c1) {

1863
    if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_indexP].State >= RRC_CONNECTED) {
1864

1865
      switch (dl_dcch_msg->message.choice.c1.present) {
1866

1867
      case DL_DCCH_MessageType__c1_PR_NOTHING:
1868 1869
        LOG_I(RRC, "[UE %d] Frame %d : Received PR_NOTHING on DL-DCCH-Message\n",
              ctxt_pP->module_id, ctxt_pP->frame);
1870
        return;
winckel's avatar
RRC:  
winckel committed
1871

1872 1873
      case DL_DCCH_MessageType__c1_PR_csfbParametersResponseCDMA2000:
        break;
1874

1875
      case DL_DCCH_MessageType__c1_PR_dlInformationTransfer: {
winckel's avatar
RRC:  
winckel committed
1876
#if defined(ENABLE_ITTI)
1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894
        DLInformationTransfer_t *dlInformationTransfer = &dl_dcch_msg->message.choice.c1.choice.dlInformationTransfer;

        if ((dlInformationTransfer->criticalExtensions.present == DLInformationTransfer__criticalExtensions_PR_c1)
            && (dlInformationTransfer->criticalExtensions.choice.c1.present
                == DLInformationTransfer__criticalExtensions__c1_PR_dlInformationTransfer_r8)
            && (dlInformationTransfer->criticalExtensions.choice.c1.choice.dlInformationTransfer_r8.dedicatedInfoType.present
                == DLInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS)) {
          /* This message hold a dedicated info NAS payload, forward it to NAS */
          struct DLInformationTransfer_r8_IEs__dedicatedInfoType *dedicatedInfoType =
                &dlInformationTransfer->criticalExtensions.choice.c1.choice.dlInformationTransfer_r8.dedicatedInfoType;
          uint32_t pdu_length;
          uint8_t *pdu_buffer;
          MessageDef *msg_p;

          pdu_length = dedicatedInfoType->choice.dedicatedInfoNAS.size;
          pdu_buffer = dedicatedInfoType->choice.dedicatedInfoNAS.buf;

          msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_DOWNLINK_DATA_IND);
1895
          NAS_DOWNLINK_DATA_IND(msg_p).UEid = ctxt_pP->module_id; // TODO set the UEid to something else ?
1896 1897 1898
          NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length = pdu_length;
          NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data = pdu_buffer;

1899
          itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p);
1900 1901
        }

winckel's avatar
RRC:  
winckel committed
1902
#endif
1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917
        break;
      }

      case DL_DCCH_MessageType__c1_PR_handoverFromEUTRAPreparationRequest:
        break;

      case DL_DCCH_MessageType__c1_PR_mobilityFromEUTRACommand:
        break;

      case DL_DCCH_MessageType__c1_PR_rrcConnectionReconfiguration:

        // first check if mobilityControlInfo  is present
        if (dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo
            != NULL) {
          /* 36.331, 5.3.5.4 Reception of an RRCConnectionReconfiguration including the mobilityControlInfo by the UE (handover)*/
1918
          if (UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.targetCellId
1919 1920
              != dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo->targetPhysCellId) {
            LOG_W(RRC,
1921 1922 1923
                  "[UE %d] Frame %d: Handover target (%d) is different from RSRP measured target (%d)..\n",
                  ctxt_pP->module_id,
                  ctxt_pP->frame,
1924
                  dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo->targetPhysCellId,
1925
                  UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.targetCellId);
1926
            return;
1927
          } else if ((target_eNB_index = get_adjacent_cell_mod_id(UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.targetCellId))
1928 1929
                     == 0xFF) {
            LOG_W(RRC,
1930 1931 1932
                  "[UE %d] Frame %d: ue_mod_idP of the target eNB not found, check the network topology\n",
                  ctxt_pP->module_id,
                  ctxt_pP->frame);
1933 1934 1935
            return;
          } else {
            LOG_I(RRC,
1936 1937 1938 1939
                  "[UE% d] Frame %d: Received rrcConnectionReconfiguration with mobilityControlInfo \n",
                  ctxt_pP->module_id,
                  ctxt_pP->frame);
            UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.measFlag = 1; // Ready to send more MeasReports if required
1940
          }
1941
        }
1942

1943 1944 1945 1946
        rrc_ue_process_rrcConnectionReconfiguration(
          ctxt_pP,
          &dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration,
          eNB_indexP);
1947 1948

        if (target_eNB_index != 0xFF) {
1949 1950 1951
          rrc_ue_generate_RRCConnectionReconfigurationComplete(
            ctxt_pP,
            target_eNB_index,
1952
              dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.rrc_TransactionIdentifier);
1953 1954 1955 1956
          UE_rrc_inst[ctxt_pP->module_id].Info[eNB_indexP].State = RRC_HO_EXECUTION;
          UE_rrc_inst[ctxt_pP->module_id].Info[target_eNB_index].State = RRC_RECONFIGURED;
          LOG_I(RRC, "[UE %d] State = RRC_RECONFIGURED during HO (eNB %d)\n",
                ctxt_pP->module_id, target_eNB_index);
Lionel Gauthier's avatar
Lionel Gauthier committed
1957 1958
#if defined(ENABLE_ITTI)
#ifdef ENABLE_RAL
1959 1960 1961 1962 1963 1964 1965
          {
            MessageDef                                 *message_ral_p = NULL;
            rrc_ral_connection_reconfiguration_ho_ind_t connection_reconfiguration_ho_ind;
            int                                         i;

            message_ral_p = itti_alloc_new_message (TASK_RRC_UE, RRC_RAL_CONNECTION_RECONFIGURATION_HO_IND);
            memset(&connection_reconfiguration_ho_ind, 0, sizeof(rrc_ral_connection_reconfiguration_ho_ind_t));
1966
            connection_reconfiguration_ho_ind.ue_id = ctxt_pP->module_id;
1967

1968 1969
            if (dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList
                != NULL) {
1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983
              connection_reconfiguration_ho_ind.num_drb      =
                dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.count;

              for (i=0; (
                     i<dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.count)
                   && (i < maxDRB); i++) {
                // why minus 1 in RRC code for drb_identity ?
                connection_reconfiguration_ho_ind.drb_id[i]   =
                  dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity;
              }
            } else {
              connection_reconfiguration_ho_ind.num_drb      = 0;
            }

1984 1985
            if (dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->srb_ToAddModList
                != NULL) {
1986
              connection_reconfiguration_ho_ind.num_srb      =
1987 1988 1989
                dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->srb_ToAddModList->list.count
                +
                UE_rrc_inst[ctxt_pP->module_id].num_srb;
1990
            } else {
1991
              connection_reconfiguration_ho_ind.num_srb      += UE_rrc_inst[ctxt_pP->module_id].num_srb;
1992 1993
            }

1994
            if (connection_reconfiguration_ho_ind.num_srb > 2 ) {
1995
              connection_reconfiguration_ho_ind.num_srb =2;
1996
            }
1997 1998 1999 2000

            memcpy (&message_ral_p->ittiMsg, (void *) &connection_reconfiguration_ho_ind, sizeof(rrc_ral_connection_reconfiguration_ho_ind_t));
            //#warning "ue_mod_idP ? for instance ? => YES"
            LOG_I(RRC, "Sending RRC_RAL_CONNECTION_RECONFIGURATION_HO_IND to mRAL\n");
2001
            itti_send_msg_to_task (TASK_RAL_UE, ctxt_pP->instance, message_ral_p);
2002
          }
Lionel Gauthier's avatar
Lionel Gauthier committed
2003 2004
#endif
#endif
2005
        } else {
2006 2007 2008
          rrc_ue_generate_RRCConnectionReconfigurationComplete(
            ctxt_pP,
            eNB_indexP,
2009
              dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.rrc_TransactionIdentifier);
2010 2011 2012 2013
          UE_rrc_inst[ctxt_pP->module_id].Info[eNB_indexP].State = RRC_RECONFIGURED;
          LOG_I(RRC, "[UE %d] State = RRC_RECONFIGURED (eNB %d)\n",
                ctxt_pP->module_id,
                eNB_indexP);
Lionel Gauthier's avatar
Lionel Gauthier committed
2014 2015
#if defined(ENABLE_ITTI)
#ifdef ENABLE_RAL
2016 2017 2018 2019 2020 2021 2022
          {
            MessageDef                                 *message_ral_p = NULL;
            rrc_ral_connection_reconfiguration_ind_t    connection_reconfiguration_ind;
            int                                         i;

            message_ral_p = itti_alloc_new_message (TASK_RRC_UE, RRC_RAL_CONNECTION_RECONFIGURATION_IND);
            memset(&connection_reconfiguration_ind, 0, sizeof(rrc_ral_connection_reconfiguration_ind_t));
2023
            connection_reconfiguration_ind.ue_id = ctxt_pP->module_id;
2024

2025 2026
            if (dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList
                != NULL) {
2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040
              connection_reconfiguration_ind.num_drb      =
                dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.count;

              for (i=0; (
                     i<dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.count)
                   && (i < maxDRB); i++) {
                // why minus 1 in RRC code for drb_identity ?
                connection_reconfiguration_ind.drb_id[i]   =
                  dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity;
              }
            } else {
              connection_reconfiguration_ind.num_drb      = 0;
            }

2041 2042
            if (dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->srb_ToAddModList
                != NULL) {
2043
              connection_reconfiguration_ind.num_srb      =
2044 2045 2046
                dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->srb_ToAddModList->list.count
                +
                UE_rrc_inst[ctxt_pP->module_id].num_srb;
2047
            } else {
2048
              connection_reconfiguration_ind.num_srb      +=UE_rrc_inst[ctxt_pP->module_id].num_srb;
2049 2050
            }

2051
            if (connection_reconfiguration_ind.num_srb > 2 ) {
2052
              connection_reconfiguration_ind.num_srb =2;
2053
            }
2054 2055 2056 2057

            memcpy (&message_ral_p->ittiMsg, (void *) &connection_reconfiguration_ind, sizeof(rrc_ral_connection_reconfiguration_ind_t));
            //#warning "ue_mod_idP ? for instance ? => YES"
            LOG_I(RRC, "Sending RRC_RAL_CONNECTION_RECONFIGURATION_IND to mRAL\n");
2058
            itti_send_msg_to_task (TASK_RAL_UE, ctxt_pP->instance, message_ral_p);
2059
          }
Lionel Gauthier's avatar
Lionel Gauthier committed
2060 2061 2062
#endif
#endif

2063 2064 2065
        }

        break;
2066

2067
      case DL_DCCH_MessageType__c1_PR_rrcConnectionRelease:
2068
#if defined(ENABLE_ITTI)
2069 2070 2071 2072 2073 2074 2075 2076 2077
        msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_CONN_RELEASE_IND);

        if ((dl_dcch_msg->message.choice.c1.choice.rrcConnectionRelease.criticalExtensions.present
             == RRCConnectionRelease__criticalExtensions_PR_c1)
            && (dl_dcch_msg->message.choice.c1.choice.rrcConnectionRelease.criticalExtensions.choice.c1.present
                == RRCConnectionRelease__criticalExtensions__c1_PR_rrcConnectionRelease_r8)) {
          NAS_CONN_RELEASE_IND(msg_p).cause =
            dl_dcch_msg->message.choice.c1.choice.rrcConnectionRelease.criticalExtensions.choice.c1.choice.rrcConnectionRelease_r8.releaseCause;
        }
winckel's avatar
winckel committed
2078

2079
        itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p);
Lionel Gauthier's avatar
Lionel Gauthier committed
2080
#if defined(ENABLE_RAL)
2081
        msg_p = itti_alloc_new_message(TASK_RRC_UE, RRC_RAL_CONNECTION_RELEASE_IND);
2082 2083
        RRC_RAL_CONNECTION_RELEASE_IND(msg_p).ue_id = ctxt_pP->module_id;
        itti_send_msg_to_task(TASK_RAL_UE, ctxt_pP->instance, msg_p);
Lionel Gauthier's avatar
Lionel Gauthier committed
2084
#endif
2085
#endif
2086
        break;
2087

2088
      case DL_DCCH_MessageType__c1_PR_securityModeCommand:
2089 2090 2091 2092 2093 2094
        LOG_I(RRC, "[UE %d] Received securityModeCommand (eNB %d)\n",
              ctxt_pP->module_id, eNB_indexP);
        rrc_ue_process_securityModeCommand(
          ctxt_pP,
          &dl_dcch_msg->message.choice.c1.choice.securityModeCommand,
          eNB_indexP);
2095
        break;
2096

2097
      case DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry:
2098 2099 2100 2101 2102 2103 2104
        LOG_I(RRC, "[UE %d] Received Capability Enquiry (eNB %d)\n",
              ctxt_pP->module_id,
              eNB_indexP);
        rrc_ue_process_ueCapabilityEnquiry(
          ctxt_pP,
          &dl_dcch_msg->message.choice.c1.choice.ueCapabilityEnquiry,
          eNB_indexP);
2105
        break;
2106

2107 2108
      case DL_DCCH_MessageType__c1_PR_counterCheck:
        break;
winckel's avatar
RRC:  
winckel committed
2109

2110
#ifdef Rel10
2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129

      case DL_DCCH_MessageType__c1_PR_ueInformationRequest_r9:
        break;

      case DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r10:
        break;

      case DL_DCCH_MessageType__c1_PR_rnReconfiguration_r10:
        break;
#endif

      case DL_DCCH_MessageType__c1_PR_spare1:
      case DL_DCCH_MessageType__c1_PR_spare2:
      case DL_DCCH_MessageType__c1_PR_spare3:
      case DL_DCCH_MessageType__c1_PR_spare4:
        break;

      default:
        break;
2130
      }
2131
    }
2132
  }
2133

2134
#ifndef NO_RRM
2135
  send_msg(&S_rrc,msg_rrc_end_scan_req(ctxt_pP->module_id,eNB_indexP));
2136 2137 2138 2139 2140 2141
#endif
}

const char siWindowLength[7][5] = {"1ms\0","2ms\0","5ms\0","10ms\0","15ms\0","20ms\0","40ms\0"};
const char siWindowLength_int[7] = {1,2,5,10,15,20,40};

2142
const char SIBType[16][6] = {"SIB3\0","SIB4\0","SIB5\0","SIB6\0","SIB7\0","SIB8\0","SIB9\0","SIB10\0","SIB11\0","SIB12\0","SIB13\0","Sp2\0","Sp3\0","Sp4\0"};
2143 2144 2145
const char SIBPeriod[7][7]= {"80ms\0","160ms\0","320ms\0","640ms\0","1280ms\0","2560ms\0","5120ms\0"};
int siPeriod_int[7] = {80,160,320,640,1280,2560,5120};

2146
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
2147 2148
int
decode_BCCH_DLSCH_Message(
2149 2150 2151 2152 2153 2154
  const protocol_ctxt_t* const ctxt_pP,
  const uint8_t                eNB_index,
  uint8_t*               const Sdu,
  const uint8_t                Sdu_len,
  const uint8_t                rsrq,
  const uint8_t                rsrp
2155
)
2156
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
2157
{
2158 2159 2160

  //BCCH_DL_SCH_Message_t bcch_message;
  BCCH_DL_SCH_Message_t *bcch_message=NULL;//_ptr=&bcch_message;
2161 2162
  SystemInformationBlockType1_t** sib1=&UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index];
  SystemInformation_t** si=UE_rrc_inst[ctxt_pP->module_id].si[eNB_index];
2163 2164
  asn_dec_rval_t dec_rval;
  uint32_t si_window;//, sib1_decoded=0, si_decoded=0;
2165
  // int i;
2166

2167
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_IN);
2168 2169


2170 2171
  if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIB1Status == 1) &&
      (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus == 1)) {
2172
    // Avoid decoding to prevent memory bloating
2173
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT);
2174 2175 2176
    return 0;
  } else {

2177
    rrc_set_sub_state (ctxt_pP->module_id, RRC_SUB_STATE_IDLE_RECEIVING_SIB);
2178 2179 2180

    //memset(&bcch_message,0,sizeof(BCCH_DL_SCH_Message_t));

2181
    /*LOG_D(RRC,"[UE %d] Decoding DL_BCCH_DLSCH_Message\n",ue_mod_idP);*/
2182 2183 2184 2185 2186 2187 2188 2189

    dec_rval = uper_decode_complete(NULL,
                                    &asn_DEF_BCCH_DL_SCH_Message,
                                    (void **)&bcch_message,
                                    (const void *)Sdu,
                                    Sdu_len);//,0,0);

    if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) {
2190 2191 2192
      LOG_E(RRC,"[UE %d] Failed to decode BCCH_DLSCH_MESSAGE (%d bits)\n",
            ctxt_pP->module_id,
            dec_rval.consumed);
2193 2194
      //free the memory
      SEQUENCE_free(&asn_DEF_BCCH_DL_SCH_Message, (void*)bcch_message, 1);
2195
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT);
2196 2197 2198 2199
      return -1;
    }

    //  xer_fprint(stdout,  &asn_DEF_BCCH_DL_SCH_Message, (void*)&bcch_message);
2200 2201

#if defined(ENABLE_ITTI)
2202
# if defined(DISABLE_ITTI_XER_PRINT)
2203 2204
    {
      MessageDef *msg_p;
2205

2206 2207
      msg_p = itti_alloc_new_message (TASK_RRC_UE, RRC_DL_BCCH_MESSAGE);
      memcpy (&msg_p->ittiMsg, (void *) bcch_message, sizeof(RrcDlBcchMessage));
2208

2209
      itti_send_msg_to_task (TASK_UNKNOWN, ctxt_pP->instance, msg_p);
2210
    }
2211
# else
2212 2213 2214
    {
      char        message_string[15000];
      size_t      message_string_size;
2215

2216 2217
      if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_BCCH_DL_SCH_Message, (void *)bcch_message)) > 0) {
        MessageDef *msg_p;
2218

2219 2220 2221
        msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_DL_BCCH, message_string_size + sizeof (IttiMsgText));
        msg_p->ittiMsg.rrc_dl_bcch.size = message_string_size;
        memcpy(&msg_p->ittiMsg.rrc_dl_bcch.text, message_string, message_string_size);
winckel's avatar
winckel committed
2222

2223
        itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p);
winckel's avatar
winckel committed
2224
      }
2225
    }
2226
# endif
2227 2228
#endif

2229 2230 2231
    if (bcch_message->message.present == BCCH_DL_SCH_MessageType_PR_c1) {
      switch (bcch_message->message.choice.c1.present) {
      case BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1:
2232 2233
        if ((ctxt_pP->frame %2) == 0) {
          if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIB1Status == 0) {
2234 2235 2236
            memcpy((void*)*sib1,
                   (void*)&bcch_message->message.choice.c1.choice.systemInformationBlockType1,
                   sizeof(SystemInformationBlockType1_t));
2237 2238
            LOG_D(RRC,"[UE %d] Decoding First SIB1\n",ctxt_pP->module_id);
            decode_SIB1(ctxt_pP, eNB_index, rsrq, rsrp);
2239
            //mac_xface->macphy_exit("after decode_SIB1");
2240
          }
2241 2242 2243 2244 2245
        }

        break;

      case BCCH_DL_SCH_MessageType__c1_PR_systemInformation:
2246 2247
        if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIB1Status == 1) &&
            (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus == 0)) {
2248
          //                                                if ((frameP %8) == 1) {  // check only in odd frames for SI
2249 2250
          si_window = (ctxt_pP->frame%(UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod/10))/
                      (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIwindowsize/10);
2251
          memcpy((void*)si[si_window], // FIXME check indexing (see line 219)
2252 2253
                 (void*)&bcch_message->message.choice.c1.choice.systemInformation,
                 sizeof(SystemInformation_t));
2254 2255 2256 2257 2258
          LOG_D(RRC,"[UE %d] Decoding SI for frameP %d, si_window %d\n",
                ctxt_pP->module_id,
                ctxt_pP->frame,
                si_window);
          decode_SI(ctxt_pP,eNB_index,si_window);
2259 2260 2261 2262 2263 2264 2265 2266 2267 2268
          //mac_xface->macphy_exit("after decode_SI");

          //                                }
        }

        break;

      case BCCH_DL_SCH_MessageType__c1_PR_NOTHING:
      default:
        break;
2269
      }
2270
    }
2271
  }
winckel's avatar
winckel committed
2272

2273
  if ((rrc_get_sub_state(ctxt_pP->module_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE)
2274
# if defined(ENABLE_USE_MME)
2275
      && (UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data != NULL)
2276
#endif
2277
     ) {
2278 2279 2280
    rrc_ue_generate_RRCConnectionRequest(ctxt_pP, 0);
    LOG_I(RRC, "not sending connection request\n");
    rrc_set_sub_state (ctxt_pP->module_id, RRC_SUB_STATE_IDLE_CONNECTING);
winckel's avatar
winckel committed
2281 2282
  }

Lionel Gauthier's avatar
 
Lionel Gauthier committed
2283 2284
  /*  if ((UE_rrc_inst[ue_mod_idP].Info[eNB_index].SIB1Status == 1) &&
      (UE_rrc_inst[ue_mod_idP].Info[eNB_index].SIStatus == 1) && (frameP >= ue_mod_idP * 20 + 10))
2285
      SEQUENCE_free(&asn_DEF_BCCH_DL_SCH_Message, (void*)bcch_message, 0);*/
2286
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT);
2287 2288

  return 0;
2289 2290 2291
}


2292
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
2293 2294
int
decode_SIB1(
2295 2296 2297 2298
  const protocol_ctxt_t* const ctxt_pP,
  const uint8_t                eNB_index,
  const uint8_t                rsrq,
  const uint8_t                rsrp
2299
)
2300
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
2301
{
2302
  SystemInformationBlockType1_t** sib1=&UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index];
2303
  int i;
2304 2305 2306
  int mcc,mnc,mccdigits,mncdigits,tac=0;
  PLMN_Identity_t *PLMN_identity;
  int plmn_ind=0;
2307

2308
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_IN);
2309

2310
  LOG_I(RRC,"[UE %d] : Dumping SIB 1\n",ctxt_pP->module_id);
2311 2312

  //  xer_fprint(stdout,&asn_DEF_SystemInformationBlockType1, (void*)*sib1);
2313 2314 2315 2316
  PLMN_identity = &(*sib1)->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->plmn_Identity;

  mccdigits = PLMN_identity->mcc->list.count;
  mncdigits = PLMN_identity->mnc.list.count;
2317

2318
  if (mccdigits == 2) {
2319 2320
    mcc = *PLMN_identity->mcc->list.array[0]*10 + *PLMN_identity->mcc->list.array[1];
  } else {
2321 2322
    mcc = *PLMN_identity->mcc->list.array[0]*100 + *PLMN_identity->mcc->list.array[1]*10 + *PLMN_identity->mcc->list.array[2];
  }
2323

2324
  if (mncdigits == 2) {
2325
    mnc = *PLMN_identity->mnc.list.array[0]*10 + *PLMN_identity->mnc.list.array[1];
2326
  } else {
2327 2328
    mnc = *PLMN_identity->mnc.list.array[0]*100 + *PLMN_identity->mnc.list.array[1]*10 + *PLMN_identity->mnc.list.array[2];
  }
2329

2330
  if ((*sib1)->cellAccessRelatedInfo.trackingAreaCode.size == 2) {
2331
    tac = ((*sib1)->cellAccessRelatedInfo.trackingAreaCode.buf[0]<<8)+(*sib1)->cellAccessRelatedInfo.trackingAreaCode.buf[1];
2332
  }
2333 2334 2335

  LOG_I(RRC,"PLMN MCC %d, MNC %d, TAC %x\n",mcc,mnc,tac);
  plmn_ind = 0;
2336

2337 2338 2339 2340 2341
  while (plmn_data[plmn_ind].mcc>0) {
    if ((plmn_data[plmn_ind].mcc == mcc) && (plmn_data[plmn_ind].mnc==mnc)) {
      LOG_I(RRC,"Found %s\n", plmn_data[plmn_ind].oper_short);
      break;
    }
2342

2343 2344
    plmn_ind++;
  }
2345

2346
  if (plmn_data[plmn_ind].mcc<0) {
2347
    LOG_I(RRC,"Found Unknown operator\n");
2348
  }
2349

2350
  LOG_I(RRC,"cellAccessRelatedInfo.cellIdentity : %x.%x.%x.%x\n",
2351 2352 2353 2354
        (*sib1)->cellAccessRelatedInfo.cellIdentity.buf[0],
        (*sib1)->cellAccessRelatedInfo.cellIdentity.buf[1],
        (*sib1)->cellAccessRelatedInfo.cellIdentity.buf[2],
        (*sib1)->cellAccessRelatedInfo.cellIdentity.buf[3]);
2355

2356 2357 2358
  LOG_I(RRC,"cellSelectionInfo.q_RxLevMin       : %d\n",(int)(*sib1)->cellSelectionInfo.q_RxLevMin);
  LOG_I(RRC,"freqBandIndicator                  : %d\n",(int)(*sib1)->freqBandIndicator);
  LOG_I(RRC,"siWindowLength                     : %s\n",siWindowLength[(*sib1)->si_WindowLength]);
2359

2360
  if ((*sib1)->schedulingInfoList.list.count>0) {
2361 2362 2363
    for (i=0; i<(*sib1)->schedulingInfoList.list.count; i++) {
      LOG_I(RRC,"siSchedulingInfoPeriod[%d]          : %s\n",i,SIBPeriod[(int)(*sib1)->schedulingInfoList.list.array[i]->si_Periodicity]);

2364
      if ((*sib1)->schedulingInfoList.list.array[i]->sib_MappingInfo.list.count>0) {
2365
        LOG_I(RRC,"siSchedulingInfoSIBType[%d]         : %s\n",i,SIBType[(int)(*(*sib1)->schedulingInfoList.list.array[i]->sib_MappingInfo.list.array[0])]);
2366
      } else {
2367
        LOG_W(RRC,"mapping list %d is null\n",i);
2368
      }
2369 2370 2371 2372
    }
  } else {
    LOG_E(RRC,"siSchedulingInfoPeriod[0]          : PROBLEM!!!\n");
    return -1;
2373 2374 2375
  }

  if ((*sib1)->tdd_Config) {
2376 2377
    LOG_I(RRC,"TDD subframe assignment            : %d\n",(int)(*sib1)->tdd_Config->subframeAssignment);
    LOG_I(RRC,"S-Subframe Config                  : %d\n",(int)(*sib1)->tdd_Config->specialSubframePatterns);
2378 2379
  }

2380 2381
  UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod     = siPeriod_int[(*sib1)->schedulingInfoList.list.array[0]->si_Periodicity];
  UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIwindowsize = siWindowLength_int[(*sib1)->si_WindowLength];
2382
  LOG_D(RRC, "[MSC_MSG][FRAME unknown][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SIB1 params eNB %d) --->][MAC_UE][MOD %02d][]\n",
2383 2384
        ctxt_pP->module_id, eNB_index, ctxt_pP->module_id);
  rrc_mac_config_req(ctxt_pP->module_id,ENB_FLAG_NO,0,eNB_index,
2385 2386
                     (RadioResourceConfigCommonSIB_t *)NULL,
                     (struct PhysicalConfigDedicated *)NULL,
2387
#ifdef Rel10
2388 2389 2390 2391 2392 2393 2394 2395
                     (SCellToAddMod_r10_t *)NULL,
                     //(struct PhysicalConfigDedicatedSCell_r10 *)NULL,
#endif
                     (MeasObjectToAddMod_t **)NULL,
                     (MAC_MainConfig_t *)NULL,
                     0,
                     (struct LogicalChannelConfig *)NULL,
                     (MeasGapConfig_t *)NULL,
2396
                     UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->tdd_Config,
2397
                     (MobilityControlInfo_t *) NULL,
2398 2399
                     &UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIwindowsize,
                     &UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod,
2400 2401 2402 2403
                     NULL,
                     NULL,
                     NULL,
                     (MBSFN_SubframeConfigList_t *)NULL
2404
#ifdef Rel10
2405 2406 2407
                     ,0,
                     (MBSFN_AreaInfoList_r9_t *)NULL,
                     (PMCH_InfoList_r9_t *)NULL
2408 2409
#endif
#ifdef CBA
2410 2411 2412
                     ,
                     0,
                     0
2413
#endif
2414
                    );
2415

2416 2417
  UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIB1Status = 1;
  UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIB1systemInfoValueTag = (*sib1)->systemInfoValueTag;
2418 2419 2420 2421 2422 2423

#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
  {
    int cell_valid = 0;

    if ((*sib1)->cellAccessRelatedInfo.cellBarred == SystemInformationBlockType1__cellAccessRelatedInfo__cellBarred_notBarred) {
2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435
      /* Cell is not barred */
      int plmn;
      int plmn_number;

      plmn_number = (*sib1)->cellAccessRelatedInfo.plmn_IdentityList.list.count;

      /* Compare requested PLMN and PLMNs from SIB1*/
      for (plmn = 0; plmn < plmn_number; plmn++) {
        PLMN_Identity_t *plmn_Identity;

        plmn_Identity = &(*sib1)->cellAccessRelatedInfo.plmn_IdentityList.list.array[plmn]->plmn_Identity;

Lionel Gauthier's avatar
Lionel Gauthier committed
2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456
       if (
             (
               (plmn_Identity->mcc == NULL)
               ||
               (
                 (UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit1 == *(plmn_Identity->mcc->list.array[0])) &&
                 (UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit2 == *(plmn_Identity->mcc->list.array[1])) &&
                 (UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit3 == *(plmn_Identity->mcc->list.array[2]))
               )
             )
             &&
             (UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit1 == *(plmn_Identity->mnc.list.array[0]))
             &&
             (UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit2 == *(plmn_Identity->mnc.list.array[1]))
             &&
             (
               ((UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit3 == 0xf) && (plmn_Identity->mnc.list.count == 2))
               ||
               (UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit3 == *(plmn_Identity->mnc.list.array[2]))
             )
           ) {
2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467
          /* PLMN match, send a confirmation to NAS */
          MessageDef  *msg_p;

          msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_CELL_SELECTION_CNF);
          NAS_CELL_SELECTION_CNF (msg_p).errCode = AS_SUCCESS;
          NAS_CELL_SELECTION_CNF (msg_p).cellID = BIT_STRING_to_uint32(&(*sib1)->cellAccessRelatedInfo.cellIdentity);
          NAS_CELL_SELECTION_CNF (msg_p).tac = BIT_STRING_to_uint16(&(*sib1)->cellAccessRelatedInfo.trackingAreaCode);
          NAS_CELL_SELECTION_CNF (msg_p).rat = 0xFF;
          NAS_CELL_SELECTION_CNF (msg_p).rsrq = rsrq;
          NAS_CELL_SELECTION_CNF (msg_p).rsrp = rsrp;

2468
          itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p);
2469 2470
          cell_valid = 1;
          break;
2471
        }
2472
      }
2473 2474
    }

2475 2476 2477
    if (cell_valid == 0) {
      /* Cell can not be used, ask PHY to try the next one */
      MessageDef  *msg_p;
2478

2479
      msg_p = itti_alloc_new_message(TASK_RRC_UE, PHY_FIND_NEXT_CELL_REQ);
2480

2481
      itti_send_msg_to_task(TASK_PHY_UE, ctxt_pP->instance, msg_p);
2482
    }
2483 2484 2485
  }
#endif

2486
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_OUT);
2487 2488 2489 2490 2491
  return 0;

}


2492
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
2493 2494
void
dump_sib2(
2495 2496
  SystemInformationBlockType2_t *sib2
)
2497
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
2498
{
2499

2500
  LOG_I(RRC,"radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.numberOfRA_Preambles : %ld\n",
2501
        sib2->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.numberOfRA_Preambles);
2502 2503 2504 2505

  //  if (radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig)
  //msg("radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig ",sib2->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig = NULL;

2506 2507
  LOG_I(RRC,"[UE]radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.powerRampingStep : %ld\n",
        sib2->radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.powerRampingStep);
2508

2509 2510
  LOG_I(RRC,"[UE]radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.preambleInitialReceivedTargetPower : %ld\n",
        sib2->radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.preambleInitialReceivedTargetPower);
2511

2512 2513 2514 2515
  LOG_I(RRC,"radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.preambleTransMax  : %ld\n",
        sib2->radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.preambleTransMax);
  LOG_I(RRC,"radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.ra_ResponseWindowSize : %ld\n",
        sib2->radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.ra_ResponseWindowSize);
2516

2517 2518
  LOG_I(RRC,"radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.mac_ContentionResolutionTimer : %ld\n",
        sib2->radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.mac_ContentionResolutionTimer);
2519

2520
  LOG_I(RRC,"radioResourceConfigCommon.rach_ConfigCommon.maxHARQ_Msg3Tx : %ld\n",
2521
        sib2->radioResourceConfigCommon.rach_ConfigCommon.maxHARQ_Msg3Tx);
2522

2523
  LOG_I(RRC,"radioResourceConfigCommon.prach_Config.rootSequenceIndex : %ld\n",sib2->radioResourceConfigCommon.prach_Config.rootSequenceIndex);
2524 2525 2526 2527 2528 2529 2530 2531
  LOG_I(RRC,"radioResourceConfigCommon.prach_Config.prach_ConfigInfo.prach_ConfigIndex : %ld\n",
        sib2->radioResourceConfigCommon.prach_Config.prach_ConfigInfo.prach_ConfigIndex);
  LOG_I(RRC,"radioResourceConfigCommon.prach_Config.prach_ConfigInfo.highSpeedFlag : %d\n",
        (int)sib2->radioResourceConfigCommon.prach_Config.prach_ConfigInfo.highSpeedFlag);
  LOG_I(RRC,"radioResourceConfigCommon.prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig : %ld\n",
        sib2->radioResourceConfigCommon.prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig);
  LOG_I(RRC,"radioResourceConfigCommon.prach_Config.prach_ConfigInfo.prach_FreqOffset %ld\n",
        sib2->radioResourceConfigCommon.prach_Config.prach_ConfigInfo.prach_FreqOffset);
2532 2533

  // PDSCH-Config
2534 2535
  LOG_I(RRC,"radioResourceConfigCommon.pdsch_ConfigCommon.referenceSignalPower  : %ld\n",sib2->radioResourceConfigCommon.pdsch_ConfigCommon.referenceSignalPower);
  LOG_I(RRC,"radioResourceConfigCommon.pdsch_ConfigCommon.p_b : %ld\n",sib2->radioResourceConfigCommon.pdsch_ConfigCommon.p_b);
2536 2537

  // PUSCH-Config
2538 2539 2540 2541 2542 2543 2544 2545
  LOG_I(RRC,"radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.n_SB  : %ld\n",
        sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.n_SB);
  LOG_I(RRC,"radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode  : %ld\n",
        sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode);
  LOG_I(RRC,"radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset : %ld\n",
        sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset);
  LOG_I(RRC,"radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM : %d\n",
        (int)sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM);
2546 2547 2548 2549 2550 2551
  LOG_I(RRC,"radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled : %d\n",
        (int)sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled);
  LOG_I(RRC,"radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH : %ld\n",
        sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH);
  LOG_I(RRC,"radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled : %d\n",
        (int)sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled);
2552 2553
  LOG_I(RRC,"radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift : %ld\n",
        sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift);
2554 2555 2556

  // PUCCH-Config

2557 2558 2559 2560
  LOG_I(RRC,"radioResourceConfigCommon.pucch_ConfigCommon.deltaPUCCH_Shift : %ld\n",sib2->radioResourceConfigCommon.pucch_ConfigCommon.deltaPUCCH_Shift);
  LOG_I(RRC,"radioResourceConfigCommon.pucch_ConfigCommon.nRB_CQI : %ld\n",sib2->radioResourceConfigCommon.pucch_ConfigCommon.nRB_CQI);
  LOG_I(RRC,"radioResourceConfigCommon.pucch_ConfigCommon.nCS_AN : %ld\n",sib2->radioResourceConfigCommon.pucch_ConfigCommon.nCS_AN);
  LOG_I(RRC,"radioResourceConfigCommon.pucch_ConfigCommon.n1PUCCH_AN : %ld\n",sib2->radioResourceConfigCommon.pucch_ConfigCommon.n1PUCCH_AN);
2561

2562
  LOG_I(RRC,"radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present : %d\n",sib2-> radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present);
2563 2564 2565 2566


  // uplinkPowerControlCommon

2567 2568
  LOG_I(RRC,"radioResourceConfigCommon.uplinkPowerControlCommon.p0_NominalPUSCH : %ld\n",
        sib2->radioResourceConfigCommon.uplinkPowerControlCommon.p0_NominalPUSCH);
2569
  LOG_I(RRC,"radioResourceConfigCommon.uplinkPowerControlCommon.alpha : %ld\n",sib2->radioResourceConfigCommon.uplinkPowerControlCommon.alpha);
2570

2571 2572
  LOG_I(RRC,"radioResourceConfigCommon.uplinkPowerControlCommon.p0_NominalPUCCH : %ld\n",
        sib2->radioResourceConfigCommon.uplinkPowerControlCommon.p0_NominalPUCCH);
2573 2574 2575 2576 2577 2578 2579 2580 2581 2582
  LOG_I(RRC,"radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1 : %ld\n",
        sib2->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1);
  LOG_I(RRC,"radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1b :%ld\n",
        sib2->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1b);
  LOG_I(RRC,"radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2  :%ld\n",
        sib2->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2);
  LOG_I(RRC,"radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2a :%ld\n",
        sib2->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2a);
  LOG_I(RRC,"radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2b :%ld\n",
        sib2->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2b);
2583

2584 2585
  LOG_I(RRC,"radioResourceConfigCommon.uplinkPowerControlCommon.deltaPreambleMsg3 : %ld\n",
        sib2->radioResourceConfigCommon.uplinkPowerControlCommon.deltaPreambleMsg3);
2586

2587
  LOG_I(RRC,"radioResourceConfigCommon.ul_CyclicPrefixLength : %ld\n", sib2->radioResourceConfigCommon.ul_CyclicPrefixLength);
2588

2589 2590 2591 2592 2593 2594
  LOG_I(RRC,"ue_TimersAndConstants.t300 : %ld\n", sib2->ue_TimersAndConstants.t300);
  LOG_I(RRC,"ue_TimersAndConstants.t301 : %ld\n", sib2->ue_TimersAndConstants.t301);
  LOG_I(RRC,"ue_TimersAndConstants.t310 : %ld\n", sib2->ue_TimersAndConstants.t310);
  LOG_I(RRC,"ue_TimersAndConstants.n310 : %ld\n", sib2->ue_TimersAndConstants.n310);
  LOG_I(RRC,"ue_TimersAndConstants.t311 : %ld\n", sib2->ue_TimersAndConstants.t311);
  LOG_I(RRC,"ue_TimersAndConstants.n311 : %ld\n", sib2->ue_TimersAndConstants.n311);
2595

2596 2597 2598 2599 2600
  LOG_I(RRC,"freqInfo.additionalSpectrumEmission : %ld\n",sib2->freqInfo.additionalSpectrumEmission);
  LOG_I(RRC,"freqInfo.ul_CarrierFreq : %p\n", sib2->freqInfo.ul_CarrierFreq);
  LOG_I(RRC,"freqInfo.ul_Bandwidth : %p\n", sib2->freqInfo.ul_Bandwidth);
  LOG_I(RRC,"mbsfn_SubframeConfigList : %p\n", sib2->mbsfn_SubframeConfigList);
  LOG_I(RRC,"timeAlignmentTimerCommon : %ld\n", sib2->timeAlignmentTimerCommon);
2601 2602
}

2603
//-----------------------------------------------------------------------------
2604 2605
void
dump_sib3(
2606 2607
  SystemInformationBlockType3_t *sib3
)
2608
//-----------------------------------------------------------------------------
2609
{
2610 2611 2612 2613

}

#ifdef Rel10
2614
//-----------------------------------------------------------------------------
2615 2616
void
dump_sib13(
2617 2618
  SystemInformationBlockType13_r9_t *sib13
)
2619
//-----------------------------------------------------------------------------
2620
{
2621 2622 2623 2624 2625 2626 2627 2628 2629

  LOG_D(RRC,"[RRC][UE] Dumping SIB13\n");
  LOG_D(RRC,"[RRC][UE] dumping sib13 second time\n");
  LOG_D(RRC,"[RRC][UE] NotificationRepetitionCoeff-r9 : %ld\n", sib13->notificationConfig_r9.notificationRepetitionCoeff_r9);
  LOG_D(RRC,"[RRC][UE] NotificationOffset-r9 : %d\n", (int)sib13->notificationConfig_r9.notificationOffset_r9);
  LOG_D(RRC,"[RRC][UE] NotificationSF-Index-r9 : %d\n", (int)sib13->notificationConfig_r9.notificationSF_Index_r9);

}
#endif
winckel's avatar
winckel committed
2630

2631
//const char SIBPeriod[7][7]= {"80ms\0","160ms\0","320ms\0","640ms\0","1280ms\0","2560ms\0","5120ms\0"};
2632

2633
//-----------------------------------------------------------------------------
2634 2635
int
decode_SI(
2636 2637 2638
  const protocol_ctxt_t* const ctxt_pP,
  const uint8_t                eNB_index,
  const uint8_t                si_window
2639
)
2640
//-----------------------------------------------------------------------------
2641
{
2642

2643
  SystemInformation_t** si=&UE_rrc_inst[ctxt_pP->module_id].si[eNB_index][si_window];
2644
  int i;
2645
  struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member *typeandinfo;
2646

2647
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI  , VCD_FUNCTION_IN);
2648 2649 2650

  // Dump contents
  if ((*si)->criticalExtensions.present==SystemInformation__criticalExtensions_PR_systemInformation_r8) {
2651
    LOG_D(RRC,"(*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count %d\n",
2652
          (*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count);
2653 2654 2655
  } else {
    LOG_D(RRC,"[UE] Unknown criticalExtension version (not Rel8)\n");
    return -1;
2656 2657
  }

2658 2659 2660
  for (i=0; i<(*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count; i++) {
    LOG_D(RRC,"SI count %d\n",i);
    typeandinfo=(*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.array[i];
2661

2662 2663
    switch(typeandinfo->present) {
    case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2:
2664 2665 2666
      UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index] = &typeandinfo->choice.sib2;
      LOG_D(RRC,"[UE %d] Frame %d Found SIB2 from eNB %d\n",ctxt_pP->module_id,ctxt_pP->frame,eNB_index);
      dump_sib2(UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]);
2667
      LOG_D(RRC, "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SIB2 params  eNB %d) --->][MAC_UE][MOD %02d][]\n",
2668 2669 2670
            ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id);
      rrc_mac_config_req(ctxt_pP->module_id,ENB_FLAG_NO,0,eNB_index,
                         &UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->radioResourceConfigCommon,
2671
                         (struct PhysicalConfigDedicated *)NULL,
2672
#ifdef Rel10
2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684
                         (SCellToAddMod_r10_t *)NULL,
                         //(struct PhysicalConfigDedicatedSCell_r10 *)NULL,
#endif
                         (MeasObjectToAddMod_t **)NULL,
                         (MAC_MainConfig_t *)NULL,
                         0,
                         (struct LogicalChannelConfig *)NULL,
                         (MeasGapConfig_t *)NULL,
                         (TDD_Config_t *)NULL,
                         (MobilityControlInfo_t *)NULL,
                         NULL,
                         NULL,
2685 2686 2687 2688
                         UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->freqInfo.ul_CarrierFreq,
                         UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->freqInfo.ul_Bandwidth,
                         &UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->freqInfo.additionalSpectrumEmission,
                         UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->mbsfn_SubframeConfigList
winckel's avatar
winckel committed
2689
#ifdef Rel10
2690 2691 2692
                         ,0,
                         (MBSFN_AreaInfoList_r9_t *)NULL,
                         (PMCH_InfoList_r9_t *)NULL
2693 2694
#endif
#ifdef CBA
2695 2696
                         ,0,
                         0
2697
#endif
2698
                        );
2699
      UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus = 1;
2700
      // After SI is received, prepare RRCConnectionRequest
2701
#ifdef Rel10
2702

2703
      if (UE_rrc_inst[ctxt_pP->module_id].MBMS_flag < 3) // see -Q option
2704
#endif
winckel's avatar
winckel committed
2705
#if !(defined(ENABLE_ITTI) && defined(ENABLE_USE_MME))
2706
        rrc_ue_generate_RRCConnectionRequest(ctxt_pP,eNB_index);
2707 2708

      LOG_I(RRC, "not sending connection request\n");
winckel's avatar
winckel committed
2709
#endif
2710

2711 2712 2713
      if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State == RRC_IDLE) {
        LOG_I(RRC,"[UE %d] Received SIB1/SIB2/SIB3 Switching to RRC_SI_RECEIVED\n",ctxt_pP->module_id);
        UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State = RRC_SI_RECEIVED;
2714
#ifdef ENABLE_RAL
2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735
        {
          MessageDef                            *message_ral_p = NULL;
          rrc_ral_system_information_ind_t       ral_si_ind;

          message_ral_p = itti_alloc_new_message (TASK_RRC_UE, RRC_RAL_SYSTEM_INFORMATION_IND);
          memset(&ral_si_ind, 0, sizeof(rrc_ral_system_information_ind_t));
          ral_si_ind.plmn_id.MCCdigit2 = '0';
          ral_si_ind.plmn_id.MCCdigit1 = '2';
          ral_si_ind.plmn_id.MNCdigit3 = '0';
          ral_si_ind.plmn_id.MCCdigit3 = '8';
          ral_si_ind.plmn_id.MNCdigit2 = '9';
          ral_si_ind.plmn_id.MNCdigit1 = '9';
          ral_si_ind.cell_id        = 1;
          ral_si_ind.dbm            = 0;
          //ral_si_ind.dbm            = fifo_dump_emos_UE.PHY_measurements->rx_rssi_dBm[eNB_index];
          // TO DO
          ral_si_ind.sinr           = 0;
          //ral_si_ind.sinr           = fifo_dump_emos_UE.PHY_measurements->subband_cqi_dB[eNB_index][phy_vars_ue->lte_frame_parms.nb_antennas_rx][0];
          // TO DO
          ral_si_ind.link_data_rate = 0;
          memcpy (&message_ral_p->ittiMsg, (void *) &ral_si_ind, sizeof(rrc_ral_system_information_ind_t));
Lionel Gauthier's avatar
 
Lionel Gauthier committed
2736
#warning "ue_mod_idP ? for instance ?"
2737
          itti_send_msg_to_task (TASK_RAL_UE, UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), message_ral_p);
2738
        }
2739 2740
#endif
      }
2741

2742 2743 2744
      break;

    case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib3:
2745 2746 2747 2748 2749
      UE_rrc_inst[ctxt_pP->module_id].sib3[eNB_index] = &typeandinfo->choice.sib3;
      LOG_I(RRC,"[UE %d] Frame %d Found SIB3 from eNB %d\n",ctxt_pP->module_id,ctxt_pP->frame,eNB_index);
      dump_sib3(UE_rrc_inst[ctxt_pP->module_id].sib3[eNB_index]);
      UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus = 1;
      rrc_set_sub_state (ctxt_pP->module_id, RRC_SUB_STATE_IDLE_SIB_COMPLETE);
2750 2751 2752
      break;

    case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib4:
2753 2754
      UE_rrc_inst[ctxt_pP->module_id].sib4[eNB_index] = &typeandinfo->choice.sib4;
      LOG_I(RRC,"[UE %d] Frame %d Found SIB4 from eNB %d\n",ctxt_pP->module_id,ctxt_pP->frame,eNB_index);
2755 2756 2757
      break;

    case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib5:
2758 2759
      UE_rrc_inst[ctxt_pP->module_id].sib5[eNB_index] = &typeandinfo->choice.sib5;
      LOG_I(RRC,"[UE %d] Found SIB5 from eNB %d\n",ctxt_pP->module_id,eNB_index);
2760 2761 2762
      break;

    case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib6:
2763 2764
      UE_rrc_inst[ctxt_pP->module_id].sib6[eNB_index] = &typeandinfo->choice.sib6;
      LOG_I(RRC,"[UE %d] Found SIB6 from eNB %d\n",ctxt_pP->module_id,eNB_index);
2765 2766 2767
      break;

    case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib7:
2768 2769
      UE_rrc_inst[ctxt_pP->module_id].sib7[eNB_index] = &typeandinfo->choice.sib7;
      LOG_I(RRC,"[UE %d] Found SIB7 from eNB %d\n",ctxt_pP->module_id,eNB_index);
2770 2771 2772
      break;

    case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib8:
2773 2774
      UE_rrc_inst[ctxt_pP->module_id].sib8[eNB_index] = &typeandinfo->choice.sib8;
      LOG_I(RRC,"[UE %d] Found SIB8 from eNB %d\n",ctxt_pP->module_id,eNB_index);
2775 2776 2777
      break;

    case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib9:
2778 2779
      UE_rrc_inst[ctxt_pP->module_id].sib9[eNB_index] = &typeandinfo->choice.sib9;
      LOG_I(RRC,"[UE %d] Found SIB9 from eNB %d\n",ctxt_pP->module_id,eNB_index);
2780 2781 2782
      break;

    case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib10:
2783 2784
      UE_rrc_inst[ctxt_pP->module_id].sib10[eNB_index] = &typeandinfo->choice.sib10;
      LOG_I(RRC,"[UE %d] Found SIB10 from eNB %d\n",ctxt_pP->module_id,eNB_index);
2785 2786 2787
      break;

    case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib11:
2788 2789
      UE_rrc_inst[ctxt_pP->module_id].sib11[eNB_index] = &typeandinfo->choice.sib11;
      LOG_I(RRC,"[UE %d] Found SIB11 from eNB %d\n",ctxt_pP->module_id,eNB_index);
2790
      break;
2791
#ifdef Rel10
2792 2793

    case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib12_v920:
2794 2795
      UE_rrc_inst[ctxt_pP->module_id].sib12[eNB_index] = &typeandinfo->choice.sib12_v920;
      LOG_I(RRC,"[RRC][UE %d] Found SIB12 from eNB %d\n",ctxt_pP->module_id,eNB_index);
2796 2797 2798
      break;

    case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920:
2799 2800 2801
      UE_rrc_inst[ctxt_pP->module_id].sib13[eNB_index] = &typeandinfo->choice.sib13_v920;
      LOG_I(RRC,"[RRC][UE %d] Found SIB13 from eNB %d\n",ctxt_pP->module_id,eNB_index);
      dump_sib13(UE_rrc_inst[ctxt_pP->module_id].sib13[eNB_index]);
2802 2803
      // adding here function to store necessary parameters for using in decode_MCCH_Message + maybe transfer to PHY layer
      LOG_D(RRC, "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SIB13 params eNB %d) --->][MAC_UE][MOD %02d][]\n",
2804 2805
            ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id);
      rrc_mac_config_req(ctxt_pP->module_id,ENB_FLAG_NO,0,eNB_index,
2806 2807
                         (RadioResourceConfigCommonSIB_t *)NULL,
                         (struct PhysicalConfigDedicated *)NULL,
2808
#ifdef Rel10
2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825
                         (SCellToAddMod_r10_t *)NULL,
                         //(struct PhysicalConfigDedicatedSCell_r10 *)NULL,
#endif
                         (MeasObjectToAddMod_t **)NULL,
                         (MAC_MainConfig_t *)NULL,
                         0,
                         (struct LogicalChannelConfig *)NULL,
                         (MeasGapConfig_t *)NULL,
                         (TDD_Config_t *)NULL,
                         (MobilityControlInfo_t *)NULL,
                         NULL,
                         NULL,
                         NULL,
                         NULL,
                         NULL,
                         (MBSFN_SubframeConfigList_t *)NULL
                         ,0,
2826
                         &UE_rrc_inst[ctxt_pP->module_id].sib13[eNB_index]->mbsfn_AreaInfoList_r9,
2827
                         (PMCH_InfoList_r9_t *)NULL
2828
#ifdef CBA
2829 2830
                         ,0,
                         0
2831
#endif
2832
                        );
2833
      UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus = 1;
2834
      break;
2835
#endif
2836 2837 2838 2839

    default:
      break;
    }
2840 2841 2842

  }

2843
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI  , VCD_FUNCTION_OUT);
2844 2845 2846
  return 0;
}

2847
// layer 3 filtering of RSRP (EUTRA) measurements: 36.331, Sec. 5.5.3.2
2848
//-----------------------------------------------------------------------------
2849 2850
void
ue_meas_filtering(
2851 2852
  const protocol_ctxt_t* const ctxt_pP,
  const uint8_t                eNB_index
2853
)
2854
//-----------------------------------------------------------------------------
2855
{
2856 2857
  float a  = UE_rrc_inst[ctxt_pP->module_id].filter_coeff_rsrp; // 'a' in 36.331 Sec. 5.5.3.2
  float a1 = UE_rrc_inst[ctxt_pP->module_id].filter_coeff_rsrq;
2858
  //float rsrp_db, rsrq_db;
2859
  uint8_t    eNB_offset;
2860

2861 2862 2863 2864
  if(UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[0] != NULL) { // Only consider 1 serving cell (index: 0)
    if (UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[0]->quantityConfigEUTRA != NULL) {
      if(UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[0]->quantityConfigEUTRA->filterCoefficientRSRP != NULL) {
        for (eNB_offset = 0; eNB_offset<1+mac_xface->get_n_adj_cells(ctxt_pP->module_id,0); eNB_offset++) {
2865 2866 2867
          //filter_factor = 1/power(2,*UE_rrc_inst[ue_mod_idP].QuantityConfig[0]->quantityConfigEUTRA->filterCoefficientRSRP/4);
          // LOG_N(RRC,"[UE %d] Frame %d : check proper operation in abstraction mode rsrp (%d), rx gain (%d) N_RB_DL (%d)\n",
          //  ue_mod_idP,frameP,mac_xface->get_RSRP(ue_mod_idP,0,eNB_offset),mac_xface->get_rx_total_gain_dB(ue_mod_idP,0),mac_xface->lte_frame_parms->N_RB_DL);
2868 2869 2870 2871 2872 2873 2874
          UE_rrc_inst[ctxt_pP->module_id].rsrp_db[eNB_offset] =
            (dB_fixed_times10(mac_xface->get_RSRP(ctxt_pP->module_id,0,eNB_offset))/10.0) -
            mac_xface->get_rx_total_gain_dB(ctxt_pP->module_id,0) -
            dB_fixed(mac_xface->lte_frame_parms->N_RB_DL*12);
          UE_rrc_inst[ctxt_pP->module_id].rsrp_db_filtered[eNB_offset] =
            (1.0-a)*UE_rrc_inst[ctxt_pP->module_id].rsrp_db_filtered[eNB_offset] +
            a*UE_rrc_inst[ctxt_pP->module_id].rsrp_db[eNB_offset];
2875 2876 2877 2878 2879
          //mac_xface->set_RSRP_filtered(ue_mod_idP,eNB_offset,UE_rrc_inst[ue_mod_idP].rsrp_db_filtered[eNB_offset]);


          //LOG_D(RRC,"RSRP_total_dB: %3.2f \n",(dB_fixed_times10(mac_xface->get_RSRP(ue_mod_idP,0,eNB_offset))/10.0)-mac_xface->get_rx_total_gain_dB(ue_mod_idP,0)-dB_fixed(mac_xface->lte_frame_parms->N_RB_DL*12));

2880 2881
          LOG_D(RRC,"RSRP_dBm: %3.2f \n",(dB_fixed_times10(mac_xface->get_RSRP(ctxt_pP->module_id,0,eNB_offset))/10.0));
          LOG_D(RRC,"gain_loss_dB: %d \n",mac_xface->get_rx_total_gain_dB(ctxt_pP->module_id,0));
2882 2883
          LOG_D(RRC,"gain_fixed_dB: %d \n",dB_fixed(mac_xface->lte_frame_parms->N_RB_DL*12));
          LOG_D(PHY,"[UE %d] Frame %d, RRC Measurements => rssi %3.1f dBm (digital: %3.1f dB)\n",
2884 2885 2886 2887
                ctxt_pP->module_id,
                ctxt_pP->frame,
                10*log10(mac_xface->get_RSSI(ctxt_pP->module_id,0))-mac_xface->get_rx_total_gain_dB(ctxt_pP->module_id,0),
                10*log10(mac_xface->get_RSSI(ctxt_pP->module_id,0)));
2888
          LOG_D(RRC,"[UE %d] Frame %d: Meas RSRP: eNB_offset: %d rsrp_coef: %3.1f filter_coef: %d before L3 filtering: rsrp: %3.1f after L3 filtering: rsrp: %3.1f \n ",
2889 2890
                ctxt_pP->module_id,
                ctxt_pP->frame, eNB_offset,a,
2891
                *UE_rrc_inst->QuantityConfig[0]->quantityConfigEUTRA->filterCoefficientRSRP,
2892 2893
                UE_rrc_inst[ctxt_pP->module_id].rsrp_db[eNB_offset],
                UE_rrc_inst[ctxt_pP->module_id].rsrp_db_filtered[eNB_offset]);
2894
        }
2895
      }
2896
    } else {
2897 2898
      for (eNB_offset = 0; eNB_offset<1+mac_xface->get_n_adj_cells(ctxt_pP->module_id,0); eNB_offset++) {
        UE_rrc_inst[ctxt_pP->module_id].rsrp_db_filtered[eNB_offset]= mac_xface->get_RSRP(ctxt_pP->module_id,0,eNB_offset);
2899 2900
        // phy_vars_ue->PHY_measurements.rsrp_filtered[eNB_offset]=UE_rrc_inst[ue_mod_idP].rsrp_db_filtered[eNB_offset];
        //mac_xface->set_RSRP_filtered(ue_mod_idP,eNB_offset,UE_rrc_inst[ue_mod_idP].rsrp_db_filtered[eNB_offset]);
2901
      }
2902 2903
    }

2904 2905 2906
    if (UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[0]->quantityConfigEUTRA != NULL) {
      if(UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[0]->quantityConfigEUTRA->filterCoefficientRSRQ != NULL) {
        for (eNB_offset = 0; eNB_offset<1+mac_xface->get_n_adj_cells(ctxt_pP->module_id,0); eNB_offset++) {
2907
          // LOG_N(RRC,"[UE %d] Frame %d : check if this operation workes properly in abstraction mode\n",ue_mod_idP,frameP);
2908 2909 2910
          UE_rrc_inst[ctxt_pP->module_id].rsrq_db[eNB_offset] = (10*log10(mac_xface->get_RSRQ(ctxt_pP->module_id,0,eNB_offset)))-20;
          UE_rrc_inst[ctxt_pP->module_id].rsrq_db_filtered[eNB_offset]=(1-a1)*UE_rrc_inst[ctxt_pP->module_id].rsrq_db_filtered[eNB_offset] +
              a1 *UE_rrc_inst[ctxt_pP->module_id].rsrq_db[eNB_offset];
2911 2912
          //mac_xface->set_RSRP_filtered(ue_mod_idP,eNB_offset,UE_rrc_inst[ue_mod_idP].rsrp_db_filtered[eNB_offset]);
          /*
2913
          LOG_D(RRC,"[UE %d] Frame %d: Meas RSRQ: eNB_offset: %d rsrq_coef: %3.2f filter_coef: %d before L3 filtering: rsrq: %3.1f after L3 filtering: rsrq: %3.1f \n ",
2914 2915 2916 2917 2918 2919 2920
          ue_mod_idP,frameP,eNB_offset,a1,
           *UE_rrc_inst->QuantityConfig[0]->quantityConfigEUTRA->filterCoefficientRSRQ,
          mac_xface->get_RSRQ(ue_mod_idP,0,eNB_offset),
          UE_rrc_inst[ue_mod_idP].rsrq_db[eNB_offset],
          UE_rrc_inst[ue_mod_idP].rsrq_db_filtered[eNB_offset]);
           */
        }
2921
      }
2922
    } else {
2923 2924
      for (eNB_offset = 0; eNB_offset<1+mac_xface->get_n_adj_cells(ctxt_pP->module_id,0); eNB_offset++) {
        UE_rrc_inst[ctxt_pP->module_id].rsrq_db_filtered[eNB_offset]= mac_xface->get_RSRQ(ctxt_pP->module_id,0,eNB_offset);
2925
      }
2926
    }
2927 2928 2929
  }
}

2930
//Below routine implements Measurement Reporting procedure from 36.331 Section 5.5.5
2931
//-----------------------------------------------------------------------------
2932 2933
void
rrc_ue_generate_MeasurementReport(
2934 2935
  const protocol_ctxt_t* const ctxt_pP,
  uint8_t                      eNB_index
2936
)
2937
//-----------------------------------------------------------------------------
2938
{
2939 2940 2941 2942 2943 2944

  uint8_t             buffer[32], size;
  uint8_t             i;
  uint8_t             target_eNB_offset;
  MeasId_t         measId;
  PhysCellId_t     cellId, targetCellId;
2945 2946 2947
  long             rsrp_t,rsrq_t;
  long             rsrp_s,rsrq_s;
  long             nElem, nElem1;
2948 2949 2950
  float            rsrp_filtered, rsrq_filtered;
  static frame_t   pframe=0;
  int              result;
2951 2952 2953

  nElem = 98;
  nElem1 = 35;
2954
  target_eNB_offset = UE_rrc_inst[ctxt_pP->module_id].Info[0].handoverTarget; // eNB_offset of target eNB: used to obtain the mod_id of target eNB
2955

2956
  for (i=0; i<MAX_MEAS_ID; i++) {
2957 2958
    if (UE_rrc_inst[ctxt_pP->module_id].measReportList[0][i] != NULL) {
      measId = UE_rrc_inst[ctxt_pP->module_id].measReportList[0][i]->measId;
2959 2960

      // Note: Values in the meas report have to be the mapped values...to implement binary search for LUT
2961
      rsrp_filtered = UE_rrc_inst[ctxt_pP->module_id].rsrp_db_filtered[eNB_index];//nid_cell];
2962 2963
      rsrp_s = binary_search_float(RSRP_meas_mapping,nElem, rsrp_filtered);

2964
      rsrq_filtered = UE_rrc_inst[ctxt_pP->module_id].rsrq_db_filtered[eNB_index];//nid_cell]; //RSRQ of serving cell
2965 2966 2967
      rsrq_s = binary_search_float(RSRQ_meas_mapping,nElem1,rsrq_filtered);//mapped RSRQ of serving cell

      LOG_D(RRC,"[UE %d] Frame %d: source eNB %d :rsrp_s: %ld rsrq_s: %ld rsrp_filtered: %f rsrq_filtered: %f \n",
2968 2969 2970 2971 2972 2973 2974 2975 2976
            ctxt_pP->module_id,
            ctxt_pP->frame,
            eNB_index,
            rsrp_s,
            rsrq_s,
            rsrp_filtered,
            rsrq_filtered);
      rsrp_t = binary_search_float(RSRP_meas_mapping,nElem,UE_rrc_inst[ctxt_pP->module_id].rsrp_db_filtered[target_eNB_offset]); //RSRP of target cell
      rsrq_t = binary_search_float(RSRQ_meas_mapping,nElem1,UE_rrc_inst[ctxt_pP->module_id].rsrq_db_filtered[target_eNB_offset]); //RSRQ of target cell
2977 2978

      LOG_D(RRC,"[UE %d] Frame %d: target eNB %d :rsrp_t: %ld rsrq_t: %ld rsrp_filtered: %f rsrq_filtered: %f \n",
2979 2980 2981 2982 2983 2984 2985
            ctxt_pP->module_id,
            ctxt_pP->frame,
            target_eNB_offset,
            rsrp_t,
            rsrq_t,
            UE_rrc_inst[ctxt_pP->module_id].rsrp_db_filtered[target_eNB_offset],
            UE_rrc_inst[ctxt_pP->module_id].rsrq_db_filtered[target_eNB_offset]);
2986 2987

      //  if (measFlag == 1) {
2988 2989
      cellId = get_adjacent_cell_id(ctxt_pP->module_id, eNB_index); //PhycellId of serving cell
      targetCellId = UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.targetCellId ;//get_adjacent_cell_id(ue_mod_idP,target_eNB_offset); //PhycellId of target cell
2990

2991 2992
      if (pframe!=ctxt_pP->frame) {
        pframe=ctxt_pP->frame;
2993
        LOG_D(RRC, "[UE %d] Frame %d: doing MeasReport: servingCell(%d) targetCell(%d) rsrp_s(%ld) rsrq_s(%ld) rsrp_t(%ld) rsrq_t(%ld) \n",
2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005
              ctxt_pP->module_id,
              ctxt_pP->frame,
              cellId,
              targetCellId,
              rsrp_s,
              rsrq_s,
              rsrp_t,
              rsrq_t);
        size = do_MeasurementReport(ctxt_pP->module_id, buffer,measId,targetCellId,rsrp_s,rsrq_s,rsrp_t,rsrq_t);
        LOG_I(RRC, "[UE %d] Frame %d : Generating Measurement Report for eNB %d\n",
              ctxt_pP->module_id, ctxt_pP->frame, eNB_index);
        result = pdcp_data_req(ctxt_pP,  SRB_FLAG_YES, DCCH, rrc_mui++, 0, size, buffer, PDCP_TRANSMISSION_MODE_DATA);
3006 3007
        AssertFatal (result == TRUE, "PDCP data request failed!\n");
        //LOG_D(RRC, "[UE %d] Frame %d Sending MeasReport (%d bytes) through DCCH%d to PDCP \n",ue_mod_idP,frameP, size, DCCH);
3008
      }
3009 3010 3011 3012

      //          measFlag = 0; //re-setting measFlag so that no more MeasReports are sent in this frameP
      //          }
    }
3013 3014 3015
  }
}

3016
// Measurement report triggering, described in 36.331 Section 5.5.4.1: called periodically
3017
//-----------------------------------------------------------------------------
3018 3019
void
ue_measurement_report_triggering(
3020 3021
  const protocol_ctxt_t* const ctxt_pP,
  const uint8_t                 eNB_index
3022
)
3023
//-----------------------------------------------------------------------------
3024
{
3025
  uint8_t               i,j;
3026 3027 3028 3029 3030 3031 3032 3033
  Hysteresis_t     hys;
  TimeToTrigger_t  ttt_ms;
  Q_OffsetRange_t  ofn;
  Q_OffsetRange_t  ocn;
  Q_OffsetRange_t  ofs = 0;
  Q_OffsetRange_t  ocs = 0;
  long             a3_offset;
  MeasObjectId_t   measObjId;
3034
  ReportConfigId_t reportConfigId;
3035

3036
  for(i=0 ; i<NB_CNX_UE ; i++) {
3037
    for(j=0 ; j<MAX_MEAS_ID ; j++) {
3038 3039 3040
      if(UE_rrc_inst[ctxt_pP->module_id].MeasId[i][j] != NULL) {
        measObjId = UE_rrc_inst[ctxt_pP->module_id].MeasId[i][j]->measObjectId;
        reportConfigId = UE_rrc_inst[ctxt_pP->module_id].MeasId[i][j]->reportConfigId;
3041

3042 3043
        if( /*UE_rrc_inst[ctxt_pP->module_id].MeasId[i][j] != NULL && */ UE_rrc_inst[ctxt_pP->module_id].MeasObj[i][measObjId-1] != NULL) {
          if(UE_rrc_inst[ctxt_pP->module_id].MeasObj[i][measObjId-1]->measObject.present == MeasObjectToAddMod__measObject_PR_measObjectEUTRA) {
3044 3045 3046
            /* consider any neighboring cell detected on the associated frequency to be
             * applicable when the concerned cell is not included in the blackCellsToAddModList
             * defined within the VarMeasConfig for this measId */
3047 3048 3049 3050 3051 3052 3053 3054 3055
            //    LOG_I(RRC,"event %d %d %p \n", measObjId,reportConfigId, UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1]);
            if((UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1] != NULL) &&
                (UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1]->reportConfig.present==ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA) &&
                (UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.present ==
                 ReportConfigEUTRA__triggerType_PR_event)) {
              hys = UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis;
              //LOG_N(RRC,"[UE%d] Frame %d Check below lines for segfault :), Fix me \n",ctxt_pP->module_id, frameP);
              ttt_ms = timeToTrigger_ms[UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId
                                        -1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger];
3056
              // Freq specific offset of neighbor cell freq
3057 3058
              ofn = 5;//((UE_rrc_inst[ctxt_pP->module_id].MeasObj[i][measObjId-1]->measObject.choice.measObjectEUTRA.offsetFreq != NULL) ?
              // *UE_rrc_inst[ctxt_pP->module_id].MeasObj[i][measObjId-1]->measObject.choice.measObjectEUTRA.offsetFreq : 15); //  /* 15 is the Default */
3059 3060
              // cellIndividualOffset of neighbor cell - not defined yet
              ocn = 0;
3061 3062
              a3_offset = UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId
                          -1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset;
3063

3064
              switch (UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present) {
3065
              case ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1:
3066 3067
                LOG_D(RRC,"[UE %d] Frame %d : A1 event: check if serving becomes better than threshold\n",
                      ctxt_pP->module_id, ctxt_pP->frame);
3068 3069 3070
                break;

              case ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2:
3071 3072
                LOG_D(RRC,"[UE %d] Frame %d : A2 event, check if serving becomes worse than a threshold\n",
                      ctxt_pP->module_id, ctxt_pP->frame);
3073 3074 3075
                break;

              case ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3:
3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086
                LOG_D(RRC,"[UE %d] Frame %d : A3 event: check if a neighboring cell becomes offset better than serving to trigger a measurement event \n",
                      ctxt_pP->module_id, ctxt_pP->frame);

                if ((check_trigger_meas_event(
                       ctxt_pP->module_id,
                       ctxt_pP->frame,
                       eNB_index,
                       i,j,ofn,ocn,hys,ofs,ocs,a3_offset,ttt_ms)) &&
                    (UE_rrc_inst[ctxt_pP->module_id].Info[0].State >= RRC_CONNECTED) &&
                    (UE_rrc_inst[ctxt_pP->module_id].Info[0].T304_active == 0 )      &&
                    (UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.measFlag == 1)) {
3087
                  //trigger measurement reporting procedure (36.331, section 5.5.5)
3088 3089
                  if (UE_rrc_inst[ctxt_pP->module_id].measReportList[i][j] == NULL) {
                    UE_rrc_inst[ctxt_pP->module_id].measReportList[i][j] = malloc(sizeof(MEAS_REPORT_LIST));
3090 3091
                  }

3092 3093 3094 3095 3096 3097 3098 3099
                  UE_rrc_inst[ctxt_pP->module_id].measReportList[i][j]->measId = UE_rrc_inst[ctxt_pP->module_id].MeasId[i][j]->measId;
                  UE_rrc_inst[ctxt_pP->module_id].measReportList[i][j]->numberOfReportsSent = 0;
                  rrc_ue_generate_MeasurementReport(
                    ctxt_pP,
                    eNB_index);
                  UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.measFlag = 1;
                  LOG_I(RRC,"[UE %d] Frame %d: A3 event detected, state: %d \n",
                        ctxt_pP->module_id, ctxt_pP->frame, UE_rrc_inst[ctxt_pP->module_id].Info[0].State);
3100
                } else {
3101 3102
                  if(UE_rrc_inst[ctxt_pP->module_id].measReportList[i][j] != NULL) {
                    free(UE_rrc_inst[ctxt_pP->module_id].measReportList[i][j]);
3103
                  }
3104

3105
                  UE_rrc_inst[ctxt_pP->module_id].measReportList[i][j] = NULL;
3106 3107 3108 3109 3110
                }

                break;

              case ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4:
3111 3112
                LOG_D(RRC,"[UE %d] Frame %d : received an A4 event, neighbor becomes offset better than a threshold\n",
                      ctxt_pP->module_id, ctxt_pP->frame);
3113 3114 3115
                break;

              case ReportConfigEUTRA__triggerType__event__eventId_PR_eventA5:
3116 3117
                LOG_D(RRC,"[UE %d] Frame %d: received an A5 event, serving becomes worse than threshold 1 and neighbor becomes better than threshold 2\n",
                      ctxt_pP->module_id, ctxt_pP->frame);
3118 3119 3120 3121
                break;

              default:
                LOG_D(RRC,"Invalid ReportConfigEUTRA__triggerType__event__eventId: %d",
3122
                      UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][j]->reportConfig.choice.reportConfigEUTRA.triggerType.present);
3123
                break;
winckel's avatar
winckel committed
3124
              }
3125
            }
winckel's avatar
winckel committed
3126
          }
3127
        }
3128
      }
3129
    }
3130 3131 3132
  }
}

Lionel Gauthier's avatar
 
Lionel Gauthier committed
3133
//check_trigger_meas_event(ue_mod_idP, frameP, eNB_index, i,j,ofn,ocn,hys,ofs,ocs,a3_offset,ttt_ms)
3134
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
3135 3136
uint8_t
check_trigger_meas_event(
3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149
  module_id_t     ue_mod_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
)
3150
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
3151
{
3152 3153
  uint8_t eNB_offset;
  uint8_t currentCellIndex = mac_xface->lte_frame_parms->Nid_cell;
3154
  uint8_t tmp_offset;
Lionel Gauthier's avatar
Lionel Gauthier committed
3155

3156
  LOG_I(RRC,"[UE %d] ofn(%d) ocn(%d) hys(%d) ofs(%d) ocs(%d) a3_offset(%d) ttt(%d) rssi %3.1f\n",
3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186
        ue_mod_idP,
        ofn,ocn,hys,ofs,ocs,a3_offset,ttt,
        10*log10(mac_xface->get_RSSI(ue_mod_idP,0))-mac_xface->get_rx_total_gain_dB(ue_mod_idP,0));

  for (eNB_offset = 0; eNB_offset<1+mac_xface->get_n_adj_cells(ue_mod_idP,0); eNB_offset++) {
    //for (eNB_offset = 1;(eNB_offset<1+mac_xface->get_n_adj_cells(ue_mod_idP,0));eNB_offset++) {
    /* RHS: Verify that idx 0 corresponds to currentCellIndex in rsrp array */
    if((eNB_offset!=eNB_index)&&(eNB_offset<NB_eNB_INST)) {
      if(eNB_offset<eNB_index) {
        tmp_offset = eNB_offset;
      } else {
        tmp_offset = eNB_offset-1;
      }

      if(UE_rrc_inst[ue_mod_idP].rsrp_db_filtered[eNB_offset]+ofn+ocn-hys > UE_rrc_inst[ue_mod_idP].rsrp_db_filtered[eNB_index]+ofs+ocs-1/*+a3_offset*/) {
        UE_rrc_inst->measTimer[ue_cnx_index][meas_index][tmp_offset] += 2; //Called every subframe = 2ms
        LOG_D(RRC,"[UE %d] Frame %d: Entry measTimer[%d][%d][%d]: %d currentCell: %d betterCell: %d \n",
              ue_mod_idP, frameP, ue_cnx_index,meas_index,tmp_offset,UE_rrc_inst->measTimer[ue_cnx_index][meas_index][tmp_offset],currentCellIndex,eNB_offset);
      } else {
        UE_rrc_inst->measTimer[ue_cnx_index][meas_index][tmp_offset] = 0; //Exit condition: Resetting the measurement timer
        LOG_D(RRC,"[UE %d] Frame %d: Exit measTimer[%d][%d][%d]: %d currentCell: %d betterCell: %d \n",
              ue_mod_idP, frameP, ue_cnx_index,meas_index,tmp_offset,UE_rrc_inst->measTimer[ue_cnx_index][meas_index][tmp_offset],currentCellIndex,eNB_offset);
      }

      if (UE_rrc_inst->measTimer[ue_cnx_index][meas_index][tmp_offset] >= ttt) {
        UE_rrc_inst->HandoverInfoUe.targetCellId = get_adjacent_cell_id(ue_mod_idP,tmp_offset); //WARNING!!!...check this!
        LOG_D(RRC,"[UE %d] Frame %d eNB %d: Handover triggered: targetCellId: %d currentCellId: %d eNB_offset: %d rsrp source: %3.1f rsrp target: %3.1f\n", \
              ue_mod_idP, frameP, eNB_index,
              UE_rrc_inst->HandoverInfoUe.targetCellId,ue_cnx_index,eNB_offset,
              (dB_fixed_times10(UE_rrc_inst[ue_mod_idP].rsrp_db[0])/10.0)-mac_xface->get_rx_total_gain_dB(ue_mod_idP,0)-dB_fixed(mac_xface->lte_frame_parms->N_RB_DL*12),
3187 3188
              (dB_fixed_times10(UE_rrc_inst[ue_mod_idP].rsrp_db[eNB_offset])/10.0)-mac_xface->get_rx_total_gain_dB(ue_mod_idP,
                  0)-dB_fixed(mac_xface->lte_frame_parms->N_RB_DL*12));
3189 3190 3191 3192 3193 3194 3195 3196 3197
        UE_rrc_inst->Info[0].handoverTarget = eNB_offset;
        //LOG_D(RRC,"PHY_ID: %d \n",UE_rrc_inst->HandoverInfoUe.targetCellId);
        return 1;
      }

      // else{
      //  LOG_D(RRC,"Condition does not hold\n");
      // }
    }
3198
  }
3199

3200 3201 3202
  return 0;
}

3203
#ifdef Rel10
3204
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
3205 3206
int
decode_MCCH_Message(
3207 3208 3209 3210 3211
  const protocol_ctxt_t* const ctxt_pP,
  const uint8_t                eNB_index,
  const uint8_t*         const Sdu,
  const uint8_t                Sdu_len,
  const uint8_t                mbsfn_sync_area
3212
)
3213
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
3214
{
3215

Lionel Gauthier's avatar
Lionel Gauthier committed
3216
  MCCH_Message_t               *mcch=NULL;
3217
  MBSFNAreaConfiguration_r9_t** mcch_message=&UE_rrc_inst[ctxt_pP->module_id].mcch_message[eNB_index];
3218

Lionel Gauthier's avatar
Lionel Gauthier committed
3219
  asn_dec_rval_t                dec_rval;
3220

3221
  if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].MCCHStatus[mbsfn_sync_area] == 1) {
3222
    LOG_D(RRC,"[UE %d] Frame %d: MCCH MESSAGE for MBSFN sync area %d has been already received!\n",
3223 3224 3225
          ctxt_pP->module_id,
          ctxt_pP->frame,
          mbsfn_sync_area);
3226 3227 3228 3229 3230 3231 3232 3233 3234
    return 0; // avoid decoding to prevent memory bloating
  } else {
    dec_rval = uper_decode_complete(NULL,
                                    &asn_DEF_MCCH_Message,
                                    (void **)&mcch,
                                    (const void *)Sdu,
                                    Sdu_len);

    if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) {
3235 3236 3237
      LOG_E(RRC,"[UE %d] Failed to decode MCCH__MESSAGE (%d bits)\n",
            ctxt_pP->module_id,
            dec_rval.consumed);
3238 3239 3240 3241 3242
      //free the memory
      SEQUENCE_free(&asn_DEF_MCCH_Message, (void*)mcch, 1);
      return -1;
    }

3243
#ifdef XER_PRINT
3244
    xer_fprint(stdout, &asn_DEF_MCCH_Message, (void*)mcch);
3245 3246
#endif

3247
    if (mcch->message.present == MCCH_MessageType_PR_c1) {
3248 3249
      LOG_D(RRC,"[UE %d] Found mcch message \n",
            ctxt_pP->module_id);
3250 3251 3252

      if(mcch->message.choice.c1.present == MCCH_MessageType__c1_PR_mbsfnAreaConfiguration_r9) {
        /*
winckel's avatar
winckel committed
3253
        memcpy((void*)*mcch_message,
3254 3255 3256
         (void*)&mcch->message.choice.c1.choice.mbsfnAreaConfiguration_r9,
         sizeof(MBSFNAreaConfiguration_r9_t)); */
        *mcch_message = &mcch->message.choice.c1.choice.mbsfnAreaConfiguration_r9;
3257 3258 3259 3260 3261 3262 3263 3264 3265
        LOG_I(RRC,"[UE %d] Frame %d : Found MBSFNAreaConfiguration from eNB %d \n",
              ctxt_pP->module_id,
              ctxt_pP->frame,
              eNB_index);
        decode_MBSFNAreaConfiguration(
          ctxt_pP->module_id,
          eNB_index,
          ctxt_pP->frame,
          mbsfn_sync_area);
3266 3267

      }
3268
    }
3269
  }
3270

3271 3272 3273
  return 0;
}

3274
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
3275 3276
void
decode_MBSFNAreaConfiguration(
3277 3278 3279 3280 3281
  module_id_t ue_mod_idP,
  uint8_t     eNB_index,
  frame_t     frameP,
  uint8_t     mbsfn_sync_area
)
3282
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
3283
{
3284
  protocol_ctxt_t               ctxt;
Lionel Gauthier's avatar
Lionel Gauthier committed
3285

3286 3287
  LOG_D(RRC,"[UE %d] Frame %d : Number of MCH(s) in the MBSFN Sync Area %d  is %d\n",
        ue_mod_idP, frameP, mbsfn_sync_area, UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->pmch_InfoList_r9.list.count);
3288
  //  store to MAC/PHY necessary parameters for receiving MTCHs
Lionel Gauthier's avatar
 
Lionel Gauthier committed
3289
  rrc_mac_config_req(ue_mod_idP,ENB_FLAG_NO,0,eNB_index,
3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308
                     (RadioResourceConfigCommonSIB_t *)NULL,
                     (struct PhysicalConfigDedicated *)NULL,
#ifdef Rel10
                     (SCellToAddMod_r10_t *)NULL,
                     //(struct PhysicalConfigDedicatedSCell_r10 *)NULL,
#endif
                     (MeasObjectToAddMod_t **)NULL,
                     (MAC_MainConfig_t *)NULL,
                     0,
                     (struct LogicalChannelConfig *)NULL,
                     (MeasGapConfig_t *)NULL,
                     (TDD_Config_t *)NULL,
                     (MobilityControlInfo_t *)NULL,
                     NULL,
                     NULL,
                     NULL,
                     NULL,
                     NULL,
                     (MBSFN_SubframeConfigList_t *)NULL
3309
#ifdef Rel10
3310 3311 3312 3313
                     ,
                     0,
                     (MBSFN_AreaInfoList_r9_t *)NULL,
                     &UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->pmch_InfoList_r9
3314 3315
#endif
#ifdef CBA
3316 3317 3318
                     ,
                     0,
                     0
3319
#endif
3320
                    );
3321

Lionel Gauthier's avatar
 
Lionel Gauthier committed
3322
  UE_rrc_inst[ue_mod_idP].Info[eNB_index].MCCHStatus[mbsfn_sync_area] = 1;
3323

3324
  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_idP, ENB_FLAG_NO, UE_rrc_inst[ue_mod_idP].Info[eNB_index].rnti, frameP, 0);
Lionel Gauthier's avatar
Lionel Gauthier committed
3325

3326
  // Config Radio Bearer for MBMS user data (similar way to configure for eNB side in init_MBMS function)
Lionel Gauthier's avatar
Lionel Gauthier committed
3327
  rrc_pdcp_config_asn1_req(&ctxt,
3328 3329 3330 3331 3332 3333 3334
                           NULL, // SRB_ToAddModList
                           NULL, // DRB_ToAddModList
                           (DRB_ToReleaseList_t*)NULL,
                           0, // security mode
                           NULL, // key rrc encryption
                           NULL, // key rrc integrity
                           NULL // key encryption
3335
#ifdef Rel10
3336
                           ,&(UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->pmch_InfoList_r9)
3337
#endif
3338
                          );
winckel's avatar
winckel committed
3339

Lionel Gauthier's avatar
Lionel Gauthier committed
3340
  rrc_rlc_config_asn1_req(&ctxt,
3341 3342 3343
                          NULL,// SRB_ToAddModList
                          NULL,// DRB_ToAddModList
                          NULL,// DRB_ToReleaseList
3344
#ifdef Rel10
3345 3346 3347
                          &(UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->pmch_InfoList_r9)
#endif
                         );
3348
  // */
3349

3350 3351 3352 3353 3354 3355 3356
}

#endif // rel10

#ifndef USER_MODE
EXPORT_SYMBOL(Rlc_info_am_config);
#endif
3357 3358

#if defined(ENABLE_ITTI)
3359
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
3360 3361
void
*rrc_ue_task(
3362 3363
  void *args_p
)
3364
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
3365
{
3366 3367 3368
  MessageDef   *msg_p;
  const char   *msg_name;
  instance_t    instance;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
3369
  unsigned int  ue_mod_id;
3370 3371
  int           result;
  SRB_INFO     *srb_info_p;
3372

3373
  protocol_ctxt_t  ctxt;
3374 3375 3376
  itti_mark_task_ready (TASK_RRC_UE);

  while(1) {
3377 3378
    // Wait for a message
    itti_receive_msg (TASK_RRC_UE, &msg_p);
3379

3380 3381
    msg_name = ITTI_MSG_NAME (msg_p);
    instance = ITTI_MSG_INSTANCE (msg_p);
3382
    ue_mod_id = UE_INSTANCE_TO_MODULE_ID(instance);
3383

3384 3385 3386 3387
    switch (ITTI_MSG_ID(msg_p)) {
    case TERMINATE_MESSAGE:
      itti_exit_task ();
      break;
3388

3389 3390 3391
    case MESSAGE_TEST:
      LOG_I(RRC, "[UE %d] Received %s\n", ue_mod_id, msg_name);
      break;
3392

3393 3394 3395
      /* MAC messages */
    case RRC_MAC_IN_SYNC_IND:
      LOG_D(RRC, "[UE %d] Received %s: frameP %d, eNB %d\n", ue_mod_id, msg_name,
3396
            RRC_MAC_IN_SYNC_IND (msg_p).frame, RRC_MAC_IN_SYNC_IND (msg_p).enb_index);
3397

3398
      UE_rrc_inst[ue_mod_id].Info[RRC_MAC_IN_SYNC_IND (msg_p).enb_index].N310_cnt = 0;
3399

3400
      if (UE_rrc_inst[ue_mod_id].Info[RRC_MAC_IN_SYNC_IND (msg_p).enb_index].T310_active == 1) {
3401
        UE_rrc_inst[ue_mod_id].Info[RRC_MAC_IN_SYNC_IND (msg_p).enb_index].N311_cnt++;
3402
      }
3403 3404 3405 3406 3407

      break;

    case RRC_MAC_OUT_OF_SYNC_IND:
      LOG_I(RRC, "[UE %d] Received %s: frameP %d, eNB %d\n", ue_mod_id, msg_name,
3408
            RRC_MAC_OUT_OF_SYNC_IND (msg_p).frame, RRC_MAC_OUT_OF_SYNC_IND (msg_p).enb_index);
3409

3410 3411
      UE_rrc_inst[ue_mod_id].Info[RRC_MAC_OUT_OF_SYNC_IND (msg_p).enb_index].N310_cnt ++;
      break;
3412

3413 3414
    case RRC_MAC_BCCH_DATA_IND:
      LOG_D(RRC, "[UE %d] Received %s: frameP %d, eNB %d\n", ue_mod_id, msg_name,
3415
            RRC_MAC_BCCH_DATA_IND (msg_p).frame, RRC_MAC_BCCH_DATA_IND (msg_p).enb_index);
3416

3417 3418 3419 3420
      PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_NO, NOT_A_RNTI, RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0);
      decode_BCCH_DLSCH_Message (&ctxt,
                                 RRC_MAC_BCCH_DATA_IND (msg_p).enb_index,
                                 RRC_MAC_BCCH_DATA_IND (msg_p).sdu,
3421
                                 RRC_MAC_BCCH_DATA_IND (msg_p).sdu_size,
3422 3423
                                 RRC_MAC_BCCH_DATA_IND (msg_p).rsrq,
                                 RRC_MAC_BCCH_DATA_IND (msg_p).rsrp);
3424
      break;
3425

3426 3427
    case RRC_MAC_CCCH_DATA_CNF:
      LOG_I(RRC, "[UE %d] Received %s: eNB %d\n", ue_mod_id, msg_name,
3428
            RRC_MAC_CCCH_DATA_CNF (msg_p).enb_index);
3429

3430 3431 3432
      // reset the tx buffer to indicate RRC that ccch was successfully transmitted (for example if contention resolution succeeds)
      UE_rrc_inst[ue_mod_id].Srb0[RRC_MAC_CCCH_DATA_CNF (msg_p).enb_index].Tx_buffer.payload_size = 0;
      break;
3433

3434
    case RRC_MAC_CCCH_DATA_IND:
3435 3436 3437 3438 3439 3440
      LOG_I(RRC, "[UE %d] RNTI %x Received %s: frameP %d, eNB %d\n",
            ue_mod_id,
            RRC_MAC_CCCH_DATA_IND (msg_p).rnti,
            msg_name,
            RRC_MAC_CCCH_DATA_IND (msg_p).frame,
            RRC_MAC_CCCH_DATA_IND (msg_p).enb_index);
3441

3442
      srb_info_p = &UE_rrc_inst[ue_mod_id].Srb0[RRC_MAC_CCCH_DATA_IND (msg_p).enb_index];
3443

3444 3445 3446
      memcpy (srb_info_p->Rx_buffer.Payload, RRC_MAC_CCCH_DATA_IND (msg_p).sdu,
              RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size);
      srb_info_p->Rx_buffer.payload_size = RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size;
3447 3448 3449
      PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_NO, RRC_MAC_CCCH_DATA_IND (msg_p).rnti, RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0);
      rrc_ue_decode_ccch (&ctxt,
                          srb_info_p,
3450 3451
                          RRC_MAC_CCCH_DATA_IND (msg_p).enb_index);
      break;
3452

3453
# ifdef Rel10
3454 3455 3456

    case RRC_MAC_MCCH_DATA_IND:
      LOG_I(RRC, "[UE %d] Received %s: frameP %d, eNB %d, mbsfn SA %d\n", ue_mod_id, msg_name,
3457
            RRC_MAC_MCCH_DATA_IND (msg_p).frame, RRC_MAC_MCCH_DATA_IND (msg_p).enb_index, RRC_MAC_MCCH_DATA_IND (msg_p).mbsfn_sync_area);
3458

3459 3460 3461 3462 3463 3464
      PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_NO, M_RNTI, RRC_MAC_MCCH_DATA_IND (msg_p).frame, 0);
      decode_MCCH_Message (
        &ctxt,
        RRC_MAC_MCCH_DATA_IND (msg_p).enb_index,
        RRC_MAC_MCCH_DATA_IND (msg_p).sdu,
        RRC_MAC_MCCH_DATA_IND (msg_p).sdu_size,
3465 3466
                           RRC_MAC_MCCH_DATA_IND (msg_p).mbsfn_sync_area);
      break;
3467
# endif
3468

3469 3470
      /* PDCP messages */
    case RRC_DCCH_DATA_IND:
3471 3472 3473 3474 3475 3476
      PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, RRC_DCCH_DATA_IND (msg_p).module_id, ENB_FLAG_NO, RRC_DCCH_DATA_IND (msg_p).rnti, RRC_DCCH_DATA_IND (msg_p).frame, 0);
      LOG_I(RRC, "[UE %d] Received %s: frameP %d, DCCH %d, eNB %d\n",
            RRC_DCCH_DATA_IND (msg_p).module_id,
            msg_name,
            RRC_DCCH_DATA_IND (msg_p).frame,
            RRC_DCCH_DATA_IND (msg_p).dcch_index,
3477
                          RRC_DCCH_DATA_IND (msg_p).eNB_index);
3478

3479 3480 3481 3482 3483 3484 3485 3486 3487 3488
      LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT"Received %s DCCH %d, eNB %d",
            PROTOCOL_RRC_CTXT_UE_ARGS(&ctxt),
            msg_name,
            RRC_DCCH_DATA_IND (msg_p).dcch_index,
            RRC_DCCH_DATA_IND (msg_p).eNB_index);
      rrc_ue_decode_dcch (
        &ctxt,
        RRC_DCCH_DATA_IND (msg_p).dcch_index,
        RRC_DCCH_DATA_IND (msg_p).sdu_p,
        RRC_DCCH_DATA_IND (msg_p).eNB_index);
3489 3490 3491 3492
      // Message buffer has been processed, free it now.
      result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), RRC_DCCH_DATA_IND (msg_p).sdu_p);
      AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
      break;
3493

3494 3495
# if defined(ENABLE_USE_MME)

3496 3497 3498 3499 3500
      /* NAS messages */
    case NAS_CELL_SELECTION_REQ:
      ue_mod_id = 0; /* TODO force ue_mod_id to first UE, NAS UE not virtualized yet */

      LOG_I(RRC, "[UE %d] Received %s: state %d, plmnID %d, rat %x\n", ue_mod_id, msg_name, rrc_get_state(ue_mod_id),
3501
            NAS_CELL_SELECTION_REQ (msg_p).plmnID, NAS_CELL_SELECTION_REQ (msg_p).rat);
3502

3503 3504 3505 3506
      if (rrc_get_state(ue_mod_id) == RRC_STATE_INACTIVE) {
        // have a look at MAC/main.c void dl_phy_sync_success(...)
        openair_rrc_ue_init(ue_mod_id,0);
      }
3507

3508 3509 3510 3511
      /* Save cell selection criterion */
      {
        UE_rrc_inst[ue_mod_id].plmnID = NAS_CELL_SELECTION_REQ (msg_p).plmnID;
        UE_rrc_inst[ue_mod_id].rat = NAS_CELL_SELECTION_REQ (msg_p).rat;
Lionel Gauthier's avatar
Lionel Gauthier committed
3512 3513 3514 3515 3516 3517 3518 3519 3520
        LOG_I(RRC, "[UE %d] Save cell selection criterion MCC %X%X%X MNC %X%X%X\n",
        		ue_mod_id,
        		UE_rrc_inst[ue_mod_id].plmnID.MCCdigit1,
        		UE_rrc_inst[ue_mod_id].plmnID.MCCdigit2,
        		UE_rrc_inst[ue_mod_id].plmnID.MCCdigit3,
        		UE_rrc_inst[ue_mod_id].plmnID.MNCdigit1,
        		UE_rrc_inst[ue_mod_id].plmnID.MNCdigit2,
        		UE_rrc_inst[ue_mod_id].plmnID.MNCdigit3);

3521
      }
3522

3523 3524 3525 3526
      switch (rrc_get_state(ue_mod_id)) {
      case RRC_STATE_INACTIVE: {
        /* Need to first activate lower layers */
        MessageDef *message_p;
3527

3528
        message_p = itti_alloc_new_message(TASK_RRC_UE, ACTIVATE_MESSAGE);
3529

3530
        itti_send_msg_to_task(TASK_L2L1, UE_MODULE_ID_TO_INSTANCE(ue_mod_id), message_p);
3531

3532 3533 3534
        rrc_set_state (ue_mod_id, RRC_STATE_IDLE);
        /* Fall through to next case */
      }
winckel's avatar
winckel committed
3535

3536 3537 3538
      case RRC_STATE_IDLE: {
        /* Ask to layer 1 to find a cell matching the criterion */
        MessageDef *message_p;
winckel's avatar
winckel committed
3539

3540
        message_p = itti_alloc_new_message(TASK_RRC_UE, PHY_FIND_CELL_REQ);
winckel's avatar
winckel committed
3541

3542 3543
        PHY_FIND_CELL_REQ (message_p).earfcn_start = 1;
        PHY_FIND_CELL_REQ (message_p).earfcn_end = 1;
winckel's avatar
winckel committed
3544

3545
        itti_send_msg_to_task(TASK_PHY_UE, UE_MODULE_ID_TO_INSTANCE(ue_mod_id), message_p);
3546
        rrc_set_sub_state (ue_mod_id, RRC_SUB_STATE_IDLE_SEARCHING);
winckel's avatar
winckel committed
3547

3548 3549
        break;
      }
3550

3551 3552 3553 3554
      case RRC_STATE_CONNECTED:
        /* should not happen */
        LOG_E(RRC, "[UE %d] request %s in RRC state %d\n", ue_mod_id, msg_name, rrc_get_state(ue_mod_id));
        break;
3555

3556 3557
      default:
        LOG_C(RRC, "[UE %d] Invalid RRC state %d\n", ue_mod_id, rrc_get_state(ue_mod_id));
3558
        break;
3559
      }
winckel's avatar
winckel committed
3560

3561
      break;
winckel's avatar
winckel committed
3562

3563 3564 3565
    case NAS_CONN_ESTABLI_REQ:
      LOG_I(RRC, "[UE %d] Received %s: cause %d, type %d, s_tmsi %d, plmnID %d\n", ue_mod_id, msg_name, NAS_CONN_ESTABLI_REQ (msg_p).cause,
            NAS_CONN_ESTABLI_REQ (msg_p).type, NAS_CONN_ESTABLI_REQ (msg_p).s_tmsi, NAS_CONN_ESTABLI_REQ (msg_p).plmnID);
winckel's avatar
winckel committed
3566

3567
      PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_NO, NOT_A_RNTI, 0, 0);
3568
      UE_rrc_inst[ue_mod_id].initialNasMsg = NAS_CONN_ESTABLI_REQ (msg_p).initialNasMsg;
winckel's avatar
winckel committed
3569

3570 3571 3572
      switch (rrc_get_state(ue_mod_id)) {
      case RRC_STATE_IDLE: {
        if (rrc_get_sub_state(ue_mod_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE) {
3573
          rrc_ue_generate_RRCConnectionRequest(&ctxt, 0);
3574
          LOG_I(RRC, "not sending connection request\n");
winckel's avatar
winckel committed
3575

3576 3577
          rrc_set_sub_state (ue_mod_id, RRC_SUB_STATE_IDLE_CONNECTING);
        }
winckel's avatar
winckel committed
3578

3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591
        break;
      }

      case RRC_STATE_INACTIVE:
      case RRC_STATE_CONNECTED:
        /* should not happen */
        LOG_E(RRC, "[UE %d] request %s in RRC state %d\n", ue_mod_id, msg_name, rrc_get_state(ue_mod_id));
        break;

      default:
        LOG_C(RRC, "[UE %d] Invalid RRC state %d\n", ue_mod_id, rrc_get_state(ue_mod_id));
        break;
      }
winckel's avatar
winckel committed
3592

3593
      break;
winckel's avatar
RRC:  
winckel committed
3594

3595 3596 3597
    case NAS_UPLINK_DATA_REQ: {
      uint32_t length;
      uint8_t *buffer;
winckel's avatar
RRC:  
winckel committed
3598

3599 3600 3601 3602 3603 3604
      LOG_I(RRC, "[UE %d] Received %s: UEid %d\n", ue_mod_id, msg_name, NAS_UPLINK_DATA_REQ (msg_p).UEid);

      /* Create message for PDCP (ULInformationTransfer_t) */
      length = do_ULInformationTransfer(&buffer, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.length, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.data);

      /* Transfer data to PDCP */
3605 3606 3607 3608 3609 3610 3611
      PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, ENB_FLAG_NO, UE_rrc_inst[ue_mod_id].Info[0].rnti, 0, 0);
      pdcp_rrc_data_req (&ctxt,
                         DCCH,
                         rrc_mui++,
                         SDU_CONFIRM_NO,
                         length, buffer,
                         PDCP_TRANSMISSION_MODE_CONTROL);
3612 3613
      break;
    }
winckel's avatar
RRC:  
winckel committed
3614

3615
# endif
winckel's avatar
RRC:  
winckel committed
3616

3617 3618
# if defined(ENABLE_RAL)

3619 3620
    case RRC_RAL_SCAN_REQ:
      LOG_I(RRC, "[UE %d] Received %s: state %d\n", ue_mod_id, msg_name);
3621

3622 3623 3624 3625
      switch (rrc_get_state(ue_mod_id)) {
      case RRC_STATE_INACTIVE: {
        /* Need to first activate lower layers */
        MessageDef *message_p;
3626

3627
        message_p = itti_alloc_new_message(TASK_RRC_UE, ACTIVATE_MESSAGE);
3628

3629
        itti_send_msg_to_task(TASK_L2L1, instance, message_p);
3630

3631 3632 3633
        rrc_set_state (ue_mod_id, RRC_STATE_IDLE);
        /* Fall through to next case */
      }
3634

3635 3636 3637 3638
      case RRC_STATE_IDLE: {
        if (rrc_get_sub_state(ue_mod_id) != RRC_SUB_STATE_IDLE_SEARCHING) {
          /* Ask to layer 1 to find a cell matching the criterion */
          MessageDef *message_p;
3639

3640
          message_p = itti_alloc_new_message(TASK_RRC_UE, PHY_FIND_CELL_REQ);
3641

3642
          rrc_set_sub_state (ue_mod_id, RRC_SUB_STATE_IDLE_SEARCHING);
3643

3644 3645 3646
          PHY_FIND_CELL_REQ (message_p).transaction_id = RRC_RAL_SCAN_REQ (msg_p).transaction_id;
          PHY_FIND_CELL_REQ (message_p).earfcn_start   = 1;
          PHY_FIND_CELL_REQ (message_p).earfcn_end     = 1; //44
3647

3648 3649
          itti_send_msg_to_task(TASK_PHY_UE, instance, message_p);
        }
3650

3651 3652
        break;
      }
3653

3654 3655 3656 3657
      case RRC_STATE_CONNECTED:
        /* should not happen */
        LOG_E(RRC, "[UE %d] request %s in RRC state %d\n", ue_mod_id, msg_name, rrc_get_state(ue_mod_id));
        break;
3658

3659 3660 3661 3662
      default:
        LOG_C(RRC, "[UE %d] Invalid RRC state %d\n", ue_mod_id, rrc_get_state(ue_mod_id));
        break;
      }
3663

3664
      break;
3665

3666 3667
    case PHY_FIND_CELL_IND:
      LOG_I(RRC, "[UE %d] Received %s: state %d\n", ue_mod_id, msg_name, rrc_get_state(ue_mod_id));
3668

3669 3670 3671 3672 3673 3674
      switch (rrc_get_state(ue_mod_id)) {
      case RRC_STATE_IDLE:
        switch (rrc_get_sub_state(ue_mod_id)) {
        case RRC_SUB_STATE_IDLE_SEARCHING: {
          MessageDef *message_p;
          int         i;
3675

3676
          message_p = itti_alloc_new_message(TASK_RRC_UE, RRC_RAL_SCAN_CONF);
3677

3678 3679
          RRC_RAL_SCAN_CONF (message_p).transaction_id = PHY_FIND_CELL_IND(msg_p).transaction_id;
          RRC_RAL_SCAN_CONF (message_p).num_scan_resp  = PHY_FIND_CELL_IND(msg_p).cell_nb;
3680

3681 3682 3683 3684 3685
          for (i = 0 ; i < PHY_FIND_CELL_IND(msg_p).cell_nb; i++) {
            // TO DO
            memset(&RRC_RAL_SCAN_CONF (message_p).link_scan_resp[i].link_addr,  0, sizeof(ral_link_addr_t));
            // TO DO
            memset(&RRC_RAL_SCAN_CONF (message_p).link_scan_resp[i].network_id, 0, sizeof(ral_network_id_t));
3686

3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714
            RRC_RAL_SCAN_CONF (message_p).link_scan_resp[i].sig_strength.choice     = RAL_SIG_STRENGTH_CHOICE_DBM;
            RRC_RAL_SCAN_CONF (message_p).link_scan_resp[i].sig_strength._union.dbm = PHY_FIND_CELL_IND(msg_p).cells[i].rsrp;
          }

          rrc_set_sub_state (ue_mod_id, RRC_SUB_STATE_IDLE);

          itti_send_msg_to_task(TASK_RAL_UE, instance, message_p);
          break;
        }

        default:
          LOG_C(RRC, "[UE %d] Invalid RRC state %d substate %d\n",
                ue_mod_id,
                rrc_get_state(ue_mod_id),
                rrc_get_sub_state(ue_mod_id));
        }

        break;

      case RRC_STATE_INACTIVE:
      case RRC_STATE_CONNECTED:
        /* should not happen */
        LOG_E(RRC, "[UE %d] indication %s in RRC state %d\n", ue_mod_id, msg_name, rrc_get_state(ue_mod_id));
        break;

      default:
        LOG_C(RRC, "[UE %d] Invalid RRC state %d\n", ue_mod_id, rrc_get_state(ue_mod_id));
        break;
3715
      }
3716

3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745
      break; // PHY_FIND_CELL_IND

    case PHY_MEAS_REPORT_IND: {
      MessageDef *message_p;
      message_p = itti_alloc_new_message(TASK_RRC_UE, RRC_RAL_MEASUREMENT_REPORT_IND);

      memcpy(&RRC_RAL_MEASUREMENT_REPORT_IND (message_p).threshold,
             &PHY_MEAS_REPORT_IND(msg_p).threshold,
             sizeof(RRC_RAL_MEASUREMENT_REPORT_IND (message_p).threshold));

      memcpy(&RRC_RAL_MEASUREMENT_REPORT_IND (message_p).link_param,
             &PHY_MEAS_REPORT_IND(msg_p).link_param,
             sizeof(RRC_RAL_MEASUREMENT_REPORT_IND (message_p).link_param));

      LOG_I(RRC, "[UE %d] PHY_MEAS_REPORT_IN: sending msg %s to %s \n", ue_mod_id, "RRC_RAL_MEASUREMENT_REPORT_IND", "TASK_RAL_UE");
      itti_send_msg_to_task(TASK_RAL_UE, instance, message_p);
      break;
    }

    case RRC_RAL_CONFIGURE_THRESHOLD_REQ:
      rrc_ue_ral_handle_configure_threshold_request(ue_mod_id, msg_p);
      break;

    case RRC_RAL_CONNECTION_ESTABLISHMENT_REQ:
      LOG_I(RRC, "[UE %d] Received %s\n", ue_mod_id, msg_name);

      switch (rrc_get_state(ue_mod_id)) {
      case RRC_STATE_IDLE: {
        if (rrc_get_sub_state(ue_mod_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE) {
3746 3747 3748
          PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, ENB_FLAG_NO, UE_rrc_inst[ue_mod_id].Info[0].rnti, 0, 0);
          rrc_ue_generate_RRCConnectionRequest(&ctxt, 0);
          LOG_I(RRC, "not sending connection request\n");
3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782
          rrc_set_sub_state (ue_mod_id, RRC_SUB_STATE_IDLE_CONNECTING);
        }

        break;
      }

      case RRC_STATE_INACTIVE:
      case RRC_STATE_CONNECTED:
        /* should not happen */
        LOG_E(RRC, "[UE %d] request %s in RRC state %d\n", ue_mod_id, msg_name, rrc_get_state(ue_mod_id));
        break;

      default:
        LOG_C(RRC, "[UE %d] Invalid RRC state %d\n", ue_mod_id, rrc_get_state(ue_mod_id));
        break;
      }

      break;

    case RRC_RAL_CONNECTION_RELEASE_REQ:
      ue_mod_id = 0; /* TODO force ue_mod_id to first UE, NAS UE not virtualized yet */
      LOG_I(RRC, "[UE %d] Received %s\n", ue_mod_id, msg_name);
      break;
#endif

    default:
      LOG_E(RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, msg_name);
      break;
    }

    result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
    msg_p = NULL;
3783 3784 3785
  }
}
#endif