rrc_eNB.c 161 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/*******************************************************************************

  Eurecom OpenAirInterface 2
  Copyright(c) 1999 - 2010 Eurecom

  This program is free software; you can redistribute it and/or modify it
  under the terms and conditions of the GNU General Public License,
  version 2, as published by the Free Software Foundation.

  This program is distributed in the hope 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.

  You should have received a copy of the GNU General Public License along with
  this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.

  The full GNU General Public License is included in this distribution in
  the file called "COPYING".

  Contact Information
  Openair Admin: openair_admin@eurecom.fr
  Openair Tech : openair_tech@eurecom.fr
  Forums       : http://forums.eurecom.fsr/openairinterface
  Address      : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France

*******************************************************************************/


/*! \file rrc_eNB.c
 * \brief rrc procedures for eNB
 * \author Raymond Knopp and Navid Nikaein
 * \date 2011
 * \version 1.0
 * \company Eurecom
 * \email: raymond.knopp@eurecom.fr and navid.nikaein@eurecom.fr
 */

#include "defs.h"
#include "extern.h"
42
#include "UTIL/assertions.h"
43
#include "asn1_conversions.h"
44
45
46
47
48
49
50
51
52
53
54
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
#include "LAYER2/RLC/rlc.h"
#include "UTIL/LOG/log.h"
#include "COMMON/mac_rrc_primitives.h"
#include "RRC/LITE/MESSAGES/asn1_msg.h"
#include "RRCConnectionRequest.h"
#include "UL-CCCH-Message.h"
#include "DL-CCCH-Message.h"
#include "UL-DCCH-Message.h"
#include "DL-DCCH-Message.h"
#include "TDD-Config.h"
55
#include "HandoverCommand.h"
56
57
58
59
#include "rlc.h"
#include "SIMULATION/ETH_TRANSPORT/extern.h"

//#ifdef Rel10
60
#include "MeasResults.h"
61
62
63
//#endif

#ifdef USER_MODE
64
65
66
67
# include "RRC/NAS/nas_config.h"
# include "RRC/NAS/rb_config.h"
# include "OCG.h"
# include "OCG_extern.h"
68
69
#endif

70
71
72
73
#if defined(ENABLE_SECURITY)
# include "UTIL/OSA/osa_defs.h"
#endif

74
#if defined(ENABLE_USE_MME)
75
76
77
# if !defined(ENABLE_ITTI)
#   include "../../S1AP/s1ap_eNB.h"
# endif
78
79
#endif

80
81
82
83
84
85
#include "pdcp.h"

#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#endif

86
87
88
89
90
91
92
93
//#define XER_PRINT

#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
94
extern void *bigphys_malloc (int);
95
96
#endif

97
extern uint16_t two_tier_hexagonal_cellIds[7];
98
extern inline unsigned int taus (void);
winckel's avatar
RRC:    
winckel committed
99

100
101
102
/* TS 36.331: RRC-TransactionIdentifier ::= INTEGER (0..3) */
static const uint8_t RRC_TRANSACTION_IDENTIFIER_NUMBER = 4;

103
104
105
/* Value to indicate an invalid UE index */
static const uint8_t UE_INDEX_INVALID = ~0;

106
107
/* Value to indicate an invalid UE initial id */
static const uint16_t UE_INITIAL_ID_INVALID = 0;
winckel's avatar
RRC:    
winckel committed
108

109
void
110
init_SI (u8 Mod_id) {
111

112
113
  u8 SIwindowsize = 1;
  u16 SIperiod = 8;
114
#ifdef Rel10
115
  int i;
116
#endif
117
  /*
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
     uint32_t mib=0;
     int i;
     int N_RB_DL,phich_resource;


     do_MIB(mac_xface->lte_frame_parms,0x321,&mib);

     for (i=0;i<1024;i+=4)
     do_MIB(mac_xface->lte_frame_parms,i,&mib);

     N_RB_DL=6;
     while (N_RB_DL != 0) {
     phich_resource = 1;
     while (phich_resource != 0) {
     for (i=0;i<2;i++) {
     mac_xface->lte_frame_parms->N_RB_DL = N_RB_DL;
     mac_xface->lte_frame_parms->phich_config_common.phich_duration=i;
     mac_xface->lte_frame_parms->phich_config_common.phich_resource = phich_resource;
     do_MIB(mac_xface->lte_frame_parms,0,&mib);
     }
     if (phich_resource == 1)
     phich_resource = 3;
     else if (phich_resource == 3)
     phich_resource = 6;
     else if (phich_resource == 6)
     phich_resource = 12;
     else if (phich_resource == 12)
     phich_resource = 0;
     }
     if (N_RB_DL == 6)
     N_RB_DL = 15;
     else if (N_RB_DL == 15)
     N_RB_DL = 25;
     else if (N_RB_DL == 25)
     N_RB_DL = 50;
     else if (N_RB_DL == 50)
     N_RB_DL = 75;
     else if (N_RB_DL == 75)
     N_RB_DL = 100;
     else if (N_RB_DL == 100)
     N_RB_DL = 0;
     }
     exit(-1);
   */
162
163
164
165

  eNB_rrc_inst[Mod_id].sizeof_SIB1 = 0;
  eNB_rrc_inst[Mod_id].sizeof_SIB23 = 0;

166
  eNB_rrc_inst[Mod_id].SIB1 = (u8 *) malloc16 (32);
167
168

  /*
169
170
171
172
173
     printf ("before SIB1 init : Nid_cell %d\n", mac_xface->lte_frame_parms->Nid_cell);
     printf ("before SIB1 init : frame_type %d,tdd_config %d\n",
     mac_xface->lte_frame_parms->frame_type,
     mac_xface->lte_frame_parms->tdd_config);
   */
174
175

  if (eNB_rrc_inst[Mod_id].SIB1)
176
177
178
179
180
181
182
183
184
185
186
    eNB_rrc_inst[Mod_id].sizeof_SIB1 = do_SIB1 (mac_xface->lte_frame_parms,
                                                (uint8_t *)
                                                eNB_rrc_inst[Mod_id].SIB1,
                                                &eNB_rrc_inst[Mod_id].
                                                siblock1,
                                                &eNB_rrc_inst[Mod_id].sib1);
  else
    {
      LOG_E (RRC, "[eNB] init_SI: FATAL, no memory for SIB1 allocated\n");
      mac_xface->macphy_exit ("");
    }
187
  /*
188
189
190
191
192
     printf ("after SIB1 init : Nid_cell %d\n", mac_xface->lte_frame_parms->Nid_cell);
     printf ("after SIB1 init : frame_type %d,tdd_config %d\n",
     mac_xface->lte_frame_parms->frame_type,
     mac_xface->lte_frame_parms->tdd_config);
   */
193
  if (eNB_rrc_inst[Mod_id].sizeof_SIB1 == 255)
194
195
196
    mac_xface->macphy_exit ("");

  eNB_rrc_inst[Mod_id].SIB23 = (u8 *) malloc16 (64);
197
  if (eNB_rrc_inst[Mod_id].SIB23)    {
198
199
200
201
202
203
204
205
206
207
208

      eNB_rrc_inst[Mod_id].sizeof_SIB23 = do_SIB23 (Mod_id,
                                                    mac_xface->
                                                    lte_frame_parms,
                                                    eNB_rrc_inst[Mod_id].
                                                    SIB23,
                                                    &eNB_rrc_inst[Mod_id].
                                                    systemInformation,
                                                    &eNB_rrc_inst[Mod_id].
                                                    sib2,
                                                    &eNB_rrc_inst[Mod_id].sib3
209
#ifdef Rel10
210
                                                    ,
211
212
                                                    &eNB_rrc_inst[Mod_id].sib13,
                                                    eNB_rrc_inst[Mod_id].MBMS_flag
213
#endif
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
        );
      /*
         eNB_rrc_inst[Mod_id].sizeof_SIB23 = do_SIB2_AT4(Mod_id,
         eNB_rrc_inst[Mod_id].SIB23,
         &eNB_rrc_inst[Mod_id].systemInformation,
         &eNB_rrc_inst[Mod_id].sib2);
       */
      if (eNB_rrc_inst[Mod_id].sizeof_SIB23 == 255)
        mac_xface->macphy_exit ("eNB_rrc_inst[Mod_id].sizeof_SIB23 == 255");

      LOG_T (RRC, "[eNB %d] SIB2/3 Contents (partial)\n", Mod_id);
      LOG_T (RRC, "[eNB %d] pusch_config_common.n_SB = %ld\n", Mod_id,
             eNB_rrc_inst[Mod_id].sib2->radioResourceConfigCommon.
             pusch_ConfigCommon.pusch_ConfigBasic.n_SB);
      LOG_T (RRC, "[eNB %d] pusch_config_common.hoppingMode = %ld\n", Mod_id,
             eNB_rrc_inst[Mod_id].sib2->radioResourceConfigCommon.
             pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode);
      LOG_T (RRC, "[eNB %d] pusch_config_common.pusch_HoppingOffset = %ld\n",
             Mod_id,
             eNB_rrc_inst[Mod_id].sib2->radioResourceConfigCommon.
             pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset);
      LOG_T (RRC, "[eNB %d] pusch_config_common.enable64QAM = %d\n", Mod_id,
             (int) eNB_rrc_inst[Mod_id].sib2->radioResourceConfigCommon.
             pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM);
      LOG_T (RRC, "[eNB %d] pusch_config_common.groupHoppingEnabled = %d\n",
             Mod_id,
             (int) eNB_rrc_inst[Mod_id].sib2->radioResourceConfigCommon.
             pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled);
      LOG_T (RRC, "[eNB %d] pusch_config_common.groupAssignmentPUSCH = %ld\n",
             Mod_id,
             eNB_rrc_inst[Mod_id].sib2->radioResourceConfigCommon.
             pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.
             groupAssignmentPUSCH);
      LOG_T (RRC,
             "[eNB %d] pusch_config_common.sequenceHoppingEnabled = %d\n",
             Mod_id,
             (int) eNB_rrc_inst[Mod_id].sib2->radioResourceConfigCommon.
             pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.
             sequenceHoppingEnabled);
      LOG_T (RRC, "[eNB %d] pusch_config_common.cyclicShift  = %ld\n", Mod_id,
             eNB_rrc_inst[Mod_id].sib2->radioResourceConfigCommon.
             pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift);
256
257
258


#ifdef Rel10
259
260
261
262
263
264
      if (eNB_rrc_inst[Mod_id].MBMS_flag > 0) {
	
        for (i=0; 
	     i< eNB_rrc_inst[Mod_id].sib2->mbsfn_SubframeConfigList->list.count;
	     i++){
	  // SIB 2
265
          //   LOG_D(RRC, "[eNB %d] mbsfn_SubframeConfigList.list.count = %ld\n", Mod_id, eNB_rrc_inst[Mod_id].sib2->mbsfn_SubframeConfigList->list.count);
266
267
268
269
270
           LOG_D (RRC, "[eNB %d] SIB13 contents for MBSFN subframe allocation %d/%d(partial)\n", 
		  Mod_id,i,eNB_rrc_inst[Mod_id].sib2->mbsfn_SubframeConfigList->list.count);
	   LOG_D (RRC, "[eNB %d] mbsfn_Subframe_pattern is  = %x\n", Mod_id,
                 eNB_rrc_inst[Mod_id].sib2->mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]>>0);
          LOG_D (RRC, "[eNB %d] radioframe_allocation_period  = %ld (just index number, not the real value)\n", Mod_id, eNB_rrc_inst[Mod_id].sib2->mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod);        // need to display the real value, using array of char (like in dumping SIB2)
271
272
          LOG_D (RRC, "[eNB %d] radioframe_allocation_offset  = %ld\n",
                 Mod_id,
273
274
                 eNB_rrc_inst[Mod_id].sib2->mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset);
	}
275
          //   SIB13
276
277
278
279
280
281
282
        for (i=0; 
	     i<  eNB_rrc_inst[Mod_id].sib13->mbsfn_AreaInfoList_r9.list.count;
	     i++){
	  LOG_D (RRC,"[eNB %d] SIB13 contents for MBSFN sync area %d/2 (partial)\n", 
		 Mod_id, i,
                 eNB_rrc_inst[Mod_id].sib13->mbsfn_AreaInfoList_r9.list.count);
	  LOG_D (RRC,"[eNB %d] MCCH Repetition Period: %d (just index number, not real value)\n",
283
                 Mod_id,
284
                 eNB_rrc_inst[Mod_id].sib13->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9);
285
          LOG_D (RRC, "[eNB %d] MCCH Offset: %d\n", Mod_id,
286
287
288
289
                 eNB_rrc_inst[Mod_id].sib13->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_Offset_r9);
       
	}
      }
290
291
#endif

292
293
294
295
296
297
298
299
300
301
302
303
304
305
      LOG_D (RRC,
             "[MSC_MSG][FRAME unknown][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SIB1.tdd & SIB2 params) --->][MAC_UE][MOD %02d][]\n",
             Mod_id, Mod_id);

      rrc_mac_config_req (Mod_id, 1, 0, 0,
                          (RadioResourceConfigCommonSIB_t *) &
                          eNB_rrc_inst[Mod_id].sib2->
                          radioResourceConfigCommon,
                          (struct PhysicalConfigDedicated *) NULL,
                          (MeasObjectToAddMod_t **) NULL,
                          (MAC_MainConfig_t *) NULL, 0,
                          (struct LogicalChannelConfig *) NULL,
                          (MeasGapConfig_t *) NULL,
                          eNB_rrc_inst[Mod_id].sib1->tdd_Config,
306
			  NULL,
307
308
309
310
311
312
313
                          &SIwindowsize, &SIperiod,
                          eNB_rrc_inst[Mod_id].sib2->freqInfo.ul_CarrierFreq,
                          eNB_rrc_inst[Mod_id].sib2->freqInfo.ul_Bandwidth,
                          &eNB_rrc_inst[Mod_id].sib2->freqInfo.
                          additionalSpectrumEmission,
                          (MBSFN_SubframeConfigList_t *) eNB_rrc_inst[Mod_id].
                          sib2->mbsfn_SubframeConfigList
314
#ifdef Rel10
315
316
317
318
319
                          ,
                          eNB_rrc_inst[Mod_id].MBMS_flag,
                          (MBSFN_AreaInfoList_r9_t *) & eNB_rrc_inst[Mod_id].
                          sib13->mbsfn_AreaInfoList_r9,
                          (PMCH_InfoList_r9_t *) NULL
320
321
#endif
#ifdef CBA
322
                          ,0,  //eNB_rrc_inst[Mod_id].num_active_cba_groups,
323
324
325
326
327
328
329
330
331
                          0     //eNB_rrc_inst[Mod_id].cba_rnti[0]
#endif
        );
    }
  else
    {
      LOG_E (RRC, "[eNB] init_SI: FATAL, no memory for SIB2/3 allocated\n");
      mac_xface->macphy_exit ("");
    }
332
333
334
}

#ifdef Rel10
335
void
336
init_MCCH (u8 Mod_id) {
337

338
  int sync_area=0;
339
  // initialize RRC_eNB_INST MCCH entry
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
  eNB_rrc_inst[Mod_id].MCCH_MESSAGE=malloc(eNB_rrc_inst[Mod_id].num_mbsfn_sync_area*sizeof(uint32_t*));
  for (sync_area = 0;
       sync_area < eNB_rrc_inst[Mod_id].num_mbsfn_sync_area;
       sync_area++){ 
  
    eNB_rrc_inst[Mod_id].sizeof_MCCH_MESSAGE[sync_area] = 0;
    eNB_rrc_inst[Mod_id].MCCH_MESSAGE[sync_area] = (u8 *) malloc16 (32);
    
    if (eNB_rrc_inst[Mod_id].MCCH_MESSAGE[sync_area] == NULL) {
      LOG_E(RRC,"[eNB %d][MAIN] init_MCCH: FATAL, no memory for MCCH MESSAGE allocated \n", Mod_id);
      mac_xface->macphy_exit("[RRC][init_MCCH] not enough memory\n");
    } else {
      eNB_rrc_inst[Mod_id].sizeof_MCCH_MESSAGE[sync_area] = do_MBSFNAreaConfig (mac_xface->lte_frame_parms,
										sync_area,
										(uint8_t *) eNB_rrc_inst[Mod_id].MCCH_MESSAGE[sync_area],
										&eNB_rrc_inst[Mod_id].mcch,
										&eNB_rrc_inst[Mod_id].mcch_message);

      LOG_I(RRC,"mcch message pointer %p for sync area %d \n", eNB_rrc_inst[Mod_id].MCCH_MESSAGE[sync_area],sync_area);
      LOG_D (RRC, "[eNB %d] MCCH_MESSAGE  contents for Sync Area %d (partial)\n", Mod_id,sync_area);
360
361
362
363
364
365
      LOG_D (RRC, "[eNB %d] CommonSF_AllocPeriod_r9 %d\n", Mod_id,
             eNB_rrc_inst[Mod_id].mcch_message->commonSF_AllocPeriod_r9);
      LOG_D (RRC,
             "[eNB %d] CommonSF_Alloc_r9.list.count (number of MBSFN Subframe Pattern) %d\n",
             Mod_id,
             eNB_rrc_inst[Mod_id].mcch_message->commonSF_Alloc_r9.list.count);
366
      LOG_D (RRC, "[eNB %d] MBSFN Subframe Pattern: %02x (in hex)\n",
367
368
369
370
371
             Mod_id,
             eNB_rrc_inst[Mod_id].mcch_message->commonSF_Alloc_r9.list.
             array[0]->subframeAllocation.choice.oneFrame.buf[0]);


372
373
374
375
      if (eNB_rrc_inst[Mod_id].sizeof_MCCH_MESSAGE[sync_area] == 255)
	mac_xface->macphy_exit ("");
      else 
	eNB_rrc_inst[Mod_id].MCCH_MESS[sync_area].Active = 1;
376
    }
377
  }
378
  //Set the eNB_rrc_inst[Mod_id].MCCH_MESS.Active to 1 (allow to  transfer MCCH message RRC->MAC in function mac_rrc_data_req)
379
 
380
381
382
383
384

  // ??Configure MCCH logical channel
  // call mac_config_req with appropriate structure from ASN.1 description

  //  LOG_I(RRC, "DUY: serviceID is %d\n",eNB_rrc_inst[Mod_id].mcch_message->pmch_InfoList_r9.list.array[0]->mbms_SessionInfoList_r9.list.array[0]->tmgi_r9.serviceId_r9.buf[2]);
385
  //  LOG_I(RRC, "DUY: session ID is %d\n",eNB_rrc_inst[Mod_id].mcch_message->pmch_InfoList_r9.list.array[0]->mbms_SessionInfoList_r9.list.array[0]->sessionId_r9->buf[0]);
386
387
388
389
390
391
392
393
394
  rrc_mac_config_req (Mod_id, 1, 0, 0,
                      (RadioResourceConfigCommonSIB_t *) NULL,
                      (struct PhysicalConfigDedicated *) NULL,
                      (MeasObjectToAddMod_t **) NULL,
                      (MAC_MainConfig_t *) NULL,
                      0,
                      (struct LogicalChannelConfig *) NULL,
                      (MeasGapConfig_t *) NULL,
                      (TDD_Config_t *) NULL,
395
		      NULL,
396
397
398
                      (u8 *) NULL,
                      (u16 *) NULL,
                      NULL, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL
399
#ifdef Rel10
400
401
402
                      ,
                      0,
                      (MBSFN_AreaInfoList_r9_t *) NULL,
403
                      (PMCH_InfoList_r9_t *) & (eNB_rrc_inst[Mod_id].mcch_message->pmch_InfoList_r9)
404
#endif
405
#ifdef CBA
406
                      , 0, 0
407
#endif
408
    );
409
410

  //LOG_I(RRC,"DUY: lcid after rrc_mac_config_req is %02d\n",eNB_rrc_inst[Mod_id].mcch_message->pmch_InfoList_r9.list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9);
411

412
413
}

414
void
415
416
init_MBMS (u8 Mod_id, u32 frame) {
  // init the configuration for MTCH 
417

418
  if (eNB_rrc_inst[Mod_id].MBMS_flag > 0) {
419

420
    LOG_D(RRC,"[eNB %d] Frame %d : Radio Bearer config request for MBMS\n", Mod_id, frame); //check the lcid
421
422
      // Configuring PDCP and RLC for MBMS Radio Bearer

423
424
      rrc_pdcp_config_asn1_req (Mod_id, frame, 1, 0, 
				NULL,      // SRB_ToAddModList
425
                                NULL,   // DRB_ToAddModList
426
427
428
429
430
                                (DRB_ToReleaseList_t *) NULL,
				0, // security mode
				NULL, // key rrc encryption
				NULL, // key rrc integrity
				NULL // key encryption
431
#ifdef Rel10
432
                                ,
433
                                &(eNB_rrc_inst[Mod_id].mcch_message->pmch_InfoList_r9)
434
#endif
435
436
437
438
439
440
441
442
443
444
445
446
			     );
    
    rrc_rlc_config_asn1_req(Mod_id, frame, 1, 0,
			    NULL,// SRB_ToAddModList
			    NULL,// DRB_ToAddModList
			    NULL,// DRB_ToReleaseList
			    &(eNB_rrc_inst[Mod_id].mcch_message->pmch_InfoList_r9));
    
    //rrc_mac_config_req();
    
  }  
  
447
448
449
}
#endif

450
/*------------------------------------------------------------------------------*/
451
static uint8_t get_next_rrc_transaction_identifier(uint8_t Mod_id)
winckel's avatar
RRC:    
winckel committed
452
453
454
{
    static uint8_t rrc_transaction_identifier[NUMBER_OF_eNB_MAX];

455
    rrc_transaction_identifier[Mod_id] = (rrc_transaction_identifier[Mod_id] + 1) % RRC_TRANSACTION_IDENTIFIER_NUMBER;
winckel's avatar
RRC:    
winckel committed
456
457
458
459

    return rrc_transaction_identifier[Mod_id];
}

460
461
462
/*------------------------------------------------------------------------------*/
/* Functions to handle UE index in eNB UE list */
static uint8_t get_next_UE_index (uint8_t Mod_id, uint8_t *UE_identity)
463
{
464
465
  uint8_t i, first_index = UE_INDEX_INVALID, reg = 0;
  static const uint8_t null_identity[5] =
466
467
468
469
470
    {0, 0, 0, 0, 0};

  DevCheck(Mod_id < NB_eNB_INST, Mod_id, NB_eNB_INST, 0);

  for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
471
    if ((first_index == UE_INDEX_INVALID)
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
        && (memcmp (eNB_rrc_inst[Mod_id].Info.UE_list[i], null_identity, sizeof(eNB_rrc_inst[0].Info.UE_list[i])))
            == 0) {
      first_index = i; // save first free position
    }

    if (memcmp (eNB_rrc_inst[Mod_id].Info.UE_list[i], UE_identity, sizeof(eNB_rrc_inst[0].Info.UE_list[i])) == 0) {
      // UE_identity already registered
      reg = 1;
    }
  }

  if (reg == 0) {
    LOG_I(RRC, "Adding UE %d\n", first_index);
    return (first_index);
  }
  else {
488
    return (UE_INDEX_INVALID);
489
490
491
  }
}

492
void rrc_remove_UE (uint8_t Mod_id, uint8_t UE_id)
493
494
495
496
497
498
499
500
501
{
  DevCheck(Mod_id < NB_eNB_INST, Mod_id, UE_id, NB_eNB_INST);
  DevCheck(UE_id < NUMBER_OF_UE_MAX, Mod_id, UE_id, NUMBER_OF_UE_MAX);

  LOG_I (RRC, "Removing UE %d\n", UE_id);
  eNB_rrc_inst[Mod_id].Info.UE[UE_id].Status = RRC_IDLE;
  memset(eNB_rrc_inst[Mod_id].Info.UE_list[UE_id], 0, sizeof(eNB_rrc_inst[0].Info.UE_list[0]));
}

502
503
504
505
506
507
/*------------------------------------------------------------------------------*/
/* Function to handle UE initial ID for S1AP initial communication */
static uint16_t get_next_ue_initial_id(uint8_t Mod_id)
{
  static uint16_t ue_initial_id[NUMBER_OF_eNB_MAX];

508
509
  ue_initial_id[Mod_id] ++;

510
511
  /* Never use UE_INITIAL_ID_INVALID this is the invalid id! */
  if(ue_initial_id[Mod_id] == UE_INITIAL_ID_INVALID)
512
513
514
  {
    ue_initial_id[Mod_id] ++;
  }
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538

  return ue_initial_id[Mod_id];
}

static uint8_t get_UE_index_from_initial_id (uint8_t Mod_id, uint16_t ue_initial_id)
{
  uint8_t ue_index;
  static const uint8_t null_identity[5] =
    {0, 0, 0, 0, 0};

  DevCheck(Mod_id < NB_eNB_INST, Mod_id, NB_eNB_INST, 0);

  for (ue_index = 0; ue_index < NUMBER_OF_UE_MAX; ue_index++) {
    /* Check if this UE is in use */
    if (memcmp (eNB_rrc_inst[Mod_id].Info.UE_list[ue_index], null_identity, sizeof(eNB_rrc_inst[0].Info.UE_list[ue_index])) != 0) {
      /* Check if the initial id match */
      if (eNB_rrc_inst[Mod_id].Info.UE[ue_index].ue_initial_id == ue_initial_id) {
        return ue_index;
      }
    }
  }
  return UE_INDEX_INVALID;
}

winckel's avatar
winckel committed
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
/*------------------------------------------------------------------------------*/
static uint8_t get_UE_index_from_eNB_ue_s1ap_id (uint8_t Mod_id, uint16_t eNB_ue_s1ap_id)
{
  uint8_t ue_index;
  static const uint8_t null_identity[5] =
    {0, 0, 0, 0, 0};

  DevCheck(Mod_id < NB_eNB_INST, Mod_id, NB_eNB_INST, 0);

  for (ue_index = 0; ue_index < NUMBER_OF_UE_MAX; ue_index++) {
    /* Check if this UE is in use */
    if (memcmp (eNB_rrc_inst[Mod_id].Info.UE_list[ue_index], null_identity, sizeof(eNB_rrc_inst[0].Info.UE_list[ue_index])) != 0) {
      /* Check if the initial id match */
      if (eNB_rrc_inst[Mod_id].Info.UE[ue_index].eNB_ue_s1ap_id == eNB_ue_s1ap_id) {
        return ue_index;
      }
    }
  }
  return UE_INDEX_INVALID;
}

560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
/*------------------------------------------------------------------------------*/
static uint8_t get_UE_index_from_s1ap_ids (uint8_t Mod_id, uint16_t ue_initial_id, uint16_t eNB_ue_s1ap_id)
{
    uint8_t ue_index;

    if (ue_initial_id == UE_INITIAL_ID_INVALID)
    {
        /* If "ue_initial_id" is not set search if "eNB_ue_s1ap_id" is know by RRC */
        ue_index = get_UE_index_from_eNB_ue_s1ap_id (Mod_id, eNB_ue_s1ap_id);
    }
    else
    {
        /* If "ue_initial_id" is set there is probably not yet an associated "eNB_ue_s1ap_id" with S1AP */
        ue_index = get_UE_index_from_initial_id(Mod_id, ue_initial_id);
    }

    return ue_index;
}

579
/*------------------------------------------------------------------------------*/
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
void rrc_lite_eNB_init_security(u8 Mod_id, u8 UE_index)
{
#if defined(ENABLE_SECURITY)
    char ascii_buffer[65];
    uint8_t i;

    memset(eNB_rrc_inst[Mod_id].kenb[UE_index], UE_index, 32);

    for (i = 0; i < 32; i++) {
        sprintf(&ascii_buffer[2 * i], "%02X", eNB_rrc_inst[Mod_id].kenb[UE_index][i]);
    }

    LOG_T(RRC, "[OSA][MOD %02d][UE %02d] kenb    = %s\n", Mod_id, UE_index, ascii_buffer);
#endif
}

596
/*------------------------------------------------------------------------------*/
winckel's avatar
RRC:    
winckel committed
597
char openair_rrc_lite_eNB_init (u8 Mod_id)
598
{
599
600
601
  /*-----------------------------------------------------------------------------*/

  unsigned char j;
602
603
604
  LOG_I (RRC, "[eNB %d] Init (UE State = RRC_IDLE)...\n", Mod_id);
  LOG_D (RRC, "[MSC_NEW][FRAME 00000][RRC_eNB][MOD %02d][]\n", Mod_id);
  LOG_D (RRC, "[MSC_NEW][FRAME 00000][IP][MOD %02d][]\n", Mod_id);
605

606
  for (j = 0; j < NUMBER_OF_UE_MAX; j++)
607
    eNB_rrc_inst[Mod_id].Info.UE[j].Status = RRC_IDLE;     //CH_READY;
608

609
610
611
612
613
614
615
  /* Init security parameters */
  for (j = 0; j < NUMBER_OF_UE_MAX; j++) {
    eNB_rrc_inst[Mod_id].ciphering_algorithm[j] = SecurityAlgorithmConfig__cipheringAlgorithm_eea2;
    eNB_rrc_inst[Mod_id].integrity_algorithm[j] = SecurityAlgorithmConfig__integrityProtAlgorithm_eia2;
    rrc_lite_eNB_init_security(Mod_id, j);
  }

616
617
#if defined(ENABLE_USE_MME)
  /* Connect eNB to MME */
618
619
  if (oai_emulation.info.mme_enabled > 0)
    {
620
# if !defined(ENABLE_ITTI)
621
622
623
624
625
      if (s1ap_eNB_init (oai_emulation.info.mme_ip_address, Mod_id) < 0)
        {
          mac_xface->macphy_exit ("");
          return -1;
        }
626
# endif
627
628
629
    }
#endif

630
  eNB_rrc_inst[Mod_id].Info.Nb_ue = 0;
631

632
  eNB_rrc_inst[Mod_id].Srb0.Active = 0;
633

634
635
636
637
  for (j = 0; j < (NUMBER_OF_UE_MAX + 1); j++)
    {
      eNB_rrc_inst[Mod_id].Srb2[j].Active = 0;
    }
638
639
640
641
642


  /// System Information INIT


643
  LOG_I (RRC, "Checking release \n");
644
645
#ifdef Rel10

646
  // Thishas to come from some top-level configuration
647
648
  printf ("Rel10 RRC detected, MBMS flag %d\n",
          eNB_rrc_inst[Mod_id].MBMS_flag);
649

650
651
#else
  printf ("Rel8 RRC\n");
652
#endif
653
654
#ifdef CBA
  for (j = 0; j < NUM_MAX_CBA_GROUP; j++)
655
    eNB_rrc_inst[Mod_id].cba_rnti[j] = CBA_OFFSET + j;
656

657
658
  if (eNB_rrc_inst[Mod_id].num_active_cba_groups > NUM_MAX_CBA_GROUP)
    eNB_rrc_inst[Mod_id].num_active_cba_groups = NUM_MAX_CBA_GROUP;
659
660
661
662
663
664
665

  LOG_D (RRC,
         "[eNB %d] Initialization of 4 cba_RNTI values (%x %x %x %x) num active groups %d\n",
         Mod_id, eNB_rrc_inst[Mod_id].cba_rnti[0],
         eNB_rrc_inst[Mod_id].cba_rnti[1], eNB_rrc_inst[Mod_id].cba_rnti[2],
         eNB_rrc_inst[Mod_id].cba_rnti[3],
         eNB_rrc_inst[Mod_id].num_active_cba_groups);
666
667
#endif

668
  init_SI (Mod_id);
669
670

#ifdef Rel10
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
  switch (eNB_rrc_inst[Mod_id].MBMS_flag) {
  case 1:
  case 2:
  case 3:
    LOG_I(RRC,"[eNB %d] Configuring 1 MBSFN sync area\n", Mod_id);
    eNB_rrc_inst[Mod_id].num_mbsfn_sync_area=1;
    break;
  case 4: 
    LOG_I(RRC,"[eNB %d] Configuring 2 MBSFN sync area\n", Mod_id);
    eNB_rrc_inst[Mod_id].num_mbsfn_sync_area=2;
    break;
  default:
    eNB_rrc_inst[Mod_id].num_mbsfn_sync_area=0;
    break;
  }
  // if we are here the eNB_rrc_inst[Mod_id].MBMS_flag > 0,
  /// MCCH INIT
  if (eNB_rrc_inst[Mod_id].MBMS_flag > 0 ) {
    init_MCCH (Mod_id);
    /// MTCH data bearer init
    init_MBMS (Mod_id, 0);
  }
  
694
#endif
695

696
697
#ifdef NO_RRM                   //init ch SRB0, SRB1 & BDTCH
  openair_rrc_on (Mod_id, 1);
698
#else
699
700
701
702
  eNB_rrc_inst[Mod_id].Last_scan_req = 0;
  send_msg (&S_rrc,
            msg_rrc_phy_synch_to_MR_ind (Mod_id,
                                         eNB_rrc_inst[Mod_id].Mac_id));
703
704
705
706
707
708
709
#endif

  return 0;

}

/*------------------------------------------------------------------------------*/
winckel's avatar
RRC:    
winckel committed
710
int rrc_eNB_decode_dcch (u8 Mod_id, u32 frame, u8 Srb_id, u8 UE_index,
711
712
                     u8 * Rx_sdu, u8 sdu_size)
{
713
714
715
716
  /*------------------------------------------------------------------------------*/

  asn_dec_rval_t dec_rval;
  //UL_DCCH_Message_t uldcchmsg;
717
718
  UL_DCCH_Message_t *ul_dcch_msg = NULL;        //&uldcchmsg;
  UE_EUTRA_Capability_t *UE_EUTRA_Capability = NULL;
719
720
721

  int i;

722
723
724
725
726
727
  if (Srb_id != 1)
    {
      LOG_E (RRC,
             "[eNB %d] Frame %d: Received message on SRB%d, should not have ...\n",
             Mod_id, frame, Srb_id);
    }
728
729
730

  //memset(ul_dcch_msg,0,sizeof(UL_DCCH_Message_t));

731
732
733
734
  LOG_D (RRC, "[eNB %d] Frame %d: Decoding UL-DCCH Message\n", Mod_id, frame);
  dec_rval = uper_decode (NULL,
                          &asn_DEF_UL_DCCH_Message,
                          (void **) &ul_dcch_msg, Rx_sdu, sdu_size, 0, 0);
735
736
737
738
739
740
741
742

#if defined(ENABLE_ITTI)
  {
    MessageDef *message_p;

    message_p = itti_alloc_new_message (TASK_RRC_ENB, RRC_UL_DCCH_MESSAGE);
    memcpy (&message_p->msg, (void *) ul_dcch_msg, sizeof(RrcUlDcchMessage));

743
    itti_send_msg_to_task (TASK_UNKNOWN, Mod_id, message_p);
744
745
746
  }
#endif

747
748
749
750
751
752
753
754
755
756
  for (i = 0; i < sdu_size; i++)
    LOG_T (RRC, "%x.", Rx_sdu[i]);
  LOG_T (RRC, "\n");

  if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0))
    {
      LOG_E (RRC, "[UE %d] Frame %d : Failed to decode UL-DCCH (%d bytes)\n",
             Mod_id, frame, dec_rval.consumed);
      return -1;
    }
757

758
759
760
761
762
763
764
  if (ul_dcch_msg->message.present == UL_DCCH_MessageType_PR_c1)
    {

      switch (ul_dcch_msg->message.choice.c1.present)
        {
        case UL_DCCH_MessageType__c1_PR_NOTHING:        /* No components present */
          break;
winckel's avatar
RRC:    
winckel committed
765

766
767
        case UL_DCCH_MessageType__c1_PR_csfbParametersRequestCDMA2000:
          break;
winckel's avatar
RRC:    
winckel committed
768

769
770
771
772
773
        case UL_DCCH_MessageType__c1_PR_measurementReport:
          LOG_D (RRC,
                 "[MSC_MSG][FRAME %05d][RLC][MOD %02d][RB %02d][--- RLC_DATA_IND "
                 "%d bytes (measurementReport) --->][RRC_eNB][MOD %02d][]\n",
                 frame, Mod_id, DCCH, sdu_size, Mod_id);
774
          rrc_eNB_process_MeasurementReport (Mod_id, frame, UE_index,
775
776
777
778
779
780
                                             &ul_dcch_msg->message.choice.c1.
                                             choice.measurementReport.
                                             criticalExtensions.choice.c1.
                                             choice.measurementReport_r8.
                                             measResults);
          break;
winckel's avatar
RRC:    
winckel committed
781

782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
        case UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete:
          LOG_D (RRC,
                 "[MSC_MSG][FRAME %05d][RLC][MOD %02d][RB %02d][--- RLC_DATA_IND %d bytes "
                 "(RRCConnectionReconfigurationComplete) --->][RRC_eNB][MOD %02d][]\n",
                 frame, Mod_id, DCCH, sdu_size, Mod_id);
          if (ul_dcch_msg->message.choice.c1.choice.
              rrcConnectionReconfigurationComplete.criticalExtensions.
              present ==
              RRCConnectionReconfigurationComplete__criticalExtensions_PR_rrcConnectionReconfigurationComplete_r8)
            {
              rrc_eNB_process_RRCConnectionReconfigurationComplete (Mod_id,
                                                                    frame,
                                                                    UE_index,
                                                                    &ul_dcch_msg->
                                                                    message.
                                                                    choice.c1.
                                                                    choice.
                                                                    rrcConnectionReconfigurationComplete.
                                                                    criticalExtensions.
                                                                    choice.
                                                                    rrcConnectionReconfigurationComplete_r8);
803
              eNB_rrc_inst[Mod_id].Info.UE[UE_index].Status = RRC_RECONFIGURED;
804
805
              LOG_I (RRC, "[eNB %d] UE %d State = RRC_RECONFIGURED \n",
                     Mod_id, UE_index);
806
807
808
809
810

#if defined(ENABLE_USE_MME)
            if (oai_emulation.info.mme_enabled == 1)
            {
# if defined(ENABLE_ITTI)
winckel's avatar
winckel committed
811
              eNB_rrc_inst[Mod_id].Info.UE[UE_index].e_rab[eNB_rrc_inst[Mod_id].Info.UE[UE_index].index_of_e_rabs - 1].status = E_RAB_STATUS_DONE;
812
            }
813
814
815
# endif
#endif
          }
816
817
818
819
820
821
822
823
824
825
826
827
828

#if defined(ENABLE_USE_MME)
          if (oai_emulation.info.mme_enabled == 1)
          {
              eNB_RRC_UE_INFO *UE_info = &eNB_rrc_inst[Mod_id].Info.UE[UE_index];

# if defined(ENABLE_ITTI)
            /* Process e RAB parameters received from S1AP one by one (the previous one is completed, eventually process the next one) */
            if  (UE_info->nb_of_e_rabs > 0)
            {
                /* Process e RAB configuration from S1AP initial_context_setup_req */
                rrc_eNB_generate_defaultRRCConnectionReconfiguration (Mod_id, frame,
                                                                      UE_index,
829
830
                                                                      UE_info->e_rab[UE_info->index_of_e_rabs].param.nas_pdu.buffer,
                                                                      UE_info->e_rab[UE_info->index_of_e_rabs].param.nas_pdu.length,
831
832
                                                                      eNB_rrc_inst[Mod_id].HO_flag);
                /* Free the NAS PDU buffer and invalidate it */
833
                if (UE_info->e_rab[UE_info->index_of_e_rabs].param.nas_pdu.buffer != NULL)
834
                {
835
                  free (UE_info->e_rab[UE_info->index_of_e_rabs].param.nas_pdu.buffer);
836
                }
837
                UE_info->e_rab[UE_info->index_of_e_rabs].param.nas_pdu.buffer = NULL;
838
                UE_info->nb_of_e_rabs --;
839
                UE_info->index_of_e_rabs ++;
840
            }
841
842
843
844
845
846
847
848
849
850
851
            else
            {
              MessageDef *msg_p;
              int e_rab;
              int e_rabs_done = 0;
              int e_rabs_failed = 0;

              msg_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_INITIAL_CONTEXT_SETUP_RESP);
              S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).eNB_ue_s1ap_id = UE_info->eNB_ue_s1ap_id;
              for (e_rab = 0; e_rab < UE_info->index_of_e_rabs; e_rab++)
              {
winckel's avatar
winckel committed
852
                if (UE_info->e_rab[e_rab].status == E_RAB_STATUS_DONE)
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
                {
                  e_rabs_done ++;
                  S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).e_rabs[e_rab].e_rab_id = UE_info->e_rab[e_rab].param.e_rab_id;
                  // TODO add other information from S1-U when it will be integrated
                }
                else
                {
                  e_rabs_failed ++;
                  S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).e_rabs_failed[e_rab].e_rab_id = UE_info->e_rab[e_rab].param.e_rab_id;
                  // TODO add cause when it will be integrated
                }
              }
              S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_e_rabs = e_rabs_done;
              S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_e_rabs_failed = e_rabs_failed;

              itti_send_msg_to_task(TASK_S1AP, Mod_id, msg_p);
            }
870
871
872
# endif
          }
#endif
873
          break;
winckel's avatar
RRC:    
winckel committed
874

875
876
877
878
879
880
        case UL_DCCH_MessageType__c1_PR_rrcConnectionReestablishmentComplete:
          LOG_D (RRC,
                 "[MSC_MSG][FRAME %05d][RLC][MOD %02d][RB %02d][--- RLC_DATA_IND %d bytes "
                 "(rrcConnectionReestablishmentComplete) --->][RRC_eNB][MOD %02d][]\n",
                 frame, Mod_id, DCCH, sdu_size, Mod_id);
          break;
winckel's avatar
RRC:    
winckel committed
881

882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
        case UL_DCCH_MessageType__c1_PR_rrcConnectionSetupComplete:
          LOG_D (RRC,
                 "[MSC_MSG][FRAME %05d][RLC][MOD %02d][RB %02d][--- RLC_DATA_IND %d bytes "
                 "(RRCConnectionSetupComplete) --->][RRC_eNB][MOD %02d][]\n",
                 frame, Mod_id, DCCH, sdu_size, Mod_id);

          if (ul_dcch_msg->message.choice.c1.choice.
              rrcConnectionSetupComplete.criticalExtensions.present ==
              RRCConnectionSetupComplete__criticalExtensions_PR_c1)
            {
              if (ul_dcch_msg->message.choice.c1.choice.
                  rrcConnectionSetupComplete.criticalExtensions.choice.c1.
                  present ==
                  RRCConnectionSetupComplete__criticalExtensions__c1_PR_rrcConnectionSetupComplete_r8)
                {
                  rrc_eNB_process_RRCConnectionSetupComplete (Mod_id, frame,
                                                              UE_index,
                                                              &ul_dcch_msg->
                                                              message.choice.
                                                              c1.choice.
                                                              rrcConnectionSetupComplete.
                                                              criticalExtensions.
                                                              choice.c1.
                                                              choice.
                                                              rrcConnectionSetupComplete_r8);
907
                  eNB_rrc_inst[Mod_id].Info.UE[UE_index].Status = RRC_CONNECTED;
908
909
910
911
912
913
914
915
916
                  LOG_I (RRC, "[eNB %d] UE %d State = RRC_CONNECTED \n",
                         Mod_id, UE_index);
                  LOG_D (RRC,
                         "[MSC_NBOX][FRAME %05d][RRC_eNB][MOD %02d][][Rx RRCConnectionSetupComplete\n"
                         "Now CONNECTED with UE %d][RRC_eNB][MOD %02d][]\n",
                         frame, Mod_id, UE_index, Mod_id);
                }
            }
          break;
winckel's avatar
RRC:    
winckel committed
917

918
919
920
921
922
923
924
925
        case UL_DCCH_MessageType__c1_PR_securityModeComplete:
          LOG_I (RRC,
                 "[eNB %d] Frame %d received securityModeComplete on UL-DCCH %d from UE %d\n",
                 Mod_id, frame, DCCH, UE_index);
          LOG_D (RRC,
                 "[MSC_MSG][FRAME %05d][RLC][MOD %02d][RB %02d][--- RLC_DATA_IND %d bytes "
                 "(securityModeComplete) --->][RRC_eNB][MOD %02d][]\n", frame,
                 Mod_id, DCCH, sdu_size, Mod_id);
926
#ifdef XER_PRINT
927
          xer_fprint (stdout, &asn_DEF_UL_DCCH_Message, (void *) ul_dcch_msg);
928
#endif
929
930
931
932
933
          // confirm with PDCP about the security mode for DCCH
          //rrc_pdcp_config_req (Mod_id, frame, 1,ACTION_SET_SECURITY_MODE, (UE_index * NB_RB_MAX) + DCCH, 0x77);
          // continue the procedure
          rrc_eNB_generate_UECapabilityEnquiry (Mod_id, frame, UE_index);
          break;
934

935
936
937
938
939
        case UL_DCCH_MessageType__c1_PR_securityModeFailure:
          LOG_D (RRC,
                 "[MSC_MSG][FRAME %05d][RLC][MOD %02d][RB %02d][--- RLC_DATA_IND %d bytes "
                 "(securityModeFailure) --->][RRC_eNB][MOD %02d][]\n", frame,
                 Mod_id, DCCH, sdu_size, Mod_id);
940
#ifdef XER_PRINT
941
          xer_fprint (stdout, &asn_DEF_UL_DCCH_Message, (void *) ul_dcch_msg);
942
#endif
943
944
945
946
947
          // cancel the security mode in PDCP

          // followup with the remaining procedure
          rrc_eNB_generate_UECapabilityEnquiry (Mod_id, frame, UE_index);
          break;
winckel's avatar
RRC:    
winckel committed
948

949
950
951
952
953
954
955
956
        case UL_DCCH_MessageType__c1_PR_ueCapabilityInformation:
          LOG_I (RRC,
                 "[eNB %d] Frame %d received ueCapabilityInformation on UL-DCCH %d from UE %d\n",
                 Mod_id, frame, DCCH, UE_index);
          LOG_D (RRC,
                 "[MSC_MSG][FRAME %05d][RLC][MOD %02d][RB %02d][--- RLC_DATA_IND %d bytes "
                 "(UECapabilityInformation) --->][RRC_eNB][MOD %02d][]\n",
                 frame, Mod_id, DCCH, sdu_size, Mod_id);
957
#ifdef XER_PRINT
958
          xer_fprint (stdout, &asn_DEF_UL_DCCH_Message, (void *) ul_dcch_msg);
959
#endif
960
961
962
963
964
965
966
967
968
969
970
971
972
973
          dec_rval = uper_decode (NULL,
                                  &asn_DEF_UE_EUTRA_Capability,
                                  (void **) &UE_EUTRA_Capability,
                                  ul_dcch_msg->message.choice.c1.choice.
                                  ueCapabilityInformation.criticalExtensions.
                                  choice.c1.choice.ueCapabilityInformation_r8.
                                  ue_CapabilityRAT_ContainerList.list.
                                  array[0]->ueCapabilityRAT_Container.buf,
                                  ul_dcch_msg->message.choice.c1.choice.
                                  ueCapabilityInformation.criticalExtensions.
                                  choice.c1.choice.ueCapabilityInformation_r8.
                                  ue_CapabilityRAT_ContainerList.list.
                                  array[0]->ueCapabilityRAT_Container.size, 0,
                                  0);
974
#ifdef XER_PRINT
975
976
          xer_fprint (stdout, &asn_DEF_UE_EUTRA_Capability,
                      (void *) UE_EUTRA_Capability);
977
#endif
978
979
980
981
982
983
984
985
986
987

#if defined(ENABLE_USE_MME)
          if (oai_emulation.info.mme_enabled == 1)
          {
              eNB_RRC_UE_INFO *UE_info = &eNB_rrc_inst[Mod_id].Info.UE[UE_index];

# if defined(ENABLE_ITTI)
            /* Process e RAB parameters received from S1AP one by one (assuming that only one will be received from real network this should be OK) */
            if  (UE_info->nb_of_e_rabs > 0)
            {
988
                /* Process the first e RAB configuration from S1AP initial_context_setup_req */
989
990
                rrc_eNB_generate_defaultRRCConnectionReconfiguration (Mod_id, frame,
                                                                      UE_index,
991
992
                                                                      UE_info->e_rab[UE_info->index_of_e_rabs].param.nas_pdu.buffer,
                                                                      UE_info->e_rab[UE_info->index_of_e_rabs].param.nas_pdu.length,
993
994
                                                                      eNB_rrc_inst[Mod_id].HO_flag);
                /* Free the NAS PDU buffer and invalidate it */
995
                if (UE_info->e_rab[UE_info->index_of_e_rabs].param.nas_pdu.buffer != NULL)
996
                {
997
                  free (UE_info->e_rab[UE_info->index_of_e_rabs].param.nas_pdu.buffer);
998
                }
999
                UE_info->e_rab[UE_info->index_of_e_rabs].param.nas_pdu.buffer = NULL;
1000
                UE_info->nb_of_e_rabs --;
1001
                UE_info->index_of_e_rabs ++;
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
            }
# endif
          }
          else
#endif
          {
            rrc_eNB_generate_defaultRRCConnectionReconfiguration (Mod_id, frame,
                                                                  UE_index,
                                                                  NULL, 0, eNB_rrc_inst[Mod_id].HO_flag);
          }
1012
          break;
winckel's avatar
RRC:    
winckel committed
1013

1014
1015
        case UL_DCCH_MessageType__c1_PR_ulHandoverPreparationTransfer:
          break;
winckel's avatar
RRC:    
winckel committed
1016

1017
        case UL_DCCH_MessageType__c1_PR_ulInformationTransfer:
winckel's avatar
RRC:    
winckel committed
1018
#if defined(ENABLE_USE_MME)
1019
1020
          {
            if (oai_emulation.info.mme_enabled == 1)
winckel's avatar
RRC:    
winckel committed
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
# if defined(ENABLE_ITTI)
            {
              ULInformationTransfer_t *ulInformationTransfer = &ul_dcch_msg->message.choice.c1.choice.ulInformationTransfer;

              if ((ulInformationTransfer->criticalExtensions.present ==
                  ULInformationTransfer__criticalExtensions_PR_c1)
                      && (ulInformationTransfer->criticalExtensions.choice.c1.present ==
                          ULInformationTransfer__criticalExtensions__c1_PR_ulInformationTransfer_r8)
                      && (ulInformationTransfer->criticalExtensions.choice.c1.choice.ulInformationTransfer_r8.dedicatedInfoType.present ==
                          ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS))
1031
              {
winckel's avatar
RRC:    
winckel committed
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
                /* This message hold a dedicated info NAS payload, forward it to NAS */
                struct ULInformationTransfer_r8_IEs__dedicatedInfoType *dedicatedInfoType =
                    &ulInformationTransfer->criticalExtensions.choice.c1.choice.ulInformationTransfer_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_ENB, S1AP_UPLINK_NAS);
winckel's avatar
winckel committed
1043
                S1AP_UPLINK_NAS (msg_p).eNB_ue_s1ap_id = eNB_rrc_inst[Mod_id].Info.UE[UE_index].eNB_ue_s1ap_id;
winckel's avatar
RRC:    
winckel committed
1044
1045
1046
                S1AP_UPLINK_NAS (msg_p).nas_pdu.length = pdu_length;
                S1AP_UPLINK_NAS (msg_p).nas_pdu.buffer = pdu_buffer;

1047
                itti_send_msg_to_task(TASK_S1AP, Mod_id, msg_p);
1048
              }
winckel's avatar
RRC:    
winckel committed
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
            }
# else
            {
              ULInformationTransfer_t *ulInformationTransfer;
              ulInformationTransfer =
                &ul_dcch_msg->message.choice.c1.choice.
                ulInformationTransfer;

              if (ulInformationTransfer->criticalExtensions.present ==
                  ULInformationTransfer__criticalExtensions_PR_c1)
                {
                  if (ulInformationTransfer->criticalExtensions.choice.c1.
                      present ==
                      ULInformationTransfer__criticalExtensions__c1_PR_ulInformationTransfer_r8)
                    {

                      ULInformationTransfer_r8_IEs_t
                        *ulInformationTransferR8;
                      ulInformationTransferR8 =
                        &ulInformationTransfer->criticalExtensions.choice.
                        c1.choice.ulInformationTransfer_r8;
                      if (ulInformationTransferR8->dedicatedInfoType.
                          present ==
                          ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS)
                        s1ap_eNB_new_data_request (Mod_id, UE_index,
                                                   ulInformationTransferR8->
                                                   dedicatedInfoType.choice.
                                                   dedicatedInfoNAS.buf,
                                                   ulInformationTransferR8->
                                                   dedicatedInfoType.choice.
                                                   dedicatedInfoNAS.size);
                    }
                }
            }
# endif
1084
          }
1085
#endif
1086
          break;
winckel's avatar
RRC:    
winckel committed
1087

1088
1089
        case UL_DCCH_MessageType__c1_PR_counterCheckResponse:
          break;
winckel's avatar
RRC:    
winckel committed
1090

1091
#ifdef Rel10
1092
1093
        case UL_DCCH_MessageType__c1_PR_ueInformationResponse_r9:
          break;
winckel's avatar
RRC:    
winckel committed
1094

1095
1096
        case UL_DCCH_MessageType__c1_PR_proximityIndication_r9:
          break;
winckel's avatar
RRC:    
winckel committed
1097

1098
1099
        case UL_DCCH_MessageType__c1_PR_rnReconfigurationComplete_r10:
          break;
winckel's avatar
RRC:    
winckel committed
1100

1101
1102
        case UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10:
          break;
winckel's avatar
RRC:    
winckel committed
1103

1104
1105
        case UL_DCCH_MessageType__c1_PR_interFreqRSTDMeasurementIndication_r10:
          break;
1106
#endif
winckel's avatar
RRC:    
winckel committed
1107

1108
1109
1110
1111
1112
1113
1114
1115
1116
        default:
          LOG_E (RRC, "[UE %d] Frame %d : Unknown message\n", Mod_id, frame);
          return -1;
        }
      return 0;
    }
  else
    {
      LOG_E (RRC, "[UE %d] Frame %d : Unknown error\n", Mod_id, frame);
1117
1118
1119
1120
1121
1122
      return -1;
    }

}

/*------------------------------------------------------------------------------*/
winckel's avatar
RRC:    
winckel committed
1123
int rrc_eNB_decode_ccch (u8 Mod_id, u32 frame, SRB_INFO * Srb_info)
1124
{
1125
1126
  /*------------------------------------------------------------------------------*/

1127
  u16 Idx, UE_index;
1128
1129
1130

  asn_dec_rval_t dec_rval;
  //UL_CCCH_Message_t ulccchmsg;
1131
  UL_CCCH_Message_t *ul_ccch_msg = NULL;        //&ulccchmsg;
1132
  RRCConnectionRequest_r8_IEs_t *rrcConnectionRequest;
1133
  int i, rval;
1134
1135
1136
1137


  //memset(ul_ccch_msg,0,sizeof(UL_CCCH_Message_t));

1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
  LOG_T (RRC, "[eNB %d] Frame %d: Decoding UL CCCH %x.%x.%x.%x.%x.%x (%p)\n",
         Mod_id, frame, ((uint8_t *) Srb_info->Rx_buffer.Payload)[0],
         ((uint8_t *) Srb_info->Rx_buffer.Payload)[1],
         ((uint8_t *) Srb_info->Rx_buffer.Payload)[2],
         ((uint8_t *) Srb_info->Rx_buffer.Payload)[3],
         ((uint8_t *) Srb_info->Rx_buffer.Payload)[4],
         ((uint8_t *) Srb_info->Rx_buffer.Payload)[5],
         (uint8_t *) Srb_info->Rx_buffer.Payload);
  dec_rval =
    uper_decode (NULL, &asn_DEF_UL_CCCH_Message, (void **) &ul_ccch_msg,
                 (uint8_t *) Srb_info->Rx_buffer.Payload, 100, 0, 0);
1149
1150
1151
1152
1153
1154
1155
1156

#if defined(ENABLE_ITTI)
  {
    MessageDef *message_p;

    message_p = itti_alloc_new_message (TASK_RRC_ENB, RRC_UL_CCCH_MESSAGE);
    memcpy (&message_p->msg, (void *) ul_ccch_msg, sizeof(RrcUlCcchMessage));

1157
    itti_send_msg_to_task (TASK_UNKNOWN, Mod_id, message_p);
1158
1159
1160
1161
  }
#endif

for (i = 0; i < 8; i++)
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
    LOG_T (RRC, "%x.", ((u8 *) & ul_ccch_msg)[i]);
  if (dec_rval.consumed == 0)
    {
      LOG_E (RRC, "[eNB %d] FATAL Error in receiving CCCH\n", Mod_id);
      return -1;                //mac_xface->macphy_exit(""); //exit(-1);
    }
  if (ul_ccch_msg->message.present == UL_CCCH_MessageType_PR_c1)
    {

      switch (ul_ccch_msg->message.choice.c1.present)
        {

        case UL_CCCH_MessageType__c1_PR_NOTHING:
          LOG_I (RRC,
                 "[eNB %d] Frame %d : Received PR_NOTHING on UL-CCCH-Message\n",
                 Mod_id, frame);
          break;

        case UL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentRequest:
          LOG_D (RRC,
                 "[MSC_MSG][FRAME %05d][MAC_eNB][MOD %02d][][--- MAC_DATA_IND (rrcConnectionReestablishmentRequest on SRB0) -->][RRC_eNB][MOD %02d][]\n",
                 frame, Mod_id, Mod_id);
          LOG_I (RRC,
                 "[eNB %d] Frame %d : RRCConnectionReestablishmentRequest not supported yet\n",
                 Mod_id, frame);
          break;

        case UL_CCCH_MessageType__c1_PR_rrcConnectionRequest:
          LOG_D (RRC,
                 "[MSC_MSG][FRAME %05d][MAC_eNB][MOD %02d][][--- MAC_DATA_IND  (rrcConnectionRequest on SRB0) -->][RRC_eNB][MOD %02d][]\n",
                 frame, Mod_id, Mod_id);

1194
1195
1196
1197
          rrcConnectionRequest = &ul_ccch_msg->message.choice.c1.choice.rrcConnectionRequest.criticalExtensions.choice.rrcConnectionRequest_r8;
          UE_index = get_next_UE_index (Mod_id,
					(u8 *) rrcConnectionRequest->ue_Identity.
					choice.randomValue.buf);
1198

1199
          if (UE_index != UE_INDEX_INVALID)
1200
            {
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
#if defined(ENABLE_ITTI)
              /* Check s-TMSI presence in message */
              eNB_rrc_inst[Mod_id].Info.UE[UE_index].Initialue_identity_s_TMSI.presence =
                      (rrcConnectionRequest->ue_Identity.present == InitialUE_Identity_PR_s_TMSI);
              if (eNB_rrc_inst[Mod_id].Info.UE[UE_index].Initialue_identity_s_TMSI.presence) {
                /* Save s-TMSI */
                S_TMSI_t s_TMSI = rrcConnectionRequest->ue_Identity.choice.s_TMSI;

                eNB_rrc_inst[Mod_id].Info.UE[UE_index].Initialue_identity_s_TMSI.mme_code = BIT_STRING_to_uint8 (&s_TMSI.mmec);
                eNB_rrc_inst[Mod_id].Info.UE[UE_index].Initialue_identity_s_TMSI.m_tmsi = BIT_STRING_to_uint32 (&s_TMSI.m_TMSI);
              }
              eNB_rrc_inst[Mod_id].Info.UE[UE_index].establishment_cause = rrcConnectionRequest->establishmentCause;
#endif
1214
1215
1216

              //      memcpy(&Rrc_xface->UE_id[Mod_id][UE_index],(u8 *)rrcConnectionRequest->ue_Identity.choice.randomValue.buf,5);
              memcpy (&eNB_rrc_inst[Mod_id].Info.UE_list[UE_index],
1217
                      (u8 *) rrcConnectionRequest->ue_Identity.choice.randomValue.buf, 5);
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231

              LOG_I (RRC,
                     "[eNB %d] Frame %d : Accept new connection from UE %d (%x%x%x%x%x)\n",
                     Mod_id, frame, UE_index,
                     eNB_rrc_inst[Mod_id].Info.UE_list[UE_index][0],
                     eNB_rrc_inst[Mod_id].Info.UE_list[UE_index][1],
                     eNB_rrc_inst[Mod_id].Info.UE_list[UE_index][2],
                     eNB_rrc_inst[Mod_id].Info.UE_list[UE_index][3],
                     eNB_rrc_inst[Mod_id].Info.UE_list[UE_index][4]);

              //CONFIG SRB2  (DCCHs, ONE per User)  //meas && lchan Cfg
              //eNB_rrc_inst[Mod_id].Info.Dtch_bd_config[UE_index].Status=NEED_RADIO_CONFIG;
              //eNB_rrc_inst[Mod_id].Info.Dtch_bd_config[UE_index].Next_eNBeck_frame=Rrc_xface->Frame_index+1;
              eNB_rrc_inst[Mod_id].Info.Nb_ue++;
1232
1233

#ifndef NO_RRM
1234
              send_msg (&S_rrc, msg_rrc_MR_attach_ind (Mod_id, Mac_id));
1235
1236
#else

1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
              Idx = (UE_index * NB_RB_MAX) + DCCH;
              // SRB1
              eNB_rrc_inst[Mod_id].Srb1[UE_index].Active = 1;
              eNB_rrc_inst[Mod_id].Srb1[UE_index].Srb_info.Srb_id = Idx;
              memcpy (&eNB_rrc_inst[Mod_id].Srb1[UE_index].Srb_info.
                      Lchan_desc[0], &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE);
              memcpy (&eNB_rrc_inst[Mod_id].Srb1[UE_index].Srb_info.
                      Lchan_desc[1], &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE);

              // SRB2
              eNB_rrc_inst[Mod_id].Srb2[UE_index].Active = 1;
              eNB_rrc_inst[Mod_id].Srb2[UE_index].Srb_info.Srb_id = Idx;
              memcpy (&eNB_rrc_inst[Mod_id].Srb2[UE_index].Srb_info.
                      Lchan_desc[0], &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE);
              memcpy (&eNB_rrc_inst[Mod_id].Srb2[UE_index].Srb_info.
                      Lchan_desc[1], &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE);

              rrc_eNB_generate_RRCConnectionSetup (Mod_id, frame, UE_index);
              //LOG_D(RRC, "[MSC_NBOX][FRAME %05d][RRC_eNB][MOD %02d][][Tx RRCConnectionSetup][RRC_eNB][MOD %02d][]\n",
              //      frame, Mod_id, Mod_id);

              //LOG_D(RRC,"[eNB %d] RLC AM allocation index@0 is %d\n",Mod_id,rlc[Mod_id].m_rlc_am_array[0].allocation);
              //LOG_D(RRC,"[eNB %d] RLC AM allocation index@1 is %d\n",Mod_id,rlc[Mod_id].m_rlc_am_array[1].allocation);
1260
              LOG_I (RRC,"[eNB %d] CALLING RLC CONFIG SRB1 (rbid %d) for UE %d\n",Mod_id, Idx, UE_index);
1261
1262
1263
1264
1265
1266
1267
1268
1269

              //      rrc_pdcp_config_req (Mod_id, frame, 1, ACTION_ADD, idx, UNDEF_SECURITY_MODE);

              //      rrc_rlc_config_req(Mod_id,frame,1,ACTION_ADD,Idx,SIGNALLING_RADIO_BEARER,Rlc_info_am_config);

              rrc_pdcp_config_asn1_req (Mod_id, frame, 1, UE_index,
                                        eNB_rrc_inst[Mod_id].
                                        SRB_configList[UE_index],
                                        (DRB_ToAddModList_t *) NULL,
1270
1271
1272
1273
1274
                                        (DRB_ToReleaseList_t *) NULL,
                                        0xff,
                                        NULL,
                                        NULL,
                                        NULL
1275
#ifdef Rel10
1276
                                        , (PMCH_InfoList_r9_t *) NULL
1277
#endif
1278
1279
1280
1281
1282
1283
1284
                );

              rrc_rlc_config_asn1_req (Mod_id, frame, 1, UE_index,
                                       eNB_rrc_inst[Mod_id].
                                       SRB_configList[UE_index],
                                       (DRB_ToAddModList_t *) NULL,
                                       (DRB_ToReleaseList_t *) NULL
1285
#ifdef Rel10
1286
                                       , (PMCH_InfoList_r9_t *) NULL
1287
#endif
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
                );
              //LOG_D(RRC,"[eNB %d] RLC AM allocation index@0 is %d\n",Mod_id,rlc[Mod_id].m_rlc_am_array[0].allocation);
              //LOG_D(RRC,"[eNB %d] RLC AM allocation index@1 is %d\n",Mod_id,rlc[Mod_id].m_rlc_am_array[1].allocation);

              /*

                 LOG_D(RRC,"[eNB %d] CALLING RLC CONFIG SRB2 (rbid %d) for UE %d\n",
                 Mod_id,Idx+1,UE_index);
                 Mac_rlc_xface->rrc_rlc_config_req(Mod_id,ACTION_ADD,Idx+1,SIGNALLING_RADIO_BEARER,Rlc_info_am_config);
                 LOG_D(RRC,"[eNB %d] RLC AM allocation index@0 is %d\n",Mod_id,rlc[Mod_id].m_rlc_am_array[0].allocation);
                 LOG_D(RRC,"[eNB %d] RLC AM allocation index@1 is %d\n",rlc[Mod_id].m_rlc_am_array[1].allocation);
               */
1300
#endif //NO_RRM
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
            }
          else
            {
              LOG_E (RRC, "can't add UE, max user count reached!\n");
            }
          break;

        default:
          LOG_E (RRC, "[eNB %d] Frame %d : Unknown message\n", Mod_id, frame);
          rval = -1;
1311
          break;
1312
1313
1314
1315
1316
1317
        }
      rval = 0;
    }
  else
    {
      LOG_E (RRC, "[eNB %d] Frame %d : Unknown error \n", Mod_id, frame);
1318
1319
1320
1321
1322
      rval = -1;
    }
  return rval;
}

winckel's avatar
RRC:    
winckel committed
1323
1324
1325
1326
void rrc_eNB_process_RRCConnectionSetupComplete (u8 Mod_id,
                                                 u32 frame,
                                                 u8 UE_index,
                                                 RRCConnectionSetupComplete_r8_IEs_t *rrcConnectionSetupComplete)
1327
{
1328
  LOG_I (RRC, "[eNB %d][RAPROC] Frame %d : Logical Channel UL-DCCH, ""processing RRCConnectionSetupComplete from UE %d\n",
1329
         Mod_id, frame, UE_index);
1330
1331

  // Forward message to S1AP layer
1332
#if defined(ENABLE_USE_MME)
1333
  if (oai_emulation.info.mme_enabled == 1)
1334
1335
1336
1337
1338
# if defined(ENABLE_ITTI)
  {
    MessageDef *message_p;

    message_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_NAS_FIRST_REQ);
1339
1340
    eNB_rrc_inst[Mod_id].Info.UE[UE_index].ue_initial_id = get_next_ue_initial_id(Mod_id);
    S1AP_NAS_FIRST_REQ (message_p).ue_initial_id = eNB_rrc_inst[Mod_id].Info.UE[UE_index].ue_initial_id;
winckel's avatar