rrc_eNB.c 222 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
87
88
#include "pdcp.h"

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

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

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

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

103
104
extern RAN_CONTEXT_t RC;

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

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

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

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

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

138
  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MIB = (uint8_t*) malloc16(4);
139
140
141
142
143
144
  // 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];
145
146
147
#ifdef Rel14
  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].pbch_repetition = configuration->pbch_repetition[CC_id];
#endif
148
  LOG_I(RRC, "Configuring MIB (N_RB_DL %d,phich_Resource %d,phich_Duration %d)\n", 
knopp's avatar
knopp committed
149
150
151
	(int)configuration->N_RB_DL[CC_id],
	(int)configuration->phich_resource[CC_id],
	(int)configuration->phich_duration[CC_id]);
152
153
154
155
156
157
158
159
160
161
162
163
164
165
  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
166

167
168
169
  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
170
#if defined(ENABLE_ITTI)
171
								   , configuration
winckel's avatar
winckel committed
172
#endif
173
								   );
174

175
  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");
176

177
  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB23 = (uint8_t*) malloc16(64);
178
179
180
181
182
  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
183
#if defined(ENABLE_ITTI)
184
								     , configuration
gauthier's avatar
   
gauthier committed
185
#endif
186
								     );
187

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

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
  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
226
#if defined(Rel10) || defined(Rel14)
227

228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
  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);
245
    }
246
247
248
249
250
251
252
253
254
255
256
257
258
259
    
    //   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);
    }
260
261
  }
  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));
262
263
#endif

264
265
266
  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));
267
268
269
270
271

#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
272
		  "sib2_br->nonCriticalExtension is null (v8.9)\n");
273
      AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension!=NULL,
knopp's avatar
knopp committed
274
		  "sib2_br->nonCriticalExtension is null (v9.2)\n");
275
      AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL,
knopp's avatar
knopp committed
276
		  "sib2_br->nonCriticalExtension is null (v11.3)\n");
277
      AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL,
knopp's avatar
knopp committed
278
279
		  "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,
280
		  "sib2_br->nonCriticalExtension is null (v13.10)\n");
knopp's avatar
knopp committed
281
      sib1_v13ext = RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension;
282
283
284
  }
#endif

285
286
287
288
289
290
291
292
293
  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
294
			 0, // rnti
295
296
297
298
299
300
301
302
303
			 (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
304
#if defined(Rel10) || defined(Rel14)
305
306
307
308
309
310
311
312
313
			 (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,
314
			 &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1->schedulingInfoList,
315
316
317
318
			 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
319
#if defined(Rel10) || defined(Rel14)
320
321
322
323
			 ,
			 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
324
#endif
325
326
327
#ifdef Rel14
			 , 
			 sib1_v13ext
328
#endif
329
			 );
330
331
}

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

342
343
  int                                 sync_area = 0;
  // initialize RRC_eNB_INST MCCH entry
344
345
  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
346

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

349
350
    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);
351

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
    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;
377
  }
378
  
gauthier's avatar
   
gauthier committed
379

380
  //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
381

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

385

386
387
388
  //  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,
389
390
391
392
			 0,0,0,0,0,
#ifdef Rel14 
			 0,
#endif
393
			 0,//rnti
394
395
			 (BCCH_BCH_Message_t *)NULL,
			 (RadioResourceConfigCommonSIB_t *) NULL,
396
397
			 (RadioResourceConfigCommonSIB_t *) NULL,
			 (struct PhysicalConfigDedicated *)NULL,
Cedric Roux's avatar
Cedric Roux committed
398
#if defined(Rel10) || defined(Rel14)
399
400
			 (SCellToAddMod_r10_t *)NULL,
			 //(struct PhysicalConfigDedicatedSCell_r10 *)NULL,
401
#endif
402
403
404
405
406
407
			 (MeasObjectToAddMod_t **) NULL,
			 (MAC_MainConfig_t *) NULL,
			 0,
			 (struct LogicalChannelConfig *)NULL,
			 (MeasGapConfig_t *) NULL,
			 (TDD_Config_t *) NULL,
408
409
410
			 (MobilityControlInfo_t *)NULL, 
			 (SchedulingInfoList_t *) NULL, 
			 0, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL
411
#if defined(Rel10) || defined(Rel14)
412
413
414
415
			 ,
			 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
416
#   endif
417
418
419
#   ifdef Rel14
			 ,
			 (SystemInformationBlockType1_v1310_IEs_t *)NULL
gauthier's avatar
   
gauthier committed
420
#   endif
421
422
423
			 );
  
  //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);
424

425
426
}

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

438
  if (RC.rrc[enb_mod_idP]->carrier[CC_id].MBMS_flag > 0) {
439
    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
440

441
442
    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
443

444
445
446
447
448
449
450
451
    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
452
#   if defined(Rel10) || defined(Rel14)
453
                             , &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9)
gauthier's avatar
   
gauthier committed
454
#   endif
455
                             ,NULL);
gauthier's avatar
   
gauthier committed
456

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

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

468
469
470
471
472
473
//-----------------------------------------------------------------------------
uint8_t
rrc_eNB_get_next_transaction_identifier(
  module_id_t enb_mod_idP
)
//-----------------------------------------------------------------------------
474
{
475
476
  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;
477
  LOG_T(RRC,"generated xid is %d\n",rrc_transaction_identifier[enb_mod_idP]);
478
479
480
481
482
  return rrc_transaction_identifier[enb_mod_idP];
}
/*------------------------------------------------------------------------------*/
/* Functions to handle UE index in eNB UE list */

winckel's avatar
winckel committed
483

484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
////-----------------------------------------------------------------------------
//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++) {
499
//        if (RC.rrc[enb_mod_idP]->Info.UE_list[i] == UE_identity) {
500
501
502
503
504
505
506
507
508
509
510
511
512
//            // UE_identity already registered
//            reg = TRUE;
//            break;
//        }
//    }
//
//    if (reg == FALSE) {
//        return (UE_MODULE_INVALID);
//    } else
//        return (i);
//}


513
//-----------------------------------------------------------------------------
gauthier's avatar
gauthier committed
514
515
// return the ue context if there is already an UE with ue_identityP, NULL otherwise
static struct rrc_eNB_ue_context_s*
516
517
518
519
520
521
522
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;
523
  RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
524
    if (ue_context_p->ue_context.random_ue_identity == ue_identityP)
gauthier's avatar
gauthier committed
525
      return ue_context_p;
526
  }
gauthier's avatar
gauthier committed
527
528
529
530
531
532
533
534
535
536
537
538
539
  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;
540
  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
541
542
543
544
    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) {
545
      printf("=> S-TMSI %x, MME %x\n",
Florian Kaltenberger's avatar
Florian Kaltenberger committed
546
547
	    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
548
549
550
      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
551
552
553
554
    }
    else
      printf("\n");

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

559
560
561
562
563
564
565
566
567
568
569
//-----------------------------------------------------------------------------
// 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(
570
571
					RC.rrc[ctxt_pP->module_id],
					ctxt_pP->rnti);
572
573

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

586
587
588
589
590
    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;
591
    }
592

593
594
595
    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;
596
    RB_INSERT(rrc_ue_tree_s, &RC.rrc[ctxt_pP->module_id]->rrc_ue_head, ue_context_p);
597
598
599
600
601
    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
602

603
604
605
606
607
608
  } 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
609
610
}

611
#if 0 //!defined(ENABLE_USE_MME)
612
613
614
615
616
617
618
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)
619
{
620
621
  module_id_t                         enb_module_id;
  struct rrc_eNB_ue_context_s*        ue_context_p = NULL;
622
  int                                 CC_id;
623
624
625

  // find enb_module_id
  for (enb_module_id = 0; enb_module_id < NUMBER_OF_eNB_MAX; enb_module_id++) {
626
627
628
    if(enb_module_id>0){ /*FIX LATER*/
      return;
    }
629
    for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
630
      if (RC.rrc[enb_module_id].carrier[CC_id].sib1 != NULL) {
631
        if (
632
633
634
635
          (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)
636
637
        ) {
          ue_context_p = rrc_eNB_get_ue_context(
638
                           RC.rrc[enb_module_id],
639
640
641
642
643
644
                           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
645

646
          //return;
647
        }
648
649
      }
    }
650
    oai_emulation.info.eNB_ue_module_id_to_rnti[enb_module_id][ue_module_idP] = rntiP;
651
  }
winckel's avatar
winckel committed
652

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

659
660
661
662
663
//-----------------------------------------------------------------------------
void
rrc_eNB_free_mem_UE_context(
  const protocol_ctxt_t*               const ctxt_pP,
  struct rrc_eNB_ue_context_s*         const ue_context_pP
664
)
665
//-----------------------------------------------------------------------------
gauthier's avatar
gauthier committed
666
{
667
668
  int i;
  LOG_T(RRC,
Cedric Roux's avatar
Cedric Roux committed
669
        PROTOCOL_RRC_CTXT_UE_FMT" Clearing UE context 0x%p (free internal structs)\n",
670
671
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
        ue_context_pP);
Cedric Roux's avatar
Cedric Roux committed
672
#if defined(Rel10) || defined(Rel14)
673
674
675
676
677
678
679
680
  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;
  }
681

682
683
684
685
  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;
  }
686

687
  memset(ue_context_pP->ue_context.DRB_active, 0, sizeof(ue_context_pP->ue_context.DRB_active));
688

689
690
691
  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;
692
693
  }

694
695
696
  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;
697
698
  }

699
700
701
702
703
  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;
    }
704
  }
705

706
707
708
709
710
711
  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;
    }
  }
712

713
714
715
716
  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;
  }
717

718
719
720
721
  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;
  }
722

723
724
725
726
  if (ue_context_pP->ue_context.measGapConfig) {
    ASN_STRUCT_FREE(asn_DEF_MeasGapConfig, ue_context_pP->ue_context.measGapConfig);
    ue_context_pP->ue_context.measGapConfig = NULL;
  }
gauthier's avatar
   
gauthier committed
727

728
729
730
731
732
733
734
  //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;
735
  }
736

737
738
739
  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;
740
  }
741

742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
  //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
764
765
}

766
//-----------------------------------------------------------------------------
767
// should be called when UE is lost by eNB
768
void
769
rrc_eNB_free_UE(const module_id_t enb_mod_idP,const struct rrc_eNB_ue_context_s*        const ue_context_pP)
770
//-----------------------------------------------------------------------------
gauthier's avatar
gauthier committed
771
{
knopp's avatar
   
knopp committed
772

773

774
  protocol_ctxt_t                     ctxt;
775
776
#if !defined(ENABLE_USE_MME)
  module_id_t                         ue_module_id;
Cedric Roux's avatar
Cedric Roux committed
777
778
  /* avoid gcc warnings */
  (void)ue_module_id;
779
#endif
780
781
782
783
784
  rnti_t rnti = ue_context_pP->ue_context.rnti;


  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(
785
                   &RC.rrc[enb_mod_idP],
786
787
                   rntiP
                 );
788
789
790
791
  */
  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
792
793

#if defined(ENABLE_USE_MME)
794
    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
795
796
797
798
799
800
    /* 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].
     */
801
#else
Florian Kaltenberger's avatar
Florian Kaltenberger committed
802
#if defined(OAI_EMU)
803
804
805
806
    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;
807
    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
808
#endif
gauthier's avatar
gauthier committed
809
#endif
810

811
    rrc_mac_remove_ue(enb_mod_idP,rnti);
812
813
    rrc_rlc_remove_ue(&ctxt);
    pdcp_remove_UE(&ctxt);
knopp's avatar
   
knopp committed
814

815
816
    rrc_eNB_remove_ue_context(
      &ctxt,
817
      RC.rrc[enb_mod_idP],
818
      (struct rrc_eNB_ue_context_s*) ue_context_pP);
819
  }
820
821
}

822
823
824
825
//-----------------------------------------------------------------------------
void
rrc_eNB_process_RRCConnectionSetupComplete(
  const protocol_ctxt_t* const ctxt_pP,
826
  rrc_eNB_ue_context_t*         ue_context_pP,
827
828
  RRCConnectionSetupComplete_r8_IEs_t * rrcConnectionSetupComplete
)
829
//-----------------------------------------------------------------------------
gauthier's avatar
gauthier committed
830
{
831
  LOG_I(RRC,
832
        PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing RRCConnectionSetupComplete from UE (SRB1 Active)\n",
833
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
winckel's avatar
winckel committed
834

nikaeinn's avatar
nikaeinn committed
835
  ue_context_pP->ue_context.Srb1.Active=1;  
Cedric Roux's avatar
Cedric Roux committed
836
837
838
  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
839
#if defined(ENABLE_USE_MME)
840
841
842

  if (EPC_MODE_ENABLED == 1) {
    // Forward message to S1AP layer
843
844
845
846
    rrc_eNB_send_S1AP_NAS_FIRST_REQ(
      ctxt_pP,
      ue_context_pP,
      rrcConnectionSetupComplete);
847
  } else
winckel's avatar
winckel committed
848
#endif
849
850
  {
    // RRC loop back (no S1AP), send SecurityModeCommand to UE
851
852
853
    rrc_eNB_generate_SecurityModeCommand(
      ctxt_pP,
      ue_context_pP);
854
855
    // rrc_eNB_generate_UECapabilityEnquiry(enb_mod_idP,frameP,ue_mod_idP);
  }
winckel's avatar
winckel committed
856
857
}

858
859
860
861
862
//-----------------------------------------------------------------------------
void
rrc_eNB_generate_SecurityModeCommand(
  const protocol_ctxt_t* const ctxt_pP,
  rrc_eNB_ue_context_t*          const ue_context_pP
863
)
864
//-----------------------------------------------------------------------------
gauthier's avatar
gauthier committed
865
{
866
867
  uint8_t                             buffer[100];
  uint8_t                             size;
gauthier's avatar
   
gauthier committed
868

Cedric Roux's avatar
Cedric Roux committed
869
870
871
  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));

872
873
874
875
876
877
  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
878

879
#ifdef RRC_MSG_PRINT
880
881
882
  uint16_t i=0;
  LOG_F(RRC,"[MSG] RRC Security Mode Command\n");

883
  for (i = 0; i < size; i++) {
884
    LOG_F(RRC,"%02x ", ((uint8_t*)buffer)[i]);
885
  }
886
887

  LOG_F(RRC,"\n");
888
889
#endif

890
  LOG_I(RRC,
891
892
893
        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
894

895
  LOG_D(RRC,
896
897
898
899
900
        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
901
902

  MSC_LOG_TX_MESSAGE(
903
904
905
906
907
908
909
910
911
    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
912

913
914
915
916
917
918
919
920
  rrc_data_req(
	       ctxt_pP,
	       DCCH,
	       rrc_eNB_mui++,
	       SDU_CONFIRM_NO,
	       size,
	       buffer,
	       PDCP_TRANSMISSION_MODE_CONTROL);
921
922
923

}

924
925
926
927
928
929
930
//-----------------------------------------------------------------------------
void
rrc_eNB_generate_UECapabilityEnquiry(
  const protocol_ctxt_t* const ctxt_pP,
  rrc_eNB_ue_context_t*          const ue_context_pP
)
//-----------------------------------------------------------------------------
931
{
932

933
934
  uint8_t                             buffer[100];
  uint8_t                             size;
935

Cedric Roux's avatar
Cedric Roux committed
936
937
938
  T(T_ENB_RRC_UE_CAPABILITY_ENQUIRY, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
    T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));

939
940
941
942
  size = do_UECapabilityEnquiry(
           ctxt_pP,
           buffer,
           rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id));
winckel's avatar
winckel committed
943

944
  LOG_I(RRC,
945
946
947
        PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate UECapabilityEnquiry (bytes %d)\n",
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
        size);
winckel's avatar
winckel committed
948

949
  LOG_D(RRC,
950
951
952
953
954
        PROTOCOL_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (UECapabilityEnquiry MUI %d) --->[PDCP][RB %02d]\n",
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
        size,
        rrc_eNB_mui,
        DCCH);
gauthier's avatar
gauthier committed
955
956

  MSC_LOG_TX_MESSAGE(
957
958
959
960
961
962
963
964
965
    MSC_RRC_ENB,
    MSC_RRC_UE,
    buffer,
    size,
    MSC_AS_TIME_FMT" rrcUECapabilityEnquiry 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
966

967
968
969
970
971
972
973
974
  rrc_data_req(
	       ctxt_pP,
	       DCCH,
	       rrc_eNB_mui++,
	       SDU_CONFIRM_NO,
	       size,
	       buffer,
	       PDCP_TRANSMISSION_MODE_CONTROL);
975
976
977

}

978
979
980
981
982
983
984
985
986
987
988
989
990
//-----------------------------------------------------------------------------
void
rrc_eNB_generate_RRCConnectionReject(
  const protocol_ctxt_t* const ctxt_pP,
  rrc_eNB_ue_context_t*          const ue_context_pP,
  const int                    CC_id
)
//-----------------------------------------------------------------------------
{
#ifdef RRC_MSG_PRINT
  int                                 cnt;
#endif

Cedric Roux's avatar
Cedric Roux committed
991
992
993
  T(T_ENB_RRC_CONNECTION_REJECT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
    T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));

994
  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size =
995
    do_RRCConnectionReject(ctxt_pP->module_id,
996
                          (uint8_t*) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload);
997
998
999
1000

#ifdef RRC_MSG_PRINT
  LOG_F(RRC,"[MSG] RRCConnectionReject\n");

1001
1002
  for (cnt = 0; cnt < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size; cnt++) {
    LOG_F(RRC,"%02x ", ((uint8_t*)RC.rrc[ctxt_pP->module_id]->Srb0.Tx_buffer.Payload)[cnt]);
1003
1004
1005
1006
1007
1008
1009
1010
  }

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

  MSC_LOG_TX_MESSAGE(
    MSC_RRC_ENB,
    MSC_RRC_UE,
1011
1012
    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Header,
    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size,
1013
1014
1015
    MSC_AS_TIME_FMT" RRCConnectionReject UE %x size %u",
    MSC_AS_TIME_ARGS(ctxt_pP),
    ue_context_pP == NULL ? -1 : ue_context_pP->ue_context.rnti,
1016
    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size);
1017
1018
1019
1020

  LOG_I(RRC,
        PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCConnectionReject (bytes %d)\n",
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
1021
        RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size);
1022
1023
}

1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
//-----------------------------------------------------------------------------
void
rrc_eNB_generate_RRCConnectionReestablishmentReject(
  const protocol_ctxt_t* const ctxt_pP,
  rrc_eNB_ue_context_t*          const ue_context_pP,
  const int                    CC_id
)
//-----------------------------------------------------------------------------
{
#ifdef RRC_MSG_PRINT
  int                                 cnt;
#endif

Cedric Roux's avatar
Cedric Roux committed
1037
1038
1039
  T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_REJECT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
    T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));

1040
  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size =
1041
    do_RRCConnectionReestablishmentReject(ctxt_pP->module_id,
1042
                          (uint8_t*) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload);
1043
1044
1045
1046

#ifdef RRC_MSG_PRINT
  LOG_F(RRC,"[MSG] RRCConnectionReestablishmentReject\n");

1047