rrc_eNB.c 305 KB
Newer Older
1
2
3
4
5
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
Cedric Roux's avatar
Cedric Roux committed
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */
21
22
23

/*! \file rrc_eNB.c
 * \brief rrc procedures for eNB
24
 * \author Navid Nikaein and  Raymond Knopp
nikaeinn's avatar
nikaeinn committed
25
 * \date 2011 - 2014
26
27
 * \version 1.0
 * \company Eurecom
nikaeinn's avatar
nikaeinn committed
28
 * \email: navid.nikaein@eurecom.fr and raymond.knopp@eurecom.fr
29
 */
gauthier's avatar
gauthier committed
30
31
#define RRC_ENB
#define RRC_ENB_C
32
33
34

#include "defs.h"
#include "extern.h"
35
#include "assertions.h"
36
#include "common/ran_context.h"
37
#include "asn1_conversions.h"
38
39
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
#include "LAYER2/RLC/rlc.h"
40
#include "LAYER2/MAC/proto.h"
41
42
43
44
#include "UTIL/LOG/log.h"
#include "COMMON/mac_rrc_primitives.h"
#include "RRC/LITE/MESSAGES/asn1_msg.h"
#include "RRCConnectionRequest.h"
45
46
#include "RRCConnectionReestablishmentRequest.h"
//#include "ReestablishmentCause.h"
47
#include "BCCH-BCH-Message.h"
48
49
50
51
52
#include "UL-CCCH-Message.h"
#include "DL-CCCH-Message.h"
#include "UL-DCCH-Message.h"
#include "DL-DCCH-Message.h"
#include "TDD-Config.h"
53
#include "HandoverCommand.h"
54
55
#include "rlc.h"
#include "SIMULATION/ETH_TRANSPORT/extern.h"
56
57
58
#include "rrc_eNB_UE_context.h"
#include "platform_types.h"
#include "msc.h"
59

60
61
#include "T.h"

Cedric Roux's avatar
Cedric Roux committed
62
//#if defined(Rel10) || defined(Rel14)
63
#include "MeasResults.h"
64
65
66
//#endif

#ifdef USER_MODE
gauthier's avatar
   
gauthier committed
67
68
69
70
#   include "RRC/NAS/nas_config.h"
#   include "RRC/NAS/rb_config.h"
#   include "OCG.h"
#   include "OCG_extern.h"
71
72
#endif

73
#if defined(ENABLE_SECURITY)
gauthier's avatar
   
gauthier committed
74
#   include "UTIL/OSA/osa_defs.h"
75
76
#endif

77
#if defined(ENABLE_USE_MME)
gauthier's avatar
   
gauthier committed
78
#   include "rrc_eNB_S1AP.h"
79
#   include "rrc_eNB_GTPV1U.h"
gauthier's avatar
   
gauthier committed
80
81
82
83
#   if defined(ENABLE_ITTI)
#   else
#      include "../../S1AP/s1ap_eNB.h"
#   endif
84
85
#endif

86
#include "pdcp.h"
87
#include "gtpv1u_eNB_task.h"
88
89

#if defined(ENABLE_ITTI)
gauthier's avatar
   
gauthier committed
90
#   include "intertask_interface.h"
91
92
#endif

93
#if ENABLE_RAL
gauthier's avatar
   
gauthier committed
94
#   include "rrc_eNB_ral.h"
gauthier's avatar
gauthier committed
95
96
#endif

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

99
#if defined(FLEXRAN_AGENT_SB_IF)
100
#include "flexran_agent_extern.h"
101
#endif
102
//#define XER_PRINT
103

104
105
extern RAN_CONTEXT_t RC;

106
#ifdef PHY_EMUL
gauthier's avatar
   
gauthier committed
107
extern EMULATION_VARS              *Emul_vars;
108
#endif
gauthier's avatar
   
gauthier committed
109
110
extern eNB_MAC_INST                *eNB_mac_inst;
extern UE_MAC_INST                 *UE_mac_inst;
111
#ifdef BIGPHYSAREA
112
extern void*                        bigphys_malloc(int);
113
114
#endif

gauthier's avatar
   
gauthier committed
115
extern uint16_t                     two_tier_hexagonal_cellIds[7];
winckel's avatar
RRC:    
winckel committed
116

gauthier's avatar
   
gauthier committed
117
mui_t                               rrc_eNB_mui = 0;
winckel's avatar
RRC:    
winckel committed
118

119
120
121
//-----------------------------------------------------------------------------
static void
init_SI(
122
123
  const protocol_ctxt_t* const ctxt_pP,
  const int              CC_id
winckel's avatar
winckel committed
124
#if defined(ENABLE_ITTI)
125
126
  ,
  RrcConfigurationReq * configuration
winckel's avatar
winckel committed
127
#endif
128
)
129
//-----------------------------------------------------------------------------
130
{
Cedric Roux's avatar
Cedric Roux committed
131
#if defined(Rel10) || defined(Rel14)
132
133
  int                                 i;
#endif
134
135
136
137
138

#ifdef Rel14
  SystemInformationBlockType1_v1310_IEs_t *sib1_v13ext=(SystemInformationBlockType1_v1310_IEs_t *)NULL;
#endif

139
  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MIB = (uint8_t*) malloc16(4);
140
141
142
143
144
145
  // copy basic parameters
  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId      = configuration->Nid_cell[CC_id];
  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB           = configuration->nb_antenna_ports[CC_id];
  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Ncp             = configuration->prefix_type[CC_id];
  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].dl_CarrierFreq  = configuration->downlink_frequency[CC_id];
  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].ul_CarrierFreq  = configuration->downlink_frequency[CC_id]+ configuration->uplink_frequency_offset[CC_id];
146
147
148
#ifdef Rel14
  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].pbch_repetition = configuration->pbch_repetition[CC_id];
#endif
149
  LOG_I(RRC, "Configuring MIB (N_RB_DL %d,phich_Resource %d,phich_Duration %d)\n", 
knopp's avatar
knopp committed
150
151
152
	(int)configuration->N_RB_DL[CC_id],
	(int)configuration->phich_resource[CC_id],
	(int)configuration->phich_duration[CC_id]);
153
154
155
156
157
158
159
160
161
162
163
164
165
166
  do_MIB(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id],
#ifdef ENABLE_ITTI
	 configuration->N_RB_DL[CC_id],
	 configuration->phich_resource[CC_id],
	 configuration->phich_duration[CC_id]
#else
	 50,0,0
#endif
	 ,0);
  

  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1 = 0;
  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB23 = 0;
  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB1 = (uint8_t*) malloc16(32);
gauthier's avatar
   
gauthier committed
167

168
169
170
  AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB1!=NULL,PROTOCOL_RRC_CTXT_FMT" init_SI: FATAL, no memory for SIB1 allocated\n",
	      PROTOCOL_RRC_CTXT_ARGS(ctxt_pP));
  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1 = do_SIB1(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id],ctxt_pP->module_id,CC_id
winckel's avatar
winckel committed
171
#if defined(ENABLE_ITTI)
172
								   , configuration
winckel's avatar
winckel committed
173
#endif
174
								   );
175

176
  AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1 != 255,"FATAL, RC.rrc[enb_mod_idP].carrier[CC_id].sizeof_SIB1 == 255");
177

178
  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB23 = (uint8_t*) malloc16(64);
179
180
181
182
183
  AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB23!=NULL,"cannot allocate memory for SIB");
  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB23 = do_SIB23(
								     ctxt_pP->module_id,
								     
								     CC_id
184
#if defined(ENABLE_ITTI)
185
								     , configuration
gauthier's avatar
   
gauthier committed
186
#endif
187
								     );
188

189
190
  AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB23 != 255,"FATAL, RC.rrc[mod].carrier[CC_id].sizeof_SIB23 == 255");
  
191

192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
  LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" SIB2/3 Contents (partial)\n",
	PROTOCOL_RRC_CTXT_ARGS(ctxt_pP));
  LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.n_SB = %ld\n",
	PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
	RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon.
	pusch_ConfigBasic.n_SB);
  LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.hoppingMode = %ld\n",
	PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
	RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon.
	pusch_ConfigBasic.hoppingMode);
  LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.pusch_HoppingOffset = %ld\n",
	PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
	RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon.
	pusch_ConfigBasic.pusch_HoppingOffset);
  LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.enable64QAM = %d\n",
	PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
	(int)RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon.
	pusch_ConfigBasic.enable64QAM);
  LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.groupHoppingEnabled = %d\n",
	PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
	(int)RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon.
	ul_ReferenceSignalsPUSCH.groupHoppingEnabled);
  LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.groupAssignmentPUSCH = %ld\n",
	PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
	RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon.
	ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH);
  LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.sequenceHoppingEnabled = %d\n",
	PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
	(int)RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon.
	ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled);
  LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.cyclicShift  = %ld\n",
	PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
	RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon.
	ul_ReferenceSignalsPUSCH.cyclicShift);
  
Cedric Roux's avatar
Cedric Roux committed
227
#if defined(Rel10) || defined(Rel14)
228

229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
  if (RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MBMS_flag > 0) {
    for (i = 0; i < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.count; i++) {
      // SIB 2
      //   LOG_D(RRC, "[eNB %d] mbsfn_SubframeConfigList.list.count = %ld\n", enb_mod_idP, RC.rrc[enb_mod_idP].sib2->mbsfn_SubframeConfigList->list.count);
      LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" SIB13 contents for MBSFN subframe allocation %d/%d(partial)\n",
	    PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
	    i,
	    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.count);
      LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" mbsfn_Subframe_pattern is  = %x\n",
	    PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
	    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0] >> 0);
      LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" radioframe_allocation_period  = %ld (just index number, not the real value)\n",
	    PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
	    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod);   // need to display the real value, using array of char (like in dumping SIB2)
      LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" radioframe_allocation_offset  = %ld\n",
	    PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
	    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset);
246
    }
247
248
249
250
251
252
253
254
255
256
257
258
259
260
    
    //   SIB13
    for (i = 0; i < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9.list.count; i++) {
      LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" SIB13 contents for MBSFN sync area %d/%d (partial)\n",
	    PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
	    i,
	    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9.list.count);
      LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" MCCH Repetition Period: %ld (just index number, not real value)\n",
	    PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
	    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9);
      LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" MCCH Offset: %ld\n",
	    PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
	    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_Offset_r9);
    }
261
262
  }
  else memset((void*)&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13,0,sizeof(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13));
263
264
#endif

265
266
267
  LOG_D(RRC,
	PROTOCOL_RRC_CTXT_FMT" RRC_UE --- MAC_CONFIG_REQ (SIB1.tdd & SIB2 params) ---> MAC_UE\n",
	PROTOCOL_RRC_CTXT_ARGS(ctxt_pP));
268
269
270
271
272

#ifdef Rel14
  if ((RC.rrc[ctxt_pP->module_id]->carrier[CC_id].mib.message.schedulingInfoSIB1_BR_r13>0) && 
      (RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR!=NULL)) {
      AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension!=NULL,
knopp's avatar
knopp committed
273
		  "sib2_br->nonCriticalExtension is null (v8.9)\n");
274
      AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension!=NULL,
knopp's avatar
knopp committed
275
		  "sib2_br->nonCriticalExtension is null (v9.2)\n");
276
      AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL,
knopp's avatar
knopp committed
277
		  "sib2_br->nonCriticalExtension is null (v11.3)\n");
278
      AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL,
knopp's avatar
knopp committed
279
280
		  "sib2_br->nonCriticalExtension is null (v12.5)\n");
      AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL,
281
		  "sib2_br->nonCriticalExtension is null (v13.10)\n");
knopp's avatar
knopp committed
282
      sib1_v13ext = RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension;
283
284
285
  }
#endif

286
287
288
289
290
291
292
293
294
  rrc_mac_config_req_eNB(ctxt_pP->module_id, CC_id,
			 RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId,
			 RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB,
			 RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Ncp,
			 RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1->freqBandIndicator,
			 RC.rrc[ctxt_pP->module_id]->carrier[CC_id].dl_CarrierFreq,
#ifdef Rel14
			 RC.rrc[ctxt_pP->module_id]->carrier[CC_id].pbch_repetition,
#endif
295
			 0, // rnti
296
297
298
299
300
301
302
303
304
			 (BCCH_BCH_Message_t *)
			 &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].mib,
			 (RadioResourceConfigCommonSIB_t *) &
			 RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon,
#if defined(Rel14)
			 (RadioResourceConfigCommonSIB_t *) &
			 RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2_BR->radioResourceConfigCommon,
#endif
			 (struct PhysicalConfigDedicated *)NULL,
Cedric Roux's avatar
Cedric Roux committed
305
#if defined(Rel10) || defined(Rel14)
306
307
308
309
310
311
312
313
314
			 (SCellToAddMod_r10_t *)NULL,
			 //(struct PhysicalConfigDedicatedSCell_r10 *)NULL,
#endif
			 (MeasObjectToAddMod_t **) NULL,
			 (MAC_MainConfig_t *) NULL, 0,
			 (struct LogicalChannelConfig *)NULL,
			 (MeasGapConfig_t *) NULL,
			 RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1->tdd_Config,
			 NULL,
315
			 &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1->schedulingInfoList,
316
317
318
319
			 RC.rrc[ctxt_pP->module_id]->carrier[CC_id].ul_CarrierFreq,
			 RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->freqInfo.ul_Bandwidth,
			 &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->freqInfo.additionalSpectrumEmission,
			 (MBSFN_SubframeConfigList_t*) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList
Cedric Roux's avatar
Cedric Roux committed
320
#if defined(Rel10) || defined(Rel14)
321
322
323
324
			 ,
			 RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MBMS_flag,
			 (MBSFN_AreaInfoList_r9_t*) & RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9,
			 (PMCH_InfoList_r9_t *) NULL
325
#endif
326
327
328
#ifdef Rel14
			 , 
			 sib1_v13ext
329
#endif
330
			 );
331
332
}

Cedric Roux's avatar
Cedric Roux committed
333
#if defined(Rel10) || defined(Rel14)
winckel's avatar
winckel committed
334
/*------------------------------------------------------------------------------*/
335
336
static void
init_MCCH(
337
338
  module_id_t enb_mod_idP,
  int CC_id
339
340
)
//-----------------------------------------------------------------------------
341
{
gauthier's avatar
   
gauthier committed
342

343
344
  int                                 sync_area = 0;
  // initialize RRC_eNB_INST MCCH entry
345
346
  RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE =
    malloc(RC.rrc[enb_mod_idP]->carrier[CC_id].num_mbsfn_sync_area * sizeof(uint8_t*));
gauthier's avatar
   
gauthier committed
347

348
  for (sync_area = 0; sync_area < RC.rrc[enb_mod_idP]->carrier[CC_id].num_mbsfn_sync_area; sync_area++) {
gauthier's avatar
   
gauthier committed
349

350
351
    RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] = 0;
    RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE[sync_area] = (uint8_t *) malloc16(32);
352

353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
    AssertFatal(RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE[sync_area] != NULL,
		"[eNB %d]init_MCCH: FATAL, no memory for MCCH MESSAGE allocated \n", enb_mod_idP);
    RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] = do_MBSFNAreaConfig(enb_mod_idP,
											    sync_area,
											    (uint8_t *)RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE[sync_area],
											    &RC.rrc[enb_mod_idP]->carrier[CC_id].mcch,
											    &RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message);
    
    LOG_I(RRC, "mcch message pointer %p for sync area %d \n",
	  RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE[sync_area],
	  sync_area);
    LOG_D(RRC, "[eNB %d] MCCH_MESSAGE  contents for Sync Area %d (partial)\n", enb_mod_idP, sync_area);
    LOG_D(RRC, "[eNB %d] CommonSF_AllocPeriod_r9 %ld\n", enb_mod_idP,
	  RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->commonSF_AllocPeriod_r9);
    LOG_D(RRC,
	  "[eNB %d] CommonSF_Alloc_r9.list.count (number of MBSFN Subframe Pattern) %d\n",
	  enb_mod_idP, RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->commonSF_Alloc_r9.list.count);
    LOG_D(RRC, "[eNB %d] MBSFN Subframe Pattern: %02x (in hex)\n",
	  enb_mod_idP,
	  RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->commonSF_Alloc_r9.list.array[0]->subframeAllocation.
	  choice.oneFrame.buf[0]);
    
    AssertFatal(RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] != 255,
		"RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] == 255");
    RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESS[sync_area].Active = 1;
378
  }
379
  
gauthier's avatar
   
gauthier committed
380

381
  //Set the RC.rrc[enb_mod_idP]->MCCH_MESS.Active to 1 (allow to  transfer MCCH message RRC->MAC in function mac_rrc_data_req)
gauthier's avatar
   
gauthier committed
382

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

386

387
388
389
  //  LOG_I(RRC, "DUY: serviceID is %d\n",RC.rrc[enb_mod_idP]->mcch_message->pmch_InfoList_r9.list.array[0]->mbms_SessionInfoList_r9.list.array[0]->tmgi_r9.serviceId_r9.buf[2]);
  //  LOG_I(RRC, "DUY: session ID is %d\n",RC.rrc[enb_mod_idP]->mcch_message->pmch_InfoList_r9.list.array[0]->mbms_SessionInfoList_r9.list.array[0]->sessionId_r9->buf[0]);
  rrc_mac_config_req_eNB(enb_mod_idP, CC_id,
390
391
392
393
			 0,0,0,0,0,
#ifdef Rel14 
			 0,
#endif
394
			 0,//rnti
395
396
			 (BCCH_BCH_Message_t *)NULL,
			 (RadioResourceConfigCommonSIB_t *) NULL,
397
398
			 (RadioResourceConfigCommonSIB_t *) NULL,
			 (struct PhysicalConfigDedicated *)NULL,
Cedric Roux's avatar
Cedric Roux committed
399
#if defined(Rel10) || defined(Rel14)
400
401
			 (SCellToAddMod_r10_t *)NULL,
			 //(struct PhysicalConfigDedicatedSCell_r10 *)NULL,
402
#endif
403
404
405
406
407
408
			 (MeasObjectToAddMod_t **) NULL,
			 (MAC_MainConfig_t *) NULL,
			 0,
			 (struct LogicalChannelConfig *)NULL,
			 (MeasGapConfig_t *) NULL,
			 (TDD_Config_t *) NULL,
409
410
411
			 (MobilityControlInfo_t *)NULL, 
			 (SchedulingInfoList_t *) NULL, 
			 0, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL
412
#if defined(Rel10) || defined(Rel14)
413
414
415
416
			 ,
			 0,
			 (MBSFN_AreaInfoList_r9_t *) NULL,
			 (PMCH_InfoList_r9_t *) & (RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9)
gauthier's avatar
   
gauthier committed
417
#   endif
418
419
420
#   ifdef Rel14
			 ,
			 (SystemInformationBlockType1_v1310_IEs_t *)NULL
gauthier's avatar
   
gauthier committed
421
#   endif
422
423
424
			 );
  
  //LOG_I(RRC,"DUY: lcid after rrc_mac_config_req is %02d\n",RC.rrc[enb_mod_idP]->mcch_message->pmch_InfoList_r9.list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9);
425

426
427
}

428
//-----------------------------------------------------------------------------
gauthier's avatar
   
gauthier committed
429
static void init_MBMS(
430
  module_id_t enb_mod_idP,
431
  int         CC_id,
432
433
434
  frame_t frameP
)
//-----------------------------------------------------------------------------
435
436
437
{
  // init the configuration for MTCH
  protocol_ctxt_t               ctxt;
gauthier's avatar
   
gauthier committed
438

439
  if (RC.rrc[enb_mod_idP]->carrier[CC_id].MBMS_flag > 0) {
440
    PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, enb_mod_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, 0,enb_mod_idP);
gauthier's avatar
   
gauthier committed
441

442
443
    LOG_D(RRC, "[eNB %d] Frame %d : Radio Bearer config request for MBMS\n", enb_mod_idP, frameP);   //check the lcid
    // Configuring PDCP and RLC for MBMS Radio Bearer
gauthier's avatar
   
gauthier committed
444

445
446
447
448
449
450
451
452
    rrc_pdcp_config_asn1_req(&ctxt,
                             (SRB_ToAddModList_t  *)NULL,  // SRB_ToAddModList
                             (DRB_ToAddModList_t  *)NULL,  // DRB_ToAddModList
                             (DRB_ToReleaseList_t *)NULL,
                             0,     // security mode
                             NULL,  // key rrc encryption
                             NULL,  // key rrc integrity
                             NULL   // key encryption
Cedric Roux's avatar
Cedric Roux committed
453
#   if defined(Rel10) || defined(Rel14)
454
                             , &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9)
gauthier's avatar
   
gauthier committed
455
#   endif
456
                             ,NULL);
gauthier's avatar
   
gauthier committed
457

458
459
460
461
    rrc_rlc_config_asn1_req(&ctxt,
                            NULL, // SRB_ToAddModList
                            NULL,   // DRB_ToAddModList
                            NULL,   // DRB_ToReleaseList
462
                            &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9));
gauthier's avatar
   
gauthier committed
463

464
465
    //rrc_mac_config_req();
  }
466
467
468
}
#endif

469
470
471
472
473
474
//-----------------------------------------------------------------------------
uint8_t
rrc_eNB_get_next_transaction_identifier(
  module_id_t enb_mod_idP
)
//-----------------------------------------------------------------------------
475
{
476
477
  static uint8_t                      rrc_transaction_identifier[NUMBER_OF_eNB_MAX];
  rrc_transaction_identifier[enb_mod_idP] = (rrc_transaction_identifier[enb_mod_idP] + 1) % RRC_TRANSACTION_IDENTIFIER_NUMBER;
478
  LOG_T(RRC,"generated xid is %d\n",rrc_transaction_identifier[enb_mod_idP]);
479
480
481
482
483
  return rrc_transaction_identifier[enb_mod_idP];
}
/*------------------------------------------------------------------------------*/
/* Functions to handle UE index in eNB UE list */

winckel's avatar
winckel committed
484

485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
////-----------------------------------------------------------------------------
//static module_id_t
//rrc_eNB_get_UE_index(
//                module_id_t enb_mod_idP,
//                uint64_t    UE_identity
//)
////-----------------------------------------------------------------------------
//{
//
//    boolean_t      reg = FALSE;
//    module_id_t    i;
//
//    AssertFatal(enb_mod_idP < NB_eNB_INST, "eNB index invalid (%d/%d)!", enb_mod_idP, NB_eNB_INST);
//
//    for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
500
//        if (RC.rrc[enb_mod_idP]->Info.UE_list[i] == UE_identity) {
501
502
503
504
505
506
507
508
509
510
511
512
513
//            // UE_identity already registered
//            reg = TRUE;
//            break;
//        }
//    }
//
//    if (reg == FALSE) {
//        return (UE_MODULE_INVALID);
//    } else
//        return (i);
//}


514
//-----------------------------------------------------------------------------
gauthier's avatar
gauthier committed
515
516
// return the ue context if there is already an UE with ue_identityP, NULL otherwise
static struct rrc_eNB_ue_context_s*
517
518
519
520
521
522
523
rrc_eNB_ue_context_random_exist(
  const protocol_ctxt_t* const ctxt_pP,
  const uint64_t               ue_identityP
)
//-----------------------------------------------------------------------------
{
  struct rrc_eNB_ue_context_s*        ue_context_p = NULL;
524
  RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
525
    if (ue_context_p->ue_context.random_ue_identity == ue_identityP)
gauthier's avatar
gauthier committed
526
      return ue_context_p;
527
  }
gauthier's avatar
gauthier committed
528
529
530
531
532
533
534
535
536
537
538
539
540
  return NULL;
}
//-----------------------------------------------------------------------------
// return the ue context if there is already an UE with the same S-TMSI(MMEC+M-TMSI), NULL otherwise
static struct rrc_eNB_ue_context_s*
rrc_eNB_ue_context_stmsi_exist(
  const protocol_ctxt_t* const ctxt_pP,
  const mme_code_t             mme_codeP,
  const m_tmsi_t               m_tmsiP
)
//-----------------------------------------------------------------------------
{
  struct rrc_eNB_ue_context_s*        ue_context_p = NULL;
541
  RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
542
543
544
545
    LOG_I(RRC,"checking for UE S-TMSI %x, mme %x (%p): rnti %x",
	  m_tmsiP, mme_codeP, ue_context_p, 
	  ue_context_p->ue_context.rnti);
    if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) {
546
      printf("=> S-TMSI %x, MME %x\n",
Florian Kaltenberger's avatar
Florian Kaltenberger committed
547
548
	    ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi,
	    ue_context_p->ue_context.Initialue_identity_s_TMSI.mme_code);
gauthier's avatar
gauthier committed
549
550
551
      if (ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi == m_tmsiP)
        if (ue_context_p->ue_context.Initialue_identity_s_TMSI.mme_code == mme_codeP)
          return ue_context_p;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
552
553
554
555
    }
    else
      printf("\n");

gauthier's avatar
gauthier committed
556
557
  }
  return NULL;
558
559
}

560
561
562
563
564
565
566
567
568
569
570
//-----------------------------------------------------------------------------
// return a new ue context structure if ue_identityP, ctxt_pP->rnti not found in collection
static struct rrc_eNB_ue_context_s*
rrc_eNB_get_next_free_ue_context(
  const protocol_ctxt_t* const ctxt_pP,
  const uint64_t               ue_identityP
)
//-----------------------------------------------------------------------------
{
  struct rrc_eNB_ue_context_s*        ue_context_p = NULL;
  ue_context_p = rrc_eNB_get_ue_context(
571
572
					RC.rrc[ctxt_pP->module_id],
					ctxt_pP->rnti);
573
574

  if (ue_context_p == NULL) {
575
#if 0
576
    RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
577
578
      if (ue_context_p->ue_context.random_ue_identity == ue_identityP) {
        LOG_D(RRC,
Cedric Roux's avatar
Cedric Roux committed
579
              PROTOCOL_RRC_CTXT_UE_FMT" Cannot create new UE context, already exist rand UE id 0x%"PRIx64", uid %u\n",
580
581
582
583
584
585
              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
              ue_identityP,
              ue_context_p->local_uid);
        return NULL;
      }
    }
586
#endif
587
    ue_context_p = rrc_eNB_allocate_new_UE_context(RC.rrc[ctxt_pP->module_id]);
winckel's avatar
winckel committed
588

589
590
591
592
593
    if (ue_context_p == NULL) {
      LOG_E(RRC,
            PROTOCOL_RRC_CTXT_UE_FMT" Cannot create new UE context, no memory\n",
            PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
      return NULL;
594
    }
595

596
597
598
    ue_context_p->ue_id_rnti                    = ctxt_pP->rnti; // here ue_id_rnti is just a key, may be something else
    ue_context_p->ue_context.rnti               = ctxt_pP->rnti; // yes duplicate, 1 may be removed
    ue_context_p->ue_context.random_ue_identity = ue_identityP;
599
    RB_INSERT(rrc_ue_tree_s, &RC.rrc[ctxt_pP->module_id]->rrc_ue_head, ue_context_p);
600
601
602
603
604
    LOG_D(RRC,
          PROTOCOL_RRC_CTXT_UE_FMT" Created new UE context uid %u\n",
          PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
          ue_context_p->local_uid);
    return ue_context_p;
winckel's avatar
winckel committed
605

606
607
608
609
610
611
  } else {
    LOG_E(RRC,
          PROTOCOL_RRC_CTXT_UE_FMT" Cannot create new UE context, already exist\n",
          PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
    return NULL;
  }
winckel's avatar
winckel committed
612
613
}

614
615
616
617
618
619
620
621
#if !defined(ENABLE_USE_MME)
void rrc_eNB_emulation_notify_ue_module_id(
  const module_id_t ue_module_idP,
  const rnti_t      rntiP,
  const uint8_t     cell_identity_byte0P,
  const uint8_t     cell_identity_byte1P,
  const uint8_t     cell_identity_byte2P,
  const uint8_t     cell_identity_byte3P)
622
{
623
624
  module_id_t                         enb_module_id;
  struct rrc_eNB_ue_context_s*        ue_context_p = NULL;
625
  int                                 CC_id;
626
627
628

  // find enb_module_id
  for (enb_module_id = 0; enb_module_id < NUMBER_OF_eNB_MAX; enb_module_id++) {
629
630
631
    if(enb_module_id>0){ /*FIX LATER*/
      return;
    }
632
    for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
633
      if (&RC.rrc[enb_module_id]->carrier[CC_id].sib1 != NULL) {
634
        if (
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
635
636
637
638
          (&RC.rrc[enb_module_id]->carrier[CC_id].sib1->cellAccessRelatedInfo.cellIdentity.buf[0] == cell_identity_byte0P) &&
          (&RC.rrc[enb_module_id]->carrier[CC_id].sib1->cellAccessRelatedInfo.cellIdentity.buf[1] == cell_identity_byte1P) &&
          (&RC.rrc[enb_module_id]->carrier[CC_id].sib1->cellAccessRelatedInfo.cellIdentity.buf[2] == cell_identity_byte2P) &&
          (&RC.rrc[enb_module_id]->carrier[CC_id].sib1->cellAccessRelatedInfo.cellIdentity.buf[3] == cell_identity_byte3P)
639
640
        ) {
          ue_context_p = rrc_eNB_get_ue_context(
641
                           RC.rrc[enb_module_id],
642
643
644
645
646
647
                           rntiP
                         );

          if (NULL != ue_context_p) {
            oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[enb_module_id][ue_context_p->local_uid] = ue_module_idP;
          }
winckel's avatar
RRC:    
winckel committed
648

649
          //return;
650
        }
651
652
      }
    }
653
    oai_emulation.info.eNB_ue_module_id_to_rnti[enb_module_id][ue_module_idP] = rntiP;
654
  }
winckel's avatar
winckel committed
655

656
657
658
659
660
  AssertFatal(enb_module_id == NUMBER_OF_eNB_MAX,
              "Cell identity not found for ue module id %u rnti %x",
              ue_module_idP, rntiP);
}
#endif
661

662
663
664
665
666
//-----------------------------------------------------------------------------
void
rrc_eNB_free_mem_UE_context(
  const protocol_ctxt_t*               const ctxt_pP,
  struct rrc_eNB_ue_context_s*         const ue_context_pP
667
)
668
//-----------------------------------------------------------------------------
gauthier's avatar
gauthier committed
669
{
670
671
  int i;
  LOG_T(RRC,
Cedric Roux's avatar
Cedric Roux committed
672
        PROTOCOL_RRC_CTXT_UE_FMT" Clearing UE context 0x%p (free internal structs)\n",
673
674
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
        ue_context_pP);
Cedric Roux's avatar
Cedric Roux committed
675
#if defined(Rel10) || defined(Rel14)
676
677
678
679
680
681
682
683
  ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[0]);
  ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[1]);
#endif

  if (ue_context_pP->ue_context.SRB_configList) {
    ASN_STRUCT_FREE(asn_DEF_SRB_ToAddModList, ue_context_pP->ue_context.SRB_configList);
    ue_context_pP->ue_context.SRB_configList = NULL;
  }
684

685
686
687
688
689
690
691
  for(i = 0;i < RRC_TRANSACTION_IDENTIFIER_NUMBER;i++){
      if (ue_context_pP->ue_context.SRB_configList2[i]) {
          free(ue_context_pP->ue_context.SRB_configList2[i]);
          ue_context_pP->ue_context.SRB_configList2[i] = NULL;
      }
  }

692
693
694
695
  if (ue_context_pP->ue_context.DRB_configList) {
    ASN_STRUCT_FREE(asn_DEF_DRB_ToAddModList, ue_context_pP->ue_context.DRB_configList);
    ue_context_pP->ue_context.DRB_configList = NULL;
  }
696

697
698
699
700
701
702
703
704
705
706
707
  for(i = 0;i < RRC_TRANSACTION_IDENTIFIER_NUMBER;i++){
      if (ue_context_pP->ue_context.DRB_configList2[i]) {
          free(ue_context_pP->ue_context.DRB_configList2[i]);
          ue_context_pP->ue_context.DRB_configList2[i] = NULL;
      }
      if (ue_context_pP->ue_context.DRB_Release_configList2[i]) {
          free(ue_context_pP->ue_context.DRB_Release_configList2[i]);
          ue_context_pP->ue_context.DRB_Release_configList2[i] = NULL;
      }
  }

708
  memset(ue_context_pP->ue_context.DRB_active, 0, sizeof(ue_context_pP->ue_context.DRB_active));
709

710
711
712
  if (ue_context_pP->ue_context.physicalConfigDedicated) {
    ASN_STRUCT_FREE(asn_DEF_PhysicalConfigDedicated, ue_context_pP->ue_context.physicalConfigDedicated);
    ue_context_pP->ue_context.physicalConfigDedicated = NULL;
713
714
  }

715
716
717
  if (ue_context_pP->ue_context.sps_Config) {
    ASN_STRUCT_FREE(asn_DEF_SPS_Config, ue_context_pP->ue_context.sps_Config);
    ue_context_pP->ue_context.sps_Config = NULL;
718
719
  }

720
721
722
723
724
  for (i=0; i < MAX_MEAS_OBJ; i++) {
    if (ue_context_pP->ue_context.MeasObj[i] != NULL) {
      ASN_STRUCT_FREE(asn_DEF_MeasObjectToAddMod, ue_context_pP->ue_context.MeasObj[i]);
      ue_context_pP->ue_context.MeasObj[i] = NULL;
    }
725
  }
726

727
728
729
730
731
732
  for (i=0; i < MAX_MEAS_CONFIG; i++) {
    if (ue_context_pP->ue_context.ReportConfig[i] != NULL) {
      ASN_STRUCT_FREE(asn_DEF_ReportConfigToAddMod, ue_context_pP->ue_context.ReportConfig[i]);
      ue_context_pP->ue_context.ReportConfig[i] = NULL;
    }
  }
733

734
735
736
737
  if (ue_context_pP->ue_context.QuantityConfig) {
    ASN_STRUCT_FREE(asn_DEF_QuantityConfig, ue_context_pP->ue_context.QuantityConfig);
    ue_context_pP->ue_context.QuantityConfig = NULL;
  }
738

739
740
741
742
  if (ue_context_pP->ue_context.mac_MainConfig) {
    ASN_STRUCT_FREE(asn_DEF_MAC_MainConfig, ue_context_pP->ue_context.mac_MainConfig);
    ue_context_pP->ue_context.mac_MainConfig = NULL;
  }
743

744
/*  if (ue_context_pP->ue_context.measGapConfig) {
745
746
    ASN_STRUCT_FREE(asn_DEF_MeasGapConfig, ue_context_pP->ue_context.measGapConfig);
    ue_context_pP->ue_context.measGapConfig = NULL;
747
748
749
750
751
  }*/
    if (ue_context_pP->ue_context.handover_info) {
      ASN_STRUCT_FREE(asn_DEF_Handover, ue_context_pP->ue_context.handover_info);
      ue_context_pP->ue_context.handover_info = NULL;
    }
gauthier's avatar
   
gauthier committed
752

753
754
755
756
757
758
759
  //SRB_INFO                           SI;
  //SRB_INFO                           Srb0;
  //SRB_INFO_TABLE_ENTRY               Srb1;
  //SRB_INFO_TABLE_ENTRY               Srb2;
  if (ue_context_pP->ue_context.measConfig) {
    ASN_STRUCT_FREE(asn_DEF_MeasConfig, ue_context_pP->ue_context.measConfig);
    ue_context_pP->ue_context.measConfig = NULL;
760
  }
761

762
763
764
  if (ue_context_pP->ue_context.measConfig) {
    ASN_STRUCT_FREE(asn_DEF_MeasConfig, ue_context_pP->ue_context.measConfig);
    ue_context_pP->ue_context.measConfig = NULL;
765
  }
766

767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
  //HANDOVER_INFO                     *handover_info;
#if defined(ENABLE_SECURITY)
  //uint8_t kenb[32];
#endif
  //e_SecurityAlgorithmConfig__cipheringAlgorithm     ciphering_algorithm;
  //e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm;
  //uint8_t                            Status;
  //rnti_t                             rnti;
  //uint64_t                           random_ue_identity;
#if defined(ENABLE_ITTI)
  //UE_S_TMSI                          Initialue_identity_s_TMSI;
  //EstablishmentCause_t               establishment_cause;
  //ReestablishmentCause_t             reestablishment_cause;
  //uint16_t                           ue_initial_id;
  //uint32_t                           eNB_ue_s1ap_id :24;
  //security_capabilities_t            security_capabilities;
  //uint8_t                            nb_of_e_rabs;
  //e_rab_param_t                      e_rab[S1AP_MAX_E_RAB];
  //uint32_t                           enb_gtp_teid[S1AP_MAX_E_RAB];
  //transport_layer_addr_t             enb_gtp_addrs[S1AP_MAX_E_RAB];
  //rb_id_t                            enb_gtp_ebi[S1AP_MAX_E_RAB];
#endif
789
790
}

791
//-----------------------------------------------------------------------------
792
// should be called when UE is lost by eNB
793
void
794
rrc_eNB_free_UE(const module_id_t enb_mod_idP,const struct rrc_eNB_ue_context_s*        const ue_context_pP)
795
//-----------------------------------------------------------------------------
gauthier's avatar
gauthier committed
796
{
knopp's avatar
   
knopp committed
797

798

799
  protocol_ctxt_t                     ctxt;
800
801
#if !defined(ENABLE_USE_MME)
  module_id_t                         ue_module_id;
Cedric Roux's avatar
Cedric Roux committed
802
803
  /* avoid gcc warnings */
  (void)ue_module_id;
804
#endif
805
  rnti_t rnti = ue_context_pP->ue_context.rnti;
806
807
808
809
810
  int i, j , CC_id, pdu_number;
  LTE_eNB_ULSCH_t *ulsch = NULL;
  nfapi_ul_config_request_body_t *ul_req_tmp = NULL;
  PHY_VARS_eNB *eNB_PHY = NULL;
  eNB_MAC_INST *eNB_MAC = RC.mac[enb_mod_idP];
811
812
813

  AssertFatal(enb_mod_idP < NB_eNB_INST, "eNB inst invalid (%d/%d) for UE %x!", enb_mod_idP, NB_eNB_INST, rnti);
  /*  ue_context_p = rrc_eNB_get_ue_context(
814
                   &RC.rrc[enb_mod_idP],
815
816
                   rntiP
                 );
817
818
819
820
  */
  if (NULL != ue_context_pP) {
    PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, enb_mod_idP, ENB_FLAG_YES, rnti, 0, 0,enb_mod_idP);
    LOG_W(RRC, "[eNB %d] Removing UE RNTI %x\n", enb_mod_idP, rnti);
gauthier's avatar
gauthier committed
821
822

#if defined(ENABLE_USE_MME)
823
824
   if( ue_context_pP->ue_context.ul_failure_timer >= 8 ) {
	LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ RNTI %x\n", enb_mod_idP, rnti);
825
    rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 21); // send cause 21: connection with ue lost
826
827
828
829
830
831
    /* From 3GPP 36300v10 p129 : 19.2.2.2.2 S1 UE Context Release Request (eNB triggered)
     * If the E-UTRAN internal reason is a radio link failure detected in the eNB, the eNB shall wait a sufficient time before
     *  triggering the S1 UE Context Release Request procedure
     *  in order to allow the UE to perform the NAS recovery
     *  procedure, see TS 23.401 [17].
     */
832
833
     return;
    }
834
#else
Florian Kaltenberger's avatar
Florian Kaltenberger committed
835
#if defined(OAI_EMU)
836
837
838
839
    AssertFatal(ue_context_pP->local_uid < NUMBER_OF_UE_MAX, "local_uid invalid (%d<%d) for UE %x!", ue_context_pP->local_uid, NUMBER_OF_UE_MAX, rnti);
    ue_module_id = oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[enb_mod_idP][ue_context_pP->local_uid];
    AssertFatal(ue_module_id < NUMBER_OF_UE_MAX, "ue_module_id invalid (%d<%d) for UE %x!", ue_module_id, NUMBER_OF_UE_MAX, rnti);
    oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[enb_mod_idP][ue_context_pP->local_uid] = -1;
840
    oai_emulation.info.eNB_ue_module_id_to_rnti[enb_mod_idP][ue_module_id] = NOT_A_RNTI;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
841
#endif
gauthier's avatar
gauthier committed
842
#endif
843
844
845
846
847
848
849
850
851
852
    for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
      eNB_PHY = RC.eNB[enb_mod_idP][CC_id];
      for (i=0; i<NUMBER_OF_UE_MAX; i++) {
        ulsch = eNB_PHY->ulsch[i];
        if((ulsch != NULL) && (ulsch->rnti == rnti)){
          LOG_I(RRC, "clean_eNb_ulsch UE %x \n", rnti);
          clean_eNb_ulsch(ulsch);
          break;
        }
      }
853

854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
      for(j = 0; j < 10; j++){
        ul_req_tmp = &eNB_MAC->UL_req_tmp[CC_id][j].ul_config_request_body;
        if(ul_req_tmp){
          pdu_number = ul_req_tmp->number_of_pdus;
          for(int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--){
            if(ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti){
              LOG_I(RRC, "remove UE %x from ul_config_pdu_list %d/%d\n", rnti, pdu_index, pdu_number);
              if(pdu_index < pdu_number -1){
                memcpy(&ul_req_tmp->ul_config_pdu_list[pdu_index], &ul_req_tmp->ul_config_pdu_list[pdu_index+1], (pdu_number-1-pdu_index) * sizeof(nfapi_ul_config_request_pdu_t));
              }
              ul_req_tmp->number_of_pdus--;
            }
          }
        }
      }
    }
870
    rrc_mac_remove_ue(enb_mod_idP,rnti);
871
872
    rrc_rlc_remove_ue(&ctxt);
    pdcp_remove_UE(&ctxt);
knopp's avatar
   
knopp committed
873

874
875
    rrc_eNB_remove_ue_context(
      &ctxt,
876
      RC.rrc[enb_mod_idP],
877
      (struct rrc_eNB_ue_context_s*) ue_context_pP);
878
  }
879
880
}

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
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
void remove_UE_from_freelist(module_id_t mod_id, rnti_t rnti)
{

    eNB_MAC_INST                             *eNB_MAC = RC.mac[mod_id];
    pthread_mutex_lock(&lock_ue_freelist);
    UE_free_list_t                           *free_list = &eNB_MAC->UE_free_list;
    free_list->UE_free_ctrl[free_list->head_freelist].rnti = 0;
    free_list->head_freelist = (free_list->head_freelist + 1) % (NUMBER_OF_UE_MAX+1);
    free_list->num_UEs--;
    pthread_mutex_unlock(&lock_ue_freelist);
}

void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, boolean_t removeFlag)
{
    UE_free_list_t                           *free_list = NULL;
    eNB_MAC_INST                             *eNB_MAC = RC.mac[mod_id];
    pthread_mutex_lock(&lock_ue_freelist);
    free_list = &eNB_MAC->UE_free_list;
    free_list->UE_free_ctrl[free_list->tail_freelist].rnti = rnti;
    free_list->UE_free_ctrl[free_list->tail_freelist].removeContextFlg = removeFlag;
    free_list->num_UEs++;
    free_list->tail_freelist = (free_list->tail_freelist + 1) % (NUMBER_OF_UE_MAX+1);
    pthread_mutex_unlock(&lock_ue_freelist);
}

void release_UE_in_freeList(module_id_t mod_id)
{
    int i, j , CC_id, pdu_number;
    protocol_ctxt_t                           ctxt;
    LTE_eNB_ULSCH_t                          *ulsch = NULL;
    nfapi_ul_config_request_body_t           *ul_req_tmp = NULL;
    PHY_VARS_eNB                             *eNB_PHY = NULL;
    struct rrc_eNB_ue_context_s              *ue_context_pP = NULL;
    eNB_MAC_INST                             *eNB_MAC = RC.mac[mod_id];
    boolean_t                                 remove_UEContext;
    rnti_t                                    rnti;
    int                                       head, tail, ue_num;

    pthread_mutex_lock(&lock_ue_freelist);
    head = eNB_MAC->UE_free_list.head_freelist;
    tail = eNB_MAC->UE_free_list.tail_freelist;
    if(head == tail){
        pthread_mutex_unlock(&lock_ue_freelist);
        return;
    }
    if(tail < head){
        tail = head + eNB_MAC->UE_free_list.num_UEs;
    }
    pthread_mutex_unlock(&lock_ue_freelist);

    for(ue_num = head; ue_num < tail; ue_num++){
        ue_num = ue_num % (NUMBER_OF_UE_MAX+1);
        rnti = eNB_MAC->UE_free_list.UE_free_ctrl[ue_num].rnti;
        if(rnti != 0){
            remove_UEContext = eNB_MAC->UE_free_list.UE_free_ctrl[ue_num].removeContextFlg;
            PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, rnti, 0, 0,mod_id);
            for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
              eNB_PHY = RC.eNB[mod_id][CC_id];
              for (i=0; i<=NUMBER_OF_UE_MAX; i++) {
                ulsch = eNB_PHY->ulsch[i];
                if((ulsch != NULL) && (ulsch->rnti == rnti)){
                    LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti);
                    clean_eNb_ulsch(ulsch);
                 }
              }

              for(j = 0; j < 10; j++){
                ul_req_tmp = &eNB_MAC->UL_req_tmp[CC_id][j].ul_config_request_body;
                if(ul_req_tmp){
                  pdu_number = ul_req_tmp->number_of_pdus;
                  for(int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--){
                    if(ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti){
                      LOG_I(RRC, "remove UE %x from ul_config_pdu_list %d/%d\n", rnti, pdu_index, pdu_number);
                      if(pdu_index < pdu_number -1){
                        memcpy(&ul_req_tmp->ul_config_pdu_list[pdu_index], &ul_req_tmp->ul_config_pdu_list[pdu_index+1], (pdu_number-1-pdu_index) * sizeof(nfapi_ul_config_request_pdu_t));
                      }
                      ul_req_tmp->number_of_pdus--;
                    }
                  }
                }
              }
            }
            rrc_mac_remove_ue(mod_id,rnti);
            rrc_rlc_remove_ue(&ctxt);
            pdcp_remove_UE(&ctxt);

            if(remove_UEContext){
                ue_context_pP = rrc_eNB_get_ue_context(
                                 RC.rrc[mod_id],rnti);
                if(ue_context_pP){
                    rrc_eNB_remove_ue_context(&ctxt,RC.rrc[mod_id],
                        (struct rrc_eNB_ue_context_s*) ue_context_pP);
                }
            }
            LOG_I(RRC, "[release_UE_in_freeList] remove UE %x from freeList\n", rnti);
            remove_UE_from_freelist(mod_id, rnti);
        }
    }
}

981
982
983
984
//-----------------------------------------------------------------------------
void
rrc_eNB_process_RRCConnectionSetupComplete(
  const protocol_ctxt_t* const ctxt_pP,
985
  rrc_eNB_ue_context_t*         ue_context_pP,
986
987
  RRCConnectionSetupComplete_r8_IEs_t * rrcConnectionSetupComplete
)
988
//-----------------------------------------------------------------------------
gauthier's avatar
gauthier committed
989
{
990
  LOG_I(RRC,
991
        PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing RRCConnectionSetupComplete from UE (SRB1 Active)\n",
992
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
winckel's avatar
winckel committed
993

nikaeinn's avatar
nikaeinn committed
994
  ue_context_pP->ue_context.Srb1.Active=1;  
Cedric Roux's avatar
Cedric Roux committed
995
996
997
  T(T_ENB_RRC_CONNECTION_SETUP_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
    T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));

winckel's avatar
winckel committed
998
#if defined(ENABLE_USE_MME)
999
1000
1001

  if (EPC_MODE_ENABLED == 1) {
    // Forward message to S1AP layer
1002
1003
1004
1005
    rrc_eNB_send_S1AP_NAS_FIRST_REQ(
      ctxt_pP,
      ue_context_pP,
      rrcConnectionSetupComplete);
1006
  } else
winckel's avatar
winckel committed
1007
#endif
1008
1009
  {
    // RRC loop back (no S1AP), send SecurityModeCommand to UE
1010
1011
1012
    rrc_eNB_generate_SecurityModeCommand(
      ctxt_pP,
      ue_context_pP);
1013
1014
    // rrc_eNB_generate_UECapabilityEnquiry(enb_mod_idP,frameP,ue_mod_idP);
  }
winckel's avatar
winckel committed
1015
1016
}

1017
1018
1019
1020
1021
//-----------------------------------------------------------------------------
void
rrc_eNB_generate_SecurityModeCommand(
  const protocol_ctxt_t* const ctxt_pP,
  rrc_eNB_ue_context_t*          const ue_context_pP
1022
)
1023
//-----------------------------------------------------------------------------
gauthier's avatar
gauthier committed
1024
{
1025
1026
  uint8_t                             buffer[100];
  uint8_t                             size;
gauthier's avatar
   
gauthier committed
1027

Cedric Roux's avatar
Cedric Roux committed
1028
1029
1030
  T(T_ENB_RRC_SECURITY_MODE_COMMAND, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
    T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));

1031
1032
1033
1034
1035
1036
  size = do_SecurityModeCommand(
           ctxt_pP,
           buffer,
           rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),
           ue_context_pP->ue_context.ciphering_algorithm,
           ue_context_pP->ue_context.integrity_algorithm);
gauthier's avatar
   
gauthier committed
1037

1038
#ifdef RRC_MSG_PRINT
1039
1040
1041
  uint16_t i=0;
  LOG_F(RRC,"[MSG] RRC Security Mode Command\n");

1042
  for (i = 0; i < size; i++) {
1043
    LOG_F(RRC,"%02x ", ((uint8_t*)buffer)[i]);
1044
  }
1045
1046

  LOG_F(RRC,"\n");
1047
1048
#endif

1049
  LOG_I(RRC,
1050
1051
1052
        PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate SecurityModeCommand (bytes %d)\n",
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
        size);
gauthier's avatar
   
gauthier committed
1053

1054
  LOG_D(RRC,
1055
1056
1057
1058
1059
        PROTOCOL_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (securityModeCommand to UE MUI %d) --->[PDCP][RB %02d]\n",
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
        size,
        rrc_eNB_mui,
        DCCH);
gauthier's avatar
gauthier committed
1060
1061

  MSC_LOG_TX_MESSAGE(
1062
1063
1064
1065
1066
1067
1068
1069
1070
    MSC_RRC_ENB,
    MSC_RRC_UE,
    buffer,
    size,
    MSC_AS_TIME_FMT" securityModeCommand UE %x MUI %d size %u",
    MSC_AS_TIME_ARGS(ctxt_pP),
    ue_context_pP->ue_context.rnti,
    rrc_eNB_mui,
    size);
gauthier's avatar
gauthier committed
1071

1072
1073
1074
1075
1076
1077
1078
1079
  rrc_data_req(
	       ctxt_pP,
	       DCCH,
	       rrc_eNB_mui++,
	       SDU_CONFIRM_NO,
	       size,
	       buffer,
	       PDCP_TRANSMISSION_MODE_CONTROL);
1080
1081
1082

}

1083
1084
1085
1086
1087
1088
1089
//-----------------------------------------------------------------------------
void
rrc_eNB_generate_UECapabilityEnquiry(
  const protocol_ctxt_t* const ctxt_pP,
  rrc_eNB_ue_context_t*          const ue_context_pP
)
//-----------------------------------------------------------------------------
1090
{
1091

1092
1093
  uint8_t                             buffer[100];
  uint8_t                             size;