rrc_eNB.c 480 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
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
25
 * \date 2011 - 2014
26 27
 * \version 1.0
 * \company Eurecom
28
 * \email: navid.nikaein@eurecom.fr and raymond.knopp@eurecom.fr
29
 */
Lionel Gauthier's avatar
Lionel Gauthier committed
30 31
#define RRC_ENB
#define RRC_ENB_C
32 33 34
#include <asn_application.h>
#include <asn_internal.h> /* for _ASN_DEFAULT_STACK_MAX */
#include <per_encoder.h>
35 36
#include "rrc_defs.h"
#include "rrc_extern.h"
37
#include "assertions.h"
38
#include "common/ran_context.h"
39
#include "asn1_conversions.h"
40
#include "asn_internal.h"
41 42
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
#include "LAYER2/RLC/rlc.h"
43
#include "LAYER2/MAC/mac_proto.h"
44
#include "common/utils/LOG/log.h"
45
#include "COMMON/mac_rrc_primitives.h"
46
#include "RRC/LTE/MESSAGES/asn1_msg.h"
47 48
#include "LTE_RRCConnectionRequest.h"
#include "LTE_RRCConnectionReestablishmentRequest.h"
49
//#include "ReestablishmentCause.h"
50 51 52 53 54 55
#include "LTE_BCCH-BCH-Message.h"
#include "LTE_UL-CCCH-Message.h"
#include "LTE_DL-CCCH-Message.h"
#include "LTE_UL-DCCH-Message.h"
#include "LTE_DL-DCCH-Message.h"
#include "LTE_TDD-Config.h"
56
#include "LTE_HandoverPreparationInformation.h"
57
#include "LTE_HandoverCommand.h"
58
#include "rlc.h"
59 60 61
#include "rrc_eNB_UE_context.h"
#include "platform_types.h"
#include "msc.h"
62 63 64
#include "LTE_SL-CommConfig-r12.h"
#include "LTE_PeriodicBSR-Timer-r12.h"
#include "LTE_RetxBSR-Timer-r12.h"
65 66 67 68 69 70
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   #include "LTE_BCCH-BCH-Message-MBMS.h"
   #include "LTE_BCCH-DL-SCH-Message-MBMS.h"
   #include "LTE_SystemInformationBlockType1-MBMS-r14.h"
   #include "LTE_NonMBSFN-SubframeConfig-r14.h"
#endif
71
#include "common/utils/LOG/vcd_signal_dumper.h"
Cedric Roux's avatar
Cedric Roux committed
72
#include "x2ap_eNB.h"
73

74 75
#include "T.h"

76 77
//#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
#include "LTE_MeasResults.h"
78 79
//#endif

80 81 82 83
#include "RRC/NAS/nas_config.h"
#include "RRC/NAS/rb_config.h"
#include "OCG.h"
#include "OCG_extern.h"
84

85
#include "UTIL/OSA/osa_defs.h"
86

87 88
#include "rrc_eNB_S1AP.h"
#include "rrc_eNB_GTPV1U.h"
89

90
#include "pdcp.h"
91
#include "gtpv1u_eNB_task.h"
92

93
#include "intertask_interface.h"
94

95
#if ENABLE_RAL
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
96
  #include "rrc_eNB_ral.h"
Lionel Gauthier's avatar
Lionel Gauthier committed
97 98
#endif

99
#include "SIMULATION/TOOLS/sim.h" // for taus
100

101

102 103
extern RAN_CONTEXT_t RC;

104
#ifdef PHY_EMUL
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
105
  extern EMULATION_VARS              *Emul_vars;
106
#endif
Lionel Gauthier's avatar
 
Lionel Gauthier committed
107 108
extern eNB_MAC_INST                *eNB_mac_inst;
extern UE_MAC_INST                 *UE_mac_inst;
109

Lionel Gauthier's avatar
 
Lionel Gauthier committed
110
extern uint16_t                     two_tier_hexagonal_cellIds[7];
winckel's avatar
RRC:  
winckel committed
111

Lionel Gauthier's avatar
 
Lionel Gauthier committed
112
mui_t                               rrc_eNB_mui = 0;
winckel's avatar
RRC:  
winckel committed
113

114
extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw);
115 116 117
extern int rrc_eNB_process_security(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, security_capabilities_t *security_capabilities_pP);
extern void process_eNB_security_key (const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, uint8_t *security_key_pP);
extern int derive_keNB_star(const uint8_t *kenb_32, const uint16_t pci, const uint32_t earfcn_dl, const bool is_rel8_only, uint8_t * kenb_star);
118

119 120 121 122
pthread_mutex_t      rrc_release_freelist;
RRC_release_list_t   rrc_release_info;
pthread_mutex_t      lock_ue_freelist;

123 124
void
openair_rrc_on(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
125
  const protocol_ctxt_t *const ctxt_pP
126 127 128 129
)
//-----------------------------------------------------------------------------
{
  int            CC_id;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
130 131
  LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" ENB:OPENAIR RRC IN....\n",
        PROTOCOL_RRC_CTXT_ARGS(ctxt_pP));
132

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
133 134 135 136
  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
    rrc_config_buffer (&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SI, BCCH, 1);
    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SI.Active = 1;
  }
137 138
}

139 140 141
//-----------------------------------------------------------------------------
static void
init_SI(
142
  const protocol_ctxt_t *const ctxt_pP,
143
  const int              CC_id,
144
  RrcConfigurationReq *configuration
145
)
146
//-----------------------------------------------------------------------------
147
{
148
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
149 150
  int                                 i;
#endif
151 152
#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 1, 0))
  LTE_SystemInformationBlockType1_v1310_IEs_t *sib1_v13ext=(LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL;
153
#endif
Cedric Roux's avatar
Cedric Roux committed
154
  LOG_D(RRC,"%s()\n\n\n\n",__FUNCTION__);
155 156

#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
157
if(configuration->radioresourceconfig[CC_id].mbms_dedicated_serving_cell == TRUE){
158 159
  LOG_I(RRC, "Configuring MIB FeMBMS (N_RB_DL %d)\n",
        (int)configuration->N_RB_DL[CC_id]);
160
  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MIB_FeMBMS = (uint8_t *) malloc16(4);
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
  do_MIB_FeMBMS(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id],
#ifdef ENABLE_ITTI
         configuration->N_RB_DL[CC_id],
         0 //additionalNonMBSFN
#else
         50,0
#endif
         ,0);
  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1_MBMS = 0;
  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB1_MBMS = (uint8_t *) malloc16(32);
  AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB1_MBMS!=NULL,PROTOCOL_RRC_CTXT_FMT" init_SI: FATAL, no memory for SIB1_MBMS allocated\n",
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP));
  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1_MBMS = do_SIB1_MBMS(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id],ctxt_pP->module_id,CC_id
#if defined(ENABLE_ITTI)
      , configuration
#endif
									     );

 LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Contents of SIB1-MBMS\n",
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)
	);
182
   LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS freqBandIndicator_r14 %ld\n",
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
		RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->freqBandIndicator_r14
	);

   for (i = 0; i < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->schedulingInfoList_MBMS_r14.list.count; i++) {
   	LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS contents for Scheduling Info List %d/%d(partial)\n",
            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
            i,
            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->schedulingInfoList_MBMS_r14.list.count);
   }
   LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS SIB13-r14 contents for MBSFN subframe allocation (partial)\n",
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)
	);

    for (i = 0; i < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9.list.count; i++) {
	LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS SIB13-r14 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].sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9.list.count);
	LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS 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].sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9);
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS MCCH Offset: %ld\n",
            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_Offset_r9);
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS MCCH Modification Period: %ld\n",
            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_ModificationPeriod_r9);
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS MCCH Signalling MCS: %ld\n",
            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.signallingMCS_r9);
214 215 216
	//LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS SIB13 sf_AllocInfo is = %x\n",
        //    PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
        //    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.sf_AllocInfo_r9.buf);
217 218 219 220 221 222 223 224 225 226 227

        if(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9.list.array[i]->ext1) {
	LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS Subcarrier Spacing MBMS: %s\n",
            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
            (*RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9.list.array[i]->ext1->subcarrierSpacingMBMS_r14 == LTE_MBSFN_AreaInfo_r9__ext1__subcarrierSpacingMBMS_r14_khz_1dot25 ? "khz_1dot25": "khz_7dot5"));
        }
    }



    if(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->nonMBSFN_SubframeConfig_r14) {
228
    	LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS non MBSFN Subframe Config radioFrameAllocationPeriod-r14 %ld\n",
229 230 231
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
		RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->nonMBSFN_SubframeConfig_r14->radioFrameAllocationPeriod_r14
	);
232
 	LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS non MBSFN Subframe Config radioFrameAllocationOffset-r14 %ld\n",
233 234 235 236 237 238 239 240 241 242 243 244 245
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
		RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->nonMBSFN_SubframeConfig_r14->radioFrameAllocationOffset_r14
	);
	LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS non MBSFN Subframe Config subframeAllocation-r14 is = %s\n",
            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.buf);



    }


  //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");
246
}
247
#endif
248

249 250
  eNB_RRC_INST *rrc = RC.rrc[ctxt_pP->module_id];
  rrc_eNB_carrier_data_t *carrier=&rrc->carrier[CC_id];
251

252 253 254 255 256 257
  carrier->MIB = (uint8_t*) malloc16(4);
  carrier->sizeof_SIB1 = 0;
  carrier->sizeof_SIB23 = 0;
  carrier->SIB1 = (uint8_t*) malloc16(32);
  
  AssertFatal(carrier->SIB1!=NULL,PROTOCOL_RRC_CTXT_FMT" init_SI: FATAL, no memory for SIB1 allocated\n",
258
	      PROTOCOL_RRC_CTXT_ARGS(ctxt_pP));
259

260
  LOG_I(RRC,"[eNB %d] Node type %d \n ", ctxt_pP->module_id, rrc->node_type);
261
  if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) {
262 263 264 265 266 267
    // copy basic Cell parameters
    carrier->physCellId      = configuration->Nid_cell[CC_id];
    carrier->p_eNB           = configuration->nb_antenna_ports[CC_id];
    carrier->Ncp             = configuration->prefix_type[CC_id];
    carrier->dl_CarrierFreq  = configuration->downlink_frequency[CC_id];
    carrier->ul_CarrierFreq  = configuration->downlink_frequency[CC_id]+ configuration->uplink_frequency_offset[CC_id];
268 269
    carrier->eutra_band      = configuration->eutra_band[CC_id];
    carrier->N_RB_DL         = configuration->N_RB_DL[CC_id];
270
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
271
    carrier->pbch_repetition = configuration->pbch_repetition[CC_id];
272
    LOG_I(RRC, "configuration->schedulingInfoSIB1_BR_r13[CC_id] %d\n",(int)configuration->schedulingInfoSIB1_BR_r13[CC_id]);
273
#endif
274

275 276
    LOG_I(RRC, "Configuring MIB (N_RB_DL %d,phich_Resource %d,phich_Duration %d)\n", 
	  (int)configuration->N_RB_DL[CC_id],
277 278
	  (int)configuration->radioresourceconfig[CC_id].phich_resource,
	  (int)configuration->radioresourceconfig[CC_id].phich_duration);
279

280 281 282 283 284
    carrier->sizeof_MIB = do_MIB(&rrc->carrier[CC_id],
                                 configuration->N_RB_DL[CC_id],
                                 configuration->radioresourceconfig[CC_id].phich_resource,
                                 configuration->radioresourceconfig[CC_id].phich_duration,
                                 0
285
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
286
                                 ,configuration->schedulingInfoSIB1_BR_r13[CC_id]
287
#endif
288
   );
289 290
    
    
291 292 293
    carrier->sizeof_SIB1 = do_SIB1(&rrc->carrier[CC_id],
                                   ctxt_pP->module_id,
                                   CC_id
294
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
295
                                   ,FALSE
296
#endif
297
                                   , configuration
298 299 300
				   );
    
    AssertFatal(carrier->sizeof_SIB1 != 255,"FATAL, RC.rrc[enb_mod_idP].carrier[CC_id].sizeof_SIB1 == 255");
301

302
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
303 304 305 306 307 308 309 310
    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1_BR = 0;

    if (configuration->schedulingInfoSIB1_BR_r13[CC_id] > 0) {
      RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB1_BR = (uint8_t *) malloc16(32);
      RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1_BR = do_SIB1(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id],
                                                                          ctxt_pP->module_id,
                                                                          CC_id, TRUE, configuration);
    }
winckel's avatar
winckel committed
311
#endif
312

313
  }
314
  if (!NODE_IS_DU(rrc->node_type)) {
315 316
    carrier->SIB23 = (uint8_t*) malloc16(64);
    AssertFatal(carrier->SIB23!=NULL,"cannot allocate memory for SIB");
317 318
    carrier->sizeof_SIB23 = do_SIB23(ctxt_pP->module_id,
                                     CC_id
319
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
320
                                     ,FALSE
kogo's avatar
kogo committed
321
#endif
322 323
                                     , configuration
                                     );
324
    
325 326
    LOG_I(RRC,"do_SIB23, size %d \n ", carrier->sizeof_SIB23);
    
327 328
    AssertFatal(carrier->sizeof_SIB23 != 255,"FATAL, RC.rrc[mod].carrier[CC_id].sizeof_SIB23 == 255");
    
329
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
330
  carrier->sizeof_SIB23_BR = 0;
331
  if (configuration->schedulingInfoSIB1_BR_r13[CC_id]>0) {
332 333
    carrier->SIB23_BR = (uint8_t*) malloc16(64);
    AssertFatal(carrier->SIB23_BR!=NULL,"cannot allocate memory for SIB");
334
    carrier->sizeof_SIB23_BR = do_SIB23(ctxt_pP->module_id, CC_id, TRUE, configuration);
335
  }
336
    
337
#endif
338
    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" SIB2/3 Contents (partial)\n",
339
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP));
340
    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.n_SB = %ld\n",
341 342
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
          carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.n_SB);
343
    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.hoppingMode = %ld\n",
344 345
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
          carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode);
346
    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.pusch_HoppingOffset = %ld\n",
347 348
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
          carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset);
349
    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.enable64QAM = %d\n",
350 351
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
          (int)carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM);
352
    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.groupHoppingEnabled = %d\n",
353 354
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
          (int)carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled);
355
    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.groupAssignmentPUSCH = %ld\n",
356 357
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
          carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH);
358
    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.sequenceHoppingEnabled = %d\n",
359 360
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
          (int)carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled);
361
    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.cyclicShift  = %ld\n",
362 363
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
          carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift);
364
    
365
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
366 367 368 369 370
    
    if (carrier->MBMS_flag > 0) {
      for (i = 0; i < carrier->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);
371 372 373 374 375 376 377 378 379 380 381 382 383
        LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" SIB13 contents for MBSFN subframe allocation %d/%d(partial)\n",
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              i,
              carrier->sib2->mbsfn_SubframeConfigList->list.count);
        LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" mbsfn_Subframe_pattern is  = %x\n",
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->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),
              carrier->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),
              carrier->sib2->mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset);
384
      }
385
      
386 387
      //   SIB13
      for (i = 0; i < carrier->sib13->mbsfn_AreaInfoList_r9.list.count; i++) {
388 389 390 391 392 393 394 395 396 397
        LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" SIB13 contents for MBSFN sync area %d/%d (partial)\n",
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              i,
              carrier->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),
              carrier->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),
              carrier->sib13->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_Offset_r9);
398
      }
399
    } 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));
400 401
    
    //TTN - SIB 18
402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432
    if (configuration->SL_configured > 0) {
      for (int j = 0; j < carrier->sib18->commConfig_r12->commRxPool_r12.list.count; j++) {
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Contents of SIB18 %d/%d \n",
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              j+1,
              carrier->sib18->commConfig_r12->commRxPool_r12.list.count);
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 rxPool_sc_CP_Len: %ld \n",
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_CP_Len_r12);
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 sc_Period_r12: %ld \n",
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_Period_r12);
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 data_CP_Len_r12: %ld \n",
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->data_CP_Len_r12);
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_Num_r12: %ld \n",
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_Num_r12);
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_Start_r12: %ld \n",
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_Start_r12);
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_End_r12: %ld \n",
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_End_r12);
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 offsetIndicator: %ld \n",
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12);
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 subframeBitmap_choice_bs_buf: %s \n",
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf);
      }
433
      
434 435 436 437 438
      //TTN - SIB 19
      for (int j = 0; j < carrier->sib19->discConfig_r12->discRxPool_r12.list.count; j++) {
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Contents of SIB19 %d/%d \n",
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              j+1,
439
              carrier->sib19->discConfig_r12->discRxPool_r12.list.count);
440
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 cp_Len_r12: %ld \n",
441 442
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->cp_Len_r12);
443
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 discPeriod_r12: %ld \n",
444 445
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->discPeriod_r12);
446
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 numRetx_r12: %ld \n",
447 448
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->numRetx_r12);
449
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 numRepetition_r12: %ld \n",
450 451
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->numRepetition_r12);
452
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_Num_r12: %ld \n",
453 454
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_Num_r12);
455
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_Start_r12: %ld \n",
456 457
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_Start_r12);
458
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_End_r12: %ld \n",
459 460
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_End_r12);
461
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 offsetIndicator: %ld \n",
462 463
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12);
464
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 subframeBitmap_choice_bs_buf: %s \n",
465 466
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf);
467
      }
468
    }
469
#endif // (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))    
470
  }
471
   
472
  LOG_D(RRC,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
473 474
        PROTOCOL_RRC_CTXT_FMT" RRC_UE --- MAC_CONFIG_REQ (SIB1.tdd & SIB2 params) ---> MAC_UE\n",
        PROTOCOL_RRC_CTXT_ARGS(ctxt_pP));
475
#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
476

477
  // LTE-M stuff here (take out CU-DU for now)
478
  if (NODE_IS_MONOLITHIC(rrc->node_type)) {
479
    if ((carrier->mib.message.schedulingInfoSIB1_BR_r13>0) && 
480
        (carrier->sib1_BR!=NULL)) {
481
      AssertFatal(carrier->sib1_BR->nonCriticalExtension!=NULL,
482
                  "sib2_br->nonCriticalExtension is null (v8.9)\n");
483
      AssertFatal(carrier->sib1_BR->nonCriticalExtension->nonCriticalExtension!=NULL,
484
                  "sib2_br->nonCriticalExtension is null (v9.2)\n");
485
      AssertFatal(carrier->sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL,
486
                  "sib2_br->nonCriticalExtension is null (v11.3)\n");
487
      AssertFatal(carrier->sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL,
488
                  "sib2_br->nonCriticalExtension is null (v12.5)\n");
489
      AssertFatal(carrier->sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL,
490
                  "sib2_br->nonCriticalExtension is null (v13.10)\n");
491

492
      sib1_v13ext = carrier->sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension;
493

islam.galal's avatar
islam.galal committed
494
      // Basic Asserts for CE_level0 PRACH configuration
495 496
      LTE_RadioResourceConfigCommonSIB_t *radioResourceConfigCommon_BR = &carrier[CC_id].sib2_BR->radioResourceConfigCommon;
      struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach=radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
497
      LTE_PRACH_ParametersListCE_r13_t	 *prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13;
islam.galal's avatar
islam.galal committed
498
      AssertFatal(prach_ParametersListCE_r13->list.count>0,"prach_ParametersListCE_r13 is empty\n");
499
                  LTE_PRACH_ParametersCE_r13_t *p = prach_ParametersListCE_r13->list.array[0];
islam.galal's avatar
islam.galal committed
500 501
      AssertFatal(p->prach_StartingSubframe_r13 != NULL, "prach_StartingSubframe_r13 celevel0 is null\n");
      AssertFatal((1<<p->numRepetitionPerPreambleAttempt_r13)<=(2<<*p->prach_StartingSubframe_r13),
502 503 504
                  "prachce0->numReptitionPerPreambleAttempt_r13 %d > prach_StartingSubframe_r13 %d\n",
                  1<<p->numRepetitionPerPreambleAttempt_r13,
                  2<<*p->prach_StartingSubframe_r13);
505 506
    }
  
507
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
508
#endif
509
  /*
510 511 512 513 514 515 516 517 518
  if (rrc->node_type == ngran_eNB_DU) {
    LOG_D(RRC, "About to call rrc_mac_config_req_eNB for ngran_eNB_DU\n");
    
    rrc_mac_config_req_eNB(ctxt_pP->module_id, CC_id,
			   carrier->physCellId,
			   carrier->p_eNB,
			   carrier->Ncp,
			   carrier->sib1->freqBandIndicator,
			   carrier->dl_CarrierFreq,
519
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
520
			   carrier->pbch_repetition,
521
#endif
522 523 524 525
			   0, // rnti
			   (BCCH_BCH_Message_t *)
			   &carrier->mib,
			   (RadioResourceConfigCommonSIB_t *) NULL,
526
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
527
			   (RadioResourceConfigCommonSIB_t *) NULL,
528
#endif
529
			   (struct PhysicalConfigDedicated *)NULL,
530
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
531 532 533 534 535 536 537 538 539 540 541 542 543 544
			   (SCellToAddMod_r10_t *)NULL,
			   //(struct PhysicalConfigDedicatedSCell_r10 *)NULL,
#endif
			   (MeasObjectToAddMod_t **) NULL,
			   (MAC_MainConfig_t *) NULL, 0,
			   (struct LogicalChannelConfig *)NULL,
			   (MeasGapConfig_t *) NULL,
			   carrier->sib1->tdd_Config,
			   NULL,
			   &carrier->sib1->schedulingInfoList,
			   carrier->ul_CarrierFreq,
			   NULL,
			   NULL,
			   NULL
545
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
546 547 548 549
			   ,
			   carrier->MBMS_flag,
			   NULL,
			   (PMCH_InfoList_r9_t *) NULL
550
#endif
551
#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
552 553 554 555 556
			   , 
			   NULL
#endif
			   );
  }
557 558
  else 
  */
559
  if (NODE_IS_MONOLITHIC(rrc->node_type)) {
560 561 562
    LOG_D(RRC, "About to call rrc_mac_config_req_eNB for ngran_eNB\n");
    
    rrc_mac_config_req_eNB(ctxt_pP->module_id, CC_id,
563 564 565 566 567 568 569 570 571 572 573 574 575
                           carrier->physCellId,
                           carrier->p_eNB,
                           carrier->Ncp,
                           carrier->sib1->freqBandIndicator,
                           carrier->dl_CarrierFreq,
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                           carrier->pbch_repetition,
#endif
                           0, // rnti
                           (LTE_BCCH_BCH_Message_t *) &carrier->mib,
                           (LTE_RadioResourceConfigCommonSIB_t *) &carrier->sib2->radioResourceConfigCommon,
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                           (LTE_RadioResourceConfigCommonSIB_t *) &carrier->sib2_BR->radioResourceConfigCommon,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
576
#endif
577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592
                           (struct LTE_PhysicalConfigDedicated *)NULL,
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                           (LTE_SCellToAddMod_r10_t *)NULL,
                           //(struct PhysicalConfigDedicatedSCell_r10 *)NULL,
#endif
                           (LTE_MeasObjectToAddMod_t **) NULL,
                           (LTE_MAC_MainConfig_t *) NULL, 0,
                           (struct LTE_LogicalChannelConfig *)NULL,
                           (LTE_MeasGapConfig_t *) NULL,
                           carrier->sib1->tdd_Config,
                           NULL,
                           &carrier->sib1->schedulingInfoList,
                           carrier->ul_CarrierFreq,
                           carrier->sib2->freqInfo.ul_Bandwidth,
                           &carrier->sib2->freqInfo.additionalSpectrumEmission,
                           (LTE_MBSFN_SubframeConfigList_t*) carrier->sib2->mbsfn_SubframeConfigList
593
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
594 595 596 597
                           ,
                           carrier->MBMS_flag,
                           (LTE_MBSFN_AreaInfoList_r9_t*) & carrier->sib13->mbsfn_AreaInfoList_r9,
                           (LTE_PMCH_InfoList_r9_t *) NULL
598
#endif
599
#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
600 601
                           ,
                           sib1_v13ext
602 603 604 605 606 607 608 609 610
#endif
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                        ,
                        RC.rrc[ctxt_pP->module_id]->carrier[CC_id].FeMBMS_flag,
                        (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL,
                        (LTE_SchedulingInfo_MBMS_r14_t *) NULL,
                        (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
                        (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
                        (LTE_MBSFN_AreaInfoList_r9_t *) NULL
611
#endif
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
612
                        );
613
  }
614 615
	/* set flag to indicate that cell information is configured. This is required
	 * in DU to trigger F1AP_SETUP procedure */
616 617 618
  pthread_mutex_lock(&rrc->cell_info_mutex);
  rrc->cell_info_configured=1;
  pthread_mutex_unlock(&rrc->cell_info_mutex);
619 620
}

621
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
winckel's avatar
winckel committed
622
/*------------------------------------------------------------------------------*/
623 624
static void
init_MCCH(
625 626
  module_id_t enb_mod_idP,
  int CC_id
627 628
)
//-----------------------------------------------------------------------------
629 630 631
{
  int                                 sync_area = 0;
  // initialize RRC_eNB_INST MCCH entry
632 633
  eNB_RRC_INST *rrc = RC.rrc[enb_mod_idP];

634
  RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE =
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
635
    malloc(RC.rrc[enb_mod_idP]->carrier[CC_id].num_mbsfn_sync_area * sizeof(uint8_t *));
Lionel Gauthier's avatar
 
Lionel Gauthier committed
636

637 638 639
  for (sync_area = 0; sync_area < RC.rrc[enb_mod_idP]->carrier[CC_id].num_mbsfn_sync_area; sync_area++) {
    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);
640
    AssertFatal(RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE[sync_area] != NULL,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
641
                "[eNB %d]init_MCCH: FATAL, no memory for MCCH MESSAGE allocated \n", enb_mod_idP);
642
    RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] = do_MBSFNAreaConfig(enb_mod_idP,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
643 644 645 646
        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);
647
    LOG_I(RRC, "mcch message pointer %p for sync area %d \n",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
648 649
          RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE[sync_area],
          sync_area);
650 651
    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,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
652
          RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->commonSF_AllocPeriod_r9);
653
    LOG_D(RRC,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
654 655
          "[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);
656
    LOG_D(RRC, "[eNB %d] MBSFN Subframe Pattern: %02x (in hex)\n",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
657 658 659
          enb_mod_idP,
          RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->commonSF_Alloc_r9.list.array[0]->subframeAllocation.
          choice.oneFrame.buf[0]);
660
    AssertFatal(RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] != 255,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
661
                "RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] == 255");
662
    RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESS[sync_area].Active = 1;
663
  }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
664

665
  //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)
666 667
  // ??Configure MCCH logical channel
  // call mac_config_req with appropriate structure from ASN.1 description
668 669
  //  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]);
670
  if (NODE_IS_MONOLITHIC(rrc->node_type)) {
671
    rrc_mac_config_req_eNB(enb_mod_idP, CC_id,
672
                           0,0,0,0,0,
673
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
674
                           0,
675
#endif
676 677 678
                           0,//rnti
                           (LTE_BCCH_BCH_Message_t *)NULL,
                           (LTE_RadioResourceConfigCommonSIB_t *) NULL,
679
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
680
                           (LTE_RadioResourceConfigCommonSIB_t *) NULL,
681
#endif
682 683
                           (struct LTE_PhysicalConfigDedicated *)NULL,
                           (LTE_SCellToAddMod_r10_t *)NULL,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
684
                         //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL,
685 686 687 688 689 690 691 692 693 694 695 696 697
                           (LTE_MeasObjectToAddMod_t **) NULL,
                           (LTE_MAC_MainConfig_t *) NULL,
                           0,
                           (struct LTE_LogicalChannelConfig *)NULL,
                           (LTE_MeasGapConfig_t *) NULL,
                           (LTE_TDD_Config_t *) NULL,
                           (LTE_MobilityControlInfo_t *)NULL,
                           (LTE_SchedulingInfoList_t *) NULL,
                           0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL
                           ,
                           0,
                           (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
                           (LTE_PMCH_InfoList_r9_t *) & (RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9)
698
#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
699 700
                           ,
                           (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL
701 702 703 704 705 706 707 708 709
#endif
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                        ,
                        0,
                        (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL,
                        (LTE_SchedulingInfo_MBMS_r14_t *) NULL,
                        (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
                        (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
                        (LTE_MBSFN_AreaInfoList_r9_t *) NULL
710
#endif
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
711
                        );
712
  }
713
  //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);
714 715
}

716
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
 
Lionel Gauthier committed
717
static void init_MBMS(
718
  module_id_t enb_mod_idP,
719
  int         CC_id,
720 721 722
  frame_t frameP
)
//-----------------------------------------------------------------------------
723 724 725
{
  // init the configuration for MTCH
  protocol_ctxt_t               ctxt;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
726

727
  if (RC.rrc[enb_mod_idP]->carrier[CC_id].MBMS_flag > 0) {
728
    PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, enb_mod_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, 0,enb_mod_idP);
729 730 731
    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
    rrc_pdcp_config_asn1_req(&ctxt,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
732 733
                             (LTE_SRB_ToAddModList_t *)NULL,   // LTE_SRB_ToAddModList
                             (LTE_DRB_ToAddModList_t *)NULL,   // LTE_DRB_ToAddModList
734
                             (LTE_DRB_ToReleaseList_t *)NULL,
735 736 737 738
                             0,     // security mode
                             NULL,  // key rrc encryption
                             NULL,  // key rrc integrity
                             NULL   // key encryption
739
                             , &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9)
740
                             ,NULL);
741
    
742
    if (!NODE_IS_CU(RC.rrc[enb_mod_idP]->node_type)) {
743
      rrc_rlc_config_asn1_req(&ctxt,
744 745 746 747
                              NULL, // LTE_SRB_ToAddModList
                              NULL,   // LTE_DRB_ToAddModList
                              NULL,   // DRB_ToReleaseList
                              &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9)
748
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
749
			      ,0, 0
750
#endif
751 752
			      );
    }
753
	    //rrc_mac_config_req();
754
  }
755 756 757
}
#endif

758 759 760 761 762 763
//-----------------------------------------------------------------------------
uint8_t
rrc_eNB_get_next_transaction_identifier(
  module_id_t enb_mod_idP
)
//-----------------------------------------------------------------------------
764
{
765 766
  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;
767
  LOG_T(RRC,"generated xid is %d\n",rrc_transaction_identifier[enb_mod_idP]);
768 769 770 771 772
  return rrc_transaction_identifier[enb_mod_idP];
}
/*------------------------------------------------------------------------------*/
/* Functions to handle UE index in eNB UE list */

winckel's avatar
winckel committed
773

774 775 776 777 778 779 780 781 782 783 784 785 786 787
////-----------------------------------------------------------------------------
//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);
//
788
//    for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
789
//        if (RC.rrc[enb_mod_idP]->Info.UE_list[i] == UE_identity) {
790 791 792 793 794 795 796 797 798 799 800 801 802
//            // UE_identity already registered
//            reg = TRUE;
//            break;
//        }
//    }
//
//    if (reg == FALSE) {
//        return (UE_MODULE_INVALID);
//    } else
//        return (i);
//}


803
//-----------------------------------------------------------------------------
gauthier's avatar
gauthier committed
804
// return the ue context if there is already an UE with ue_identityP, NULL otherwise
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
805
static struct rrc_eNB_ue_context_s *
806
rrc_eNB_ue_context_random_exist(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
807
  const protocol_ctxt_t *const ctxt_pP,
808 809 810 811
  const uint64_t               ue_identityP
)
//-----------------------------------------------------------------------------
{
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
812
  struct rrc_eNB_ue_context_s        *ue_context_p = NULL;
813
  RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
814
    if (ue_context_p->ue_context.random_ue_identity == ue_identityP)
gauthier's avatar
gauthier committed
815
      return ue_context_p;
816
  }
gauthier's avatar
gauthier committed
817 818 819 820
  return NULL;
}
//-----------------------------------------------------------------------------
// return the ue context if there is already an UE with the same S-TMSI(MMEC+M-TMSI), NULL otherwise
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
821
static struct rrc_eNB_ue_context_s *
gauthier's avatar
gauthier committed
822
rrc_eNB_ue_context_stmsi_exist(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
823
  const protocol_ctxt_t *const ctxt_pP,
gauthier's avatar
gauthier committed
824 825 826 827 828
  const mme_code_t             mme_codeP,
  const m_tmsi_t               m_tmsiP
)
//-----------------------------------------------------------------------------
{
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
829
  struct rrc_eNB_ue_context_s        *ue_context_p = NULL;
830
  RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
kaltenbe's avatar
kaltenbe committed
831
    LOG_I(RRC,"checking for UE S-TMSI %x, mme %x (%p): rnti %x",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
832 833 834
          m_tmsiP, mme_codeP, ue_context_p,
          ue_context_p->ue_context.rnti);

kaltenbe's avatar
kaltenbe committed
835
    if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) {
836
      printf("=> S-TMSI %x, MME %x\n",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
837 838 839
             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
840 841 842
      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;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
843
    } else
kaltenbe's avatar
kaltenbe committed
844
      printf("\n");
gauthier's avatar
gauthier committed
845 846
  }
  return NULL;
847 848
}

849 850
//-----------------------------------------------------------------------------
// return a new ue context structure if ue_identityP, ctxt_pP->rnti not found in collection
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
851
static struct rrc_eNB_ue_context_s *
852
rrc_eNB_get_next_free_ue_context(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
853
  const protocol_ctxt_t *const ctxt_pP,
854 855 856 857
  const uint64_t               ue_identityP
)
//-----------------------------------------------------------------------------
{
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
858
  struct rrc_eNB_ue_context_s        *ue_context_p = NULL;
859
  ue_context_p = rrc_eNB_get_ue_context(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
860 861
                   RC.rrc[ctxt_pP->module_id],
                   ctxt_pP->rnti);
862 863

  if (ue_context_p == NULL) {
864
    ue_context_p = rrc_eNB_allocate_new_UE_context(RC.rrc[ctxt_pP->module_id]);
winckel's avatar
winckel committed
865

866 867 868 869 870
    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;
871
    }
872

873 874 875
    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;
876
    RB_INSERT(rrc_ue_tree_s, &RC.rrc[ctxt_pP->module_id]->rrc_ue_head, ue_context_p);
877 878 879 880 881 882 883 884 885 886 887
    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;
  } 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;
  }
888
  return(ue_context_p);
winckel's avatar
winckel committed
889 890
}

891 892 893
//-----------------------------------------------------------------------------
void
rrc_eNB_free_mem_UE_context(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
894 895
  const protocol_ctxt_t               *const ctxt_pP,
  struct rrc_eNB_ue_context_s         *const ue_context_pP
896
)
897
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
898
{
899 900
  int i;
  LOG_T(RRC,
Cedric Roux's avatar
Cedric Roux committed
901
        PROTOCOL_RRC_CTXT_UE_FMT" Clearing UE context 0x%p (free internal structs)\n",
902 903
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
        ue_context_pP);
904 905 906
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
  ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LTE_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[0]);
  ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LTE_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[1]);
907 908 909
#endif

  if (ue_context_pP->ue_context.SRB_configList) {
910
    ASN_STRUCT_FREE(asn_DEF_LTE_SRB_ToAddModList, ue_context_pP->ue_context.SRB_configList);
911 912
    ue_context_pP->ue_context.SRB_configList = NULL;
  }
913

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
914 915 916 917 918
  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;
    }
919 920
  }

921
  if (ue_context_pP->ue_context.DRB_configList) {
922
    ASN_STRUCT_FREE(asn_DEF_LTE_DRB_ToAddModList, ue_context_pP->ue_context.DRB_configList);
923 924
    ue_context_pP->ue_context.DRB_configList = NULL;
  }
925

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
926 927 928 929 930 931 932 933 934 935
  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;
    }
936 937
  }

938
  memset(ue_context_pP->ue_context.DRB_active, 0, sizeof(ue_context_pP->ue_context.DRB_active));
939

940
  if (ue_context_pP->ue_context.physicalConfigDedicated) {
941
    ASN_STRUCT_FREE(asn_DEF_LTE_PhysicalConfigDedicated, ue_context_pP->ue_context.physicalConfigDedicated);
942
    ue_context_pP->ue_context.physicalConfigDedicated = NULL;
943 944
  }

945
  if (ue_context_pP->ue_context.sps_Config) {
946
    ASN_STRUCT_FREE(asn_DEF_LTE_SPS_Config, ue_context_pP->ue_context.sps_Config);
947
    ue_context_pP->ue_context.sps_Config = NULL;
948 949
  }

950 951
  for (i=0; i < MAX_MEAS_OBJ; i++) {
    if (ue_context_pP->ue_context.MeasObj[i] != NULL) {
952
      ASN_STRUCT_FREE(asn_DEF_LTE_MeasObjectToAddMod, ue_context_pP->ue_context.MeasObj[i]);
953 954
      ue_context_pP->ue_context.MeasObj[i] = NULL;
    }
955
  }
956

957 958
  for (i=0; i < MAX_MEAS_CONFIG; i++) {
    if (ue_context_pP->ue_context.ReportConfig[i] != NULL) {
959
      ASN_STRUCT_FREE(asn_DEF_LTE_ReportConfigToAddMod, ue_context_pP->ue_context.ReportConfig[i]);
960 961 962
      ue_context_pP->ue_context.ReportConfig[i] = NULL;
    }
  }
963

964
  if (ue_context_pP->ue_context.QuantityConfig) {
965
    ASN_STRUCT_FREE(asn_DEF_LTE_QuantityConfig, ue_context_pP->ue_context.QuantityConfig);
966 967
    ue_context_pP->ue_context.QuantityConfig = NULL;
  }
968

969
  if (ue_context_pP->ue_context.mac_MainConfig) {
970
    ASN_STRUCT_FREE(asn_DEF_LTE_MAC_MainConfig, ue_context_pP->ue_context.mac_MainConfig);
971 972
    ue_context_pP->ue_context.mac_MainConfig = NULL;
  }
973

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
974 975 976 977 978
  /*  if (ue_context_pP->ue_context.measGapConfig) {
      ASN_STRUCT_FREE(asn_DEF_LTE_MeasGapConfig, ue_context_pP->ue_context.measGapConfig);
      ue_context_pP->ue_context.measGapConfig = NULL;
    }*/
  if (ue_context_pP->ue_context.handover_info) {
Konstantinos Alexandris's avatar
Konstantinos Alexandris committed
979 980
    /* TODO: be sure free is enough here (check memory leaks) */
    free(ue_context_pP->ue_context.handover_info);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
981 982
    ue_context_pP->ue_context.handover_info = NULL;
  }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
983

984 985
  if (ue_context_pP->ue_context.measurement_info) {
    /* TODO: be sure free is enough here (check memory leaks) */
986 987 988 989 990 991 992 993
    if (ue_context_pP->ue_context.measurement_info->events) {
      if (ue_context_pP->ue_context.measurement_info->events->a3_event) {
        free(ue_context_pP->ue_context.measurement_info->events->a3_event);
        ue_context_pP->ue_context.measurement_info->events->a3_event = NULL;
      }
      free(ue_context_pP->ue_context.measurement_info->events);
      ue_context_pP->ue_context.measurement_info->events = NULL;
    }
994 995 996 997
    free(ue_context_pP->ue_context.measurement_info);
    ue_context_pP->ue_context.measurement_info = NULL;
  }

998 999 1000 1001 1002
  //SRB_INFO                           SI;
  //SRB_INFO                           Srb0;
  //SRB_INFO_TABLE_ENTRY               Srb1;
  //SRB_INFO_TABLE_ENTRY               Srb2;
  if (ue_context_pP->ue_context.measConfig) {
1003
    ASN_STRUCT_FREE(asn_DEF_LTE_MeasConfig, ue_context_pP->ue_context.measConfig);
1004
    ue_context_pP->ue_context.measConfig = NULL;
1005
  }
1006

1007
  if (ue_context_pP->ue_context.measConfig) {
1008
    ASN_STRUCT_FREE(asn_DEF_LTE_MeasConfig, ue_context_pP->ue_context.measConfig);
1009
    ue_context_pP->ue_context.measConfig = NULL;
1010
  }
1011

1012
#if 0
1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032
  //HANDOVER_INFO                     *handover_info;
  //uint8_t kenb[32];
  //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
1033
#endif
1034 1035
}

1036
//-----------------------------------------------------------------------------
1037
/*
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1038
* Should be called when UE context in eNB should be released
1039
* or when S1 command UE_CONTEXT_RELEASE_REQ should be sent
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1040
*/
1041
void
1042 1043 1044
rrc_eNB_free_UE(
  const module_id_t enb_mod_idP,
  const struct rrc_eNB_ue_context_s *const ue_context_pP)
1045
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
1046
{
1047
  rnti_t rnti = ue_context_pP->ue_context.rnti;
1048

1049
  if (enb_mod_idP >= NB_eNB_INST) {
1050
    LOG_E(RRC, "eNB instance invalid (%d/%d) for UE %x!\n",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1051 1052 1053
          enb_mod_idP,
          NB_eNB_INST,
          rnti);
1054
    return;
1055
  }
Lionel Gauthier's avatar
Lionel Gauthier committed
1056

1057
   if(EPC_MODE_ENABLED) {
1058
     if (!NODE_IS_DU(RC.rrc[enb_mod_idP]->node_type)) {
1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072
       if((ue_context_pP->ue_context.ul_failure_timer >= 20000) && (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) {
         LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 21, radio connection with ue lost\n",
               enb_mod_idP,
               rnti);
         rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP,
                                                  ue_context_pP,
                                                  S1AP_CAUSE_RADIO_NETWORK,
                                                  21); // send cause 21: radio connection with ue lost
        /* 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].
         */
        return;
1073
      }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1074

1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086
      if((ue_context_pP->ue_context.ue_rrc_inactivity_timer >= RC.rrc[enb_mod_idP]->configuration.rrc_inactivity_timer_thres) &&
          (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED) &&
          (RC.rrc[enb_mod_idP]->configuration.rrc_inactivity_timer_thres > 0)) {
        LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 20, user inactivity\n",
              enb_mod_idP,
              rnti);
        rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP,
                                                 ue_context_pP,
                                                 S1AP_CAUSE_RADIO_NETWORK,
                                                 20); // send cause 20: user inactivity
        return;
      }
1087
    }
1088
  }
1089

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1090 1091 1092
  LOG_W(RRC, "[eNB %d] Removing UE RNTI %x\n",
        enb_mod_idP,
        rnti);
1093 1094
  // add UE info to freeList
  LOG_I(RRC, "Put UE %x into freeList\n",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1095
        rnti);
1096
  put_UE_in_freelist(enb_mod_idP, rnti, 1);
1097
}
Raymond Knopp's avatar
 
Raymond Knopp committed
1098

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1099 1100 1101 1102 1103 1104 1105 1106
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);
1107 1108
}

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1109 1110 1111 1112 1113 1114 1115 1116
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++;
1117 1118
  eNB_MAC->UE_release_req.ue_release_request_body.ue_release_request_TLVs_list[eNB_MAC->UE_release_req.ue_release_request_body.number_of_TLVs].rnti = rnti;
  eNB_MAC->UE_release_req.ue_release_request_body.number_of_TLVs++;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1119 1120
  free_list->tail_freelist = (free_list->tail_freelist + 1) % (NUMBER_OF_UE_MAX+1);
  pthread_mutex_unlock(&lock_ue_freelist);
1121 1122
}

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139
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;
  LTE_eNB_DLSCH_t                          *dlsch = 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) {
1140
    pthread_mutex_unlock(&lock_ue_freelist);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1141 1142
    return;
  }
1143

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1144 1145 1146
  if(tail < head) {
    tail = head + eNB_MAC->UE_free_list.num_UEs;
  }
1147

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175
  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<MAX_MOBILES_PER_ENB; i++) {
          ulsch = eNB_PHY->ulsch[i];
          if((ulsch != NULL) && (ulsch->rnti == rnti)) {
            void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch);
            LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti);
            clean_eNb_ulsch(ulsch);
          }

          dlsch = eNB_PHY->dlsch[i][0];
          if((dlsch != NULL) && (dlsch->rnti == rnti)) {
            void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch);
            LOG_I(RRC, "clean_eNb_dlsch dlsch[%d] UE %x \n", i, rnti);
            clean_eNb_dlsch(dlsch);
          }
        }
1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188
        ulsch = eNB_PHY->ulsch[i];
        if((ulsch != NULL) && (ulsch->rnti == rnti)) {
          void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch);
          LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti);
          clean_eNb_ulsch(ulsch);
        }

        for (i=0; i<NUMBER_OF_UCI_VARS_MAX; i++) {
          if(eNB_PHY->uci_vars[i].rnti == rnti) {
            LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti);
            memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI));
          }
        }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1189

1190 1191 1192
        if (flexran_agent_get_rrc_xface(mod_id)) {
          flexran_agent_get_rrc_xface(mod_id)->flexran_agent_notify_ue_state_change(
              mod_id, rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207
        }

        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) ||
                  (ul_req_tmp->ul_config_pdu_list[pdu_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) ||
                  (ul_req_tmp->ul_config_pdu_list[pdu_index].uci_cqi_pdu.ue_information.ue_information_rel8.rnti == rnti) ||
                  (ul_req_tmp->ul_config_pdu_list[pdu_index].uci_sr_pdu.ue_information.ue_information_rel8.rnti == rnti) ||
                  (ul_req_tmp->ul_config_pdu_list[pdu_index].srs_pdu.srs_pdu_rel8.rnti == rnti)) {
                LOG_I(RRC, "remove UE %x from ul_config_pdu_list %d/%d\n", rnti, pdu_index, pdu_number);
1208

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1209 1210
                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));
1211
                }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1212 1213

                ul_req_tmp->number_of_pdus--;
1214 1215
              }
            }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1216 1217 1218 1219
          }
        }
      }

1220
      if (!NODE_IS_CU(RC.rrc[mod_id]->node_type)) {
1221 1222 1223 1224
        rrc_mac_remove_ue(mod_id,rnti);
        rrc_rlc_remove_ue(&ctxt);
        pdcp_remove_UE(&ctxt);
      }
1225
      else {
1226 1227 1228 1229 1230 1231 1232 1233
        MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, F1AP_UE_CONTEXT_RELEASE_CMD);
        F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = rnti;
        F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK;
        F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release
        F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = NULL;
        F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container_length = 0;
        itti_send_msg_to_task(TASK_CU_F1, mod_id, m);
      }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1234 1235

      if(remove_UEContext) {
1236
        ue_context_pP = rrc_eNB_get_ue_context(RC.rrc[mod_id],rnti);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1237 1238 1239 1240

        if(ue_context_pP) {
          rrc_eNB_remove_ue_context(&ctxt,RC.rrc[mod_id],
                                    (struct rrc_eNB_ue_context_s *) ue_context_pP);
1241
        }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1242 1243 1244 1245
      }

      LOG_I(RRC, "[release_UE_in_freeList] remove UE %x from freeList\n", rnti);
      remove_UE_from_freelist(mod_id, rnti);
1246
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1247
  }
1248 1249
}

1250 1251
int rrc_eNB_previous_SRB2(rrc_eNB_ue_context_t*         ue_context_pP)
{
Haruki NAOI's avatar
Haruki NAOI committed
1252
  struct LTE_SRB_ToAddMod                *SRB2_config = NULL;
1253
  uint8_t i;
Haruki NAOI's avatar
Haruki NAOI committed
1254 1255
  LTE_SRB_ToAddModList_t*                 SRB_configList = ue_context_pP->ue_context.SRB_configList;
  LTE_SRB_ToAddModList_t**                SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[ue_context_pP->ue_context.reestablishment_xid];
1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277
  if (*SRB_configList2 != NULL) {
    if((*SRB_configList2)->list.count!=0){
      LOG_D(RRC, "rrc_eNB_previous_SRB2 SRB_configList2(%p) count is %d\n           SRB_configList2->list.array[0] addr is %p",
              SRB_configList2, (*SRB_configList2)->list.count,  (*SRB_configList2)->list.array[0]);
    }
    for (i = 0; (i < (*SRB_configList2)->list.count) && (i < 3); i++) {
      if ((*SRB_configList2)->list.array[i]->srb_Identity == 2 ){
        SRB2_config = (*SRB_configList2)->list.array[i];
        break;
      }
    }
  }else{
    LOG_E(RRC, "rrc_eNB_previous_SRB2 SRB_configList2 NULL\n");
  }

  if (SRB2_config != NULL) {
    ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config);
  }else{
    LOG_E(RRC, "rrc_eNB_previous_SRB2 SRB2_config NULL\n");
  }
  return 0;
}
1278
//-----------------------------------------------------------------------------
1279 1280 1281
/*
* Process the rrc connection setup complete message from UE (SRB1 Active)
*/
1282 1283
void
rrc_eNB_process_RRCConnectionSetupComplete(
1284 1285
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t *ue_context_pP,
1286
  LTE_RRCConnectionSetupComplete_r8_IEs_t *rrcConnectionSetupComplete
1287
)
1288
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
1289
{
1290
  LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing LTE_RRCConnectionSetupComplete from UE (SRB1 Active)\n",
1291
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
1292

1293 1294
  ue_context_pP->ue_context.Srb1.Active = 1;
  ue_context_pP->ue_context.Status = RRC_CONNECTED;
1295 1296 1297 1298 1299 1300 1301
  ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity timer when UE goes into RRC_CONNECTED

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

1303 1304
  if (EPC_MODE_ENABLED == 1) {
    // Forward message to S1AP layer
1305
    rrc_eNB_send_S1AP_NAS_FIRST_REQ(ctxt_pP, ue_context_pP, rrcConnectionSetupComplete);
1306
  } else {
1307
    // RRC loop back (no S1AP), send SecurityModeCommand to UE
1308
    rrc_eNB_generate_SecurityModeCommand(ctxt_pP, ue_context_pP);
1309
  }
winckel's avatar
winckel committed
1310 1311
}

1312 1313 1314
//-----------------------------------------------------------------------------
void
rrc_eNB_generate_SecurityModeCommand(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1315 1316
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t          *const ue_context_pP
1317
)
1318
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
1319
{
1320 1321
  uint8_t                             buffer[100];
  uint8_t                             size;
Cedric Roux's avatar
Cedric Roux committed
1322 1323
  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));
1324 1325 1326 1327 1328 1329
  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);
1330
  LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Security Mode Command\n");
1331
  LOG_I(RRC,
1332 1333 1334
        PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate SecurityModeCommand (bytes %d)\n",
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
        size);
1335
  LOG_D(RRC,
1336 1337 1338 1339 1340
        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);
1341
  MSC_LOG_TX_MESSAGE(
1342 1343 1344 1345 1346 1347 1348 1349 1350
    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);
1351

1352
  if (!NODE_IS_DU(RC.rrc[ctxt_pP->module_id]->node_type)) {
1353
    LOG_I(RRC,"calling rrc_data_req :securityModeCommand\n");
1354

1355 1356 1357 1358 1359 1360 1361 1362
    rrc_data_req(ctxt_pP,
                 DCCH,
                 rrc_eNB_mui++,
                 SDU_CONFIRM_NO,
                 size,
                 buffer,
                 PDCP_TRANSMISSION_MODE_CONTROL);
  }
1363 1364
}

1365 1366 1367
//-----------------------------------------------------------------------------
void
rrc_eNB_generate_UECapabilityEnquiry(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1368 1369
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t          *const ue_context_pP
1370 1371
)
//-----------------------------------------------------------------------------
1372 1373 1374
{
  uint8_t                             buffer[100];
  uint8_t                             size;
Cedric Roux's avatar
Cedric Roux committed
1375 1376
  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));
1377 1378 1379 1380
  size = do_UECapabilityEnquiry(
           ctxt_pP,
           buffer,
           rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id));
1381
  LOG_I(RRC,
1382 1383 1384
        PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate UECapabilityEnquiry (bytes %d)\n",
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
        size);
1385
  LOG_D(RRC,
1386 1387 1388 1389 1390
        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);
1391
  MSC_LOG_TX_MESSAGE(
1392 1393 1394 1395 1396 1397 1398 1399 1400
    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);
1401
  rrc_data_req(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1402 1403 1404 1405 1406 1407 1408
    ctxt_pP,
    DCCH,
    rrc_eNB_mui++,
    SDU_CONFIRM_NO,
    size,
    buffer,
    PDCP_TRANSMISSION_MODE_CONTROL);
1409 1410
}

1411 1412 1413
//-----------------------------------------------------------------------------
void
rrc_eNB_generate_RRCConnectionReject(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1414 1415
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t          *const ue_context_pP,
1416 1417 1418 1419
  const int                    CC_id
)
//-----------------------------------------------------------------------------
{
Cedric Roux's avatar
Cedric Roux committed
1420 1421 1422
  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));

1423
  eNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
1424
  ue_p->Srb0.Tx_buffer.payload_size =
1425
    do_RRCConnectionReject(ctxt_pP->module_id,
1426
                          (uint8_t*) ue_p->Srb0.Tx_buffer.Payload);
1427

1428
  LOG_DUMPMSG(RRC,DEBUG_RRC,
1429
              (char *)(ue_p->Srb0.Tx_buffer.Payload),
1430
              ue_p->Srb0.Tx_buffer.payload_size,
1431
              "[MSG] RRCConnectionReject\n");
1432 1433 1434
  MSC_LOG_TX_MESSAGE(
    MSC_RRC_ENB,
    MSC_RRC_UE,
1435 1436
    ue_p->Srb0.Tx_buffer.Header,
    ue_p->Srb0.Tx_buffer.payload_size,
1437
    MSC_AS_TIME_FMT" LTE_RRCConnectionReject UE %x size %u",
1438 1439
    MSC_AS_TIME_ARGS(ctxt_pP),
    ue_context_pP == NULL ? -1 : ue_context_pP->ue_context.rnti,
1440
    ue_p->Srb0.Tx_buffer.payload_size);
1441
  LOG_I(RRC,
1442
        PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionReject (bytes %d)\n",
1443
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
1444
        ue_p->Srb0.Tx_buffer.payload_size);
1445 1446
}

1447
//-----------------------------------------------------------------------------
1448 1449 1450
/*
 * Generate a RCC Connection Reestablishment after requested
 */
1451
void
1452
rrc_eNB_generate_RRCConnectionReestablishment(
1453 1454 1455
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t  *const ue_context_pP,
  const int             CC_id)
1456 1457
//-----------------------------------------------------------------------------
{
1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477
  int UE_id = -1;
  LTE_LogicalChannelConfig_t *SRB1_logicalChannelConfig = NULL;
  LTE_SRB_ToAddModList_t     **SRB_configList;
  LTE_SRB_ToAddMod_t         *SRB1_config = NULL;
  rrc_eNB_carrier_data_t     *carrier = NULL;
  eNB_RRC_UE_t               *ue_context = NULL;

  module_id_t module_id = ctxt_pP->module_id;
  uint16_t rnti = ctxt_pP->rnti;

  T(T_ENB_RRC_CONNECTION_REESTABLISHMENT,
    T_INT(module_id),
    T_INT(ctxt_pP->frame),
    T_INT(ctxt_pP->subframe),
    T_INT(rnti));

  SRB_configList = &(ue_context_pP->ue_context.SRB_configList);
  carrier = &(RC.rrc[ctxt_pP->module_id]->carrier[CC_id]);
  ue_context = &(ue_context_pP->ue_context);

OAI-admin's avatar
OAI-admin committed
1478
  ue_context->Srb0.Tx_buffer.payload_size = do_RRCConnectionReestablishment(ctxt_pP,
1479 1480
                                                                         ue_context_pP,
                                                                         CC_id,
OAI-admin's avatar
OAI-admin committed
1481
                                                                         (uint8_t *) ue_context->Srb0.Tx_buffer.Payload,
1482 1483 1484 1485 1486 1487
                                                                         (uint8_t) carrier->p_eNB, // at this point we do not have the UE capability information, so it can only be TM1 or TM2
                                                                         rrc_eNB_get_next_transaction_identifier(module_id),
                                                                         SRB_configList,
                                                                         &(ue_context->physicalConfigDedicated));

  LOG_DUMPMSG(RRC, DEBUG_RRC,
OAI-admin's avatar
OAI-admin committed
1488 1489
              (char *)(ue_context->Srb0.Tx_buffer.Payload),
              ue_context->Srb0.Tx_buffer.payload_size,
1490 1491 1492
              "[MSG] RRCConnectionReestablishment \n");

  /* Configure SRB1 for UE */
1493
  if (*SRB_configList != NULL) {
1494
    for (int cnt = 0; cnt < (*SRB_configList)->list.count; cnt++) {
1495 1496
      if ((*SRB_configList)->list.array[cnt]->srb_Identity == 1) {
        SRB1_config = (*SRB_configList)->list.array[cnt];
1497

1498
        if (SRB1_config->logicalChannelConfig) {
1499 1500
          if (SRB1_config->logicalChannelConfig->present == LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) {
            SRB1_logicalChannelConfig = &(SRB1_config->logicalChannelConfig->choice.explicitValue);
1501
          } else {
1502
            SRB1_logicalChannelConfig = &(SRB1_logicalChannelConfig_defaultValue);
1503 1504
          }
        } else {
1505
          SRB1_logicalChannelConfig = &(SRB1_logicalChannelConfig_defaultValue);
1506
        }
1507

1508
        LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ  (SRB1) ---> MAC_eNB\n",
1509
              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
1510
        if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) {
1511 1512 1513 1514 1515 1516 1517
          rrc_mac_config_req_eNB(module_id,
                                 ue_context->primaryCC_id,
                                 0,
                                 0,
                                 0,
                                 0,
                                 0,
1518
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1519
                                 0,
1520
#endif
1521
                                 rnti,
1522 1523
                                 (LTE_BCCH_BCH_Message_t *) NULL,
                                 (LTE_RadioResourceConfigCommonSIB_t *) NULL,
1524
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1525
                                 (LTE_RadioResourceConfigCommonSIB_t *) NULL,
1526
#endif
1527
                                 (struct LTE_PhysicalConfigDedicated * ) ue_context->physicalConfigDedicated,
1528
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
1529 1530 1531
                                 (LTE_SCellToAddMod_r10_t *)NULL,
#endif
                                 (LTE_MeasObjectToAddMod_t **) NULL,
1532
                                 ue_context->mac_MainConfig,
1533 1534
                                 1,
                                 SRB1_logicalChannelConfig,
1535
                                 ue_context->measGapConfig,
1536 1537 1538
                                 (LTE_TDD_Config_t *) NULL,
                                 NULL,
                                 (LTE_SchedulingInfoList_t *) NULL,
1539 1540 1541 1542
                                 0,
                                 NULL,
                                 NULL,
                                 (LTE_MBSFN_SubframeConfigList_t *) NULL
1543
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
1544 1545 1546
                                 , 0,
                                 (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
                                 (LTE_PMCH_InfoList_r9_t *) NULL
1547
#endif
1548
#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
1549
                                 ,(LTE_SystemInformationBlockType1_v1310_IEs_t *) NULL
1550 1551 1552 1553 1554 1555 1556 1557 1558
#endif
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                        ,
                        0,
                        (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL,
                        (LTE_SchedulingInfo_MBMS_r14_t *) NULL,
                        (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
                        (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
                        (LTE_MBSFN_AreaInfoList_r9_t *) NULL
1559
#endif
1560
                                 );
1561 1562
          break;
        }
1563 1564 1565
      }  // if ((*SRB_configList)->list.array[cnt]->srb_Identity == 1)
    }  // for (int cnt = 0; cnt < (*SRB_configList)->list.count; cnt++)
  }  // if (*SRB_configList != NULL)
1566

1567 1568
  MSC_LOG_TX_MESSAGE(MSC_RRC_ENB,
                     MSC_RRC_UE,
OAI-admin's avatar
OAI-admin committed
1569 1570
                     ue_context->Srb0.Tx_buffer.Header,
                     ue_context->Srb0.Tx_buffer.payload_size,
1571
                     MSC_AS_TIME_FMT" LTE_RRCConnectionReestablishment UE %x size %u",
1572
                     MSC_AS_TIME_ARGS(ctxt_pP),
1573
                     ue_context->rnti,
OAI-admin's avatar
OAI-admin committed
1574
                     ue_context->Srb0.Tx_buffer.payload_size);
Cedric Roux's avatar
Cedric Roux committed
1575

1576
  LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionReestablishment (bytes %d)\n",
1577
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
OAI-admin's avatar
OAI-admin committed
1578
        ue_context->Srb0.Tx_buffer.payload_size);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1579

1580 1581 1582 1583 1584 1585 1586
  UE_id = find_UE_id(module_id, rnti);

  if (UE_id != -1) {
    /* Activate reject timer, if RRCComplete not received after 10 frames, reject UE */
    RC.mac[module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1;
    /* Reject UE after 10 frames, LTE_RRCConnectionReestablishmentReject is triggered */
    RC.mac[module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 100;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1587
  } else {
1588 1589 1590
    LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Generating LTE_RRCConnectionReestablishment without UE_id(MAC) rnti %x\n",
          PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
          rnti);
1591
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1592

1593 1594
}

1595 1596
//-----------------------------------------------------------------------------
void
1597
rrc_eNB_process_RRCConnectionReestablishmentComplete(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1598
  const protocol_ctxt_t *const ctxt_pP,
Cedric Roux's avatar
Cedric Roux committed
1599
  const rnti_t reestablish_rnti,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1600
  rrc_eNB_ue_context_t         *ue_context_pP,
1601
  const uint8_t xid,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1602
  LTE_RRCConnectionReestablishmentComplete_r8_IEs_t *LTE_RRCConnectionReestablishmentComplete
1603 1604
)
//-----------------------------------------------------------------------------
1605
{
1606
  LOG_I(RRC,
1607
        PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, processing LTE_RRCConnectionReestablishmentComplete from UE (SRB1 Active)\n",
1608 1609 1610
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
  T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
    T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1611 1612 1613 1614
  LTE_DRB_ToAddModList_t                 *DRB_configList = ue_context_pP->ue_context.DRB_configList;
  LTE_SRB_ToAddModList_t                 *SRB_configList = ue_context_pP->ue_context.SRB_configList;
  LTE_SRB_ToAddModList_t                **SRB_configList2 = NULL;
  LTE_DRB_ToAddModList_t                **DRB_configList2 = NULL;
1615 1616
  struct LTE_SRB_ToAddMod                *SRB2_config = NULL;
  struct LTE_DRB_ToAddMod                *DRB_config = NULL;
1617
  int i = 0;
1618 1619
  uint8_t                             buffer[RRC_BUF_SIZE];
  uint16_t                            size;
1620 1621 1622 1623
  LTE_MeasObjectToAddModList_t       *MeasObj_list                     = NULL;
  LTE_MeasObjectToAddMod_t           *MeasObj                          = NULL;
  LTE_ReportConfigToAddModList_t     *ReportConfig_list                = NULL;
  LTE_ReportConfigToAddMod_t         *ReportConfig_per, *ReportConfig_A1,
1624
                                     *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5;
1625 1626 1627 1628 1629 1630 1631 1632 1633
  LTE_MeasIdToAddModList_t           *MeasId_list                      = NULL;
  LTE_MeasIdToAddMod_t               *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5;
  LTE_RSRP_Range_t                   *rsrp                             = NULL;
  struct LTE_MeasConfig__speedStatePars  *Sparams                          = NULL;
  LTE_QuantityConfig_t                   *quantityConfig                   = NULL;
  LTE_CellsToAddMod_t                    *CellToAdd                        = NULL;
  LTE_CellsToAddModList_t                *CellsToAddModList                = NULL;
  struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL;
  LTE_DedicatedInfoNAS_t                 *dedicatedInfoNas                 = NULL;
1634 1635
  /* for no gcc warnings */
  (void)dedicatedInfoNas;
1636
  LTE_C_RNTI_t                           *cba_RNTI                         = NULL;
1637
  int                                    measurements_enabled;
1638
  uint8_t next_xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id);
1639 1640
  int ret = 0;

1641
  ue_context_pP->ue_context.Status = RRC_CONNECTED;
1642
  ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED
1643
  ue_context_pP->ue_context.reestablishment_xid = next_xid;
1644
  SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid];
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1645

1646 1647
  // get old configuration of SRB2
  if (*SRB_configList2 != NULL) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1648
    if((*SRB_configList2)->list.count!=0) {
1649
      LOG_D(RRC, "SRB_configList2(%p) count is %d\n           SRB_configList2->list.array[0] addr is %p",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1650
            SRB_configList2, (*SRB_configList2)->list.count,  (*SRB_configList2)->list.array[0]);
1651
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1652

1653
    for (i = 0; (i < (*SRB_configList2)->list.count) && (i < 3); i++) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1654
      if ((*SRB_configList2)->list.array[i]->srb_Identity == 2 ) {
1655 1656 1657 1658 1659 1660
        LOG_D(RRC, "get SRB2_config from (ue_context_pP->ue_context.SRB_configList2[%d])\n", xid);
        SRB2_config = (*SRB_configList2)->list.array[i];
        break;
      }
    }
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1661

frtabu's avatar
frtabu committed
1662 1663
  SRB_configList2 = &(ue_context_pP->ue_context.SRB_configList2[next_xid]);
  DRB_configList2 = &(ue_context_pP->ue_context.DRB_configList2[next_xid]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1664

frtabu's avatar
frtabu committed
1665 1666 1667
  if (*SRB_configList2) {
    free(*SRB_configList2);
    LOG_D(RRC, "free(ue_context_pP->ue_context.SRB_configList2[%d])\n", next_xid);
1668
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1669

1670
  *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1671

1672 1673 1674 1675 1676
  if (SRB2_config != NULL) {
    // Add SRB2 to SRB configuration list
    ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config);
    ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config);
    LOG_D(RRC, "Add SRB2_config (srb_Identity:%ld) to ue_context_pP->ue_context.SRB_configList\n",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1677
          SRB2_config->srb_Identity);
1678
    LOG_D(RRC, "Add SRB2_config (srb_Identity:%ld) to ue_context_pP->ue_context.SRB_configList2[%d]\n",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1679
          SRB2_config->srb_Identity, next_xid);
1680 1681 1682 1683
  } else {
    // SRB configuration list only contains SRB1.
    LOG_W(RRC,"SRB2 configuration does not exist in SRB configuration list\n");
  }
1684

frtabu's avatar
frtabu committed
1685 1686 1687
  if (*DRB_configList2) {
    free(*DRB_configList2);
    LOG_D(RRC, "free(ue_context_pP->ue_context.DRB_configList2[%d])\n", next_xid);
1688
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1689

1690
  *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
1691

1692 1693
  if (DRB_configList != NULL) {
    LOG_D(RRC, "get DRB_config from (ue_context_pP->ue_context.DRB_configList)\n");
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1694

1695 1696
    for (i = 0; (i < DRB_configList->list.count) && (i < 3); i++) {
      DRB_config = DRB_configList->list.array[i];
1697
      // Add DRB to DRB configuration list, for LTE_RRCConnectionReconfigurationComplete
1698
      ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config);
1699
    }
1700
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1701

1702 1703
  ue_context_pP->ue_context.Srb1.Active = 1;
  //ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = 2;
1704 1705

  if (EPC_MODE_ENABLED) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717
  hashtable_rc_t    h_rc;
  int               j;
  rrc_ue_s1ap_ids_t *rrc_ue_s1ap_ids_p = NULL;
  uint16_t ue_initial_id = ue_context_pP->ue_context.ue_initial_id;
  uint32_t eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id;
  eNB_RRC_INST *rrc_instance_p = RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)];

  if (eNB_ue_s1ap_id > 0) {
    h_rc = hashtable_get(rrc_instance_p->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void **)&rrc_ue_s1ap_ids_p);

    if  (h_rc == HASH_TABLE_OK) {
      rrc_ue_s1ap_ids_p->ue_rnti = ctxt_pP->rnti;
1718
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1719
  }
Navid Nikaein's avatar
Navid Nikaein committed
1720

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1721 1722
  if (ue_initial_id != 0) {
    h_rc = hashtable_get(rrc_instance_p->initial_id2_s1ap_ids, (hash_key_t)ue_initial_id, (void **)&rrc_ue_s1ap_ids_p);
1723

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1724 1725
    if  (h_rc == HASH_TABLE_OK) {
      rrc_ue_s1ap_ids_p->ue_rnti = ctxt_pP->rnti;
1726
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1727
  }
1728

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742
  gtpv1u_enb_create_tunnel_req_t  create_tunnel_req;
  /* Save e RAB information for later */
  memset(&create_tunnel_req, 0, sizeof(create_tunnel_req));

  for ( j = 0, i = 0; i < NB_RB_MAX; i++) {
    if (ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_ESTABLISHED || ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_DONE) {
      create_tunnel_req.eps_bearer_id[j]   = ue_context_pP->ue_context.e_rab[i].param.e_rab_id;
      create_tunnel_req.sgw_S1u_teid[j]  = ue_context_pP->ue_context.e_rab[i].param.gtp_teid;
      memcpy(&create_tunnel_req.sgw_addr[j],
             &ue_context_pP->ue_context.e_rab[i].param.sgw_addr,
             sizeof(transport_layer_addr_t));
      j++;
    }
  }
1743

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1744 1745
  create_tunnel_req.rnti       = ctxt_pP->rnti; // warning put zero above
  create_tunnel_req.num_tunnels    = j;
1746 1747

    ret = gtpv1u_update_s1u_tunnel(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1748 1749 1750
    ctxt_pP->instance,
    &create_tunnel_req,
    reestablish_rnti);
1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775
    if ( ret != 0 ) {
      LOG_E(RRC,"gtpv1u_update_s1u_tunnel failed,start to release UE %x\n",reestablish_rnti);
      // update s1u tunnel failed,reset rnti?
      if (eNB_ue_s1ap_id > 0) {
        h_rc = hashtable_get(rrc_instance_p->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void**)&rrc_ue_s1ap_ids_p);
        if (h_rc == HASH_TABLE_OK ) {
          rrc_ue_s1ap_ids_p->ue_rnti = reestablish_rnti;
        }
      }
      if (ue_initial_id != 0) {
        h_rc = hashtable_get(rrc_instance_p->initial_id2_s1ap_ids, (hash_key_t)ue_initial_id, (void**)&rrc_ue_s1ap_ids_p);
        if (h_rc == HASH_TABLE_OK ) {
          rrc_ue_s1ap_ids_p->ue_rnti = reestablish_rnti;
        }
      }
      ue_context_pP->ue_context.ue_release_timer_s1 = 1;
      ue_context_pP->ue_context.ue_release_timer_thres_s1 = 100;
      ue_context_pP->ue_context.ue_release_timer = 0;
      ue_context_pP->ue_context.ue_reestablishment_timer = 0;
      ue_context_pP->ue_context.ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ
      rrc_eNB_free_UE(ctxt_pP->module_id,ue_context_pP);
      ue_context_pP->ue_context.ul_failure_timer = 0;
      put_UE_in_freelist(ctxt_pP->module_id, ctxt_pP->rnti, 0);
      return;
    }
1776 1777
  } /* EPC_MODE_ENABLED */

1778 1779 1780
  /* Update RNTI in ue_context */
  ue_context_pP->ue_id_rnti                    = ctxt_pP->rnti; // here ue_id_rnti is just a key, may be something else
  ue_context_pP->ue_context.rnti               = ctxt_pP->rnti;
1781 1782

  if (EPC_MODE_ENABLED) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1783 1784 1785 1786 1787 1788
  uint8_t send_security_mode_command = FALSE;
  rrc_pdcp_config_security(
    ctxt_pP,
    ue_context_pP,
    send_security_mode_command);
  LOG_D(RRC, "set security successfully \n");
1789 1790
  }

1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823
  // Measurement ID list
  MeasId_list = CALLOC(1, sizeof(*MeasId_list));
  memset((void *)MeasId_list, 0, sizeof(*MeasId_list));
  MeasId0 = CALLOC(1, sizeof(*MeasId0));
  MeasId0->measId = 1;
  MeasId0->measObjectId = 1;
  MeasId0->reportConfigId = 1;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId0);
  MeasId1 = CALLOC(1, sizeof(*MeasId1));
  MeasId1->measId = 2;
  MeasId1->measObjectId = 1;
  MeasId1->reportConfigId = 2;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId1);
  MeasId2 = CALLOC(1, sizeof(*MeasId2));
  MeasId2->measId = 3;
  MeasId2->measObjectId = 1;
  MeasId2->reportConfigId = 3;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId2);
  MeasId3 = CALLOC(1, sizeof(*MeasId3));
  MeasId3->measId = 4;
  MeasId3->measObjectId = 1;
  MeasId3->reportConfigId = 4;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId3);
  MeasId4 = CALLOC(1, sizeof(*MeasId4));
  MeasId4->measId = 5;
  MeasId4->measObjectId = 1;
  MeasId4->reportConfigId = 5;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId4);
  MeasId5 = CALLOC(1, sizeof(*MeasId5));
  MeasId5->measId = 6;
  MeasId5->measObjectId = 1;
  MeasId5->reportConfigId = 6;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId5);
1824
  //  LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measIdToAddModList = MeasId_list;
1825 1826 1827 1828 1829 1830 1831
  // Add one EUTRA Measurement Object
  MeasObj_list = CALLOC(1, sizeof(*MeasObj_list));
  memset((void *)MeasObj_list, 0, sizeof(*MeasObj_list));
  // Configure MeasObject
  MeasObj = CALLOC(1, sizeof(*MeasObj));
  memset((void *)MeasObj, 0, sizeof(*MeasObj));
  MeasObj->measObjectId = 1;
1832
  MeasObj->measObject.present = LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA;
1833 1834
  MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 3350; //band 7, 2.68GHz
  //MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 36090; //band 33, 1.909GHz
1835
  MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = LTE_AllowedMeasBandwidth_mbw25;
1836 1837 1838 1839 1840 1841 1842
  MeasObj->measObject.choice.measObjectEUTRA.presenceAntennaPort1 = 1;
  MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf = CALLOC(1, sizeof(uint8_t));
  MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf[0] = 0;
  MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.size = 1;
  MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.bits_unused = 6;
  MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = NULL;   // Default is 15 or 0dB
  MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList =
1843
    (LTE_CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList));
1844 1845 1846 1847
  CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList;

  // Add adjacent cell lists (6 per eNB)
  for (i = 0; i < 6; i++) {
1848
    CellToAdd = (LTE_CellsToAddMod_t *) CALLOC(1, sizeof(*CellToAdd));
1849 1850
    CellToAdd->cellIndex = i + 1;
    CellToAdd->physCellId = get_adjacent_cell_id(ctxt_pP->module_id, i);
1851
    CellToAdd->cellIndividualOffset = LTE_Q_OffsetRange_dB0;
1852 1853 1854 1855
    ASN_SEQUENCE_ADD(&CellsToAddModList->list, CellToAdd);
  }

  ASN_SEQUENCE_ADD(&MeasObj_list->list, MeasObj);
1856
  //  LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measObjectToAddModList = MeasObj_list;
1857 1858 1859 1860 1861 1862 1863 1864 1865
  // Report Configurations for periodical, A1-A5 events
  ReportConfig_list = CALLOC(1, sizeof(*ReportConfig_list));
  ReportConfig_per = CALLOC(1, sizeof(*ReportConfig_per));
  ReportConfig_A1 = CALLOC(1, sizeof(*ReportConfig_A1));
  ReportConfig_A2 = CALLOC(1, sizeof(*ReportConfig_A2));
  ReportConfig_A3 = CALLOC(1, sizeof(*ReportConfig_A3));
  ReportConfig_A4 = CALLOC(1, sizeof(*ReportConfig_A4));
  ReportConfig_A5 = CALLOC(1, sizeof(*ReportConfig_A5));
  ReportConfig_per->reportConfigId = 1;
1866
  ReportConfig_per->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
1867
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.present =
1868
    LTE_ReportConfigEUTRA__triggerType_PR_periodical;
1869
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.choice.periodical.purpose =
1870 1871 1872
    LTE_ReportConfigEUTRA__triggerType__periodical__purpose_reportStrongestCells;
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
1873
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
1874 1875
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
1876 1877
  ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_per);
  ReportConfig_A1->reportConfigId = 2;
1878
  ReportConfig_A1->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
1879
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.present =
1880
    LTE_ReportConfigEUTRA__triggerType_PR_event;
1881
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
1882
    LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1;
1883
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA1.
1884
  a1_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
1885 1886
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA1.
  a1_Threshold.choice.threshold_RSRP = 10;
1887 1888
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
1889
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
1890 1891
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
1892 1893
  ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A1);

1894
  if (RC.rrc[ctxt_pP->module_id]->HO_flag == 1 /*HO_MEASUREMENT */ ) {
1895 1896 1897
    LOG_I(RRC, "[eNB %d] frame %d: requesting A2, A3, A4, A5, and A6 event reporting\n",
          ctxt_pP->module_id, ctxt_pP->frame);
    ReportConfig_A2->reportConfigId = 3;
1898
    ReportConfig_A2->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
1899
    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.present =
1900
      LTE_ReportConfigEUTRA__triggerType_PR_event;
1901
    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
1902
      LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2;
1903
    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
1904
    eventA2.a2_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
1905 1906 1907
    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
    eventA2.a2_Threshold.choice.threshold_RSRP = 10;
    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
1908 1909
      LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
1910
    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
1911 1912
    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
1913 1914
    ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A2);
    ReportConfig_A3->reportConfigId = 4;
1915
    ReportConfig_A3->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
1916
    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.present =
1917
      LTE_ReportConfigEUTRA__triggerType_PR_event;
1918
    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
1919
      LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3;
1920 1921 1922 1923
    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset = 1;   //10;
    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
    eventA3.reportOnLeave = 1;
    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
1924 1925
      LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
1926
    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
1927 1928
    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
1929 1930
    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis = 0.5; // FIXME ...hysteresis is of type long!
    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger =
1931
      LTE_TimeToTrigger_ms40;
1932 1933
    ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A3);
    ReportConfig_A4->reportConfigId = 5;
1934
    ReportConfig_A4->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
1935
    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.present =
1936
      LTE_ReportConfigEUTRA__triggerType_PR_event;
1937
    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
1938
      LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4;
1939
    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
1940
    eventA4.a4_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
1941 1942 1943
    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
    eventA4.a4_Threshold.choice.threshold_RSRP = 10;
    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
1944 1945
      LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
1946
    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
1947 1948
    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
1949 1950
    ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A4);
    ReportConfig_A5->reportConfigId = 6;
1951
    ReportConfig_A5->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
1952
    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.present =
1953
      LTE_ReportConfigEUTRA__triggerType_PR_event;
1954
    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
1955
      LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA5;
1956
    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
1957
    eventA5.a5_Threshold1.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
1958
    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
1959
    eventA5.a5_Threshold2.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
1960 1961 1962 1963 1964
    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
    eventA5.a5_Threshold1.choice.threshold_RSRP = 10;
    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
    eventA5.a5_Threshold2.choice.threshold_RSRP = 10;
    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
1965 1966
      LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
1967
    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
1968 1969
    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
1970
    ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A5);
1971
    //  LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list;
1972 1973 1974 1975 1976 1977
#if 0
    /* TODO: set a proper value.
     * 20 means: UE does not report if RSRP of serving cell is higher
     * than -120 dB (see 36.331 5.5.3.1).
     * This is too low for the X2 handover experiment.
     */
1978
    rsrp = CALLOC(1, sizeof(LTE_RSRP_Range_t));
1979
    *rsrp = 20;
1980
#endif
1981
    Sparams = CALLOC(1, sizeof(*Sparams));
1982 1983 1984
    Sparams->present = LTE_MeasConfig__speedStatePars_PR_setup;
    Sparams->choice.setup.timeToTrigger_SF.sf_High = LTE_SpeedStateScaleFactors__sf_Medium_oDot75;
    Sparams->choice.setup.timeToTrigger_SF.sf_Medium = LTE_SpeedStateScaleFactors__sf_High_oDot5;
1985 1986
    Sparams->choice.setup.mobilityStateParameters.n_CellChangeHigh = 10;
    Sparams->choice.setup.mobilityStateParameters.n_CellChangeMedium = 5;
1987 1988
    Sparams->choice.setup.mobilityStateParameters.t_Evaluation = LTE_MobilityStateParameters__t_Evaluation_s60;
    Sparams->choice.setup.mobilityStateParameters.t_HystNormal = LTE_MobilityStateParameters__t_HystNormal_s120;
1989 1990
    quantityConfig = CALLOC(1, sizeof(*quantityConfig));
    memset((void *)quantityConfig, 0, sizeof(*quantityConfig));
1991
    quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(struct LTE_QuantityConfigEUTRA));
1992 1993 1994 1995 1996 1997 1998 1999
    memset((void *)quantityConfig->quantityConfigEUTRA, 0, sizeof(*quantityConfig->quantityConfigEUTRA));
    quantityConfig->quantityConfigCDMA2000 = NULL;
    quantityConfig->quantityConfigGERAN = NULL;
    quantityConfig->quantityConfigUTRA = NULL;
    quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP =
      CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP)));
    quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ =
      CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ)));
2000 2001
    *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = LTE_FilterCoefficient_fc4;
    *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = LTE_FilterCoefficient_fc4;
2002 2003 2004 2005 2006 2007
    LOG_I(RRC,
          "[eNB %d] Frame %d: potential handover preparation: store the information in an intermediate structure in case of failure\n",
          ctxt_pP->module_id, ctxt_pP->frame);
    // store the information in an intermediate structure for Hanodver management
    //rrc_inst->handover_info.as_config.sourceRadioResourceConfig.srb_ToAddModList = CALLOC(1,sizeof());
    ue_context_pP->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_pP->ue_context.handover_info)));
2008
    //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.srb_ToAddModList,(void *)SRB_list,sizeof(LTE_SRB_ToAddModList_t));
2009
    ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.srb_ToAddModList = *SRB_configList2;
2010
    //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.drb_ToAddModList,(void *)DRB_list,sizeof(LTE_DRB_ToAddModList_t));
2011 2012 2013 2014
    ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToAddModList = DRB_configList;
    ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToReleaseList = NULL;
    ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig =
      CALLOC(1, sizeof(*ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2015
    memcpy((void *)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig,
2016
           (void *)ue_context_pP->ue_context.mac_MainConfig, sizeof(LTE_MAC_MainConfig_t));
2017
    ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated =
2018
      CALLOC(1, sizeof(LTE_PhysicalConfigDedicated_t));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2019 2020
    memcpy((void *)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated,
           (void *)ue_context_pP->ue_context.physicalConfigDedicated, sizeof(LTE_PhysicalConfigDedicated_t));
2021 2022 2023 2024 2025 2026 2027
    ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.sps_Config = NULL;
    //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.sps_Config,(void *)rrc_inst->sps_Config[ue_mod_idP],sizeof(SPS_Config_t));
  }

#ifdef CBA
  //struct PUSCH_CBAConfigDedicated_vlola  *pusch_CBAConfigDedicated_vlola;
  uint8_t                            *cba_RNTI_buf;
2028
  cba_RNTI = CALLOC(1, sizeof(LTE_C_RNTI_t));
2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050
  cba_RNTI_buf = CALLOC(1, 2 * sizeof(uint8_t));
  cba_RNTI->buf = cba_RNTI_buf;
  cba_RNTI->size = 2;
  cba_RNTI->bits_unused = 0;

  // associate UEs to the CBa groups as a function of their UE id
  if (rrc_inst->num_active_cba_groups) {
    cba_RNTI->buf[0] = rrc_inst->cba_rnti[ue_mod_idP % rrc_inst->num_active_cba_groups] & 0xff;
    cba_RNTI->buf[1] = 0xff;
    LOG_D(RRC,
          "[eNB %d] Frame %d: cba_RNTI = %x in group %d is attribued to UE %d\n",
          enb_mod_idP, frameP,
          rrc_inst->cba_rnti[ue_mod_idP % rrc_inst->num_active_cba_groups],
          ue_mod_idP % rrc_inst->num_active_cba_groups, ue_mod_idP);
  } else {
    cba_RNTI->buf[0] = 0x0;
    cba_RNTI->buf[1] = 0x0;
    LOG_D(RRC, "[eNB %d] Frame %d: no cba_RNTI is configured for UE %d\n", enb_mod_idP, frameP, ue_mod_idP);
  }

#endif
  /* Initialize NAS list */
2051
  dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList));
2052 2053 2054 2055

  /* Add all NAS PDUs to the list */
  for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) {
    if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) {
2056
      dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t));
2057 2058
      memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t));
      OCTET_STRING_fromBuf(dedicatedInfoNas,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2059
                           (char *)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer,
2060
                           ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length);
2061
      LOG_D(RRC, "Add LTE_DedicatedInfoNAS(%d) to LTE_DedicatedInfoNASList\n", i);
2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072
      ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas);
    }

    /* TODO parameters yet to process ... */
    {
      //      ue_context_pP->ue_context.e_rab[i].param.qos;
      //      ue_context_pP->ue_context.e_rab[i].param.sgw_addr;
      //      ue_context_pP->ue_context.e_rab[i].param.gtp_teid;
    }
    /* TODO should test if e RAB are Ok before! */
    ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE;
2073
    ue_context_pP->ue_context.e_rab[i].xid    = xid;
2074
    LOG_D(RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2075
          i, ue_context_pP->ue_context.e_rab[i].status, "E_RAB_STATUS_DONE");
2076 2077 2078 2079 2080 2081 2082 2083
  }

  /* If list is empty free the list and reset the address */
  if (dedicatedInfoNASList->list.count == 0) {
    free(dedicatedInfoNASList);
    dedicatedInfoNASList = NULL;
  }

2084 2085
  measurements_enabled = RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]->configuration.enable_x2 ||
                         RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]->configuration.enable_measurement_reports;
Cedric Roux's avatar
Cedric Roux committed
2086

2087
  // send LTE_RRCConnectionReconfiguration
2088 2089 2090 2091
  memset(buffer, 0, RRC_BUF_SIZE);
  size = do_RRCConnectionReconfiguration(ctxt_pP,
                                         buffer,
                                         next_xid,   //Transaction_id,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2092 2093 2094 2095 2096
                                         (LTE_SRB_ToAddModList_t *)*SRB_configList2, // SRB_configList
                                         (LTE_DRB_ToAddModList_t *)DRB_configList,
                                         (LTE_DRB_ToReleaseList_t *)NULL, // DRB2_list,
                                         (struct LTE_SPS_Config *)NULL,   // maybe ue_context_pP->ue_context.sps_Config,
                                         (struct LTE_PhysicalConfigDedicated *)ue_context_pP->ue_context.physicalConfigDedicated,
Cedric Roux's avatar
Cedric Roux committed
2097 2098 2099
//#ifdef EXMIMO_IOT
//                                         NULL, NULL, NULL,NULL,
//#else
2100 2101 2102
                                         measurements_enabled ? (LTE_MeasObjectToAddModList_t *)MeasObj_list : NULL, // MeasObj_list,
                                         measurements_enabled ? (LTE_ReportConfigToAddModList_t *)ReportConfig_list : NULL, // ReportConfig_list,
                                         measurements_enabled ? (LTE_QuantityConfig_t *)quantityConfig : NULL, //quantityConfig,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2103
                                         (LTE_MeasIdToAddModList_t *)NULL,
Cedric Roux's avatar
Cedric Roux committed
2104
//#endif
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2105 2106 2107
                                         (LTE_MAC_MainConfig_t *)ue_context_pP->ue_context.mac_MainConfig,
                                         (LTE_MeasGapConfig_t *)NULL,
                                         (LTE_MobilityControlInfo_t *)NULL,
2108
                                         (LTE_SecurityConfigHO_t *)NULL,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2109 2110 2111 2112 2113 2114
                                         (struct LTE_MeasConfig__speedStatePars *)Sparams, // Sparams,
                                         (LTE_RSRP_Range_t *)rsrp, // rsrp,
                                         (LTE_C_RNTI_t *)cba_RNTI, // cba_RNTI
                                         (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)dedicatedInfoNASList, //dedicatedInfoNASList
                                         (LTE_SL_CommConfig_r12_t *)NULL,
                                         (LTE_SL_DiscConfig_r12_t *)NULL
2115
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2116
                                         , (LTE_SCellToAddMod_r10_t *)NULL
2117 2118
#endif
                                        );
2119 2120
  LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size,
              "[MSG] RRC Connection Reconfiguration\n");
2121 2122 2123 2124 2125 2126 2127 2128 2129 2130

  /* Free all NAS PDUs */
  for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) {
    if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) {
      /* Free the NAS PDU buffer and invalidate it */
      free(ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer);
      ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer = NULL;
    }
  }

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2131
  if(size==65535) {
2132 2133 2134
    LOG_E(RRC,"RRC decode err!!! do_RRCConnectionReconfiguration\n");
    put_UE_in_freelist(ctxt_pP->module_id, reestablish_rnti, 0);
    return;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2135
  } else {
2136
    LOG_I(RRC,
2137
          "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE id %x)\n",
2138 2139 2140 2141 2142 2143 2144 2145 2146
          ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti);
    LOG_D(RRC,
          "[FRAME %05d][RRC_eNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
          ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_eNB_mui, ctxt_pP->module_id, DCCH);
    MSC_LOG_TX_MESSAGE(
      MSC_RRC_ENB,
      MSC_RRC_UE,
      buffer,
      size,
2147
      MSC_AS_TIME_FMT" LTE_RRCConnectionReconfiguration UE %x MUI %d size %u",
2148 2149 2150 2151 2152
      MSC_AS_TIME_ARGS(ctxt_pP),
      ue_context_pP->ue_context.rnti,
      rrc_eNB_mui,
      size);
    rrc_data_req(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2153 2154 2155 2156 2157 2158 2159
      ctxt_pP,
      DCCH,
      rrc_eNB_mui++,
      SDU_CONFIRM_NO,
      size,
      buffer,
      PDCP_TRANSMISSION_MODE_CONTROL);
2160
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2161

2162
  // delete UE data of prior RNTI.  UE use current RNTI.
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200
  //  protocol_ctxt_t ctxt_prior = *ctxt_pP;
  //  ctxt_prior.rnti = reestablish_rnti;
  //
  //  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[ctxt_prior.module_id];
  //  for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
  //    eNB_PHY = RC.eNB[ctxt_prior.module_id][CC_id];
  //    for (int i=0; i<MAX_MOBILES_PER_ENB; i++) {
  //      ulsch = eNB_PHY->ulsch[i];
  //      if((ulsch != NULL) && (ulsch->rnti == ctxt_prior.rnti)){
  //        void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch);
  //        LOG_I(RRC, "clean_eNb_ulsch UE %x \n", ctxt_prior.rnti);
  //        clean_eNb_ulsch(ulsch);
  //        break;
  //      }
  //    }
  //
  //    for(int j = 0; j < 10; j++){
  //      ul_req_tmp = &eNB_MAC->UL_req_tmp[CC_id][j].ul_config_request_body;
  //      if(ul_req_tmp){
  //        int 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 == ctxt_prior.rnti){
  //            LOG_I(RRC, "remove UE %x from ul_config_pdu_list %d/%d\n", ctxt_prior.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(ctxt_prior.module_id, ctxt_prior.rnti);
  //  rrc_rlc_remove_ue(&ctxt_prior);
  //  pdcp_remove_UE(&ctxt_prior);
2201 2202 2203
  // add UE info to freeList for RU_thread to remove the UE instead of remove it here
  LOG_I(RRC, "[RRCConnectionReestablishment]put UE %x into freeList\n", reestablish_rnti);
  put_UE_in_freelist(ctxt_pP->module_id, reestablish_rnti, 0);
2204 2205 2206 2207 2208
}

//-----------------------------------------------------------------------------
void
rrc_eNB_generate_RRCConnectionReestablishmentReject(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2209 2210
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t          *const ue_context_pP,
2211 2212 2213 2214
  const int                    CC_id
)
//-----------------------------------------------------------------------------
{
2215
 if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
2216
  int UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2217 2218

  if(UE_id != -1) {
2219 2220
    RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1;
    RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 20;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2221
  } else {
2222
    LOG_E(RRC,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2223 2224
          PROTOCOL_RRC_CTXT_UE_FMT" Generating LTE_RRCConnectionReestablishmentReject without UE_id(MAC) rnti %x\n",
          PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti);
2225
  }
2226
 }
2227 2228
  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));
Wang He's avatar
Wang He committed
2229
  if (ue_context_pP != NULL) {
2230 2231 2232
  eNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; 

  ue_p->Srb0.Tx_buffer.payload_size =
2233
    do_RRCConnectionReestablishmentReject(ctxt_pP->module_id,
2234
                          (uint8_t*) ue_p->Srb0.Tx_buffer.Payload);
2235

2236
  LOG_DUMPMSG(RRC,DEBUG_RRC,
2237 2238
              (char *)(ue_p->Srb0.Tx_buffer.Payload),
              ue_p->Srb0.Tx_buffer.payload_size,
2239
              "[MSG] RRCConnectionReestablishmentReject\n");
2240 2241 2242
  MSC_LOG_TX_MESSAGE(
    MSC_RRC_ENB,
    MSC_RRC_UE,
2243 2244
    ue_p->Srb0.Tx_buffer.Header,
    ue_p->Srb0.Tx_buffer.payload_size,
2245
    MSC_AS_TIME_FMT" LTE_RRCConnectionReestablishmentReject UE %x size %u",
2246 2247
    MSC_AS_TIME_ARGS(ctxt_pP),
    ue_context_pP == NULL ? -1 : ue_context_pP->ue_context.rnti,
2248
    ue_p->Srb0.Tx_buffer.payload_size);
2249 2250

  LOG_I(RRC,
2251
        PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionReestablishmentReject (bytes %d)\n",
2252
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
2253
        ue_p->Srb0.Tx_buffer.payload_size);
Wang He's avatar
Wang He committed
2254 2255 2256
  } else {
    LOG_I(RRC,"rrc_eNB_generate_RRCConnectionReestablishmentReject : ue_contextpP is NULL\n");
  }
2257 2258 2259
}

//-----------------------------------------------------------------------------
2260 2261 2262 2263
/*
* Generate the RRC Connection Release to UE.
* If received, UE should switch to RRC_IDLE mode.
*/
2264 2265
void
rrc_eNB_generate_RRCConnectionRelease(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2266 2267
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t *const ue_context_pP
2268 2269 2270
)
//-----------------------------------------------------------------------------
{
root's avatar
root committed
2271
  uint8_t buffer[RRC_BUF_SIZE];
2272
  uint16_t size = 0;
root's avatar
root committed
2273
  memset(buffer, 0, RRC_BUF_SIZE);
2274 2275 2276
  T(T_ENB_RRC_CONNECTION_RELEASE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
    T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
  size = do_RRCConnectionRelease(ctxt_pP->module_id, buffer,rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id));
2277 2278
  ue_context_pP->ue_context.ue_reestablishment_timer = 0;
  ue_context_pP->ue_context.ue_release_timer = 0;
2279
  ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0;
2280
  LOG_I(RRC,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2281
        PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate RRCConnectionRelease (bytes %d)\n",
2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
        size);
  LOG_D(RRC,
        PROTOCOL_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (rrcConnectionRelease MUI %d) --->[PDCP][RB %u]\n",
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
        size,
        rrc_eNB_mui,
        DCCH);
  MSC_LOG_TX_MESSAGE(
    MSC_RRC_ENB,
    MSC_RRC_UE,
    buffer,
    size,
2295
    MSC_AS_TIME_FMT" LTE_RRCConnectionRelease UE %x MUI %d size %u",
2296 2297 2298 2299
    MSC_AS_TIME_ARGS(ctxt_pP),
    ue_context_pP->ue_context.rnti,
    rrc_eNB_mui,
    size);
2300 2301 2302
  while (pthread_mutex_trylock(&rrc_release_freelist)) {
    /* spin... */
  }
2303 2304 2305
  for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) {
    if (rrc_release_info.RRC_release_ctrl[release_num].flag == 0) {
      if (ue_context_pP->ue_context.ue_release_timer_s1 > 0) {
2306
        rrc_release_info.RRC_release_ctrl[release_num].flag = 1;
2307
      } else {
2308 2309
        rrc_release_info.RRC_release_ctrl[release_num].flag = 2;
      }
2310

2311 2312 2313
      rrc_release_info.RRC_release_ctrl[release_num].rnti = ctxt_pP->rnti;
      rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui = rrc_eNB_mui;
      rrc_release_info.num_UEs++;
2314
      LOG_D(RRC, "Generate DLSCH Release send: index %d rnti %x mui %d flag %d \n",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2315 2316 2317 2318
            release_num,
            ctxt_pP->rnti,
            rrc_eNB_mui,
            rrc_release_info.RRC_release_ctrl[release_num].flag);
2319 2320 2321
      break;
    }
  }
2322

2323
  pthread_mutex_unlock(&rrc_release_freelist);
2324
  if (NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340
    MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, F1AP_UE_CONTEXT_RELEASE_CMD);
    F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = ctxt_pP->rnti;
    F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK;
    F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release
    F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = buffer;
    F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container_length = size;
    itti_send_msg_to_task(TASK_CU_F1, ctxt_pP->module_id, m);
  } else {
    rrc_data_req(ctxt_pP,
                 DCCH,
                 rrc_eNB_mui++,
                 SDU_CONFIRM_NO,
                 size,
                 buffer,
                 PDCP_TRANSMISSION_MODE_CONTROL);
  }
2341 2342
}

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2343
uint8_t qci_to_priority[9]= {2,4,3,5,1,6,7,8,9};
2344 2345 2346 2347

// TBD: this directive can be remived if we create a similar e_rab_param_t structure in RRC context
//-----------------------------------------------------------------------------
void
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2348 2349 2350 2351
rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP,
    rrc_eNB_ue_context_t          *const ue_context_pP,
    const uint8_t                ho_state
                                                      )
2352 2353 2354 2355 2356
//-----------------------------------------------------------------------------
{
  uint8_t                             buffer[RRC_BUF_SIZE];
  uint16_t                            size;
  int i;
2357 2358 2359 2360 2361 2362 2363
  struct LTE_DRB_ToAddMod                *DRB_config                       = NULL;
  struct LTE_RLC_Config                  *DRB_rlc_config                   = NULL;
  struct LTE_PDCP_Config                 *DRB_pdcp_config                  = NULL;
  struct LTE_PDCP_Config__rlc_AM         *PDCP_rlc_AM                      = NULL;
  struct LTE_PDCP_Config__rlc_UM         *PDCP_rlc_UM                      = NULL;
  struct LTE_LogicalChannelConfig        *DRB_lchan_config                 = NULL;
  struct LTE_LogicalChannelConfig__ul_SpecificParameters
2364
    *DRB_ul_SpecificParameters        = NULL;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2365 2366 2367
  //  LTE_DRB_ToAddModList_t**                DRB_configList=&ue_context_pP->ue_context.DRB_configList;
  LTE_DRB_ToAddModList_t                *DRB_configList=ue_context_pP->ue_context.DRB_configList;
  LTE_DRB_ToAddModList_t                **DRB_configList2=NULL;
2368
  //DRB_ToAddModList_t**                RRC_DRB_configList=&ue_context_pP->ue_context.DRB_configList;
2369 2370
  struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL;
  LTE_DedicatedInfoNAS_t                 *dedicatedInfoNas                 = NULL;
2371 2372 2373
  /* for no gcc warnings */
  (void)dedicatedInfoNas;
  long  *logicalchannelgroup_drb;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2374
  //  int drb_identity_index=0;
2375 2376
  uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id);   //Transaction_id,
  DRB_configList2=&ue_context_pP->ue_context.DRB_configList2[xid];
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2377

2378 2379 2380
  if (*DRB_configList2) {
    free(*DRB_configList2);
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2381

2382
  //*DRB_configList = CALLOC(1, sizeof(*DRB_configList));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2383
  *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
2384
  /* Initialize NAS list */
2385
  dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList));
2386 2387
  int e_rab_done=0;

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2388 2389 2390 2391 2392
  for ( i = 0  ;
        i < ue_context_pP->ue_context.setup_e_rabs ;
        i++) {
    if (e_rab_done >= ue_context_pP->ue_context.nb_of_e_rabs) {
      break;
2393
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2394

2395 2396
    // bypass the new and already configured erabs
    if (ue_context_pP->ue_context.e_rab[i].status >= E_RAB_STATUS_DONE) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2397
      //      drb_identity_index++;
2398 2399 2400
      continue;
    }

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2401
    DRB_config = CALLOC(1, sizeof(*DRB_config));
2402 2403
    DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long));
    // allowed value 5..15, value : x+4
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2404 2405 2406
    *(DRB_config->eps_BearerIdentity) = ue_context_pP->ue_context.e_rab[i].param.e_rab_id;//+ 4; // especial case generation
    //   DRB_config->drb_Identity =  1 + drb_identity_index + e_rab_done;// + i ;// (LTE_DRB_Identity_t) ue_context_pP->ue_context.e_rab[i].param.e_rab_id;
    // 1 + drb_identiy_index;
2407 2408 2409 2410 2411 2412 2413 2414
    DRB_config->drb_Identity = i+1;
    DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long));
    *(DRB_config->logicalChannelIdentity) = DRB_config->drb_Identity + 2; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2
    DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config));
    DRB_config->rlc_Config = DRB_rlc_config;
    DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config));
    DRB_config->pdcp_Config = DRB_pdcp_config;
    DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long));
2415
    *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity;
2416 2417 2418
    DRB_pdcp_config->rlc_AM = NULL;
    DRB_pdcp_config->rlc_UM = NULL;

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2419
    switch (ue_context_pP->ue_context.e_rab[i].param.qos.qci) {
2420 2421 2422 2423
      /*
       * type: realtime data with medium packer error rate
       * action: swtich to RLC UM
       */
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442
      case 1: // 100ms, 10^-2, p2, GBR
      case 2: // 150ms, 10^-3, p4, GBR
      case 3: // 50ms, 10^-3, p3, GBR
      case 4:  // 300ms, 10^-6, p5
      case 7: // 100ms, 10^-3, p7, GBR
      case 9: // 300ms, 10^-6, p9
      case 65: // 75ms, 10^-2, p0.7, mission critical voice, GBR
      case 66: // 100ms, 10^-2, p2, non-mission critical  voice , GBR
        // RLC
        DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional;
        DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10;
        DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10;
        DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35;
        // PDCP
        PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM));
        DRB_pdcp_config->rlc_UM = PDCP_rlc_UM;
        PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits;
        break;

2443 2444 2445 2446
      /*
       * type: non-realtime data with low packer error rate
       * action: swtich to RLC AM
       */
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470
      case 5:  // 100ms, 10^-6, p1 , IMS signaling
      case 6:  // 300ms, 10^-6, p6
      case 8: // 300ms, 10^-6, p8
      case 69: // 60ms, 10^-6, p0.5, mission critical delay sensitive data, Lowest Priority
      case 70: // 200ms, 10^-6, p5.5, mision critical data
        // RLC
        DRB_rlc_config->present = LTE_RLC_Config_PR_am;
        DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms50;
        DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p16;
        DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity;
        DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8;
        DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35;
        DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms25;
        // PDCP
        PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM));
        DRB_pdcp_config->rlc_AM = PDCP_rlc_AM;
        PDCP_rlc_AM->statusReportRequired = FALSE;
        break;

      default :
        LOG_E(RRC,"not supported qci %d\n", ue_context_pP->ue_context.e_rab[i].param.qos.qci);
        ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_FAILED;
        ue_context_pP->ue_context.e_rab[i].xid = xid;
        e_rab_done++;
2471 2472 2473 2474 2475 2476
        free(DRB_pdcp_config->discardTimer);
        free(DRB_pdcp_config);
        free(DRB_rlc_config);
        free(DRB_config->logicalChannelIdentity);
        free(DRB_config->eps_BearerIdentity);
        free(DRB_config);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2477
        continue;
2478 2479
    }

2480
    DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed;
2481 2482 2483 2484 2485
    DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config));
    DRB_config->logicalChannelConfig = DRB_lchan_config;
    DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters));
    DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters;

2486
    if (ue_context_pP->ue_context.e_rab[i].param.qos.qci < 9 )
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2487
      DRB_ul_SpecificParameters->priority = qci_to_priority[ue_context_pP->ue_context.e_rab[i].param.qos.qci-1] + 3;
2488
    // ue_context_pP->ue_context.e_rab[i].param.qos.allocation_retention_priority.priority_level;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2489
    else
2490 2491
      DRB_ul_SpecificParameters->priority= 4;

2492
    DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2493
    //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
2494
    DRB_ul_SpecificParameters->bucketSizeDuration =
2495
      LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
2496 2497 2498 2499 2500 2501 2502
    logicalchannelgroup_drb = CALLOC(1, sizeof(long));
    *logicalchannelgroup_drb = 1;//(i+1) % 3;
    DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb;
    ASN_SEQUENCE_ADD(&DRB_configList->list, DRB_config);
    ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config);
    //ue_context_pP->ue_context.DRB_configList2[drb_identity_index] = &(*DRB_configList);
    LOG_I(RRC,"EPS ID %ld, DRB ID %ld (index %d), QCI %d, priority %ld, LCID %ld LCGID %ld \n",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2503 2504 2505 2506 2507 2508 2509
          *DRB_config->eps_BearerIdentity,
          DRB_config->drb_Identity, i,
          ue_context_pP->ue_context.e_rab[i].param.qos.qci,
          DRB_ul_SpecificParameters->priority,
          *(DRB_config->logicalChannelIdentity),
          *DRB_ul_SpecificParameters->logicalChannelGroup
         );
2510
    e_rab_done++;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2511
    ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE;
2512 2513 2514
    ue_context_pP->ue_context.e_rab[i].xid = xid;
    {
      if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2515 2516 2517 2518 2519 2520 2521 2522 2523
        dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t));
        memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t));
        OCTET_STRING_fromBuf(dedicatedInfoNas,
                             (char *)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer,
                             ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length);
        ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas);
        LOG_I(RRC,"add NAS info with size %d (rab id %d)\n",ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length, i);
      } else {
        LOG_W(RRC,"Not received activate dedicated EPS bearer context request\n");
2524
      }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2525

2526 2527
      /* TODO parameters yet to process ... */
      {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2528 2529 2530
        //      ue_context_pP->ue_context.e_rab[i].param.qos;
        //      ue_context_pP->ue_context.e_rab[i].param.sgw_addr;
        //      ue_context_pP->ue_context.e_rab[i].param.gtp_teid;
2531 2532 2533 2534 2535 2536 2537 2538 2539 2540
      }
    }
  }

  /* If list is empty free the list and reset the address */
  if (dedicatedInfoNASList != NULL) {
    if (dedicatedInfoNASList->list.count == 0) {
      free(dedicatedInfoNASList);
      dedicatedInfoNASList = NULL;
      LOG_W(RRC,"dedlicated NAS list is empty, free the list and reset the address\n");
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2541
    }
2542 2543 2544 2545 2546
  } else {
    LOG_W(RRC,"dedlicated NAS list is empty\n");
  }

  memset(buffer, 0, RRC_BUF_SIZE);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2547 2548 2549 2550 2551 2552 2553 2554
  size = do_RRCConnectionReconfiguration(ctxt_pP,
                                         buffer,
                                         xid,
                                         (LTE_SRB_ToAddModList_t *)NULL,
                                         (LTE_DRB_ToAddModList_t *)*DRB_configList2,
                                         (LTE_DRB_ToReleaseList_t *)NULL, // DRB2_list,
                                         (struct LTE_SPS_Config *)NULL,   // *sps_Config,
                                         NULL, NULL, NULL, NULL,NULL,
Cedric Roux's avatar
Cedric Roux committed
2555
                                         NULL, NULL,  NULL, NULL, NULL, NULL, NULL,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2556 2557 2558
                                         (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)dedicatedInfoNASList,
                                         (LTE_SL_CommConfig_r12_t *)NULL,
                                         (LTE_SL_DiscConfig_r12_t *)NULL
2559
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2560
                                         , (LTE_SCellToAddMod_r10_t *)NULL
2561 2562
#endif
                                        );
2563
  LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Connection Reconfiguration\n");
2564 2565 2566 2567 2568 2569 2570 2571 2572 2573

  /* Free all NAS PDUs */
  for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) {
    if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) {
      /* Free the NAS PDU buffer and invalidate it */
      free(ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer);
      ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer = NULL;
    }
  }

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2574
  LOG_I(RRC,
2575
        "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE RNTI %x)\n",
2576 2577 2578 2579 2580 2581 2582 2583 2584
        ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti);
  LOG_D(RRC,
        "[FRAME %05d][RRC_eNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
        ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_eNB_mui, ctxt_pP->module_id, DCCH);
  MSC_LOG_TX_MESSAGE(
    MSC_RRC_ENB,
    MSC_RRC_UE,
    buffer,
    size,
2585
    MSC_AS_TIME_FMT" dedicated LTE_RRCConnectionReconfiguration UE %x MUI %d size %u",
2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599
    MSC_AS_TIME_ARGS(ctxt_pP),
    ue_context_pP->ue_context.rnti,
    rrc_eNB_mui,
    size);
  rrc_data_req(
    ctxt_pP,
    DCCH,
    rrc_eNB_mui++,
    SDU_CONFIRM_NO,
    size,
    buffer,
    PDCP_TRANSMISSION_MODE_CONTROL);
}
int
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2600 2601 2602 2603
rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP,
    rrc_eNB_ue_context_t          *const ue_context_pP,
    const uint8_t                ho_state
                                                    )
2604 2605 2606 2607 2608
//-----------------------------------------------------------------------------
{
  uint8_t                             buffer[RRC_BUF_SIZE];
  uint16_t                            size;
  int i, j;
2609 2610 2611 2612 2613 2614 2615
  struct LTE_DRB_ToAddMod                *DRB_config                       = NULL;
  struct LTE_RLC_Config                  *DRB_rlc_config                   = NULL;
  struct LTE_PDCP_Config                 *DRB_pdcp_config                  = NULL;
  struct LTE_PDCP_Config__rlc_AM         *PDCP_rlc_AM                      = NULL;
  struct LTE_PDCP_Config__rlc_UM         *PDCP_rlc_UM                      = NULL;
  struct LTE_LogicalChannelConfig        *DRB_lchan_config                 = NULL;
  struct LTE_LogicalChannelConfig__ul_SpecificParameters
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2616 2617 2618
    *DRB_ul_SpecificParameters        = NULL;
  LTE_DRB_ToAddModList_t                 *DRB_configList = ue_context_pP->ue_context.DRB_configList;
  LTE_DRB_ToAddModList_t                *DRB_configList2 = NULL;
2619 2620
  struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL;
  LTE_DedicatedInfoNAS_t                 *dedicatedInfoNas                 = NULL;
2621 2622 2623 2624 2625
  /* for no gcc warnings */
  (void)dedicatedInfoNas;
  uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id);   // Transaction_id,
  DRB_configList2 = CALLOC(1, sizeof(*DRB_configList2));
  /* Initialize NAS list */
2626
  dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList));
2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642

  for (i = 0; i < ue_context_pP->ue_context.nb_of_modify_e_rabs; i++) {
    // bypass the new and already configured erabs
    if (ue_context_pP->ue_context.modify_e_rab[i].status >= E_RAB_STATUS_DONE) {
      ue_context_pP->ue_context.modify_e_rab[i].xid = xid;
      continue;
    }

    if (ue_context_pP->ue_context.modify_e_rab[i].cause != S1AP_CAUSE_NOTHING) {
      // set xid of failure RAB
      ue_context_pP->ue_context.modify_e_rab[i].xid = xid;
      ue_context_pP->ue_context.modify_e_rab[i].status = E_RAB_STATUS_FAILED;
      continue;
    }

    DRB_config = NULL;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2643

2644 2645 2646 2647 2648 2649 2650
    // search exist DRB_config
    for (j = 0; j < DRB_configList->list.count; j++) {
      if((uint8_t)*(DRB_configList->list.array[j]->eps_BearerIdentity) == ue_context_pP->ue_context.modify_e_rab[i].param.e_rab_id) {
        DRB_config = DRB_configList->list.array[j];
        break;
      }
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2651

2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663
    if (NULL == DRB_config) {
      ue_context_pP->ue_context.modify_e_rab[i].xid = xid;
      ue_context_pP->ue_context.modify_e_rab[i].status = E_RAB_STATUS_FAILED;
      // TODO use which cause
      ue_context_pP->ue_context.modify_e_rab[i].cause = S1AP_CAUSE_RADIO_NETWORK;
      ue_context_pP->ue_context.modify_e_rab[i].cause_value = 0;//S1ap_CauseRadioNetwork_unspecified;
      ue_context_pP->ue_context.nb_of_failed_e_rabs++;
      continue;
    }

    DRB_rlc_config = DRB_config->rlc_Config;
    DRB_pdcp_config = DRB_config->pdcp_Config;
2664
    *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2665

2666
    switch (ue_context_pP->ue_context.modify_e_rab[i].param.qos.qci) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689
      /*
       * type: realtime data with medium packer error rate
       * action: swtich to RLC UM
       */
      case 1: // 100ms, 10^-2, p2, GBR
      case 2: // 150ms, 10^-3, p4, GBR
      case 3: // 50ms, 10^-3, p3, GBR
      case 4:  // 300ms, 10^-6, p5
      case 7: // 100ms, 10^-3, p7, GBR
      case 9: // 300ms, 10^-6, p9
      case 65: // 75ms, 10^-2, p0.7, mission critical voice, GBR
      case 66: // 100ms, 10^-2, p2, non-mission critical  voice , GBR
        // RLC
        DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional;
        DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10;
        DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10;
        DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35;

        // PDCP
        if (DRB_pdcp_config->rlc_AM) {
          free(DRB_pdcp_config->rlc_AM);
          DRB_pdcp_config->rlc_AM = NULL;
        }
2690

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742
        if (DRB_pdcp_config->rlc_UM) {
          free(DRB_pdcp_config->rlc_UM);
          DRB_pdcp_config->rlc_UM = NULL;
        }

        PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM));
        DRB_pdcp_config->rlc_UM = PDCP_rlc_UM;
        PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits;
        break;

      /*
       * type: non-realtime data with low packer error rate
       * action: swtich to RLC AM
       */
      case 5:  // 100ms, 10^-6, p1 , IMS signaling
      case 6:  // 300ms, 10^-6, p6
      case 8: // 300ms, 10^-6, p8
      case 69: // 60ms, 10^-6, p0.5, mission critical delay sensitive data, Lowest Priority
      case 70: // 200ms, 10^-6, p5.5, mision critical data
        // RLC
        DRB_rlc_config->present = LTE_RLC_Config_PR_am;
        DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms50;
        DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p16;
        DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity;
        DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8;
        DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35;
        DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms25;

        // PDCP
        if (DRB_pdcp_config->rlc_AM) {
          free(DRB_pdcp_config->rlc_AM);
          DRB_pdcp_config->rlc_AM = NULL;
        }

        if (DRB_pdcp_config->rlc_UM) {
          free(DRB_pdcp_config->rlc_UM);
          DRB_pdcp_config->rlc_UM = NULL;
        }

        PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM));
        DRB_pdcp_config->rlc_AM = PDCP_rlc_AM;
        PDCP_rlc_AM->statusReportRequired = FALSE;
        break;

      default :
        LOG_E(RRC, "not supported qci %d\n", ue_context_pP->ue_context.modify_e_rab[i].param.qos.qci);
        ue_context_pP->ue_context.modify_e_rab[i].status = E_RAB_STATUS_FAILED;
        ue_context_pP->ue_context.modify_e_rab[i].xid = xid;
        ue_context_pP->ue_context.modify_e_rab[i].cause = S1AP_CAUSE_RADIO_NETWORK;
        ue_context_pP->ue_context.modify_e_rab[i].cause_value = 37;//S1ap_CauseRadioNetwork_not_supported_QCI_value;
        ue_context_pP->ue_context.nb_of_failed_e_rabs++;
        continue;
2743 2744
    }

2745
    DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed;
2746 2747 2748 2749 2750 2751
    DRB_lchan_config = DRB_config->logicalChannelConfig;
    DRB_ul_SpecificParameters = DRB_lchan_config->ul_SpecificParameters;

    if (ue_context_pP->ue_context.modify_e_rab[i].param.qos.qci < 9 )
      DRB_ul_SpecificParameters->priority = qci_to_priority[ue_context_pP->ue_context.modify_e_rab[i].param.qos.qci-1] + 3;
    else
2752 2753
      DRB_ul_SpecificParameters->priority= 4;

2754
    DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8;
2755
    DRB_ul_SpecificParameters->bucketSizeDuration =
2756
      LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
2757 2758
    ASN_SEQUENCE_ADD(&(DRB_configList2)->list, DRB_config);
    LOG_I(RRC, "EPS ID %ld, DRB ID %ld (index %d), QCI %d, priority %ld, LCID %ld LCGID %ld \n",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2759 2760 2761 2762 2763 2764 2765
          *DRB_config->eps_BearerIdentity,
          DRB_config->drb_Identity, i,
          ue_context_pP->ue_context.modify_e_rab[i].param.qos.qci,
          DRB_ul_SpecificParameters->priority,
          *(DRB_config->logicalChannelIdentity),
          *DRB_ul_SpecificParameters->logicalChannelGroup
         );
2766 2767 2768
    //e_rab_done++;
    ue_context_pP->ue_context.modify_e_rab[i].status = E_RAB_STATUS_DONE;
    ue_context_pP->ue_context.modify_e_rab[i].xid = xid;
2769
    {
2770
      if (ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.buffer != NULL) {
2771
        dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t));
2772 2773
        memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t));
        OCTET_STRING_fromBuf(dedicatedInfoNas,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2774 2775
                             (char *)ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.buffer,
                             ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.length);
2776 2777
        ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas);
        LOG_I(RRC, "add NAS info with size %d (rab id %d)\n",ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.length, i);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2778
      } else {
2779
        LOG_W(RRC, "Not received activate dedicated EPS bearer context request\n");
2780
      }
2781 2782
    }
  }
2783 2784 2785 2786 2787 2788 2789

  /* If list is empty free the list and reset the address */
  if (dedicatedInfoNASList != NULL) {
    if (dedicatedInfoNASList->list.count == 0) {
      free(dedicatedInfoNASList);
      dedicatedInfoNASList = NULL;
      LOG_W(RRC,"dedlicated NAS list is empty, free the list and reset the address\n");
2790
    }
2791 2792 2793 2794
  } else {
    LOG_W(RRC,"dedlicated NAS list is empty\n");
  }

2795
  memset(buffer, 0, RRC_BUF_SIZE);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2796 2797 2798 2799 2800 2801 2802 2803
  size = do_RRCConnectionReconfiguration(ctxt_pP,
                                         buffer,
                                         xid,
                                         (LTE_SRB_ToAddModList_t *)NULL,
                                         (LTE_DRB_ToAddModList_t *)DRB_configList2,
                                         (LTE_DRB_ToReleaseList_t *)NULL, // DRB2_list,
                                         (struct LTE_SPS_Config *)NULL,   // *sps_Config,
                                         NULL, NULL, NULL, NULL,NULL,
Cedric Roux's avatar
Cedric Roux committed
2804
                                         NULL, NULL,  NULL, NULL, NULL, NULL, NULL,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2805 2806 2807
                                         (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)dedicatedInfoNASList,
                                         (LTE_SL_CommConfig_r12_t *)NULL,
                                         (LTE_SL_DiscConfig_r12_t *)NULL
2808
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2809
                                         , (LTE_SCellToAddMod_r10_t *)NULL
2810
#endif
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2811
                                        );
2812 2813
  LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size,
              "[MSG] RRC Connection Reconfiguration\n");
2814 2815

  /* Free all NAS PDUs */
2816 2817
  for (i = 0; i < ue_context_pP->ue_context.nb_of_modify_e_rabs; i++) {
    if (ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.buffer != NULL) {
2818
      /* Free the NAS PDU buffer and invalidate it */
2819 2820
      free(ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.buffer);
      ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.buffer = NULL;
2821 2822 2823
    }
  }

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2824
  LOG_I(RRC,
2825
        "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE RNTI %x)\n",
2826 2827 2828 2829 2830 2831 2832 2833 2834
        ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti);
  LOG_D(RRC,
        "[FRAME %05d][RRC_eNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
        ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_eNB_mui, ctxt_pP->module_id, DCCH);
  MSC_LOG_TX_MESSAGE(
    MSC_RRC_ENB,
    MSC_RRC_UE,
    buffer,
    size,
2835
    MSC_AS_TIME_FMT" dedicated LTE_RRCConnectionReconfiguration UE %x MUI %d size %u",
2836 2837 2838 2839
    MSC_AS_TIME_ARGS(ctxt_pP),
    ue_context_pP->ue_context.rnti,
    rrc_eNB_mui,
    size);
2840
  rrc_data_req(
2841 2842 2843 2844 2845 2846 2847
    ctxt_pP,
    DCCH,
    rrc_eNB_mui++,
    SDU_CONFIRM_NO,
    size,
    buffer,
    PDCP_TRANSMISSION_MODE_CONTROL);
2848 2849 2850 2851 2852
  return 0;
}

//-----------------------------------------------------------------------------
void
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2853 2854 2855 2856 2857
rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release(  const protocol_ctxt_t   *const ctxt_pP,
    rrc_eNB_ue_context_t    *const ue_context_pP,
    uint8_t                  xid,
    uint32_t                 nas_length,
    uint8_t                 *nas_buffer)
2858 2859
//-----------------------------------------------------------------------------
{
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2860 2861 2862 2863 2864 2865 2866
  uint8_t                             buffer[RRC_BUF_SIZE];
  int                                 i;
  uint16_t                            size  = 0;
  LTE_DRB_ToReleaseList_t                **DRB_Release_configList2=NULL;
  LTE_DRB_Identity_t *DRB_release;
  struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL;
  DRB_Release_configList2=&ue_context_pP->ue_context.DRB_Release_configList2[xid];
2867

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879
  if (*DRB_Release_configList2) {
    free(*DRB_Release_configList2);
  }

  *DRB_Release_configList2 = CALLOC(1, sizeof(**DRB_Release_configList2));

  for(i = 0; i < NB_RB_MAX; i++) {
    if((ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_TORELEASE) && ue_context_pP->ue_context.e_rab[i].xid == xid) {
      DRB_release = CALLOC(1, sizeof(LTE_DRB_Identity_t));
      *DRB_release = i+1;
      ASN_SEQUENCE_ADD(&(*DRB_Release_configList2)->list, DRB_release);
      //free(DRB_release);
2880
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2881
  }
2882

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916
  /* If list is empty free the list and reset the address */
  if (nas_length > 0) {
    LTE_DedicatedInfoNAS_t                 *dedicatedInfoNas                 = NULL;
    dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList));
    dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t));
    memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t));
    OCTET_STRING_fromBuf(dedicatedInfoNas,
                         (char *)nas_buffer,
                         nas_length);
    ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas);
    LOG_I(RRC,"add NAS info with size %d\n",nas_length);
  } else {
    LOG_W(RRC,"dedlicated NAS list is empty\n");
  }

  memset(buffer, 0, RRC_BUF_SIZE);
  size = do_RRCConnectionReconfiguration(ctxt_pP,
                                         buffer,
                                         xid,
                                         NULL,
                                         NULL,
                                         (LTE_DRB_ToReleaseList_t *)*DRB_Release_configList2,
                                         NULL,
                                         NULL,
                                         NULL,
                                         NULL,
                                         NULL,
                                         NULL,
                                         NULL,
                                         NULL,
                                         NULL,
                                         NULL,
                                         NULL,
                                         NULL,
Cedric Roux's avatar
Cedric Roux committed
2917
                                         NULL,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2918 2919 2920
                                         (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)dedicatedInfoNASList,
                                         (LTE_SL_CommConfig_r12_t *)NULL,
                                         (LTE_SL_DiscConfig_r12_t *)NULL
2921
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2922
                                         , (LTE_SCellToAddMod_r10_t *)NULL
2923
#endif
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2924 2925 2926 2927 2928
                                        );
  ue_context_pP->ue_context.e_rab_release_command_flag = 1;
  LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size,
              "[MSG] RRC Connection Reconfiguration\n");

2929 2930
  /* Free all NAS PDUs */
  if (nas_length > 0) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2931 2932
    /* Free the NAS PDU buffer and invalidate it */
    free(nas_buffer);
2933 2934 2935
  }

  LOG_I(RRC,
2936
        "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE RNTI %x)\n",
2937 2938 2939 2940 2941 2942 2943 2944 2945
        ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti);
  LOG_D(RRC,
        "[FRAME %05d][RRC_eNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
        ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_eNB_mui, ctxt_pP->module_id, DCCH);
  MSC_LOG_TX_MESSAGE(
    MSC_RRC_ENB,
    MSC_RRC_UE,
    buffer,
    size,
2946
    MSC_AS_TIME_FMT" dedicated LTE_RRCConnectionReconfiguration UE %x MUI %d size %u",
2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958
    MSC_AS_TIME_ARGS(ctxt_pP),
    ue_context_pP->ue_context.rnti,
    rrc_eNB_mui,
    size);
  rrc_data_req(
    ctxt_pP,
    DCCH,
    rrc_eNB_mui++,
    SDU_CONFIRM_NO,
    size,
    buffer,
    PDCP_TRANSMISSION_MODE_CONTROL);
2959
}
2960

2961
//-----------------------------------------------------------------------------
2962 2963 2964 2965 2966 2967
/*
 * Generate the basic (first) RRC Connection Reconfiguration (non BR UE)
 */
void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP,
                                                          rrc_eNB_ue_context_t  *const ue_context_pP,
                                                          const uint8_t                ho_state)
2968
//-----------------------------------------------------------------------------
2969
{
2970 2971 2972 2973 2974 2975
  uint8_t   buffer[RRC_BUF_SIZE];
  uint16_t  size;
  int       i;
  
  /* Configure SRB1/SRB2, PhysicalConfigDedicated, LTE_MAC_MainConfig for UE */
  eNB_RRC_INST                           *rrc_inst = RC.rrc[ctxt_pP->module_id];
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2976
  struct LTE_PhysicalConfigDedicated    **physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated;
2977 2978 2979 2980
  struct LTE_SRB_ToAddMod                *SRB2_config                      = NULL;
  struct LTE_SRB_ToAddMod__rlc_Config    *SRB2_rlc_config                  = NULL;
  struct LTE_SRB_ToAddMod__logicalChannelConfig *SRB2_lchan_config         = NULL;
  struct LTE_LogicalChannelConfig__ul_SpecificParameters
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2981 2982
    *SRB2_ul_SpecificParameters       = NULL;
  LTE_SRB_ToAddModList_t                 *SRB_configList = ue_context_pP->ue_context.SRB_configList;
2983
  LTE_SRB_ToAddModList_t                 **SRB_configList2                 = NULL;
2984 2985 2986 2987 2988 2989 2990
  struct LTE_DRB_ToAddMod                *DRB_config                       = NULL;
  struct LTE_RLC_Config                  *DRB_rlc_config                   = NULL;
  struct LTE_PDCP_Config                 *DRB_pdcp_config                  = NULL;
  struct LTE_PDCP_Config__rlc_AM         *PDCP_rlc_AM                      = NULL;
  struct LTE_PDCP_Config__rlc_UM         *PDCP_rlc_UM                      = NULL;
  struct LTE_LogicalChannelConfig        *DRB_lchan_config                 = NULL;
  struct LTE_LogicalChannelConfig__ul_SpecificParameters
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2991 2992
    *DRB_ul_SpecificParameters        = NULL;
  LTE_DRB_ToAddModList_t                **DRB_configList = &ue_context_pP->ue_context.DRB_configList;
2993
  LTE_DRB_ToAddModList_t                **DRB_configList2                  = NULL;
2994 2995 2996 2997 2998
  LTE_MAC_MainConfig_t                   *mac_MainConfig                   = NULL;
  LTE_MeasObjectToAddModList_t           *MeasObj_list                     = NULL;
  LTE_MeasObjectToAddMod_t               *MeasObj                          = NULL;
  LTE_ReportConfigToAddModList_t         *ReportConfig_list                = NULL;
  LTE_ReportConfigToAddMod_t             *ReportConfig_per, *ReportConfig_A1,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2999
                                         *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5;
3000 3001
  LTE_MeasIdToAddModList_t               *MeasId_list                      = NULL;
  LTE_MeasIdToAddMod_t                   *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5;
3002

3003
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
3004
  long                                   *sr_ProhibitTimer_r9              = NULL;
winckel's avatar
winckel committed
3005
#endif
3006 3007 3008 3009 3010

  long                                   *logicalchannelgroup              = NULL;
  long                                   *logicalchannelgroup_drb          = NULL;
  long                                   *maxHARQ_Tx                       = NULL; 
  long                                   *periodicBSR_Timer                = NULL;
3011 3012 3013
  LTE_RSRP_Range_t                       *rsrp                             = NULL;
  struct LTE_MeasConfig__speedStatePars  *Sparams                          = NULL;
  LTE_QuantityConfig_t                   *quantityConfig                   = NULL;
3014 3015 3016
  LTE_CellsToAddMod_t                    *CellToAdd                        = NULL;
  LTE_CellsToAddModList_t                *CellsToAddModList                = NULL;
  struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL;
3017
  LTE_DedicatedInfoNAS_t                 *dedicatedInfoNas                 = NULL;
3018 3019 3020
  
  /* For no gcc warnings */
  (void) dedicatedInfoNas;
3021
  LTE_C_RNTI_t                           *cba_RNTI                         = NULL;
3022
  int                                    measurements_enabled;
3023
  uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id);   //Transaction_id,
3024 3025
  uint8_t cc_id = ue_context_pP->ue_context.primaryCC_id;
  LTE_UE_EUTRA_Capability_t *UEcap = ue_context_pP->ue_context.UE_Capability;
3026 3027

#ifdef CBA // Contention Based Access
3028
  uint8_t                            *cba_RNTI_buf;
3029
  cba_RNTI = CALLOC(1, sizeof(LTE_C_RNTI_t));
3030 3031 3032 3033 3034
  cba_RNTI_buf = CALLOC(1, 2 * sizeof(uint8_t));
  cba_RNTI->buf = cba_RNTI_buf;
  cba_RNTI->size = 2;
  cba_RNTI->bits_unused = 0;

3035
  /* Associate UEs to the CBA groups as a function of their UE id */
3036 3037 3038
  if (rrc_inst->num_active_cba_groups) {
    cba_RNTI->buf[0] = rrc_inst->cba_rnti[ue_mod_idP % rrc_inst->num_active_cba_groups] & 0xff;
    cba_RNTI->buf[1] = 0xff;
3039 3040 3041
    LOG_D(RRC, "[eNB %d] Frame %d: cba_RNTI = %x in group %d is attribued to UE %d\n",
          enb_mod_idP, 
          frameP,
3042 3043 3044 3045 3046
          rrc_inst->cba_rnti[ue_mod_idP % rrc_inst->num_active_cba_groups],
          ue_mod_idP % rrc_inst->num_active_cba_groups, ue_mod_idP);
  } else {
    cba_RNTI->buf[0] = 0x0;
    cba_RNTI->buf[1] = 0x0;
3047 3048 3049 3050
    LOG_D(RRC, "[eNB %d] Frame %d: no cba_RNTI is configured for UE %d\n", 
          enb_mod_idP, 
          frameP, 
          ue_mod_idP);
3051
  }
3052
#endif
3053 3054 3055 3056 3057 3058 3059 3060 3061

  T(T_ENB_RRC_CONNECTION_RECONFIGURATION, 
    T_INT(ctxt_pP->module_id), 
    T_INT(ctxt_pP->frame),
    T_INT(ctxt_pP->subframe), 
    T_INT(ctxt_pP->rnti));

  /* Configure SRB2 */
  SRB_configList2 = &(ue_context_pP->ue_context.SRB_configList2[xid]);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3062

3063 3064 3065
  if (*SRB_configList2) {
    free(*SRB_configList2);
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3066

3067 3068
  *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
  memset(*SRB_configList2, 0, sizeof(**SRB_configList2));
3069 3070 3071 3072
  SRB2_config = CALLOC(1, sizeof(*SRB2_config));
  SRB2_config->srb_Identity = 2;
  SRB2_rlc_config = CALLOC(1, sizeof(*SRB2_rlc_config));
  SRB2_config->rlc_Config = SRB2_rlc_config;
3073 3074 3075 3076 3077 3078 3079 3080
  SRB2_rlc_config->present = LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue;
  SRB2_rlc_config->choice.explicitValue.present = LTE_RLC_Config_PR_am;
  SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms15;
  SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p8;
  SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kB1000;
  SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t32;
  SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35;
  SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms10;
3081 3082
  SRB2_lchan_config = CALLOC(1, sizeof(*SRB2_lchan_config));
  SRB2_config->logicalChannelConfig = SRB2_lchan_config;
3083
  SRB2_lchan_config->present = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue;
3084
  SRB2_ul_SpecificParameters = CALLOC(1, sizeof(*SRB2_ul_SpecificParameters));
3085
  SRB2_ul_SpecificParameters->priority = 3; // let some priority for SRB1 and dedicated DRBs
3086 3087 3088 3089
  SRB2_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
  SRB2_ul_SpecificParameters->bucketSizeDuration = LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
  
  /* LCG for CCCH and DCCH is 0 as defined in 36331 */
3090 3091 3092 3093
  logicalchannelgroup = CALLOC(1, sizeof(long));
  *logicalchannelgroup = 0;
  SRB2_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup;
  SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters = SRB2_ul_SpecificParameters;
3094 3095 3096
  
  ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config); // this list has the configuration for SRB1 and SRB2
  ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config); // this list has only the configuration for SRB2
3097

3098
  /* Configure DRB */
3099
  // list for all the configured DRB
3100 3101 3102
  if (*DRB_configList) {
    free(*DRB_configList);
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3103

3104
  *DRB_configList = CALLOC(1, sizeof(**DRB_configList));
3105
  memset(*DRB_configList, 0, sizeof(**DRB_configList));
3106 3107
  
  DRB_configList2=&ue_context_pP->ue_context.DRB_configList2[xid]; // list for the configured DRB for a this xid
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3108

3109 3110 3111
  if (*DRB_configList2) {
    free(*DRB_configList2);
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3112

3113 3114
  *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
  memset(*DRB_configList2, 0, sizeof(**DRB_configList2));
3115
  
3116 3117 3118 3119
  DRB_config = CALLOC(1, sizeof(*DRB_config));
  DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long));
  *(DRB_config->eps_BearerIdentity) = 5L; // LW set to first value, allowed value 5..15, value : x+4
  // NN: this is the 1st DRB for this ue, so set it to 1
3120
  DRB_config->drb_Identity = (LTE_DRB_Identity_t) 1;  // (ue_mod_idP+1); //allowed values 1..32, value: x
3121 3122 3123 3124
  DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long));
  *(DRB_config->logicalChannelIdentity) = (long)3; // value : x+2
  DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config));
  DRB_config->rlc_Config = DRB_rlc_config;
3125

3126
#ifdef RRC_DEFAULT_RAB_IS_AM
3127 3128 3129 3130 3131 3132 3133
  DRB_rlc_config->present = LTE_RLC_Config_PR_am;
  DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms50;
  DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p16;
  DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity;
  DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8;
  DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35;
  DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms25;
3134
#else
3135 3136 3137
  DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional;
  DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10;
  DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10;
3138

3139
#ifdef CBA
3140
  DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering   = LTE_T_Reordering_ms5; //T_Reordering_ms25;
3141
#else
3142
  DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35;
3143
#endif
3144

3145
#endif
3146

3147 3148 3149
  DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config));
  DRB_config->pdcp_Config = DRB_pdcp_config;
  DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long));
3150
  *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity;
3151 3152
  DRB_pdcp_config->rlc_AM = NULL;
  DRB_pdcp_config->rlc_UM = NULL;
3153
  /* Avoid gcc warnings */
Cedric Roux's avatar
Cedric Roux committed
3154
  (void)PDCP_rlc_AM;
Cedric Roux's avatar
Cedric Roux committed
3155
  (void)PDCP_rlc_UM;
3156

3157
#ifdef RRC_DEFAULT_RAB_IS_AM // EXMIMO_IOT
3158 3159 3160
  PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM));
  DRB_pdcp_config->rlc_AM = PDCP_rlc_AM;
  PDCP_rlc_AM->statusReportRequired = FALSE;
3161
#else
3162 3163
  PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM));
  DRB_pdcp_config->rlc_UM = PDCP_rlc_UM;
3164
  PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits;
3165
#endif
3166

3167
  DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed;
3168 3169 3170 3171
  DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config));
  DRB_config->logicalChannelConfig = DRB_lchan_config;
  DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters));
  DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters;
3172 3173 3174
  DRB_ul_SpecificParameters->priority = 12; // lower priority than srb1, srb2 and other dedicated bearer
  DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8; // LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
  DRB_ul_SpecificParameters->bucketSizeDuration = LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
3175 3176 3177 3178
  // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM)
  logicalchannelgroup_drb = CALLOC(1, sizeof(long));
  *logicalchannelgroup_drb = 1;
  DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb;
3179
  
3180
  ASN_SEQUENCE_ADD(&(*DRB_configList)->list, DRB_config);
3181
  ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config);
3182 3183 3184
  
  /* MAC Main Config */
  // The different parts of MAC main config are set below
3185
  mac_MainConfig = CALLOC(1, sizeof(*mac_MainConfig));
3186
  ue_context_pP->ue_context.mac_MainConfig = mac_MainConfig;
3187 3188
  mac_MainConfig->ul_SCH_Config = CALLOC(1, sizeof(*mac_MainConfig->ul_SCH_Config));
  maxHARQ_Tx = CALLOC(1, sizeof(long));
3189
  *maxHARQ_Tx = LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5;
3190
  mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx;
3191 3192

  /* BSR reconfiguration */
3193
  periodicBSR_Timer = CALLOC(1, sizeof(long));
3194
  *periodicBSR_Timer = LTE_PeriodicBSR_Timer_r12_sf64; //LTE_PeriodicBSR_Timer_r12_infinity; // LTE_PeriodicBSR_Timer_r12_sf64; // LTE_PeriodicBSR_Timer_r12_sf20
3195
  mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer;
3196
  mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; // LTE_RetxBSR_Timer_r12_sf320; // LTE_RetxBSR_Timer_r12_sf5120
3197
  mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE
3198
  mac_MainConfig->timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_infinity;
3199 3200

  /* PHR reconfiguration */
3201
  mac_MainConfig->phr_Config = CALLOC(1, sizeof(*mac_MainConfig->phr_Config));
3202
  mac_MainConfig->phr_Config->present = LTE_MAC_MainConfig__phr_Config_PR_setup;
3203 3204 3205 3206
  mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf500; // sf20 = 20 subframes // LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_infinity
  mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf200; // sf20 = 20 subframes // LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf1000
  mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB3;  // Value dB1 =1 dB, dB3 = 3 dB

3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221
  if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
    /* CDRX Configuration */
    // Need to check if UE is a BR UE
    rnti_t rnti = ue_context_pP->ue_id_rnti;
    module_id_t module_id = ctxt_pP->module_id;
    int UE_id = find_UE_id(module_id, rnti);
    eNB_MAC_INST *mac = RC.mac[module_id];
    UE_list_t *UE_list = &(mac->UE_list);

    if (UE_id != -1) {
      if ((rrc_inst->carrier[cc_id].sib1->tdd_Config == NULL) && 
        (UE_list->UE_template[ue_context_pP->ue_context.primaryCC_id][UE_id].rach_resource_type == 0)) {
      // CDRX can be only configured in case of FDD and non BR UE (09/04/19)
      
      LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n");
3222

3223 3224 3225 3226 3227 3228
      /* Process the IE drx_Config */
      if (cc_id < MAX_NUM_CCs) {
        mac_MainConfig->drx_Config = do_DrxConfig(module_id, cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE
      } else {
        LOG_E(RRC, "Invalid CC_id for DRX configuration\n");
      }
3229

3230 3231
      /* Set timers and thresholds values in local MAC context of UE */
      eNB_Config_Local_DRX(module_id, ue_context_pP->ue_id_rnti, mac_MainConfig->drx_Config);
3232

3233
      LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n");
3234

3235 3236 3237 3238 3239
      } else { // CDRX not implemented for TDD and LTE-M (09/04/19)
        mac_MainConfig->drx_Config = NULL;
      }
    } else { // UE_id invalid
      LOG_E(RRC, "Invalid UE_id found!\n");
3240 3241
      mac_MainConfig->drx_Config = NULL;
    }
3242 3243
  } else { // No CDRX with the CU/DU split in this version
    LOG_E(RRC, "CU/DU split activated\n");
3244 3245 3246
    mac_MainConfig->drx_Config = NULL;
  }

3247
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
3248
  sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long));
3249
  *sr_ProhibitTimer_r9 = 0;   // SR tx on PUCCH, Value in number of SR period(s). Value 0 = no timer for SR, Value 2 = 2*SR
3250
  mac_MainConfig->ext1 = CALLOC(1, sizeof(struct LTE_MAC_MainConfig__ext1));
3251
  mac_MainConfig->ext1->sr_ProhibitTimer_r9 = sr_ProhibitTimer_r9;
3252 3253
#endif

3254 3255 3256
  // change the transmission mode for the primary component carrier
  // TODO: add codebook subset restriction here
  // TODO: change TM for secondary CC in SCelltoaddmodlist
3257
  if (*physicalConfigDedicated) {
3258
    if ((*physicalConfigDedicated)->antennaInfo) {
3259 3260
      (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.transmissionMode = rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode;
      LOG_D(RRC,"Setting transmission mode to %ld+1\n",rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode);
3261

3262
      if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm3) {
3263
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=     
3264
	  CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
3265
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
3266
	  LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm3;
3267 3268 3269 3270
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf= MALLOC(1);
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf[0] = 0xc0;
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.size=1;
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.bits_unused=6;
3271
      } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm4) {
3272
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=     
3273
	  CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
3274
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
3275
	  LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm4;
3276 3277 3278 3279
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf= MALLOC(1);
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf[0] = 0xfc;
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.size=1;
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.bits_unused=2;
3280
      } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm5) {
3281
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=     
3282
	  CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
3283
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
3284
	  LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm5;
3285 3286 3287 3288
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf= MALLOC(1);
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf[0] = 0xf0;
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.size=1;
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.bits_unused=4;
3289
      } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm6) {
3290
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=     
3291
	  CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
3292
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
3293
	  LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm6;
3294 3295 3296 3297 3298
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf= MALLOC(1);
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf[0] = 0xf0;
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.size=1;
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.bits_unused=4;
      }
3299
    } else {
3300 3301
      LOG_E(RRC,"antenna_info not present in physical_config_dedicated. Not reconfiguring!\n");
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3302

3303 3304 3305 3306 3307 3308 3309 3310 3311
    /* CSI RRC Reconfiguration */
    if ((*physicalConfigDedicated)->cqi_ReportConfig != NULL) {
      if ((rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode == LTE_AntennaInfoDedicated__transmissionMode_tm4) ||
          (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode == LTE_AntennaInfoDedicated__transmissionMode_tm5) ||
          (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode == LTE_AntennaInfoDedicated__transmissionMode_tm6)) {

        // feedback mode needs to be set as well
	      // TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable
        LOG_I(RRC, "Setting cqi reporting mode to rm31 (hardcoded)\n");
3312

3313
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
3314
        *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic) = LTE_CQI_ReportModeAperiodic_rm31; // HLC CQI, single PMI
3315
#else
3316
        *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic) = LTE_CQI_ReportConfig__cqi_ReportModeAperiodic_rm31; // HLC CQI, single PMI
3317 3318
#endif
      }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3319
    } else {
3320 3321
      LOG_E(RRC,"cqi_ReportConfig not present in physical_config_dedicated. Not reconfiguring!\n");
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3322
  } else {
3323
    LOG_E(RRC,"physical_config_dedicated not present in LTE_RRCConnectionReconfiguration. Not reconfiguring!\n");
3324
  }
3325

3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358
  // Measurement ID list
  MeasId_list = CALLOC(1, sizeof(*MeasId_list));
  memset((void *)MeasId_list, 0, sizeof(*MeasId_list));
  MeasId0 = CALLOC(1, sizeof(*MeasId0));
  MeasId0->measId = 1;
  MeasId0->measObjectId = 1;
  MeasId0->reportConfigId = 1;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId0);
  MeasId1 = CALLOC(1, sizeof(*MeasId1));
  MeasId1->measId = 2;
  MeasId1->measObjectId = 1;
  MeasId1->reportConfigId = 2;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId1);
  MeasId2 = CALLOC(1, sizeof(*MeasId2));
  MeasId2->measId = 3;
  MeasId2->measObjectId = 1;
  MeasId2->reportConfigId = 3;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId2);
  MeasId3 = CALLOC(1, sizeof(*MeasId3));
  MeasId3->measId = 4;
  MeasId3->measObjectId = 1;
  MeasId3->reportConfigId = 4;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId3);
  MeasId4 = CALLOC(1, sizeof(*MeasId4));
  MeasId4->measId = 5;
  MeasId4->measObjectId = 1;
  MeasId4->reportConfigId = 5;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId4);
  MeasId5 = CALLOC(1, sizeof(*MeasId5));
  MeasId5->measId = 6;
  MeasId5->measObjectId = 1;
  MeasId5->reportConfigId = 6;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId5);
3359
  //  LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measIdToAddModList = MeasId_list;
3360 3361 3362 3363 3364 3365 3366
  // Add one EUTRA Measurement Object
  MeasObj_list = CALLOC(1, sizeof(*MeasObj_list));
  memset((void *)MeasObj_list, 0, sizeof(*MeasObj_list));
  // Configure MeasObject
  MeasObj = CALLOC(1, sizeof(*MeasObj));
  memset((void *)MeasObj, 0, sizeof(*MeasObj));
  MeasObj->measObjectId = 1;
3367
  MeasObj->measObject.present = LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA;
3368 3369 3370 3371
  MeasObj->measObject.choice.measObjectEUTRA.carrierFreq =
      to_earfcn_DL(RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0],
                   RC.rrc[ctxt_pP->module_id]->configuration.downlink_frequency[0],
                   RC.rrc[ctxt_pP->module_id]->configuration.N_RB_DL[0]);
3372
  MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = LTE_AllowedMeasBandwidth_mbw25;
3373 3374 3375 3376 3377 3378
  MeasObj->measObject.choice.measObjectEUTRA.presenceAntennaPort1 = 1;
  MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf = CALLOC(1, sizeof(uint8_t));
  MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf[0] = 0;
  MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.size = 1;
  MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.bits_unused = 6;
  MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = NULL;   // Default is 15 or 0dB
3379 3380 3381 3382 3383 3384

  if (RC.rrc[ctxt_pP->module_id]->num_neigh_cells > 0) {
    MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList =
      (LTE_CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList));
    CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList;
  }
3385 3386 3387 3388 3389 3390 3391

  if (!ue_context_pP->ue_context.measurement_info) {
    ue_context_pP->ue_context.measurement_info = CALLOC(1,sizeof(*(ue_context_pP->ue_context.measurement_info)));
  }

  //TODO: Assign proper values
  ue_context_pP->ue_context.measurement_info->offsetFreq = 0;
3392
  ue_context_pP->ue_context.measurement_info->cellIndividualOffset[0] = LTE_Q_OffsetRange_dB0;
3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403

  /* TODO: Extend to multiple carriers */
  // Add adjacent cell lists (max 6 per eNB)
  for (i = 0; i < RC.rrc[ctxt_pP->module_id]->num_neigh_cells; i++) {
    CellToAdd = (LTE_CellsToAddMod_t *) CALLOC(1, sizeof(*CellToAdd));
    CellToAdd->cellIndex = i + 1;
    CellToAdd->physCellId = RC.rrc[ctxt_pP->module_id]->neigh_cells_id[i][0];//get_adjacent_cell_id(ctxt_pP->module_id, i);
    CellToAdd->cellIndividualOffset = LTE_Q_OffsetRange_dB0;
    ue_context_pP->ue_context.measurement_info->cellIndividualOffset[i+1] = CellToAdd->cellIndividualOffset;
    ASN_SEQUENCE_ADD(&CellsToAddModList->list, CellToAdd);
  }
3404
  ASN_SEQUENCE_ADD(&MeasObj_list->list, MeasObj);
3405
  //  LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measObjectToAddModList = MeasObj_list;
3406 3407 3408 3409 3410

  if (!ue_context_pP->ue_context.measurement_info->events) {
    ue_context_pP->ue_context.measurement_info->events = CALLOC(1,sizeof(*(ue_context_pP->ue_context.measurement_info->events)));
  }

3411 3412 3413 3414 3415 3416 3417 3418 3419
  // Report Configurations for periodical, A1-A5 events
  ReportConfig_list = CALLOC(1, sizeof(*ReportConfig_list));
  ReportConfig_per = CALLOC(1, sizeof(*ReportConfig_per));
  ReportConfig_A1 = CALLOC(1, sizeof(*ReportConfig_A1));
  ReportConfig_A2 = CALLOC(1, sizeof(*ReportConfig_A2));
  ReportConfig_A3 = CALLOC(1, sizeof(*ReportConfig_A3));
  ReportConfig_A4 = CALLOC(1, sizeof(*ReportConfig_A4));
  ReportConfig_A5 = CALLOC(1, sizeof(*ReportConfig_A5));
  ReportConfig_per->reportConfigId = 1;
3420
  ReportConfig_per->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
3421
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.present =
3422
    LTE_ReportConfigEUTRA__triggerType_PR_periodical;
3423
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.choice.periodical.purpose =
3424 3425 3426
    LTE_ReportConfigEUTRA__triggerType__periodical__purpose_reportStrongestCells;
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
3427
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
3428 3429
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
3430 3431
  ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_per);
  ReportConfig_A1->reportConfigId = 2;
3432
  ReportConfig_A1->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
3433
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.present =
3434
    LTE_ReportConfigEUTRA__triggerType_PR_event;
3435
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
3436
    LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1;
3437
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA1.
3438
  a1_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
3439 3440
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA1.
  a1_Threshold.choice.threshold_RSRP = 10;
3441 3442
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
3443
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
3444 3445
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
3446
  ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A1);
3447
  //if (ho_state == 1 /*HO_MEASURMENT */ ) {
Cedric Roux's avatar
Cedric Roux committed
3448 3449 3450
  LOG_I(RRC, "[eNB %d] frame %d: requesting A2, A3, A4, and A5 event reporting\n",
        ctxt_pP->module_id, ctxt_pP->frame);
  ReportConfig_A2->reportConfigId = 3;
3451
  ReportConfig_A2->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
Cedric Roux's avatar
Cedric Roux committed
3452
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.present =
3453
    LTE_ReportConfigEUTRA__triggerType_PR_event;
Cedric Roux's avatar
Cedric Roux committed
3454
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
3455
    LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2;
Cedric Roux's avatar
Cedric Roux committed
3456
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
3457
  eventA2.a2_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
Cedric Roux's avatar
Cedric Roux committed
3458 3459 3460
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
  eventA2.a2_Threshold.choice.threshold_RSRP = 10;
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
3461 3462
    LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
Cedric Roux's avatar
Cedric Roux committed
3463
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
3464 3465
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
Cedric Roux's avatar
Cedric Roux committed
3466 3467
  ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A2);
  ReportConfig_A3->reportConfigId = 4;
3468
  ReportConfig_A3->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
Cedric Roux's avatar
Cedric Roux committed
3469
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.present =
3470
    LTE_ReportConfigEUTRA__triggerType_PR_event;
Cedric Roux's avatar
Cedric Roux committed
3471
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
3472
    LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3;
Cedric Roux's avatar
Cedric Roux committed
3473 3474 3475 3476
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset = 0;   //10;
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
  eventA3.reportOnLeave = 1;
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
3477 3478
    LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
Cedric Roux's avatar
Cedric Roux committed
3479
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
3480 3481
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
Cedric Roux's avatar
Cedric Roux committed
3482 3483
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis = 0; // FIXME ...hysteresis is of type long!
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger =
3484
    LTE_TimeToTrigger_ms40;
Cedric Roux's avatar
Cedric Roux committed
3485 3486
  ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A3);
  ReportConfig_A4->reportConfigId = 5;
3487
  ReportConfig_A4->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
Cedric Roux's avatar
Cedric Roux committed
3488
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.present =
3489
    LTE_ReportConfigEUTRA__triggerType_PR_event;
Cedric Roux's avatar
Cedric Roux committed
3490
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
3491
    LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4;
Cedric Roux's avatar
Cedric Roux committed
3492
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
3493
  eventA4.a4_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
Cedric Roux's avatar
Cedric Roux committed
3494 3495 3496
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
  eventA4.a4_Threshold.choice.threshold_RSRP = 10;
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
3497 3498
    LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
Cedric Roux's avatar
Cedric Roux committed
3499
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
3500 3501
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
Cedric Roux's avatar
Cedric Roux committed
3502 3503
  ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A4);
  ReportConfig_A5->reportConfigId = 6;
3504
  ReportConfig_A5->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
Cedric Roux's avatar
Cedric Roux committed
3505
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.present =
3506
    LTE_ReportConfigEUTRA__triggerType_PR_event;
Cedric Roux's avatar
Cedric Roux committed
3507
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
3508
    LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA5;
Cedric Roux's avatar
Cedric Roux committed
3509
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
3510
  eventA5.a5_Threshold1.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
Cedric Roux's avatar
Cedric Roux committed
3511
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
3512
  eventA5.a5_Threshold2.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
Cedric Roux's avatar
Cedric Roux committed
3513 3514 3515 3516 3517
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
  eventA5.a5_Threshold1.choice.threshold_RSRP = 10;
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
  eventA5.a5_Threshold2.choice.threshold_RSRP = 10;
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
3518 3519
    LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
Cedric Roux's avatar
Cedric Roux committed
3520
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
3521 3522
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
Cedric Roux's avatar
Cedric Roux committed
3523
  ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A5);
3524
  //  LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list;
3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536

  /* A3 event update */
  if (!ue_context_pP->ue_context.measurement_info->events->a3_event) {
      ue_context_pP->ue_context.measurement_info->events->a3_event = CALLOC(1,sizeof(*(ue_context_pP->ue_context.measurement_info->events->a3_event)));
  }

  ue_context_pP->ue_context.measurement_info->events->a3_event->a3_offset = ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset;
  ue_context_pP->ue_context.measurement_info->events->a3_event->reportOnLeave = ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.reportOnLeave;
  ue_context_pP->ue_context.measurement_info->events->a3_event->hysteresis = ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis;
  ue_context_pP->ue_context.measurement_info->events->a3_event->timeToTrigger = ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger;
  ue_context_pP->ue_context.measurement_info->events->a3_event->maxReportCells = ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.maxReportCells;

3537 3538 3539 3540 3541 3542
#if 0
    /* TODO: set a proper value.
     * 20 means: UE does not report if RSRP of serving cell is higher
     * than -120 dB (see 36.331 5.5.3.1).
     * This is too low for the X2 handover experiment.
     */
3543
  rsrp = CALLOC(1, sizeof(LTE_RSRP_Range_t));
Cedric Roux's avatar
Cedric Roux committed
3544
  *rsrp = 20;
3545
#endif
Cedric Roux's avatar
Cedric Roux committed
3546
  Sparams = CALLOC(1, sizeof(*Sparams));
3547 3548 3549
  Sparams->present = LTE_MeasConfig__speedStatePars_PR_setup;
  Sparams->choice.setup.timeToTrigger_SF.sf_High = LTE_SpeedStateScaleFactors__sf_Medium_oDot75;
  Sparams->choice.setup.timeToTrigger_SF.sf_Medium = LTE_SpeedStateScaleFactors__sf_High_oDot5;
Cedric Roux's avatar
Cedric Roux committed
3550 3551
  Sparams->choice.setup.mobilityStateParameters.n_CellChangeHigh = 10;
  Sparams->choice.setup.mobilityStateParameters.n_CellChangeMedium = 5;
3552 3553
  Sparams->choice.setup.mobilityStateParameters.t_Evaluation = LTE_MobilityStateParameters__t_Evaluation_s60;
  Sparams->choice.setup.mobilityStateParameters.t_HystNormal = LTE_MobilityStateParameters__t_HystNormal_s120;
Cedric Roux's avatar
Cedric Roux committed
3554 3555
  quantityConfig = CALLOC(1, sizeof(*quantityConfig));
  memset((void *)quantityConfig, 0, sizeof(*quantityConfig));
3556
  quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(struct LTE_QuantityConfigEUTRA));
Cedric Roux's avatar
Cedric Roux committed
3557 3558 3559 3560 3561 3562 3563 3564
  memset((void *)quantityConfig->quantityConfigEUTRA, 0, sizeof(*quantityConfig->quantityConfigEUTRA));
  quantityConfig->quantityConfigCDMA2000 = NULL;
  quantityConfig->quantityConfigGERAN = NULL;
  quantityConfig->quantityConfigUTRA = NULL;
  quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP =
    CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP)));
  quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ =
    CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ)));
3565 3566
  *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = LTE_FilterCoefficient_fc4;
  *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = LTE_FilterCoefficient_fc4;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3567

3568 3569 3570
  ue_context_pP->ue_context.measurement_info->filterCoefficientRSRP = *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP;
  ue_context_pP->ue_context.measurement_info->filterCoefficientRSRQ = *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ;

3571
  /* Initialize NAS list */
3572
  dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList));
3573 3574

  /* Add all NAS PDUs to the list */
3575 3576
  for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) {
    if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) {
3577
      dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t));
3578
      memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3579 3580
      OCTET_STRING_fromBuf(dedicatedInfoNas,
                           (char *)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer,
3581
                           ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length);
3582
      ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas);
3583
    }
3584

3585 3586
    /* TODO parameters yet to process ... */
    {
3587 3588 3589
      //      ue_context_pP->ue_context.e_rab[i].param.qos;
      //      ue_context_pP->ue_context.e_rab[i].param.sgw_addr;
      //      ue_context_pP->ue_context.e_rab[i].param.gtp_teid;
3590
    }
3591 3592

    /* TODO should test if e RAB are OK before! */
3593
    ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3594 3595
    LOG_D(RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n",
          i, ue_context_pP->ue_context.e_rab[i].status, "E_RAB_STATUS_DONE");
3596
  }
3597 3598

  /* If list is empty free the list and reset the address */
3599 3600 3601
  if (dedicatedInfoNASList->list.count == 0) {
    free(dedicatedInfoNASList);
    dedicatedInfoNASList = NULL;
3602 3603
  }

3604 3605
  measurements_enabled = RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]->configuration.enable_x2 ||
                         RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]->configuration.enable_measurement_reports;
Cedric Roux's avatar
Cedric Roux committed
3606

3607
  memset(buffer, 0, RRC_BUF_SIZE);
3608

3609 3610
  size = do_RRCConnectionReconfiguration(ctxt_pP,
                                         buffer,
3611 3612 3613 3614 3615 3616
                                         xid, // Transaction_id,
                                         (LTE_SRB_ToAddModList_t *) *SRB_configList2, // SRB_configList
                                         (LTE_DRB_ToAddModList_t *) *DRB_configList,
                                         (LTE_DRB_ToReleaseList_t *) NULL, // DRB2_list,
                                         (struct LTE_SPS_Config *) NULL,   // *sps_Config,
                                         (struct LTE_PhysicalConfigDedicated *) *physicalConfigDedicated,
3617 3618 3619 3620
                                         measurements_enabled ? (LTE_MeasObjectToAddModList_t *) MeasObj_list : NULL,
                                         measurements_enabled ? (LTE_ReportConfigToAddModList_t *) ReportConfig_list : NULL,
                                         measurements_enabled ? (LTE_QuantityConfig_t *) quantityConfig : NULL,
                                         measurements_enabled ? (LTE_MeasIdToAddModList_t *) MeasId_list : NULL,
3621 3622 3623 3624 3625 3626 3627 3628 3629 3630
                                         (LTE_MAC_MainConfig_t *) mac_MainConfig,
                                         (LTE_MeasGapConfig_t *) NULL,
                                         (LTE_MobilityControlInfo_t *) NULL,
                                         (LTE_SecurityConfigHO_t *) NULL,
                                         (struct LTE_MeasConfig__speedStatePars *) Sparams,
                                         (LTE_RSRP_Range_t *) rsrp,
                                         (LTE_C_RNTI_t *) cba_RNTI,
                                         (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *) dedicatedInfoNASList,
                                         (LTE_SL_CommConfig_r12_t *) NULL,
                                         (LTE_SL_DiscConfig_r12_t *) NULL
3631
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
3632
                                         , (LTE_SCellToAddMod_r10_t *) NULL
3633 3634
#endif
                                        );
3635 3636

  LOG_DUMPMSG(RRC, DEBUG_RRC,(char *)buffer, size, "[MSG] RRC Connection Reconfiguration\n");
3637 3638 3639 3640 3641 3642 3643 3644 3645

  /* Free all NAS PDUs */
  for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) {
    if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) {
      /* Free the NAS PDU buffer and invalidate it */
      free(ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer);
      ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer = NULL;
    }
  }
3646

3647
  LOG_I(RRC, "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE id %x)\n",
3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678
        ctxt_pP->module_id, 
        ctxt_pP->frame, 
        size, 
        ue_context_pP->ue_context.rnti);

  LOG_D(RRC, "[FRAME %05d][RRC_eNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
        ctxt_pP->frame, 
        ctxt_pP->module_id, 
        size, 
        ue_context_pP->ue_context.rnti, 
        rrc_eNB_mui, 
        ctxt_pP->module_id, 
        DCCH);

  MSC_LOG_TX_MESSAGE(MSC_RRC_ENB,
                     MSC_RRC_UE,
                     buffer,
                     size,
                     MSC_AS_TIME_FMT" LTE_RRCConnectionReconfiguration UE %x MUI %d size %u",
                     MSC_AS_TIME_ARGS(ctxt_pP),
                     ue_context_pP->ue_context.rnti,
                     rrc_eNB_mui,
                     size);

  rrc_data_req(ctxt_pP,
               DCCH,
               rrc_eNB_mui++,
               SDU_CONFIRM_NO,
               size,
               buffer,
               PDCP_TRANSMISSION_MODE_CONTROL);
3679 3680 3681

  free(Sparams);
  Sparams = NULL;
3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693

  free(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP);
  quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = NULL;

  free(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ);
  quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = NULL;

  free(quantityConfig->quantityConfigEUTRA);
  quantityConfig->quantityConfigEUTRA = NULL;

  free(quantityConfig);
  quantityConfig = NULL;
3694
}
3695

3696 3697
//-----------------------------------------------------------------------------
void
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3698 3699
flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP,
    rrc_eNB_ue_context_t          *const ue_context_pP,
3700
    const uint8_t                ho_state)
3701
//-----------------------------------------------------------------------------
3702
{
3703 3704 3705 3706 3707 3708
  uint8_t   buffer[RRC_BUF_SIZE];
  uint16_t  size;
  int       i;

  /* Configure SRB1/SRB2, PhysicalConfigDedicated, LTE_MAC_MainConfig for UE */
  eNB_RRC_INST                           *rrc_inst = RC.rrc[ctxt_pP->module_id];
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3709
  struct LTE_PhysicalConfigDedicated    **physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated;
3710 3711 3712 3713
  struct LTE_SRB_ToAddMod                *SRB2_config                      = NULL;
  struct LTE_SRB_ToAddMod__rlc_Config    *SRB2_rlc_config                  = NULL;
  struct LTE_SRB_ToAddMod__logicalChannelConfig *SRB2_lchan_config         = NULL;
  struct LTE_LogicalChannelConfig__ul_SpecificParameters
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3714 3715
    *SRB2_ul_SpecificParameters       = NULL;
  LTE_SRB_ToAddModList_t                 *SRB_configList = ue_context_pP->ue_context.SRB_configList;
3716
  LTE_SRB_ToAddModList_t                 **SRB_configList2                 = NULL;
3717 3718 3719 3720 3721 3722 3723
  struct LTE_DRB_ToAddMod                *DRB_config                       = NULL;
  struct LTE_RLC_Config                  *DRB_rlc_config                   = NULL;
  struct LTE_PDCP_Config                 *DRB_pdcp_config                  = NULL;
  struct LTE_PDCP_Config__rlc_AM         *PDCP_rlc_AM                      = NULL;
  struct LTE_PDCP_Config__rlc_UM         *PDCP_rlc_UM                      = NULL;
  struct LTE_LogicalChannelConfig        *DRB_lchan_config                 = NULL;
  struct LTE_LogicalChannelConfig__ul_SpecificParameters
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3724 3725
    *DRB_ul_SpecificParameters        = NULL;
  LTE_DRB_ToAddModList_t                **DRB_configList = &ue_context_pP->ue_context.DRB_configList;
3726
  LTE_DRB_ToAddModList_t                **DRB_configList2                  = NULL;
3727 3728 3729 3730
  LTE_MAC_MainConfig_t                   *mac_MainConfig                   = NULL;
  LTE_MeasObjectToAddModList_t           *MeasObj_list                     = NULL;
  LTE_MeasObjectToAddMod_t               *MeasObj                          = NULL;
  LTE_ReportConfigToAddModList_t         *ReportConfig_list                = NULL;
3731 3732
  LTE_ReportConfigToAddMod_t             *ReportConfig_per, *ReportConfig_A1,
                                         *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5;
3733
  LTE_MeasIdToAddModList_t               *MeasId_list                      = NULL;
3734 3735 3736 3737
  LTE_MeasIdToAddMod_t                   *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5;

#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
  long                                   *sr_ProhibitTimer_r9              = NULL;
winckel's avatar
winckel committed
3738
#endif
3739 3740 3741 3742 3743

  long                                   *logicalchannelgroup              = NULL;
  long                                   *logicalchannelgroup_drb          = NULL;
  long                                   *maxHARQ_Tx                       = NULL;
  long                                   *periodicBSR_Timer                = NULL;
3744 3745 3746 3747 3748 3749 3750
  LTE_RSRP_Range_t                       *rsrp                             = NULL;
  struct LTE_MeasConfig__speedStatePars  *Sparams                          = NULL;
  LTE_QuantityConfig_t                   *quantityConfig                   = NULL;
  LTE_CellsToAddMod_t                    *CellToAdd                        = NULL;
  LTE_CellsToAddModList_t                *CellsToAddModList                = NULL;
  struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL;
  LTE_DedicatedInfoNAS_t                 *dedicatedInfoNas                 = NULL;
3751 3752 3753

  /* For no gcc warnings */
  (void) dedicatedInfoNas;
3754
  LTE_C_RNTI_t                           *cba_RNTI                         = NULL;
3755
  int                                    measurements_enabled;
3756
  uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id);   //Transaction_id,
3757 3758 3759 3760
  uint8_t cc_id = ue_context_pP->ue_context.primaryCC_id;
  LTE_UE_EUTRA_Capability_t *UEcap = ue_context_pP->ue_context.UE_Capability;

#ifdef CBA // Contention Based Access
3761
  uint8_t                            *cba_RNTI_buf;
3762
  cba_RNTI = CALLOC(1, sizeof(LTE_C_RNTI_t));
3763 3764 3765 3766 3767
  cba_RNTI_buf = CALLOC(1, 2 * sizeof(uint8_t));
  cba_RNTI->buf = cba_RNTI_buf;
  cba_RNTI->size = 2;
  cba_RNTI->bits_unused = 0;

3768
  /* Associate UEs to the CBA groups as a function of their UE id */
3769 3770 3771
  if (rrc_inst->num_active_cba_groups) {
    cba_RNTI->buf[0] = rrc_inst->cba_rnti[ue_mod_idP % rrc_inst->num_active_cba_groups] & 0xff;
    cba_RNTI->buf[1] = 0xff;
3772 3773 3774
    LOG_D(RRC, "[eNB %d] Frame %d: cba_RNTI = %x in group %d is attribued to UE %d\n",
          enb_mod_idP,
          frameP,
3775 3776 3777 3778 3779
          rrc_inst->cba_rnti[ue_mod_idP % rrc_inst->num_active_cba_groups],
          ue_mod_idP % rrc_inst->num_active_cba_groups, ue_mod_idP);
  } else {
    cba_RNTI->buf[0] = 0x0;
    cba_RNTI->buf[1] = 0x0;
3780 3781 3782 3783
    LOG_D(RRC, "[eNB %d] Frame %d: no cba_RNTI is configured for UE %d\n",
          enb_mod_idP,
          frameP,
          ue_mod_idP);
3784
  }
3785
#endif
3786 3787 3788 3789 3790 3791 3792 3793 3794

  T(T_ENB_RRC_CONNECTION_RECONFIGURATION,
    T_INT(ctxt_pP->module_id),
    T_INT(ctxt_pP->frame),
    T_INT(ctxt_pP->subframe),
    T_INT(ctxt_pP->rnti));

  /* Configure SRB2 */
  SRB_configList2 = &(ue_context_pP->ue_context.SRB_configList2[xid]);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3795

3796 3797 3798
  if (*SRB_configList2) {
    free(*SRB_configList2);
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3799

3800 3801
  *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
  memset(*SRB_configList2, 0, sizeof(**SRB_configList2));
3802 3803 3804 3805
  SRB2_config = CALLOC(1, sizeof(*SRB2_config));
  SRB2_config->srb_Identity = 2;
  SRB2_rlc_config = CALLOC(1, sizeof(*SRB2_rlc_config));
  SRB2_config->rlc_Config = SRB2_rlc_config;
3806 3807 3808 3809 3810 3811 3812 3813
  SRB2_rlc_config->present = LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue;
  SRB2_rlc_config->choice.explicitValue.present = LTE_RLC_Config_PR_am;
  SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms15;
  SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p8;
  SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kB1000;
  SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t32;
  SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35;
  SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms10;
3814 3815
  SRB2_lchan_config = CALLOC(1, sizeof(*SRB2_lchan_config));
  SRB2_config->logicalChannelConfig = SRB2_lchan_config;
3816
  SRB2_lchan_config->present = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue;
3817
  SRB2_ul_SpecificParameters = CALLOC(1, sizeof(*SRB2_ul_SpecificParameters));
3818
  SRB2_ul_SpecificParameters->priority = 3; // let some priority for SRB1 and dedicated DRBs
3819 3820 3821 3822
  SRB2_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
  SRB2_ul_SpecificParameters->bucketSizeDuration = LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;

  /* LCG for CCCH and DCCH is 0 as defined in 36331 */
3823 3824 3825 3826 3827
  logicalchannelgroup = CALLOC(1, sizeof(long));
  *logicalchannelgroup = 0;
  SRB2_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup;
  SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters = SRB2_ul_SpecificParameters;

3828 3829 3830 3831
  ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config); // this list has the configuration for SRB1 and SRB2
  ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config); // this list has only the configuration for SRB2

  /* Configure DRB */
3832
  // list for all the configured DRB
3833 3834 3835
  if (*DRB_configList) {
    free(*DRB_configList);
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3836

3837
  *DRB_configList = CALLOC(1, sizeof(**DRB_configList));
3838
  memset(*DRB_configList, 0, sizeof(**DRB_configList));
3839 3840

  DRB_configList2=&ue_context_pP->ue_context.DRB_configList2[xid]; // list for the configured DRB for a this xid
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3841

3842 3843 3844
  if (*DRB_configList2) {
    free(*DRB_configList2);
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3845

3846 3847
  *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
  memset(*DRB_configList2, 0, sizeof(**DRB_configList2));
3848

3849 3850 3851 3852
  DRB_config = CALLOC(1, sizeof(*DRB_config));
  DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long));
  *(DRB_config->eps_BearerIdentity) = 5L; // LW set to first value, allowed value 5..15, value : x+4
  // NN: this is the 1st DRB for this ue, so set it to 1
3853
  DRB_config->drb_Identity = (LTE_DRB_Identity_t) 1;  // (ue_mod_idP+1); //allowed values 1..32, value: x
3854 3855 3856 3857
  DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long));
  *(DRB_config->logicalChannelIdentity) = (long)3; // value : x+2
  DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config));
  DRB_config->rlc_Config = DRB_rlc_config;
3858

3859
#ifdef RRC_DEFAULT_RAB_IS_AM
3860 3861 3862 3863 3864 3865 3866
  DRB_rlc_config->present = LTE_RLC_Config_PR_am;
  DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms50;
  DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p16;
  DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity;
  DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8;
  DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35;
  DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms25;
3867
#else
3868 3869 3870
  DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional;
  DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10;
  DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10;
3871

3872
#ifdef CBA
3873
  DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering   = LTE_T_Reordering_ms5; //T_Reordering_ms25;
3874
#else
3875
  DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35;
3876
#endif
3877

3878
#endif
3879

3880 3881 3882
  DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config));
  DRB_config->pdcp_Config = DRB_pdcp_config;
  DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long));
3883
  *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity;
3884 3885
  DRB_pdcp_config->rlc_AM = NULL;
  DRB_pdcp_config->rlc_UM = NULL;
3886
  /* Avoid gcc warnings */
Cedric Roux's avatar
Cedric Roux committed
3887
  (void)PDCP_rlc_AM;
Cedric Roux's avatar
Cedric Roux committed
3888
  (void)PDCP_rlc_UM;
3889

3890
#ifdef RRC_DEFAULT_RAB_IS_AM // EXMIMO_IOT
3891 3892 3893
  PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM));
  DRB_pdcp_config->rlc_AM = PDCP_rlc_AM;
  PDCP_rlc_AM->statusReportRequired = FALSE;
3894
#else
3895 3896
  PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM));
  DRB_pdcp_config->rlc_UM = PDCP_rlc_UM;
3897
  PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits;
3898
#endif
3899

3900
  DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed;
3901 3902 3903 3904
  DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config));
  DRB_config->logicalChannelConfig = DRB_lchan_config;
  DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters));
  DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters;
3905 3906 3907
  DRB_ul_SpecificParameters->priority = 12; // lower priority than srb1, srb2 and other dedicated bearer
  DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8; // LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
  DRB_ul_SpecificParameters->bucketSizeDuration = LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
3908 3909 3910 3911
  // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM)
  logicalchannelgroup_drb = CALLOC(1, sizeof(long));
  *logicalchannelgroup_drb = 1;
  DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb;
3912

3913
  ASN_SEQUENCE_ADD(&(*DRB_configList)->list, DRB_config);
3914
  ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config);
3915 3916 3917

  /* MAC Main Config */
  // The different parts of MAC main config are set below
3918 3919 3920
  mac_MainConfig = CALLOC(1, sizeof(*mac_MainConfig));
  mac_MainConfig->ul_SCH_Config = CALLOC(1, sizeof(*mac_MainConfig->ul_SCH_Config));
  maxHARQ_Tx = CALLOC(1, sizeof(long));
3921
  *maxHARQ_Tx = LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5;
3922
  mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx;
3923 3924

  /* BSR reconfiguration */
3925
  periodicBSR_Timer = CALLOC(1, sizeof(long));
3926
  *periodicBSR_Timer = LTE_PeriodicBSR_Timer_r12_sf64; //LTE_PeriodicBSR_Timer_r12_infinity; // LTE_PeriodicBSR_Timer_r12_sf64; // LTE_PeriodicBSR_Timer_r12_sf20
3927
  mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer;
3928
  mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; // LTE_RetxBSR_Timer_r12_sf320; // LTE_RetxBSR_Timer_r12_sf5120
3929
  mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE
3930
  mac_MainConfig->timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_infinity;
3931 3932

  /* PHR reconfiguration */
3933
  mac_MainConfig->phr_Config = CALLOC(1, sizeof(*mac_MainConfig->phr_Config));
3934
  mac_MainConfig->phr_Config->present = LTE_MAC_MainConfig__phr_Config_PR_setup;
3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979
  mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf500; // sf20 = 20 subframes // LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_infinity
  mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf200; // sf20 = 20 subframes // LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf1000
  mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB3;  // Value dB1 =1 dB, dB3 = 3 dB

  if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
    /* CDRX Configuration */
    // Need to check if UE is a BR UE
    rnti_t rnti = ue_context_pP->ue_id_rnti;
    module_id_t module_id = ctxt_pP->module_id;
    int UE_id = find_UE_id(module_id, rnti);
    eNB_MAC_INST *mac = RC.mac[module_id];
    UE_list_t *UE_list = &(mac->UE_list);

    if (UE_id != -1) {
      if ((rrc_inst->carrier[cc_id].sib1->tdd_Config == NULL) &&
        (UE_list->UE_template[ue_context_pP->ue_context.primaryCC_id][UE_id].rach_resource_type == 0)) {
      // CDRX can be only configured in case of FDD and non BR UE (09/04/19)

      LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n");

      /* Process the IE drx_Config */
      if (cc_id < MAX_NUM_CCs) {
        mac_MainConfig->drx_Config = do_DrxConfig(module_id, cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE
      } else {
        LOG_E(RRC, "Invalid CC_id for DRX configuration\n");
      }

      /* Set timers and thresholds values in local MAC context of UE */
      eNB_Config_Local_DRX(module_id, ue_context_pP->ue_id_rnti, mac_MainConfig->drx_Config);

      LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n");

      } else { // CDRX not implemented for TDD and LTE-M (09/04/19)
        mac_MainConfig->drx_Config = NULL;
      }
    } else { // UE_id invalid
      LOG_E(RRC, "Invalid UE_id found!\n");
      mac_MainConfig->drx_Config = NULL;
    }
  } else { // No CDRX with the CU/DU split in this version
    LOG_E(RRC, "CU/DU split activated\n");
    mac_MainConfig->drx_Config = NULL;
  }

#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
3980
  sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long));
3981
  *sr_ProhibitTimer_r9 = 0;   // SR tx on PUCCH, Value in number of SR period(s). Value 0 = no timer for SR, Value 2 = 2*SR
3982
  mac_MainConfig->ext1 = CALLOC(1, sizeof(struct LTE_MAC_MainConfig__ext1));
3983
  mac_MainConfig->ext1->sr_ProhibitTimer_r9 = sr_ProhibitTimer_r9;
3984 3985
#endif

3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000
  // free the old LTE_MAC_MainConfig_t: get a pointer to "old" memory, assign
  // the new values in the ue_context, then free it
  // Note: can not completely avoid race condition with FlexRAN
  LTE_MAC_MainConfig_t *old_mac_MainConfig = ue_context_pP->ue_context.mac_MainConfig;
  ue_context_pP->ue_context.mac_MainConfig = mac_MainConfig;
  free(old_mac_MainConfig->ul_SCH_Config->periodicBSR_Timer);
  free(old_mac_MainConfig->ul_SCH_Config->maxHARQ_Tx);
  free(old_mac_MainConfig->ul_SCH_Config);
  free(old_mac_MainConfig->phr_Config);
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
  free(old_mac_MainConfig->ext1->sr_ProhibitTimer_r9);
  free(old_mac_MainConfig->ext1);
#endif
  free(old_mac_MainConfig);

4001 4002 4003
  // change the transmission mode for the primary component carrier
  // TODO: add codebook subset restriction here
  // TODO: change TM for secondary CC in SCelltoaddmodlist
4004
  if (*physicalConfigDedicated) {
4005
    if ((*physicalConfigDedicated)->antennaInfo) {
4006 4007
      (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.transmissionMode = rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode;
      LOG_D(RRC,"Setting transmission mode to %ld+1\n",rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode);
4008

4009
      if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm3) {
4010
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
4011 4012 4013 4014 4015 4016 4017 4018
	  CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
	  LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm3;
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf= MALLOC(1);
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf[0] = 0xc0;
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.size=1;
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.bits_unused=6;
      } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm4) {
4019
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
4020 4021 4022 4023 4024 4025 4026
	  CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
	  LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm4;
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf= MALLOC(1);
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf[0] = 0xfc;
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.size=1;
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.bits_unused=2;
4027
      } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm5) {
4028
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
4029 4030 4031 4032 4033 4034 4035
	  CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
	  LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm5;
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf= MALLOC(1);
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf[0] = 0xf0;
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.size=1;
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.bits_unused=4;
4036
      } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm6) {
4037
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
4038 4039 4040 4041 4042 4043 4044
	  CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
	  LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm6;
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf= MALLOC(1);
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf[0] = 0xf0;
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.size=1;
	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.bits_unused=4;
4045
      }
4046
    } else {
4047 4048
      LOG_E(RRC,"antenna_info not present in physical_config_dedicated. Not reconfiguring!\n");
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4049

4050
    /* CSI RRC Reconfiguration */
4051 4052 4053 4054
    if ((*physicalConfigDedicated)->cqi_ReportConfig != NULL) {
      if ((rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode == LTE_AntennaInfoDedicated__transmissionMode_tm4) ||
          (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode == LTE_AntennaInfoDedicated__transmissionMode_tm5) ||
          (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode == LTE_AntennaInfoDedicated__transmissionMode_tm6)) {
4055 4056 4057 4058

        // feedback mode needs to be set as well
	      // TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable
        LOG_I(RRC, "Setting cqi reporting mode to rm31 (hardcoded)\n");
4059

4060
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
4061
        *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic) = LTE_CQI_ReportModeAperiodic_rm31; // HLC CQI, single PMI
4062
#else
4063
        *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic) = LTE_CQI_ReportConfig__cqi_ReportModeAperiodic_rm31; // HLC CQI, single PMI
4064 4065
#endif
      }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4066
    } else {
4067 4068
      LOG_E(RRC,"cqi_ReportConfig not present in physical_config_dedicated. Not reconfiguring!\n");
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4069
  } else {
4070
    LOG_E(RRC,"physical_config_dedicated not present in LTE_RRCConnectionReconfiguration. Not reconfiguring!\n");
4071
  }
4072

4073 4074 4075 4076 4077 4078 4079 4080
  // Measurement ID list
  MeasId_list = CALLOC(1, sizeof(*MeasId_list));
  memset((void *)MeasId_list, 0, sizeof(*MeasId_list));
  MeasId0 = CALLOC(1, sizeof(*MeasId0));
  MeasId0->measId = 1;
  MeasId0->measObjectId = 1;
  MeasId0->reportConfigId = 1;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId0);
4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107
  MeasId1 = CALLOC(1, sizeof(*MeasId1));
  MeasId1->measId = 2;
  MeasId1->measObjectId = 1;
  MeasId1->reportConfigId = 2;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId1);
  MeasId2 = CALLOC(1, sizeof(*MeasId2));
  MeasId2->measId = 3;
  MeasId2->measObjectId = 1;
  MeasId2->reportConfigId = 3;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId2);
  MeasId3 = CALLOC(1, sizeof(*MeasId3));
  MeasId3->measId = 4;
  MeasId3->measObjectId = 1;
  MeasId3->reportConfigId = 4;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId3);
  MeasId4 = CALLOC(1, sizeof(*MeasId4));
  MeasId4->measId = 5;
  MeasId4->measObjectId = 1;
  MeasId4->reportConfigId = 5;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId4);
  MeasId5 = CALLOC(1, sizeof(*MeasId5));
  MeasId5->measId = 6;
  MeasId5->measObjectId = 1;
  MeasId5->reportConfigId = 6;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId5);
  //  LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measIdToAddModList = MeasId_list;
  // Add one EUTRA Measurement Object
4108 4109
  MeasObj_list = CALLOC(1, sizeof(*MeasObj_list));
  memset((void *)MeasObj_list, 0, sizeof(*MeasObj_list));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4110
  // Configure MeasObject
4111 4112 4113
  MeasObj = CALLOC(1, sizeof(*MeasObj));
  memset((void *)MeasObj, 0, sizeof(*MeasObj));
  MeasObj->measObjectId = 1;
4114
  MeasObj->measObject.present = LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA;
4115 4116 4117 4118
  MeasObj->measObject.choice.measObjectEUTRA.carrierFreq =
      to_earfcn_DL(RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0],
                   RC.rrc[ctxt_pP->module_id]->configuration.downlink_frequency[0],
                   RC.rrc[ctxt_pP->module_id]->configuration.N_RB_DL[0]);
4119
  MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = LTE_AllowedMeasBandwidth_mbw25;
4120 4121 4122 4123 4124
  MeasObj->measObject.choice.measObjectEUTRA.presenceAntennaPort1 = 1;
  MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf = CALLOC(1, sizeof(uint8_t));
  MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf[0] = 0;
  MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.size = 1;
  MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.bits_unused = 6;
4125
//<<<<<<< HEAD
4126
  MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = NULL;   // Default is 15 or 0dB
wujing's avatar
wujing committed
4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151
  if (rrc_inst->carrier[0].sib1->tdd_Config!=NULL) {
    MeasObj->measObject.choice.measObjectEUTRA.ext1 = CALLOC(1, sizeof(struct LTE_MeasObjectEUTRA__ext1));
    MeasObj->measObject.choice.measObjectEUTRA.ext1->measCycleSCell_r10 = NULL;
    MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10 = CALLOC(1, sizeof(struct LTE_MeasSubframePatternConfigNeigh_r10));
    MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->present=LTE_MeasSubframePatternConfigNeigh_r10_PR_setup;
    MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.present=LTE_MeasSubframePattern_r10_PR_subframePatternTDD_r10;
    MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.present=LTE_MeasSubframePattern_r10__subframePatternTDD_r10_PR_subframeConfig1_5_r10;
    MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf=CALLOC(3, sizeof(uint8_t));
    MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.size=3;
    MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.bits_unused=4; 
    switch (rrc_inst->carrier[0].sib1->tdd_Config->subframeAssignment) {
    case 1: //subframe 0,4,5,9
      MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[0]=0x8C;
      MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[1]=0x63;
      MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[2]=0x10;
      break;

    default: //subframe 0 , 5
      MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[0]=0x84;
      MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[1]=0x21;
      MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[2]=0x00;
      break;
    }
  }

4152
  MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList =
4153
    (LTE_CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList));
4154
  CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList;
4155 4156 4157 4158
//=======
//  MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = (LTE_Q_OffsetRange_t *) CALLOC(1,sizeof(LTE_Q_OffsetRange_t));
//  *(MeasObj->measObject.choice.measObjectEUTRA.offsetFreq) = ue_context_pP->ue_context.measurement_info->offsetFreq;   // Default is 15 or 0dB
//>>>>>>> origin/OAI_develop
4159

4160 4161 4162 4163 4164 4165 4166 4167 4168
  if (RC.rrc[ctxt_pP->module_id]->num_neigh_cells > 0) {
    MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList =
      (LTE_CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList));
    CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList;
  }

  /* TODO: Extend to multiple carriers */
  // Add adjacent cell lists (max 6 per eNB)
  for (i = 0; i < RC.rrc[ctxt_pP->module_id]->num_neigh_cells; i++) {
4169
    CellToAdd = (LTE_CellsToAddMod_t *) CALLOC(1, sizeof(*CellToAdd));
4170
    CellToAdd->cellIndex = i + 1;
4171 4172
    CellToAdd->physCellId = RC.rrc[ctxt_pP->module_id]->neigh_cells_id[i][0];//get_adjacent_cell_id(ctxt_pP->module_id, i);
    CellToAdd->cellIndividualOffset = ue_context_pP->ue_context.measurement_info->cellIndividualOffset[i+1];
4173 4174 4175
    ASN_SEQUENCE_ADD(&CellsToAddModList->list, CellToAdd);
  }
  ASN_SEQUENCE_ADD(&MeasObj_list->list, MeasObj);
4176
  //  LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measObjectToAddModList = MeasObj_list;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
4177

4178
  // Report Configurations for periodical, A1-A5 events
4179 4180
  ReportConfig_list = CALLOC(1, sizeof(*ReportConfig_list));
  ReportConfig_per = CALLOC(1, sizeof(*ReportConfig_per));
4181 4182 4183 4184 4185
  ReportConfig_A1 = CALLOC(1, sizeof(*ReportConfig_A1));
  ReportConfig_A2 = CALLOC(1, sizeof(*ReportConfig_A2));
  ReportConfig_A3 = CALLOC(1, sizeof(*ReportConfig_A3));
  ReportConfig_A4 = CALLOC(1, sizeof(*ReportConfig_A4));
  ReportConfig_A5 = CALLOC(1, sizeof(*ReportConfig_A5));
4186
  ReportConfig_per->reportConfigId = 1;
4187
  ReportConfig_per->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4188 4189 4190 4191 4192 4193 4194
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.present =
    LTE_ReportConfigEUTRA__triggerType_PR_periodical;
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.choice.periodical.purpose =
    LTE_ReportConfigEUTRA__triggerType__periodical__purpose_reportStrongestCells;
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
4195 4196
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
4197
  ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_per);
4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291
  ReportConfig_A1->reportConfigId = 2;
  ReportConfig_A1->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.present =
    LTE_ReportConfigEUTRA__triggerType_PR_event;
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
    LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1;
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA1.
  a1_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA1.
  a1_Threshold.choice.threshold_RSRP = 10;
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
  ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A1);
  //if (ho_state == 1 /*HO_MEASURMENT */ ) {
  LOG_I(RRC, "[eNB %d] frame %d: requesting A2, A3, A4, and A5 event reporting\n",
        ctxt_pP->module_id, ctxt_pP->frame);
  ReportConfig_A2->reportConfigId = 3;
  ReportConfig_A2->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.present =
    LTE_ReportConfigEUTRA__triggerType_PR_event;
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
    LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2;
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
  eventA2.a2_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
  eventA2.a2_Threshold.choice.threshold_RSRP = 10;
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
    LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
  ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A2);
  ReportConfig_A3->reportConfigId = 4;
  ReportConfig_A3->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.present =
    LTE_ReportConfigEUTRA__triggerType_PR_event;
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
    LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3;
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset = ue_context_pP->ue_context.measurement_info->events->a3_event->a3_offset;//10;
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
  eventA3.reportOnLeave = ue_context_pP->ue_context.measurement_info->events->a3_event->reportOnLeave;
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
    LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.maxReportCells = ue_context_pP->ue_context.measurement_info->events->a3_event->maxReportCells;
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis = ue_context_pP->ue_context.measurement_info->events->a3_event->hysteresis;
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger =
    ue_context_pP->ue_context.measurement_info->events->a3_event->timeToTrigger;
  ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A3);
  ReportConfig_A4->reportConfigId = 5;
  ReportConfig_A4->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.present =
    LTE_ReportConfigEUTRA__triggerType_PR_event;
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
    LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4;
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
  eventA4.a4_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
  eventA4.a4_Threshold.choice.threshold_RSRP = 10;
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
    LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
  ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A4);
  ReportConfig_A5->reportConfigId = 6;
  ReportConfig_A5->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.present =
    LTE_ReportConfigEUTRA__triggerType_PR_event;
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
    LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA5;
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
  eventA5.a5_Threshold1.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
  eventA5.a5_Threshold2.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
  eventA5.a5_Threshold1.choice.threshold_RSRP = 10;
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
  eventA5.a5_Threshold2.choice.threshold_RSRP = 10;
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
    LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
  ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A5);
  //  LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list;
4292

4293 4294 4295 4296 4297 4298
#if 0
    /* TODO: set a proper value.
     * 20 means: UE does not report if RSRP of serving cell is higher
     * than -120 dB (see 36.331 5.5.3.1).
     * This is too low for the X2 handover experiment.
     */
4299 4300
  rsrp = CALLOC(1, sizeof(LTE_RSRP_Range_t));
  *rsrp = 20;
4301
#endif
4302 4303 4304 4305 4306 4307 4308 4309
  Sparams = CALLOC(1, sizeof(*Sparams));
  Sparams->present = LTE_MeasConfig__speedStatePars_PR_setup;
  Sparams->choice.setup.timeToTrigger_SF.sf_High = LTE_SpeedStateScaleFactors__sf_Medium_oDot75;
  Sparams->choice.setup.timeToTrigger_SF.sf_Medium = LTE_SpeedStateScaleFactors__sf_High_oDot5;
  Sparams->choice.setup.mobilityStateParameters.n_CellChangeHigh = 10;
  Sparams->choice.setup.mobilityStateParameters.n_CellChangeMedium = 5;
  Sparams->choice.setup.mobilityStateParameters.t_Evaluation = LTE_MobilityStateParameters__t_Evaluation_s60;
  Sparams->choice.setup.mobilityStateParameters.t_HystNormal = LTE_MobilityStateParameters__t_HystNormal_s120;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320
  quantityConfig = CALLOC(1, sizeof(*quantityConfig));
  memset((void *)quantityConfig, 0, sizeof(*quantityConfig));
  quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(struct LTE_QuantityConfigEUTRA));
  memset((void *)quantityConfig->quantityConfigEUTRA, 0, sizeof(*quantityConfig->quantityConfigEUTRA));
  quantityConfig->quantityConfigCDMA2000 = NULL;
  quantityConfig->quantityConfigGERAN = NULL;
  quantityConfig->quantityConfigUTRA = NULL;
  quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP =
    CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP)));
  quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ =
    CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ)));
4321 4322 4323
  *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = ue_context_pP->ue_context.measurement_info->filterCoefficientRSRP;
  *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = ue_context_pP->ue_context.measurement_info->filterCoefficientRSRQ;

4324
  /* Initialize NAS list */
4325
  dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList));
4326 4327

  /* Add all NAS PDUs to the list */
4328 4329
  for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) {
    if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) {
4330
      dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t));
4331
      memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4332 4333
      OCTET_STRING_fromBuf(dedicatedInfoNas,
                           (char *)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer,
4334
                           ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length);
4335
      ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas);
4336
    }
4337

4338
    /* TODO parameters yet to process ... */
4339 4340 4341 4342 4343 4344 4345
    {
      //      ue_context_pP->ue_context.e_rab[i].param.qos;
      //      ue_context_pP->ue_context.e_rab[i].param.sgw_addr;
      //      ue_context_pP->ue_context.e_rab[i].param.gtp_teid;
    }

    /* TODO should test if e RAB are OK before! */
4346
    ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4347 4348
    LOG_D(RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n",
          i, ue_context_pP->ue_context.e_rab[i].status, "E_RAB_STATUS_DONE");
4349 4350 4351 4352 4353 4354 4355 4356
  }

  /* If list is empty free the list and reset the address */
  if (dedicatedInfoNASList->list.count == 0) {
    free(dedicatedInfoNASList);
    dedicatedInfoNASList = NULL;
  }

4357 4358
  measurements_enabled = RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]->configuration.enable_x2 ||
                         RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]->configuration.enable_measurement_reports;
Cedric Roux's avatar
Cedric Roux committed
4359

4360
  memset(buffer, 0, RRC_BUF_SIZE);
4361

4362 4363
  size = do_RRCConnectionReconfiguration(ctxt_pP,
                                         buffer,
4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383
                                         xid, // Transaction_id,
                                         (LTE_SRB_ToAddModList_t *) *SRB_configList2, // SRB_configList
                                         (LTE_DRB_ToAddModList_t *) *DRB_configList,
                                         (LTE_DRB_ToReleaseList_t *) NULL, // DRB2_list,
                                         (struct LTE_SPS_Config *) NULL,   // *sps_Config,
                                         (struct LTE_PhysicalConfigDedicated *) *physicalConfigDedicated,
                                         measurements_enabled ? (LTE_MeasObjectToAddModList_t *) MeasObj_list : NULL,
                                         measurements_enabled ? (LTE_ReportConfigToAddModList_t *) ReportConfig_list : NULL,
                                         measurements_enabled ? (LTE_QuantityConfig_t *) quantityConfig : NULL,
                                         measurements_enabled ? (LTE_MeasIdToAddModList_t *) MeasId_list : NULL,
                                         (LTE_MAC_MainConfig_t *) mac_MainConfig,
                                         (LTE_MeasGapConfig_t *) NULL,
                                         (LTE_MobilityControlInfo_t *) NULL,
                                         (LTE_SecurityConfigHO_t *) NULL,
                                         (struct LTE_MeasConfig__speedStatePars *) Sparams,
                                         (LTE_RSRP_Range_t *) rsrp,
                                         (LTE_C_RNTI_t *) cba_RNTI,
                                         (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *) dedicatedInfoNASList,
                                         (LTE_SL_CommConfig_r12_t *) NULL,
                                         (LTE_SL_DiscConfig_r12_t *) NULL
4384
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
4385
                                         , (LTE_SCellToAddMod_r10_t *) NULL
4386
#endif
4387
                                        );
4388 4389

  LOG_DUMPMSG(RRC, DEBUG_RRC,(char *)buffer, size, "[MSG] RRC Connection Reconfiguration\n");
4390 4391

  /* Free all NAS PDUs */
4392 4393
  for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) {
    if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) {
4394
      /* Free the NAS PDU buffer and invalidate it */
4395 4396
      free(ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer);
      ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer = NULL;
4397
    }
4398 4399
  }

4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431
  LOG_I(RRC, "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE id %x)\n",
        ctxt_pP->module_id,
        ctxt_pP->frame,
        size,
        ue_context_pP->ue_context.rnti);

  LOG_D(RRC, "[FRAME %05d][RRC_eNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
        ctxt_pP->frame,
        ctxt_pP->module_id,
        size,
        ue_context_pP->ue_context.rnti,
        rrc_eNB_mui,
        ctxt_pP->module_id,
        DCCH);

  MSC_LOG_TX_MESSAGE(MSC_RRC_ENB,
                     MSC_RRC_UE,
                     buffer,
                     size,
                     MSC_AS_TIME_FMT" LTE_RRCConnectionReconfiguration UE %x MUI %d size %u",
                     MSC_AS_TIME_ARGS(ctxt_pP),
                     ue_context_pP->ue_context.rnti,
                     rrc_eNB_mui,
                     size);

  rrc_data_req(ctxt_pP,
               DCCH,
               rrc_eNB_mui++,
               SDU_CONFIRM_NO,
               size,
               buffer,
               PDCP_TRANSMISSION_MODE_CONTROL);
4432

4433 4434 4435 4436 4437 4438 4439 4440 4441
  free(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ);
  quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = NULL;

  free(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP);
  quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = NULL;

  free(quantityConfig->quantityConfigEUTRA);
  quantityConfig->quantityConfigEUTRA = NULL;

4442 4443
  free(quantityConfig);
  quantityConfig = NULL;
winckel's avatar
winckel committed
4444
}
4445

4446 4447 4448
//-----------------------------------------------------------------------------
int
rrc_eNB_generate_RRCConnectionReconfiguration_SCell(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4449 4450
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t *const ue_context_pP,
4451 4452 4453
  uint32_t dl_CarrierFreq_r10
)
//-----------------------------------------------------------------------------
4454
{
4455 4456
  uint8_t size;
  uint8_t buffer[100];
4457
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
4458
  uint8_t sCellIndexToAdd = 0; //one SCell so far
4459 4460 4461

  //   uint8_t sCellIndexToAdd;
  //   sCellIndexToAdd = rrc_find_free_SCell_index(enb_mod_idP, ue_mod_idP, 1);
4462
  //  if (RC.rrc[enb_mod_idP]->sCell_config[ue_mod_idP][sCellIndexToAdd] ) {
4463 4464
  if (ue_context_pP->ue_context.sCell_config != NULL) {
    ue_context_pP->ue_context.sCell_config[sCellIndexToAdd].cellIdentification_r10->dl_CarrierFreq_r10 = dl_CarrierFreq_r10;
4465
  } else {
4466 4467
    LOG_E(RRC,"Scell not configured!\n");
    return(-1);
4468 4469
  }

4470
#endif
4471
  size = do_RRCConnectionReconfiguration(ctxt_pP,
4472
                                         buffer,
4473
                                         rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),//Transaction_id,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485
                                         (LTE_SRB_ToAddModList_t *)NULL,
                                         (LTE_DRB_ToAddModList_t *)NULL,
                                         (LTE_DRB_ToReleaseList_t *)NULL,
                                         (struct LTE_SPS_Config *)NULL,
                                         (struct LTE_PhysicalConfigDedicated *)NULL,
                                         (LTE_MeasObjectToAddModList_t *)NULL,
                                         (LTE_ReportConfigToAddModList_t *)NULL,
                                         (LTE_QuantityConfig_t *)NULL,
                                         (LTE_MeasIdToAddModList_t *)NULL,
                                         (LTE_MAC_MainConfig_t *)NULL,
                                         (LTE_MeasGapConfig_t *)NULL,
                                         (LTE_MobilityControlInfo_t *)NULL,
4486
                                         (LTE_SecurityConfigHO_t *)NULL,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4487 4488 4489 4490 4491 4492
                                         (struct LTE_MeasConfig__speedStatePars *)NULL,
                                         (LTE_RSRP_Range_t *)NULL,
                                         (LTE_C_RNTI_t *)NULL,
                                         (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)NULL,
                                         (LTE_SL_CommConfig_r12_t *)NULL,
                                         (LTE_SL_DiscConfig_r12_t *)NULL
4493
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
4494
                                         , ue_context_pP->ue_context.sCell_config
4495
#endif
4496
                                        );
4497
  LOG_I(RRC,"[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE id %x)\n",
4498
        ctxt_pP->module_id,ctxt_pP->frame, size, ue_context_pP->ue_context.rnti);
4499
  MSC_LOG_TX_MESSAGE(
4500 4501 4502 4503
    MSC_RRC_ENB,
    MSC_RRC_UE,
    buffer,
    size,
4504
    MSC_AS_TIME_FMT" LTE_RRCConnectionReconfiguration UE %x MUI %d size %u",
4505 4506 4507 4508
    MSC_AS_TIME_ARGS(ctxt_pP),
    ue_context_pP->ue_context.rnti,
    rrc_eNB_mui,
    size);
4509
  rrc_data_req(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4510 4511 4512 4513 4514 4515 4516
    ctxt_pP,
    DCCH,
    rrc_eNB_mui++,
    SDU_CONFIRM_NO,
    size,
    buffer,
    PDCP_TRANSMISSION_MODE_CONTROL);
4517 4518 4519 4520
  return(0);
}


4521 4522 4523
//-----------------------------------------------------------------------------
void
rrc_eNB_process_MeasurementReport(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4524 4525 4526
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t         *ue_context_pP,
  const LTE_MeasResults_t   *const measResults2
4527 4528
)
//-----------------------------------------------------------------------------
4529
{
4530 4531
  int i=0;
  int neighboring_cells=-1;
4532 4533
  int ncell_index = 0;
  long ncell_max = -150;
4534 4535 4536
  uint32_t earfcn_dl;
  uint8_t KeNB_star[32] = { 0 };

Cedric Roux's avatar
Cedric Roux committed
4537 4538 4539
  T(T_ENB_RRC_MEASUREMENT_REPORT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
    T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));

4540 4541
  if (measResults2 == NULL )
    return;
4542

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4543 4544 4545 4546
  if (measResults2->measId > 0 ) {
    if (ue_context_pP->ue_context.measResults == NULL) {
      ue_context_pP->ue_context.measResults = CALLOC(1, sizeof(LTE_MeasResults_t));
    }
4547

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4548
    ue_context_pP->ue_context.measResults->measId=measResults2->measId;
Cedric Roux's avatar
Cedric Roux committed
4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580

    switch (measResults2->measId) {
      case 1:
        LOG_D(RRC,"Periodic report at frame %d and subframe %d \n", ctxt_pP->frame, ctxt_pP->subframe);
        break;

      case 2:
        LOG_D(RRC,"A1 event report (Serving becomes better than absolute threshold) at frame %d and subframe %d \n", ctxt_pP->frame, ctxt_pP->subframe);
        break;

      case 3:
        LOG_D(RRC,"A2 event report (Serving becomes worse than absolute threshold) at frame %d and subframe %d \n", ctxt_pP->frame, ctxt_pP->subframe);
        break;

      case 4:
        LOG_D(RRC,"A3 event report (Neighbour becomes amount of offset better than PCell) at frame %d and subframe %d \n", ctxt_pP->frame, ctxt_pP->subframe);
        break;

      case 5:
        LOG_D(RRC,"A4 event report (Neighbour becomes better than absolute threshold) at frame %d and subframe %d \n", ctxt_pP->frame, ctxt_pP->subframe);
        break;

      case 6:
        LOG_D(RRC,"A5 event report (PCell becomes worse than absolute threshold1 AND Neighbour becomes better than another absolute threshold2) at frame %d and subframe %d \n", ctxt_pP->frame,
              ctxt_pP->subframe);
        break;

      default:
        LOG_D(RRC,"Other event report frame %d and subframe %d \n", ctxt_pP->frame, ctxt_pP->subframe);
        break;
    }

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595
    ue_context_pP->ue_context.measResults->measResultPCell.rsrpResult=measResults2->measResultPCell.rsrpResult;
    ue_context_pP->ue_context.measResults->measResultPCell.rsrqResult=measResults2->measResultPCell.rsrqResult;
    LOG_D(RRC, "[eNB %d]Frame %d: UE %x (Measurement Id %d): RSRP of Source %ld\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rnti, (int)measResults2->measId,
          ue_context_pP->ue_context.measResults->measResultPCell.rsrpResult-140);
    LOG_D(RRC, "[eNB %d]Frame %d: UE %x (Measurement Id %d): RSRQ of Source %ld\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rnti, (int)measResults2->measId,
          ue_context_pP->ue_context.measResults->measResultPCell.rsrqResult/2 - 20);
  }

  if (measResults2->measResultNeighCells == NULL)
    return;

  if (measResults2->measResultNeighCells->choice.measResultListEUTRA.list.count > 0) {
    neighboring_cells = measResults2->measResultNeighCells->choice.measResultListEUTRA.list.count;

    if (ue_context_pP->ue_context.measResults->measResultNeighCells == NULL) {
Cedric Roux's avatar
Cedric Roux committed
4596
      ue_context_pP->ue_context.measResults->measResultNeighCells = CALLOC(1, sizeof(*ue_context_pP->ue_context.measResults->measResultNeighCells));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4597
    }
4598

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4599
    for (i=0; i < neighboring_cells; i++) {
Cedric Roux's avatar
Cedric Roux committed
4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610
      if (i>=ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count) {
        //printf("NeighCells number: %d \n", ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count);
        ASN_SEQUENCE_ADD(&ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list,measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i]);
      }

      ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->physCellId =
        measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->physCellId;
      ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult =
        measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult;
      ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrqResult =
        measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrqResult;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4611 4612
      LOG_D(RRC, "Physical Cell Id %d\n",
            (int)ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->physCellId);
Cedric Roux's avatar
Cedric Roux committed
4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630
      LOG_D(RRC, "RSRP of Target %ld\n",
            (*ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult)-140);
      LOG_D(RRC, "RSRQ of Target %ld\n",
            (*ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrqResult)/2 - 20);

      if ( *measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult >= ncell_max ) {
        ncell_max = *measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult;
        ncell_index = i;
      }

      //LOG_D(RRC, "Physical Cell Id2 %d\n",
      //(int)measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->physCellId);
      //LOG_D(RRC, "RSRP of Target2 %ld\n",
      //(*(measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->
      //measResult.rsrpResult))-140);
      //LOG_D(RRC, "RSRQ of Target2 %ld\n",
      //(*(measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->
      //measResult.rsrqResult))/2 - 20);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4631 4632 4633
    }
  }

4634 4635 4636
  /* Decide whether to trigger HO or not */
  if (!(measResults2->measId == 4))
    return;
Cedric Roux's avatar
Cedric Roux committed
4637

Cedric Roux's avatar
Cedric Roux committed
4638
  /* if X2AP is disabled, do nothing */
4639
  if (!RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]->configuration.enable_x2)
Cedric Roux's avatar
Cedric Roux committed
4640 4641
    return;

4642 4643 4644
  if (RC.rrc[ctxt_pP->module_id]->x2_ho_net_control)
    return;

4645
  LOG_D(RRC, "A3 event is triggered...\n");
4646

4647 4648 4649 4650 4651 4652 4653
  /* if the UE is not in handover mode, start handover procedure */
  if (ue_context_pP->ue_context.Status != RRC_HO_EXECUTION) {
    MessageDef      *msg;
    LOG_I(RRC, "Send HO preparation message at frame %d and subframe %d \n", ctxt_pP->frame, ctxt_pP->subframe);
    /* HO info struct may not be needed anymore */
    ue_context_pP->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_pP->ue_context.handover_info)));
    ue_context_pP->ue_context.Status = RRC_HO_EXECUTION;
luaihui's avatar
luaihui committed
4654

4655
    ue_context_pP->ue_context.handover_info->state = HO_REQUEST;
luaihui's avatar
luaihui committed
4656

4657 4658 4659
    /* HO Preparation message */
    msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_HANDOVER_REQ);
    rrc_eNB_generate_HandoverPreparationInformation(
Cedric Roux's avatar
Cedric Roux committed
4660 4661 4662
      ue_context_pP,
      X2AP_HANDOVER_REQ(msg).rrc_buffer,
      &X2AP_HANDOVER_REQ(msg).rrc_buffer_size);
4663
    X2AP_HANDOVER_REQ(msg).rnti = ctxt_pP->rnti;
4664
    X2AP_HANDOVER_REQ(msg).target_physCellId = measResults2->measResultNeighCells->choice.
Cedric Roux's avatar
Cedric Roux committed
4665
        measResultListEUTRA.list.array[ncell_index]->physCellId;
4666 4667 4668 4669 4670 4671 4672 4673
    X2AP_HANDOVER_REQ(msg).ue_gummei.mcc = ue_context_pP->ue_context.ue_gummei.mcc;
    X2AP_HANDOVER_REQ(msg).ue_gummei.mnc = ue_context_pP->ue_context.ue_gummei.mnc;
    X2AP_HANDOVER_REQ(msg).ue_gummei.mnc_len = ue_context_pP->ue_context.ue_gummei.mnc_len;
    X2AP_HANDOVER_REQ(msg).ue_gummei.mme_code = ue_context_pP->ue_context.ue_gummei.mme_code;
    X2AP_HANDOVER_REQ(msg).ue_gummei.mme_group_id = ue_context_pP->ue_context.ue_gummei.mme_group_id;
    // Don't know how to get this ID?
    X2AP_HANDOVER_REQ(msg).mme_ue_s1ap_id = ue_context_pP->ue_context.mme_ue_s1ap_id;
    X2AP_HANDOVER_REQ(msg).security_capabilities = ue_context_pP->ue_context.security_capabilities;
4674 4675 4676 4677 4678
    // compute keNB*
    earfcn_dl = (uint32_t)to_earfcn_DL(RC.rrc[ctxt_pP->module_id]->carrier[0].eutra_band, RC.rrc[ctxt_pP->module_id]->carrier[0].dl_CarrierFreq,
    RC.rrc[ctxt_pP->module_id]->carrier[0].N_RB_DL);
    derive_keNB_star(ue_context_pP->ue_context.kenb, X2AP_HANDOVER_REQ(msg).target_physCellId, earfcn_dl, true, KeNB_star);
    memcpy(X2AP_HANDOVER_REQ(msg).kenb, KeNB_star, 32);
4679 4680 4681 4682
    X2AP_HANDOVER_REQ(msg).kenb_ncc = ue_context_pP->ue_context.kenb_ncc;
    //X2AP_HANDOVER_REQ(msg).ue_ambr=ue_context_pP->ue_context.ue_ambr;
    X2AP_HANDOVER_REQ(msg).nb_e_rabs_tobesetup = ue_context_pP->ue_context.setup_e_rabs;

Cedric Roux's avatar
Cedric Roux committed
4683 4684 4685 4686 4687 4688 4689 4690
    for (int i=0; i<ue_context_pP->ue_context.setup_e_rabs; i++) {
      X2AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].e_rab_id = ue_context_pP->ue_context.e_rab[i].param.e_rab_id;
      X2AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].eNB_addr = ue_context_pP->ue_context.e_rab[i].param.sgw_addr;
      X2AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].gtp_teid = ue_context_pP->ue_context.e_rab[i].param.gtp_teid;
      X2AP_HANDOVER_REQ(msg).e_rab_param[i].qos.qci = ue_context_pP->ue_context.e_rab[i].param.qos.qci;
      X2AP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.priority_level = ue_context_pP->ue_context.e_rab[i].param.qos.allocation_retention_priority.priority_level;
      X2AP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability = ue_context_pP->ue_context.e_rab[i].param.qos.allocation_retention_priority.pre_emp_capability;
      X2AP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability = ue_context_pP->ue_context.e_rab[i].param.qos.allocation_retention_priority.pre_emp_vulnerability;
4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702
    }

    /* TODO: don't do that, X2AP should find the target by itself */
    //X2AP_HANDOVER_REQ(msg).target_mod_id = 0;
    LOG_I(RRC,
          "[eNB %d] Frame %d: potential handover preparation: store the information in an intermediate structure in case of failure\n",
          ctxt_pP->module_id, ctxt_pP->frame);
    itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), msg);
  } else {
    LOG_D(RRC, "[eNB %d] Frame %d: Ignoring MeasReport from UE %x as Handover is in progress... \n", ctxt_pP->module_id, ctxt_pP->frame,
          ctxt_pP->rnti);
  }
4703 4704
}

4705 4706 4707
//-----------------------------------------------------------------------------
void
rrc_eNB_generate_HandoverPreparationInformation(
4708
  //const protocol_ctxt_t* const ctxt_pP,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4709
  rrc_eNB_ue_context_t *const ue_context_pP,
Cedric Roux's avatar
Cedric Roux committed
4710
  uint8_t                     *buffer,
4711
  int                          *_size
Cedric Roux's avatar
Cedric Roux committed
4712
) {
4713
  memset(buffer, 0, 8192);
Cedric Roux's avatar
Cedric Roux committed
4714
  char *ho_buf = (char *) buffer;
4715
  int ho_size;
4716
  ho_size = do_HandoverPreparation(ho_buf, 8192, ue_context_pP->ue_context.UE_Capability, ue_context_pP->ue_context.UE_Capability_size);
4717
  *_size = ho_size;
4718 4719
}

4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730
void rrc_eNB_process_x2_setup_request(int mod_id, x2ap_setup_req_t *m) {
  if (RC.rrc[mod_id]->num_neigh_cells > MAX_NUM_NEIGH_CELLs) {
     LOG_E(RRC, "Error: number of neighbouring cells is exceeded \n");
     return;
  }

  if (m->num_cc > MAX_NUM_CCs) {
     LOG_E(RRC, "Error: number of neighbouring cells carriers is exceeded \n");
     return;
  }

4731
  RC.rrc[mod_id]->num_neigh_cells++;
4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748
  RC.rrc[mod_id]->num_neigh_cells_cc[RC.rrc[mod_id]->num_neigh_cells-1] = m->num_cc;
  for (int i=0; i<m->num_cc; i++) {
    RC.rrc[mod_id]->neigh_cells_id[RC.rrc[mod_id]->num_neigh_cells-1][i] = m->Nid_cell[i];
  }
}

void rrc_eNB_process_x2_setup_response(int mod_id, x2ap_setup_resp_t *m) {
  if (RC.rrc[mod_id]->num_neigh_cells > MAX_NUM_NEIGH_CELLs) {
     LOG_E(RRC, "Error: number of neighbouring cells is exceeded \n");
     return;
  }

  if (m->num_cc > MAX_NUM_CCs) {
     LOG_E(RRC, "Error: number of neighbouring cells carriers is exceeded \n");
     return;
  }

4749
  RC.rrc[mod_id]->num_neigh_cells++;
4750 4751 4752 4753 4754 4755
  RC.rrc[mod_id]->num_neigh_cells_cc[RC.rrc[mod_id]->num_neigh_cells-1] = m->num_cc;
  for (int i=0; i<m->num_cc; i++) {
    RC.rrc[mod_id]->neigh_cells_id[RC.rrc[mod_id]->num_neigh_cells-1][i] = m->Nid_cell[i];
  }
}

Cedric Roux's avatar
Cedric Roux committed
4756
void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_req_t *m) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4757
  struct rrc_eNB_ue_context_s        *ue_context_target_p = NULL;
4758 4759 4760 4761
  /* TODO: get proper UE rnti */
  int rnti = taus() & 0xffff;
  int i;
  //global_rnti = rnti;
4762 4763 4764
  LTE_HandoverPreparationInformation_t *ho = NULL;
  LTE_HandoverPreparationInformation_r8_IEs_t *ho_info;
  asn_dec_rval_t                      dec_rval;
4765
  ue_context_target_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
4766

4767 4768 4769 4770
  if (ue_context_target_p != NULL) {
    LOG_E(RRC, "\nError in obtaining free UE id in target eNB for handover \n");
    return;
  }
4771

4772
  ue_context_target_p = rrc_eNB_allocate_new_UE_context(RC.rrc[mod_id]);
Cedric Roux's avatar
Cedric Roux committed
4773

4774 4775 4776 4777 4778 4779 4780 4781 4782 4783
  if (ue_context_target_p == NULL) {
    LOG_E(RRC, "Cannot create new UE context\n");
    return;
  }

  ue_context_target_p->ue_id_rnti = rnti;
  ue_context_target_p->ue_context.rnti = rnti;
  RB_INSERT(rrc_ue_tree_s, &RC.rrc[mod_id]->rrc_ue_head, ue_context_target_p);
  LOG_D(RRC, "eNB %d: Created new UE context uid %u\n", mod_id, ue_context_target_p->local_uid);
  ue_context_target_p->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_target_p->ue_context.handover_info)));
luaihui's avatar
luaihui committed
4784 4785
  //ue_context_target_p->ue_context.Status = RRC_HO_EXECUTION;
  //ue_context_target_p->ue_context.handover_info->state = HO_ACK;
4786 4787
  ue_context_target_p->ue_context.handover_info->x2_id = m->x2_id;
  ue_context_target_p->ue_context.handover_info->assoc_id = m->target_assoc_id;
4788 4789 4790 4791 4792 4793
  memset (ue_context_target_p->ue_context.nh, 0, 32);
  ue_context_target_p->ue_context.nh_ncc = -1;
  memcpy (ue_context_target_p->ue_context.kenb, m->kenb, 32);
  ue_context_target_p->ue_context.kenb_ncc = m->kenb_ncc;
  ue_context_target_p->ue_context.security_capabilities.encryption_algorithms = m->security_capabilities.encryption_algorithms;
  ue_context_target_p->ue_context.security_capabilities.integrity_algorithms = m->security_capabilities.integrity_algorithms;
4794

4795
  dec_rval = uper_decode(NULL,
4796
                         &asn_DEF_LTE_HandoverPreparationInformation,
4797 4798 4799 4800
                         (void **)&ho,
                         m->rrc_buffer,
                         m->rrc_buffer_size, 0, 0);

4801 4802 4803 4804
 if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
     xer_fprint(stdout, &asn_DEF_LTE_HandoverPreparationInformation, ho);
 }

4805
  if (dec_rval.code != RC_OK ||
4806 4807
      ho->criticalExtensions.present != LTE_HandoverPreparationInformation__criticalExtensions_PR_c1 ||
      ho->criticalExtensions.choice.c1.present != LTE_HandoverPreparationInformation__criticalExtensions__c1_PR_handoverPreparationInformation_r8) {
4808 4809 4810 4811 4812 4813 4814 4815
    LOG_E(RRC, "could not decode Handover Preparation\n");
    abort();
  }

  ho_info = &ho->criticalExtensions.choice.c1.choice.handoverPreparationInformation_r8;

  if (ue_context_target_p->ue_context.UE_Capability) {
    LOG_I(RRC, "freeing old UE capabilities for UE %x\n", rnti);
4816
    ASN_STRUCT_FREE(asn_DEF_LTE_UE_EUTRA_Capability,
4817 4818 4819 4820 4821
                    ue_context_target_p->ue_context.UE_Capability);
    ue_context_target_p->ue_context.UE_Capability = 0;
  }

  dec_rval = uper_decode(NULL,
4822
                         &asn_DEF_LTE_UE_EUTRA_Capability,
4823 4824 4825 4826 4827 4828 4829
                         (void **)&ue_context_target_p->ue_context.UE_Capability,
                         ho_info->ue_RadioAccessCapabilityInfo.list.array[0]->ueCapabilityRAT_Container.buf,
                         ho_info->ue_RadioAccessCapabilityInfo.list.array[0]->ueCapabilityRAT_Container.size, 0, 0);

  ue_context_target_p->ue_context.UE_Capability_size = ho_info->ue_RadioAccessCapabilityInfo.list.array[0]->ueCapabilityRAT_Container.size;

  if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
4830
     xer_fprint(stdout, &asn_DEF_LTE_UE_EUTRA_Capability, ue_context_target_p->ue_context.UE_Capability);
4831 4832 4833 4834
  }

  if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
      LOG_E(RRC, "Failed to decode UE capabilities (%zu bytes)\n", dec_rval.consumed);
4835
      ASN_STRUCT_FREE(asn_DEF_LTE_UE_EUTRA_Capability,
4836 4837 4838
                      ue_context_target_p->ue_context.UE_Capability);
      ue_context_target_p->ue_context.UE_Capability = 0;
  }
4839

4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850
  ue_context_target_p->ue_context.nb_of_e_rabs = m->nb_e_rabs_tobesetup;
  ue_context_target_p->ue_context.setup_e_rabs = m->nb_e_rabs_tobesetup;
  ue_context_target_p->ue_context.mme_ue_s1ap_id = m->mme_ue_s1ap_id;
  ue_context_target_p->ue_context.ue_gummei.mcc = m->ue_gummei.mcc;
  ue_context_target_p->ue_context.ue_gummei.mnc = m->ue_gummei.mnc;
  ue_context_target_p->ue_context.ue_gummei.mnc_len = m->ue_gummei.mnc_len;
  ue_context_target_p->ue_context.ue_gummei.mme_code = m->ue_gummei.mme_code;
  ue_context_target_p->ue_context.ue_gummei.mme_group_id = m->ue_gummei.mme_group_id;
  LOG_I(RRC, "eNB %d: Update the E-RABS %u\n", mod_id, ue_context_target_p->ue_context.nb_of_e_rabs);

  for (i = 0; i < ue_context_target_p->ue_context.nb_of_e_rabs; i++) {
Cedric Roux's avatar
Cedric Roux committed
4851 4852 4853 4854 4855 4856 4857
    ue_context_target_p->ue_context.e_rab[i].status = E_RAB_STATUS_NEW;
    ue_context_target_p->ue_context.e_rab[i].param.e_rab_id = m->e_rabs_tobesetup[i].e_rab_id;
    ue_context_target_p->ue_context.e_rab[i].param.sgw_addr = m->e_rabs_tobesetup[i].eNB_addr;
    ue_context_target_p->ue_context.e_rab[i].param.gtp_teid= m->e_rabs_tobesetup[i].gtp_teid;
    LOG_I(RRC, "eNB %d: Update the UE context after HO, e_rab_id %u gtp_teid %u\n", mod_id,
          ue_context_target_p->ue_context.e_rab[i].param.e_rab_id,
          ue_context_target_p->ue_context.e_rab[i].param.gtp_teid);
4858
  }
luaihui's avatar
luaihui committed
4859 4860 4861 4862
  rrc_eNB_process_X2AP_TUNNEL_SETUP_REQ(mod_id, ue_context_target_p);

  ue_context_target_p->ue_context.Status = RRC_HO_EXECUTION;
  ue_context_target_p->ue_context.handover_info->state = HO_ACK;
4863 4864
}

4865
void rrc_eNB_process_handoverCommand(
Cedric Roux's avatar
Cedric Roux committed
4866 4867 4868
  int                         mod_id,
  struct rrc_eNB_ue_context_s *ue_context,
  x2ap_handover_req_ack_t     *m) {
4869
  asn_dec_rval_t dec_rval;
4870
  LTE_HandoverCommand_t *ho = NULL;
4871 4872
  dec_rval = uper_decode(
               NULL,
4873
               &asn_DEF_LTE_HandoverCommand,
Cedric Roux's avatar
Cedric Roux committed
4874
               (void **)&ho,
4875 4876 4877 4878 4879 4880
               m->rrc_buffer,
               m->rrc_buffer_size,
               0,
               0);

  if (dec_rval.code != RC_OK ||
4881 4882
      ho->criticalExtensions.present != LTE_HandoverCommand__criticalExtensions_PR_c1 ||
      ho->criticalExtensions.choice.c1.present != LTE_HandoverCommand__criticalExtensions__c1_PR_handoverCommand_r8) {
4883 4884 4885 4886 4887 4888 4889
    LOG_E(RRC, "could not decode Handover Command\n");
    abort();
  }

  unsigned char *buf = ho->criticalExtensions.choice.c1.choice.handoverCommand_r8.handoverCommandMessage.buf;
  int size = ho->criticalExtensions.choice.c1.choice.handoverCommand_r8.handoverCommandMessage.size;

Cedric Roux's avatar
Cedric Roux committed
4890 4891 4892 4893
  if (size > RRC_BUF_SIZE) {
    printf("%s:%d: fatal\n", __FILE__, __LINE__);
    abort();
  }
4894 4895 4896

  memcpy(ue_context->ue_context.handover_info->buf, buf, size);
  ue_context->ue_context.handover_info->size = size;
winckel's avatar
winckel committed
4897
}
4898

4899
void rrc_eNB_handover_ue_context_release(
Cedric Roux's avatar
Cedric Roux committed
4900 4901
        protocol_ctxt_t *const ctxt_pP,
        struct rrc_eNB_ue_context_s *ue_context_p) {
4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932
  int e_rab = 0;
  //MessageDef *msg_release_p = NULL;
  MessageDef *msg_delete_tunnels_p = NULL;
  uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id;

  //msg_release_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE);
  //itti_send_msg_to_task(TASK_S1AP, ctxt_pP->module_id, msg_release_p);
  s1ap_ue_context_release(ctxt_pP->instance, ue_context_p->ue_context.eNB_ue_s1ap_id);

  //MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id);
  msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ);
  memset(&GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p)));

  GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;

  for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
    GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] =
      ue_context_p->ue_context.enb_gtp_ebi[e_rab];
    // erase data
    ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0;
    memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
    ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0;
  }

  itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p);
  struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL;
  rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0, eNB_ue_s1ap_id);

  if (rrc_ue_s1ap_ids != NULL) {
    rrc_eNB_S1AP_remove_ue_ids(RC.rrc[ctxt_pP->module_id], rrc_ue_s1ap_ids);
  }
winckel's avatar
winckel committed
4933
}
Cedric Roux's avatar
Cedric Roux committed
4934 4935 4936 4937 4938 4939 4940 4941 4942 4943

/* This function may be incorrect. */
void rrc_eNB_handover_cancel(
        protocol_ctxt_t              *const ctxt_pP,
        struct rrc_eNB_ue_context_s  *ue_context_p) {
  int s1_cause = 1;                        /* 1 = tx2relocoverall-expiry */

  rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(ctxt_pP->module_id, ue_context_p,
      S1AP_CAUSE_RADIO_NETWORK, s1_cause);
}
4944

4945 4946 4947 4948 4949 4950 4951

int
flexran_rrc_eNB_trigger_handover (int mod_id,
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t  *ue_context_pP,
  int target_cell_id) {

4952 4953 4954
  uint32_t earfcn_dl;
  uint8_t KeNB_star[32] = { 0 };
  int cell_found = 0;
4955

4956 4957 4958 4959 4960
  /* if X2AP is disabled, do nothing */
  if (!is_x2ap_enabled()) {
    LOG_E(RRC, "X2 is disabled\n");
    return -1;
  }
4961

4962
  /* Check if eNB id belongs to the supported ones-Extend for multiple carrieres */
4963 4964 4965 4966 4967 4968 4969 4970
  for (int i=0; i < RC.rrc[mod_id]->num_neigh_cells; i++) {
    if (RC.rrc[mod_id]->neigh_cells_id[i][0] == target_cell_id) {
      cell_found = 1;
      break;
    }
  }

  /* Check if eNB id was found */
4971 4972
  if (!cell_found) {
    LOG_E(RRC, "%s(): cannot find target eNB with phyCellId %d\n", __func__, target_cell_id);
4973
    return -1;
4974
  }
4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038

  /* Handover process is following */
  LOG_D(RRC, "Handover is triggered by FlexRAN controller...\n");

  /* if the UE is not in handover mode, start handover procedure */
  if (ue_context_pP->ue_context.Status != RRC_HO_EXECUTION) {
    MessageDef      *msg;
    LOG_I(RRC, "Send HO preparation message at frame %d and subframe %d \n", ctxt_pP->frame, ctxt_pP->subframe);
    /* Check memory leakage for handover info */
    //if (ue_context_pP->ue_context.handover_info) {
      //free(ue_context_pP->ue_context.handover_info);
    //}
    ue_context_pP->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_pP->ue_context.handover_info)));
    ue_context_pP->ue_context.Status = RRC_HO_EXECUTION;
    ue_context_pP->ue_context.handover_info->state = HO_REQUEST;
    /* HO Preparation message */
    msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_HANDOVER_REQ);
    rrc_eNB_generate_HandoverPreparationInformation(
      ue_context_pP,
      X2AP_HANDOVER_REQ(msg).rrc_buffer,
      &X2AP_HANDOVER_REQ(msg).rrc_buffer_size);
    X2AP_HANDOVER_REQ(msg).rnti = ctxt_pP->rnti;
    X2AP_HANDOVER_REQ(msg).target_physCellId = target_cell_id;
    X2AP_HANDOVER_REQ(msg).ue_gummei.mcc = ue_context_pP->ue_context.ue_gummei.mcc;
    X2AP_HANDOVER_REQ(msg).ue_gummei.mnc = ue_context_pP->ue_context.ue_gummei.mnc;
    X2AP_HANDOVER_REQ(msg).ue_gummei.mnc_len = ue_context_pP->ue_context.ue_gummei.mnc_len;
    X2AP_HANDOVER_REQ(msg).ue_gummei.mme_code = ue_context_pP->ue_context.ue_gummei.mme_code;
    X2AP_HANDOVER_REQ(msg).ue_gummei.mme_group_id = ue_context_pP->ue_context.ue_gummei.mme_group_id;
    // Don't know how to get this ID?
    X2AP_HANDOVER_REQ(msg).mme_ue_s1ap_id = ue_context_pP->ue_context.mme_ue_s1ap_id;
    X2AP_HANDOVER_REQ(msg).security_capabilities = ue_context_pP->ue_context.security_capabilities;
    // compute keNB*
    earfcn_dl = (uint32_t)to_earfcn_DL(RC.rrc[ctxt_pP->module_id]->carrier[0].eutra_band, RC.rrc[ctxt_pP->module_id]->carrier[0].dl_CarrierFreq,
    RC.rrc[ctxt_pP->module_id]->carrier[0].N_RB_DL);
    derive_keNB_star(ue_context_pP->ue_context.kenb, X2AP_HANDOVER_REQ(msg).target_physCellId, earfcn_dl, true, KeNB_star);
    memcpy(X2AP_HANDOVER_REQ(msg).kenb, KeNB_star, 32);
    X2AP_HANDOVER_REQ(msg).kenb_ncc = ue_context_pP->ue_context.kenb_ncc;
    //X2AP_HANDOVER_REQ(msg).ue_ambr=ue_context_pP->ue_context.ue_ambr;
    X2AP_HANDOVER_REQ(msg).nb_e_rabs_tobesetup = ue_context_pP->ue_context.setup_e_rabs;

    for (int i=0; i<ue_context_pP->ue_context.setup_e_rabs; i++) {
      X2AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].e_rab_id = ue_context_pP->ue_context.e_rab[i].param.e_rab_id;
      X2AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].eNB_addr = ue_context_pP->ue_context.e_rab[i].param.sgw_addr;
      X2AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].gtp_teid = ue_context_pP->ue_context.e_rab[i].param.gtp_teid;
      X2AP_HANDOVER_REQ(msg).e_rab_param[i].qos.qci = ue_context_pP->ue_context.e_rab[i].param.qos.qci;
      X2AP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.priority_level = ue_context_pP->ue_context.e_rab[i].param.qos.allocation_retention_priority.priority_level;
      X2AP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability = ue_context_pP->ue_context.e_rab[i].param.qos.allocation_retention_priority.pre_emp_capability;
      X2AP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability = ue_context_pP->ue_context.e_rab[i].param.qos.allocation_retention_priority.pre_emp_vulnerability;
    }

    /* TODO: don't do that, X2AP should find the target by itself */
    //X2AP_HANDOVER_REQ(msg).target_mod_id = 0;
    LOG_I(RRC,
          "[eNB %d] Frame %d: potential handover preparation: store the information in an intermediate structure in case of failure\n",
          ctxt_pP->module_id, ctxt_pP->frame);
    itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), msg);
  } else {
    LOG_D(RRC, "[eNB %d] Frame %d: Ignoring MeasReport from UE %x as Handover is in progress... \n", ctxt_pP->module_id, ctxt_pP->frame,
          ctxt_pP->rnti);
  }

  return 0;
}

5039 5040
void
check_handovers(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5041
  protocol_ctxt_t *const ctxt_pP
5042
)
5043
//-----------------------------------------------------------------------------
5044
{
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5045
  struct rrc_eNB_ue_context_s        *ue_context_p;
5046
  RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
5047
    ctxt_pP->rnti  = ue_context_p->ue_id_rnti;
5048

5049 5050 5051
    if (ue_context_p->ue_context.Status == RRC_HO_EXECUTION && ue_context_p->ue_context.handover_info != NULL) {
      /* in the source, UE in HO_PREPARE mode */
      if (ue_context_p->ue_context.handover_info->state == HO_PREPARE) {
5052
        LOG_D(RRC,
5053
              "[eNB %d] Frame %d: Incoming handover detected for new UE_id %x) \n",
5054 5055
              ctxt_pP->module_id,
              ctxt_pP->frame,
5056 5057 5058
              ctxt_pP->rnti);
        // source eNB generates rrcconnectionreconfiguration to prepare the HO
        LOG_I(RRC,
Cedric Roux's avatar
Cedric Roux committed
5059 5060
              "[eNB %d] Frame %d : Logical Channel UL-DCCH, processing RRCHandoverPreparationInformation, sending RRCConnectionReconfiguration to UE %d \n",
              ctxt_pP->module_id, ctxt_pP->frame, ue_context_p->ue_context.rnti);
5061
        rrc_data_req(
5062
          ctxt_pP,
5063 5064
                               DCCH,
                               rrc_eNB_mui++,
5065 5066 5067
                               SDU_CONFIRM_NO,
                               ue_context_p->ue_context.handover_info->size,
                               ue_context_p->ue_context.handover_info->buf,
5068 5069
          PDCP_TRANSMISSION_MODE_CONTROL);

5070
        ue_context_p->ue_context.handover_info->state = HO_COMPLETE;
Cedric Roux's avatar
Cedric Roux committed
5071
        LOG_I(RRC, "RRC Sends RRCConnectionReconfiguration to UE %d  at frame %d and subframe %d \n", ue_context_p->ue_context.rnti, ctxt_pP->frame,ctxt_pP->subframe);
5072
      }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5073

5074 5075 5076 5077
      /* in the target, UE in HO_ACK mode */
      if (ue_context_p->ue_context.handover_info->state == HO_ACK) {
        MessageDef *msg;
        // Configure target
luaihui's avatar
luaihui committed
5078 5079
        ue_context_p->ue_context.handover_info->state = HO_FORWARDING;

5080 5081
        msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_HANDOVER_REQ_ACK);
        rrc_eNB_generate_HO_RRCConnectionReconfiguration(ctxt_pP, ue_context_p, X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer,
Cedric Roux's avatar
Cedric Roux committed
5082
            &X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer_size);
5083
        rrc_eNB_configure_rbs_handover(ue_context_p,ctxt_pP);
5084

5085 5086 5087
        X2AP_HANDOVER_REQ_ACK(msg).rnti = ue_context_p->ue_context.rnti;
        X2AP_HANDOVER_REQ_ACK(msg).x2_id_target = ue_context_p->ue_context.handover_info->x2_id;
        X2AP_HANDOVER_REQ_ACK(msg).source_assoc_id = ue_context_p->ue_context.handover_info->assoc_id;
5088 5089 5090
        /* Call admission control not implemented yet */
        X2AP_HANDOVER_REQ_ACK(msg).nb_e_rabs_tobesetup = ue_context_p->ue_context.setup_e_rabs;

Cedric Roux's avatar
Cedric Roux committed
5091
        for (int i=0; i<ue_context_p->ue_context.setup_e_rabs; i++) {
luaihui's avatar
luaihui committed
5092
          /* set gtpv teid info */
5093
          X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].e_rab_id = ue_context_p->ue_context.e_rab[i].param.e_rab_id;
luaihui's avatar
luaihui committed
5094 5095
	  X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].gtp_teid = ue_context_p->ue_context.enb_gtp_x2u_teid[i];
          X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr = ue_context_p->ue_context.enb_gtp_x2u_addrs[i];
5096
        }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5097

5098
        itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), msg);
Cedric Roux's avatar
Cedric Roux committed
5099
        LOG_I(RRC, "RRC Sends X2 HO ACK to the source eNB at frame %d and subframe %d \n", ctxt_pP->frame,ctxt_pP->subframe);
5100
      }
winckel's avatar
winckel committed
5101
    }
luaihui's avatar
luaihui committed
5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246

    if (ue_context_p->ue_context.Status == RRC_RECONFIGURED 
	&& ue_context_p->ue_context.handover_info != NULL && 
	ue_context_p->ue_context.handover_info->forwarding_state == FORWARDING_NO_EMPTY ) {

#if defined(ENABLE_ITTI)
      MessageDef	 *msg_p;
      int		 result;
      protocol_ctxt_t  ctxt;

      do {
        // Checks if a message has been sent to PDCP sub-task
	itti_poll_msg (TASK_DATA_FORWARDING, &msg_p);
  
	if (msg_p != NULL) {
  
	  switch (ITTI_MSG_ID(msg_p)) {
	    case GTPV1U_ENB_DATA_FORWARDING_IND:
	    PROTOCOL_CTXT_SET_BY_MODULE_ID(
			&ctxt,
			GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).module_id,
			GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).enb_flag,
			GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rnti,
			GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).frame, 
		        0,
		        GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).eNB_index);
	    LOG_D(RRC, PROTOCOL_CTXT_FMT"[check_handovers]Received %s from %s: instance %d, rb_id %d, muiP %d, confirmP %d, mode %d\n",
		  PROTOCOL_CTXT_ARGS(&ctxt),
		  ITTI_MSG_NAME (msg_p),
		  ITTI_MSG_ORIGIN_NAME(msg_p),
		  ITTI_MSG_INSTANCE (msg_p),
		  GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id,
		  GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).muip,
		  GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).confirmp,
		  GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).mode);
  
	    LOG_I(RRC, "Before calling pdcp_data_req from check_handovers! GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id: %d \n", GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id);
            result = pdcp_data_req (&ctxt,
				    SRB_FLAG_NO,
			            GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id,
				    GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).muip,
				    GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).confirmp,
			            GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).sdu_size,
				    GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).sdu_p,
				    GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).mode
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
				    , NULL, NULL
#endif
				    );
	    if (result != TRUE){
              LOG_E(RRC, "target enb send data forwarding buffer to PDCP request failed!\n");   
            }else{
              LOG_D(RRC, "target enb send data forwarding buffer to PDCP!\n");
            }

            // Message buffer has been processed, free it now.
	    result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).sdu_p);
	    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
            break;
  
	default:
	  LOG_E(RRC, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p));
	  break;
	}
  
	result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
	AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
      }
    } while(msg_p != NULL);
    ue_context_p->ue_context.handover_info->forwarding_state = FORWARDING_EMPTY;
    }
    if( ue_context_p->ue_context.Status == RRC_RECONFIGURED &&
	ue_context_p->ue_context.handover_info != NULL &&
	ue_context_p->ue_context.handover_info->forwarding_state == FORWARDING_EMPTY &&
	ue_context_p->ue_context.handover_info->endmark_state == ENDMARK_NO_EMPTY &&
	ue_context_p->ue_context.handover_info->state == HO_END_MARKER	  ){

      MessageDef	 *msg_p;
      int		 result;
      protocol_ctxt_t  ctxt;

      do {
        // Checks if a message has been sent to PDCP sub-task
        itti_poll_msg (TASK_END_MARKER, &msg_p);

        if (msg_p != NULL) {

	switch (ITTI_MSG_ID(msg_p)) {
	  case GTPV1U_ENB_END_MARKER_IND:
	    PROTOCOL_CTXT_SET_BY_MODULE_ID(
	        &ctxt,
		GTPV1U_ENB_END_MARKER_IND (msg_p).module_id,
	        GTPV1U_ENB_END_MARKER_IND (msg_p).enb_flag,
		GTPV1U_ENB_END_MARKER_IND (msg_p).rnti,
		GTPV1U_ENB_END_MARKER_IND (msg_p).frame,
		0,
		GTPV1U_ENB_END_MARKER_IND (msg_p).eNB_index);
	    LOG_I(RRC, PROTOCOL_CTXT_FMT"[check_handovers]Received %s from %s: instance %d, rb_id %d, muiP %d, confirmP %d, mode %d\n",
		  PROTOCOL_CTXT_ARGS(&ctxt),
		  ITTI_MSG_NAME (msg_p),
		  ITTI_MSG_ORIGIN_NAME(msg_p),
		  ITTI_MSG_INSTANCE (msg_p),
		  GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id,
		  GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).muip,
		  GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).confirmp,
		  GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).mode);

	    LOG_D(RRC, "Before calling pdcp_data_req from check_handovers! GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id: %d \n", GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id);
	    result = pdcp_data_req (&ctxt,
		  		    SRB_FLAG_NO,
		  		    GTPV1U_ENB_END_MARKER_IND (msg_p).rb_id,
		  		    GTPV1U_ENB_END_MARKER_IND (msg_p).muip,
		  		    GTPV1U_ENB_END_MARKER_IND (msg_p).confirmp,
		  		    GTPV1U_ENB_END_MARKER_IND (msg_p).sdu_size,
		  		    GTPV1U_ENB_END_MARKER_IND (msg_p).sdu_p,
		  		    GTPV1U_ENB_END_MARKER_IND (msg_p).mode
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
		  		    , NULL, NULL
#endif
		  		   );
	    if (result != TRUE){
              LOG_E(RRC, "target enb send spgw buffer to PDCP request failed!\n");
	    }else{
	      LOG_D(RRC, "target enb send spgw buffer to PDCP!\n");
	    }

	    // Message buffer has been processed, free it now.
	    result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), GTPV1U_ENB_END_MARKER_IND (msg_p).sdu_p);
	    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
	    break;

	    default:
	      LOG_E(RRC, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p));
	      break;
          }

          result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
          AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
        }
      } while(msg_p != NULL);

      ue_context_p->ue_context.handover_info->endmark_state = ENDMARK_EMPTY;
      ue_context_p->ue_context.handover_info->state = HO_FORWARDING_COMPLETE;

#endif
5247
    }
5248
  }
5249
}
winckel's avatar
RRC:  
winckel committed
5250

5251
void
Cedric Roux's avatar
Cedric Roux committed
5252 5253 5254 5255 5256 5257
rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP,
    rrc_eNB_ue_context_t  *const ue_context_pP,
    uint8_t               *buffer,
    int                    *_size
    //const uint8_t        ho_state
                                                )
5258
//-----------------------------------------------------------------------------
5259
{
5260
  uint16_t                            size;
5261 5262 5263
  int                                 i;
  uint8_t                             rv[2];
  // configure SRB1/SRB2, PhysicalConfigDedicated, MAC_MainConfig for UE
Cedric Roux's avatar
Cedric Roux committed
5264
  eNB_RRC_INST                       *rrc_inst = RC.rrc[ctxt_pP->module_id];
5265
  struct LTE_PhysicalConfigDedicated **physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated;
5266
  // phy config dedicated
5267
  LTE_PhysicalConfigDedicated_t      *physicalConfigDedicated2;
5268
  // srb 1: for HO
5269 5270 5271 5272
  struct LTE_SRB_ToAddMod            *SRB1_config                      = NULL;
  struct LTE_SRB_ToAddMod__rlc_Config *SRB1_rlc_config                 = NULL;
  struct LTE_SRB_ToAddMod__logicalChannelConfig *SRB1_lchan_config     = NULL;
  struct LTE_LogicalChannelConfig__ul_SpecificParameters
Cedric Roux's avatar
Cedric Roux committed
5273
    *SRB1_ul_SpecificParameters       = NULL;
5274 5275 5276 5277
  struct LTE_SRB_ToAddMod            *SRB2_config                      = NULL;
  struct LTE_SRB_ToAddMod__rlc_Config *SRB2_rlc_config                 = NULL;
  struct LTE_SRB_ToAddMod__logicalChannelConfig *SRB2_lchan_config     = NULL;
  struct LTE_LogicalChannelConfig__ul_SpecificParameters
Cedric Roux's avatar
Cedric Roux committed
5278
    *SRB2_ul_SpecificParameters       = NULL;
5279 5280 5281 5282 5283 5284 5285 5286 5287
  LTE_SRB_ToAddModList_t             *SRB_configList = ue_context_pP->ue_context.SRB_configList;
  LTE_SRB_ToAddModList_t             **SRB_configList2                 = NULL;
  struct LTE_DRB_ToAddMod            *DRB_config                       = NULL;
  struct LTE_RLC_Config              *DRB_rlc_config                   = NULL;
  struct LTE_PDCP_Config             *DRB_pdcp_config                  = NULL;
  struct LTE_PDCP_Config__rlc_AM     *PDCP_rlc_AM                      = NULL;
  struct LTE_PDCP_Config__rlc_UM     *PDCP_rlc_UM                      = NULL;
  struct LTE_LogicalChannelConfig    *DRB_lchan_config                 = NULL;
  struct LTE_LogicalChannelConfig__ul_SpecificParameters
Cedric Roux's avatar
Cedric Roux committed
5288
    *DRB_ul_SpecificParameters        = NULL;
5289 5290 5291 5292 5293 5294 5295
  LTE_DRB_ToAddModList_t            **DRB_configList = &ue_context_pP->ue_context.DRB_configList;
  LTE_DRB_ToAddModList_t            **DRB_configList2 = NULL;
  LTE_MAC_MainConfig_t               *mac_MainConfig                   = NULL;
  LTE_MeasObjectToAddModList_t       *MeasObj_list                     = NULL;
  LTE_MeasObjectToAddMod_t           *MeasObj                          = NULL;
  LTE_ReportConfigToAddModList_t     *ReportConfig_list                = NULL;
  LTE_ReportConfigToAddMod_t         *ReportConfig_per, *ReportConfig_A1,
5296
                                     *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5;
5297 5298 5299
  LTE_MeasIdToAddModList_t           *MeasId_list                      = NULL;
  LTE_MeasIdToAddMod_t               *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5;
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
5300 5301 5302
  long                               *sr_ProhibitTimer_r9              = NULL;
  //     uint8_t sCellIndexToAdd = rrc_find_free_SCell_index(enb_mod_idP, ue_mod_idP, 1);
  //uint8_t                            sCellIndexToAdd = 0;
5303 5304 5305
#endif
  long                               *logicalchannelgroup, *logicalchannelgroup_drb;
  long                               *maxHARQ_Tx, *periodicBSR_Timer;
5306 5307 5308 5309 5310
  LTE_RSRP_Range_t                   *rsrp                             = NULL;
  struct LTE_MeasConfig__speedStatePars *Sparams                       = NULL;
  LTE_QuantityConfig_t               *quantityConfig                   = NULL;
  LTE_MobilityControlInfo_t          *mobilityInfo                     = NULL;
  LTE_SecurityConfigHO_t             *securityConfigHO                 = NULL;
5311 5312
  LTE_CellsToAddMod_t                *CellToAdd                        = NULL;
  LTE_CellsToAddModList_t            *CellsToAddModList                = NULL;
5313 5314
  struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL;
  LTE_DedicatedInfoNAS_t             *dedicatedInfoNas                 = NULL;
5315 5316
  /* for no gcc warnings */
  (void)dedicatedInfoNas;
5317
  LTE_C_RNTI_t                       *cba_RNTI                         = NULL;
5318
  int                                measurements_enabled;
5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344
  uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id);   //Transaction_id,
#ifdef CBA
  //struct PUSCH_CBAConfigDedicated_vlola  *pusch_CBAConfigDedicated_vlola;
  uint8_t                            *cba_RNTI_buf;
  cba_RNTI = CALLOC(1, sizeof(C_RNTI_t));
  cba_RNTI_buf = CALLOC(1, 2 * sizeof(uint8_t));
  cba_RNTI->buf = cba_RNTI_buf;
  cba_RNTI->size = 2;
  cba_RNTI->bits_unused = 0;

  // associate UEs to the CBa groups as a function of their UE id
  if (rrc_inst->num_active_cba_groups) {
    cba_RNTI->buf[0] = rrc_inst->cba_rnti[ue_mod_idP % rrc_inst->num_active_cba_groups] & 0xff;
    cba_RNTI->buf[1] = 0xff;
    LOG_D(RRC,
          "[eNB %d] Frame %d: cba_RNTI = %x in group %d is attribued to UE %d\n",
          enb_mod_idP, frameP,
          rrc_inst->cba_rnti[ue_mod_idP % rrc_inst->num_active_cba_groups],
          ue_mod_idP % rrc_inst->num_active_cba_groups, ue_mod_idP);
  } else {
    cba_RNTI->buf[0] = 0x0;
    cba_RNTI->buf[1] = 0x0;
    LOG_D(RRC, "[eNB %d] Frame %d: no cba_RNTI is configured for UE %d\n", enb_mod_idP, frameP, ue_mod_idP);
  }

#endif
Cedric Roux's avatar
Cedric Roux committed
5345 5346
  T(T_ENB_RRC_CONNECTION_RECONFIGURATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
    T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
5347 5348 5349 5350
  rv[0] = (ue_context_pP->ue_context.rnti >> 8) & 255;
  rv[1] = ue_context_pP->ue_context.rnti & 255;
  LOG_I(RRC, "target UE rnti = %x (decimal: %d)\n", ue_context_pP->ue_context.rnti, ue_context_pP->ue_context.rnti);
  LOG_D(RRC, "[eNB %d] Frame %d : handover preparation: add target eNB SRB1 and PHYConfigDedicated reconfiguration\n",
5351
        ctxt_pP->module_id, ctxt_pP->frame);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
5352

5353 5354
  if (SRB_configList) {
    free(SRB_configList);
5355
  }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
5356

5357 5358
  SRB_configList = CALLOC(1, sizeof(*SRB_configList));
  memset(SRB_configList, 0, sizeof(*SRB_configList));
5359 5360 5361 5362
  SRB1_config = CALLOC(1, sizeof(*SRB1_config));
  SRB1_config->srb_Identity = 1;
  SRB1_rlc_config = CALLOC(1, sizeof(*SRB1_rlc_config));
  SRB1_config->rlc_Config = SRB1_rlc_config;
5363 5364 5365 5366 5367 5368 5369 5370
  SRB1_rlc_config->present = LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue;
  SRB1_rlc_config->choice.explicitValue.present = LTE_RLC_Config_PR_am;
  SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms15;
  SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p8;
  SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kB1000;
  SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t16;
  SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35;
  SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms10;
5371 5372
  SRB1_lchan_config = CALLOC(1, sizeof(*SRB1_lchan_config));
  SRB1_config->logicalChannelConfig = SRB1_lchan_config;
5373
  SRB1_lchan_config->present = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue;
5374 5375 5376 5377 5378
  SRB1_ul_SpecificParameters = CALLOC(1, sizeof(*SRB1_ul_SpecificParameters));
  SRB1_lchan_config->choice.explicitValue.ul_SpecificParameters = SRB1_ul_SpecificParameters;
  SRB1_ul_SpecificParameters->priority = 1;
  //assign_enum(&SRB1_ul_SpecificParameters->prioritisedBitRate,LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity);
  SRB1_ul_SpecificParameters->prioritisedBitRate =
5379
    LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
5380 5381
  //assign_enum(&SRB1_ul_SpecificParameters->bucketSizeDuration,LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50);
  SRB1_ul_SpecificParameters->bucketSizeDuration =
5382
    LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
5383 5384 5385
  logicalchannelgroup = CALLOC(1, sizeof(long));
  *logicalchannelgroup = 0;
  SRB1_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup;
5386 5387 5388 5389 5390
  ASN_SEQUENCE_ADD(&SRB_configList->list, SRB1_config);
  ue_context_pP->ue_context.SRB_configList = SRB_configList;
  // Configure SRB2
  /// SRB2
  SRB_configList2=&ue_context_pP->ue_context.SRB_configList2[xid];
Cedric Roux's avatar
Cedric Roux committed
5391

5392 5393 5394
  if (*SRB_configList2) {
    free(*SRB_configList2);
  }
Cedric Roux's avatar
Cedric Roux committed
5395

5396 5397 5398 5399 5400 5401
  *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
  memset(*SRB_configList2, 0, sizeof(**SRB_configList2));
  SRB2_config = CALLOC(1, sizeof(*SRB2_config));
  SRB2_config->srb_Identity = 2;
  SRB2_rlc_config = CALLOC(1, sizeof(*SRB2_rlc_config));
  SRB2_config->rlc_Config = SRB2_rlc_config;
5402 5403 5404 5405 5406 5407 5408 5409
  SRB2_rlc_config->present = LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue;
  SRB2_rlc_config->choice.explicitValue.present = LTE_RLC_Config_PR_am;
  SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms15;
  SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p8;
  SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kB1000;
  SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t32;
  SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35;
  SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms10;
5410 5411
  SRB2_lchan_config = CALLOC(1, sizeof(*SRB2_lchan_config));
  SRB2_config->logicalChannelConfig = SRB2_lchan_config;
5412
  SRB2_lchan_config->present = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue;
5413 5414 5415
  SRB2_ul_SpecificParameters = CALLOC(1, sizeof(*SRB2_ul_SpecificParameters));
  SRB2_ul_SpecificParameters->priority = 3; // let some priority for SRB1 and dedicated DRBs
  SRB2_ul_SpecificParameters->prioritisedBitRate =
5416
    LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
5417
  SRB2_ul_SpecificParameters->bucketSizeDuration =
5418
    LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434
  // LCG for CCCH and DCCH is 0 as defined in 36331
  logicalchannelgroup = CALLOC(1, sizeof(long));
  *logicalchannelgroup = 0;
  SRB2_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup;
  SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters = SRB2_ul_SpecificParameters;
  // this list has the configuration for SRB1 and SRB2
  ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config);
  // this list has only the configuration for SRB2
  ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config);

  // Configure DRB
  //*DRB_configList = CALLOC(1, sizeof(*DRB_configList));
  // list for all the configured DRB
  if (*DRB_configList) {
    free(*DRB_configList);
  }
Cedric Roux's avatar
Cedric Roux committed
5435

5436 5437 5438 5439
  *DRB_configList = CALLOC(1, sizeof(**DRB_configList));
  memset(*DRB_configList, 0, sizeof(**DRB_configList));
  // list for the configured DRB for a this xid
  DRB_configList2=&ue_context_pP->ue_context.DRB_configList2[xid];
Cedric Roux's avatar
Cedric Roux committed
5440

5441 5442 5443
  if (*DRB_configList2) {
    free(*DRB_configList2);
  }
Cedric Roux's avatar
Cedric Roux committed
5444

5445 5446 5447 5448 5449 5450 5451 5452
  *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
  memset(*DRB_configList2, 0, sizeof(**DRB_configList2));
  /// DRB
  DRB_config = CALLOC(1, sizeof(*DRB_config));
  DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long));
  *(DRB_config->eps_BearerIdentity) = 5L; // LW set to first value, allowed value 5..15, value : x+4
  // DRB_config->drb_Identity = (DRB_Identity_t) 1; //allowed values 1..32
  // NN: this is the 1st DRB for this ue, so set it to 1
5453
  DRB_config->drb_Identity = (LTE_DRB_Identity_t) 1;  // (ue_mod_idP+1); //allowed values 1..32, value: x
5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466
  DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long));
  *(DRB_config->logicalChannelIdentity) = (long)3; // value : x+2
  DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config));
  DRB_config->rlc_Config = DRB_rlc_config;
#ifdef RRC_DEFAULT_RAB_IS_AM
  DRB_rlc_config->present = RLC_Config_PR_am;
  DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = T_PollRetransmit_ms50;
  DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = PollPDU_p16;
  DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = PollByte_kBinfinity;
  DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = UL_AM_RLC__maxRetxThreshold_t8;
  DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = T_Reordering_ms35;
  DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms25;
#else
5467 5468 5469
  DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional;
  DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10;
  DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10;
5470
#ifdef CBA
5471
  DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering   = LTE_T_Reordering_ms5;//T_Reordering_ms25;
5472
#else
5473
  DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35;
5474 5475 5476 5477 5478
#endif
#endif
  DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config));
  DRB_config->pdcp_Config = DRB_pdcp_config;
  DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long));
5479
  *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity;
5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491
  DRB_pdcp_config->rlc_AM = NULL;
  DRB_pdcp_config->rlc_UM = NULL;
  /* avoid gcc warnings */
  (void)PDCP_rlc_AM;
  (void)PDCP_rlc_UM;
#ifdef RRC_DEFAULT_RAB_IS_AM // EXMIMO_IOT
  PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM));
  DRB_pdcp_config->rlc_AM = PDCP_rlc_AM;
  PDCP_rlc_AM->statusReportRequired = FALSE;
#else
  PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM));
  DRB_pdcp_config->rlc_UM = PDCP_rlc_UM;
5492
  PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits;
5493
#endif
5494
  DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed;
5495 5496 5497 5498 5499
  DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config));
  DRB_config->logicalChannelConfig = DRB_lchan_config;
  DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters));
  DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters;
  DRB_ul_SpecificParameters->priority = 12;    // lower priority than srb1, srb2 and other dedicated bearer
5500
  DRB_ul_SpecificParameters->prioritisedBitRate =LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ;
Cedric Roux's avatar
Cedric Roux committed
5501
  //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
5502
  DRB_ul_SpecificParameters->bucketSizeDuration =
5503
    LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514
  // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM)
  logicalchannelgroup_drb = CALLOC(1, sizeof(long));
  *logicalchannelgroup_drb = 1;
  DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb;
  ASN_SEQUENCE_ADD(&(*DRB_configList)->list, DRB_config);
  ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config);
  //ue_context_pP->ue_context.DRB_configList2[0] = &(*DRB_configList);
  mac_MainConfig = CALLOC(1, sizeof(*mac_MainConfig));
  ue_context_pP->ue_context.mac_MainConfig = mac_MainConfig;
  mac_MainConfig->ul_SCH_Config = CALLOC(1, sizeof(*mac_MainConfig->ul_SCH_Config));
  maxHARQ_Tx = CALLOC(1, sizeof(long));
5515
  *maxHARQ_Tx = LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5;
5516 5517
  mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx;
  periodicBSR_Timer = CALLOC(1, sizeof(long));
5518
  *periodicBSR_Timer = LTE_PeriodicBSR_Timer_r12_sf64;
5519
  mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer;
5520
  mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320;
5521
  mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE
5522
  mac_MainConfig->timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_infinity;
5523 5524
  mac_MainConfig->drx_Config = NULL;
  mac_MainConfig->phr_Config = CALLOC(1, sizeof(*mac_MainConfig->phr_Config));
5525 5526 5527 5528 5529
  mac_MainConfig->phr_Config->present = LTE_MAC_MainConfig__phr_Config_PR_setup;
  mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; // sf20 = 20 subframes
  mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; // sf20 = 20 subframes
  mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1;  // Value dB1 =1 dB, dB3 = 3 dB
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
5530 5531
  sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long));
  *sr_ProhibitTimer_r9 = 0;   // SR tx on PUCCH, Value in number of SR period(s). Value 0 = no timer for SR, Value 2= 2*SR
5532
  mac_MainConfig->ext1 = CALLOC(1, sizeof(struct LTE_MAC_MainConfig__ext1));
5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545
  mac_MainConfig->ext1->sr_ProhibitTimer_r9 = sr_ProhibitTimer_r9;
  //sps_RA_ConfigList_rlola = NULL;
#endif

  //change the transmission mode for the primary component carrier
  //TODO: add codebook subset restriction here
  //TODO: change TM for secondary CC in SCelltoaddmodlist
  /// now reconfigure phy config dedicated
  if (*physicalConfigDedicated) {
    free(*physicalConfigDedicated);
  }

  //if (*physicalConfigDedicated) {
5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560
  physicalConfigDedicated2 = CALLOC(1, sizeof(*physicalConfigDedicated2));
  *physicalConfigDedicated = physicalConfigDedicated2;
  physicalConfigDedicated2->pdsch_ConfigDedicated =
    CALLOC(1, sizeof(*physicalConfigDedicated2->pdsch_ConfigDedicated));
  physicalConfigDedicated2->pucch_ConfigDedicated =
    CALLOC(1, sizeof(*physicalConfigDedicated2->pucch_ConfigDedicated));
  physicalConfigDedicated2->pusch_ConfigDedicated =
    CALLOC(1, sizeof(*physicalConfigDedicated2->pusch_ConfigDedicated));
  physicalConfigDedicated2->uplinkPowerControlDedicated =
    CALLOC(1, sizeof(*physicalConfigDedicated2->uplinkPowerControlDedicated));
  physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH =
    CALLOC(1, sizeof(*physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH));
  physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH =
    CALLOC(1, sizeof(*physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH));
  physicalConfigDedicated2->cqi_ReportConfig = NULL;  //CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig));
5561
  physicalConfigDedicated2->soundingRS_UL_ConfigDedicated = NULL; //CALLOC(1,sizeof(*physicalConfigDedicated2->soundingRS_UL_ConfigDedicated));
5562 5563 5564 5565 5566 5567
  physicalConfigDedicated2->antennaInfo = CALLOC(1, sizeof(*physicalConfigDedicated2->antennaInfo));
  physicalConfigDedicated2->schedulingRequestConfig =
    CALLOC(1, sizeof(*physicalConfigDedicated2->schedulingRequestConfig));
  // PDSCH
  //assign_enum(&physicalConfigDedicated2->pdsch_ConfigDedicated->p_a,
  //          PDSCH_ConfigDedicated__p_a_dB0);
5568
  physicalConfigDedicated2->pdsch_ConfigDedicated->p_a = LTE_PDSCH_ConfigDedicated__p_a_dB0;
5569 5570
  // PUCCH
  physicalConfigDedicated2->pucch_ConfigDedicated->ackNackRepetition.present =
5571
    LTE_PUCCH_ConfigDedicated__ackNackRepetition_PR_release;
5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582
  physicalConfigDedicated2->pucch_ConfigDedicated->ackNackRepetition.choice.release = 0;
  physicalConfigDedicated2->pucch_ConfigDedicated->tdd_AckNackFeedbackMode = NULL;    //PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing;
  // Pusch_config_dedicated
  physicalConfigDedicated2->pusch_ConfigDedicated->betaOffset_ACK_Index = 0;  // 2.00
  physicalConfigDedicated2->pusch_ConfigDedicated->betaOffset_RI_Index = 0;   // 1.25
  physicalConfigDedicated2->pusch_ConfigDedicated->betaOffset_CQI_Index = 8;  // 2.25
  // UplinkPowerControlDedicated
  physicalConfigDedicated2->uplinkPowerControlDedicated->p0_UE_PUSCH = 0; // 0 dB
  //assign_enum(&physicalConfigDedicated2->uplinkPowerControlDedicated->deltaMCS_Enabled,
  // UplinkPowerControlDedicated__deltaMCS_Enabled_en1);
  physicalConfigDedicated2->uplinkPowerControlDedicated->deltaMCS_Enabled =
5583
    LTE_UplinkPowerControlDedicated__deltaMCS_Enabled_en1;
5584 5585 5586 5587 5588 5589
  physicalConfigDedicated2->uplinkPowerControlDedicated->accumulationEnabled = 1; // should be TRUE in order to have 0dB power offset
  physicalConfigDedicated2->uplinkPowerControlDedicated->p0_UE_PUCCH = 0; // 0 dB
  physicalConfigDedicated2->uplinkPowerControlDedicated->pSRS_Offset = 0; // 0 dB
  physicalConfigDedicated2->uplinkPowerControlDedicated->filterCoefficient =
    CALLOC(1, sizeof(*physicalConfigDedicated2->uplinkPowerControlDedicated->filterCoefficient));
  //  assign_enum(physicalConfigDedicated2->uplinkPowerControlDedicated->filterCoefficient,FilterCoefficient_fc4); // fc4 dB
5590
  *physicalConfigDedicated2->uplinkPowerControlDedicated->filterCoefficient = LTE_FilterCoefficient_fc4;  // fc4 dB
5591
  // TPC-PDCCH-Config
5592 5593
  physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->present = LTE_TPC_PDCCH_Config_PR_setup;
  physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_Index.present = LTE_TPC_Index_PR_indexOfFormat3;
5594 5595 5596 5597
  physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_Index.choice.indexOfFormat3 = 1;
  physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_RNTI.buf = CALLOC(1, 2);
  physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_RNTI.size = 2;
  physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_RNTI.buf[0] = 0x12;
5598
  physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_RNTI.buf[1] = 0x34 + ue_context_pP->local_uid;
5599
  physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_RNTI.bits_unused = 0;
5600 5601
  physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->present = LTE_TPC_PDCCH_Config_PR_setup;
  physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_Index.present = LTE_TPC_Index_PR_indexOfFormat3;
5602 5603 5604 5605
  physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_Index.choice.indexOfFormat3 = 1;
  physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.buf = CALLOC(1, 2);
  physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.size = 2;
  physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.buf[0] = 0x22;
5606
  physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.buf[1] = 0x34 + ue_context_pP->local_uid;
5607 5608 5609
  physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.bits_unused = 0;
  //AntennaInfoDedicated
  physicalConfigDedicated2->antennaInfo = CALLOC(1, sizeof(*physicalConfigDedicated2->antennaInfo));
5610
  physicalConfigDedicated2->antennaInfo->present = LTE_PhysicalConfigDedicated__antennaInfo_PR_explicitValue;
5611
  //if ((*physicalConfigDedicated)->antennaInfo) {
Cedric Roux's avatar
Cedric Roux committed
5612 5613
  (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.transmissionMode = rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode;
  LOG_D(RRC,"Setting transmission mode to %ld+1\n",rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode);
Cedric Roux's avatar
Cedric Roux committed
5614

Cedric Roux's avatar
Cedric Roux committed
5615
  if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm3) {
Cedric Roux's avatar
Cedric Roux committed
5616
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
5617
      CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
Cedric Roux's avatar
Cedric Roux committed
5618
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
5619
      LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm3;
Cedric Roux's avatar
Cedric Roux committed
5620 5621 5622 5623
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf= MALLOC(1);
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf[0] = 0xc0;
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.size=1;
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.bits_unused=6;
Cedric Roux's avatar
Cedric Roux committed
5624
  } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm4) {
Cedric Roux's avatar
Cedric Roux committed
5625
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
5626
      CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
Cedric Roux's avatar
Cedric Roux committed
5627
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
5628
      LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm4;
Cedric Roux's avatar
Cedric Roux committed
5629 5630 5631 5632
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf= MALLOC(1);
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf[0] = 0xfc;
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.size=1;
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.bits_unused=2;
Cedric Roux's avatar
Cedric Roux committed
5633
  } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm5) {
Cedric Roux's avatar
Cedric Roux committed
5634
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
5635
      CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
Cedric Roux's avatar
Cedric Roux committed
5636
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
5637
      LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm5;
Cedric Roux's avatar
Cedric Roux committed
5638 5639 5640 5641
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf= MALLOC(1);
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf[0] = 0xf0;
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.size=1;
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.bits_unused=4;
Cedric Roux's avatar
Cedric Roux committed
5642
  } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm6) {
Cedric Roux's avatar
Cedric Roux committed
5643
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
5644
      CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
Cedric Roux's avatar
Cedric Roux committed
5645
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
5646
      LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm6;
Cedric Roux's avatar
Cedric Roux committed
5647 5648 5649 5650 5651
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf= MALLOC(1);
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf[0] = 0xf0;
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.size=1;
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.bits_unused=4;
  }
5652

5653
  physicalConfigDedicated2->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.present =
5654
    LTE_AntennaInfoDedicated__ue_TransmitAntennaSelection_PR_release;
5655
  physicalConfigDedicated2->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.release = 0;
5656 5657
  //}
  //else {
Cedric Roux's avatar
Cedric Roux committed
5658
  //LOG_E(RRC,"antenna_info not present in physical_config_dedicated. Not reconfiguring!\n");
5659 5660
  //}
  // CQI ReportConfig
Cedric Roux's avatar
Cedric Roux committed
5661 5662 5663 5664 5665
  physicalConfigDedicated2->cqi_ReportConfig = CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig));
  physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic = CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic));
  physicalConfigDedicated2->cqi_ReportConfig->nomPDSCH_RS_EPRE_Offset = 0; // 0 dB
  //physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic=NULL;
  physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic=CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic));
5666
  physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->present =  LTE_CQI_ReportPeriodic_PR_release;
5667 5668

  //if ((*physicalConfigDedicated)->cqi_ReportConfig) {
Cedric Roux's avatar
Cedric Roux committed
5669 5670 5671
  if ((rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm4) ||
      (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm5) ||
      (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm6)) {
Cedric Roux's avatar
Cedric Roux committed
5672 5673 5674
    //feedback mode needs to be set as well
    //TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable
    printf("setting cqi reporting mode to rm31\n");
5675 5676
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
    *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportModeAperiodic_rm31;
5677
#else
Cedric Roux's avatar
Cedric Roux committed
5678
    *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=CQI_ReportConfig__cqi_ReportModeAperiodic_rm31; // HLC CQI, no PMI
5679
#endif
Cedric Roux's avatar
Cedric Roux committed
5680
  } else {
5681 5682
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
    *physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic= LTE_CQI_ReportModeAperiodic_rm30;
5683
#else
Cedric Roux's avatar
Cedric Roux committed
5684
    *physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic=CQI_ReportConfig__cqi_ReportModeAperiodic_rm30; // HLC CQI, no PMI
5685
#endif
Cedric Roux's avatar
Cedric Roux committed
5686 5687
  }

5688 5689
  //}
  //else {
Cedric Roux's avatar
Cedric Roux committed
5690
  //LOG_E(RRC,"cqi_ReportConfig not present in physical_config_dedicated. Not reconfiguring!\n");
5691
  //}
5692
  // SchedulingRequestConfig
5693
  physicalConfigDedicated2->schedulingRequestConfig->present = LTE_SchedulingRequestConfig_PR_setup;
5694
  physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = ue_context_pP->local_uid;
5695

5696
  if (rrc_inst->carrier[0].sib1->tdd_Config==NULL) {  // FDD
5697 5698
    physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 5 + (ue_context_pP->local_uid %
        10);   // Isr = 5 (every 10 subframes, offset=2+UE_id mod3)
5699
  } else {
5700
    switch (rrc_inst->carrier[0].sib1->tdd_Config->subframeAssignment) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5701 5702 5703 5704
      case 1:
        physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 7 + (ue_context_pP->local_uid & 1) + ((
              ue_context_pP->local_uid & 3) >> 1) * 5;    // Isr = 5 (every 10 subframes, offset=2 for UE0, 3 for UE1, 7 for UE2, 8 for UE3 , 2 for UE4 etc..)
        break;
5705

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5706 5707 5708 5709
      case 3:
        physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 7 + (ue_context_pP->local_uid %
            3);    // Isr = 5 (every 10 subframes, offset=2 for UE0, 3 for UE1, 3 for UE2, 2 for UE3 , etc..)
        break;
5710

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5711 5712 5713 5714
      case 4:
        physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 7 + (ue_context_pP->local_uid &
            1);    // Isr = 5 (every 10 subframes, offset=2 for UE0, 3 for UE1, 3 for UE2, 2 for UE3 , etc..)
        break;
5715

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5716 5717 5718
      default:
        physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 7; // Isr = 5 (every 10 subframes, offset=2 for all UE0 etc..)
        break;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
5719
    }
5720
  }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
5721

5722 5723 5724 5725
  //  assign_enum(&physicalConfigDedicated2->schedulingRequestConfig->choice.setup.dsr_TransMax,
  //SchedulingRequestConfig__setup__dsr_TransMax_n4);
  //  assign_enum(&physicalConfigDedicated2->schedulingRequestConfig->choice.setup.dsr_TransMax = SchedulingRequestConfig__setup__dsr_TransMax_n4;
  physicalConfigDedicated2->schedulingRequestConfig->choice.setup.dsr_TransMax =
5726
    LTE_SchedulingRequestConfig__setup__dsr_TransMax_n4;
5727
  LOG_D(RRC,
5728 5729
        "handover_config [FRAME %05d][RRC_eNB][MOD %02d][][--- MAC_CONFIG_REQ  (SRB1 UE %x) --->][MAC_eNB][MOD %02d][]\n",
        ctxt_pP->frame, ctxt_pP->module_id, ue_context_pP->ue_context.rnti, ctxt_pP->module_id);
5730
  rrc_mac_config_req_eNB(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5731 5732 5733
    ctxt_pP->module_id,
    ue_context_pP->ue_context.primaryCC_id,
    0,0,0,0,0,
5734
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5735 5736 5737 5738 5739
    0,
#endif
    ue_context_pP->ue_context.rnti,
    (LTE_BCCH_BCH_Message_t *) NULL,
    (LTE_RadioResourceConfigCommonSIB_t *) NULL,
5740
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5741
    (LTE_RadioResourceConfigCommonSIB_t *) NULL,
5742
#endif
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5743
    ue_context_pP->ue_context.physicalConfigDedicated,
5744
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5745 5746 5747 5748 5749 5750
    (LTE_SCellToAddMod_r10_t *)NULL,
    //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL,
#endif
    (LTE_MeasObjectToAddMod_t **) NULL,
    ue_context_pP->ue_context.mac_MainConfig,
    1,
5751
    NULL,//SRB1_logicalChannelConfig,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5752 5753 5754 5755 5756 5757 5758 5759
    ue_context_pP->ue_context.measGapConfig,
    (LTE_TDD_Config_t *) NULL,
    (LTE_MobilityControlInfo_t *) NULL,
    (LTE_SchedulingInfoList_t *) NULL,
    0,
    NULL,
    NULL,
    (LTE_MBSFN_SubframeConfigList_t *) NULL
5760
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5761
    , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL
5762
#endif
5763
#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5764 5765
    ,
    (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL
5766 5767 5768 5769 5770 5771 5772 5773 5774
#endif
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                        ,
                        0,
                        (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL,
                        (LTE_SchedulingInfo_MBMS_r14_t *) NULL,
                        (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
                        (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
                        (LTE_MBSFN_AreaInfoList_r9_t *) NULL
5775
#endif
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5776
  );
5777 5778 5779 5780 5781 5782 5783 5784
  // Configure target eNB SRB2
  /// SRB2
  SRB2_config = CALLOC(1, sizeof(*SRB2_config));
  SRB_configList2 = CALLOC(1, sizeof(*SRB_configList2));
  memset(SRB_configList2, 0, sizeof(*SRB_configList2));
  SRB2_config->srb_Identity = 2;
  SRB2_rlc_config = CALLOC(1, sizeof(*SRB2_rlc_config));
  SRB2_config->rlc_Config = SRB2_rlc_config;
5785 5786 5787 5788 5789 5790 5791 5792
  SRB2_rlc_config->present = LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue;
  SRB2_rlc_config->choice.explicitValue.present = LTE_RLC_Config_PR_am;
  SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms15;
  SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p8;
  SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kB1000;
  SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t32;
  SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35;
  SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms10;
5793 5794
  SRB2_lchan_config = CALLOC(1, sizeof(*SRB2_lchan_config));
  SRB2_config->logicalChannelConfig = SRB2_lchan_config;
5795
  SRB2_lchan_config->present = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue;
5796 5797 5798
  SRB2_ul_SpecificParameters = CALLOC(1, sizeof(*SRB2_ul_SpecificParameters));
  SRB2_ul_SpecificParameters->priority = 1;
  SRB2_ul_SpecificParameters->prioritisedBitRate =
5799
    LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
5800
  SRB2_ul_SpecificParameters->bucketSizeDuration =
5801
    LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
5802 5803 5804 5805 5806 5807
  // LCG for CCCH and DCCH is 0 as defined in 36331
  logicalchannelgroup = CALLOC(1, sizeof(long));
  *logicalchannelgroup = 0;
  SRB2_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup;
  SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters = SRB2_ul_SpecificParameters;
  ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config);
5808
  ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config);
5809 5810 5811 5812
  // Configure target eNB DRB
  DRB_configList2 = CALLOC(1, sizeof(*DRB_configList2));
  /// DRB
  DRB_config = CALLOC(1, sizeof(*DRB_config));
5813
  //DRB_config->drb_Identity = (LTE_DRB_Identity_t) 1; //allowed values 1..32
5814
  // NN: this is the 1st DRB for this ue, so set it to 1
5815
  DRB_config->drb_Identity = (LTE_DRB_Identity_t) 1;  // (ue_mod_idP+1); //allowed values 1..32
5816 5817 5818 5819
  DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long));
  *(DRB_config->logicalChannelIdentity) = (long)3;
  DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config));
  DRB_config->rlc_Config = DRB_rlc_config;
5820 5821 5822 5823
  DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional;
  DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10;
  DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10;
  DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35;
5824 5825 5826 5827 5828 5829
  DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config));
  DRB_config->pdcp_Config = DRB_pdcp_config;
  DRB_pdcp_config->discardTimer = NULL;
  DRB_pdcp_config->rlc_AM = NULL;
  PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM));
  DRB_pdcp_config->rlc_UM = PDCP_rlc_UM;
5830 5831
  PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits;
  DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed;
5832 5833 5834 5835 5836 5837
  DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config));
  DRB_config->logicalChannelConfig = DRB_lchan_config;
  DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters));
  DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters;
  DRB_ul_SpecificParameters->priority = 2;    // lower priority than srb1, srb2
  DRB_ul_SpecificParameters->prioritisedBitRate =
5838
    LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
5839
  DRB_ul_SpecificParameters->bucketSizeDuration =
5840
    LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
5841 5842 5843 5844
  // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM)
  logicalchannelgroup_drb = CALLOC(1, sizeof(long));
  *logicalchannelgroup_drb = 1;
  DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb;
5845
  ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config);
5846
  mac_MainConfig = CALLOC(1, sizeof(*mac_MainConfig));
5847
  ue_context_pP->ue_context.mac_MainConfig = mac_MainConfig;
5848 5849
  mac_MainConfig->ul_SCH_Config = CALLOC(1, sizeof(*mac_MainConfig->ul_SCH_Config));
  maxHARQ_Tx = CALLOC(1, sizeof(long));
5850
  *maxHARQ_Tx = LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5;
5851 5852
  mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx;
  periodicBSR_Timer = CALLOC(1, sizeof(long));
5853
  *periodicBSR_Timer = LTE_PeriodicBSR_Timer_r12_sf64;
5854
  mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer;
5855
  mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320;
5856 5857 5858
  mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE
  mac_MainConfig->drx_Config = NULL;
  mac_MainConfig->phr_Config = CALLOC(1, sizeof(*mac_MainConfig->phr_Config));
5859 5860 5861 5862 5863
  mac_MainConfig->phr_Config->present = LTE_MAC_MainConfig__phr_Config_PR_setup;
  mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; // sf20 = 20 subframes
  mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; // sf20 = 20 subframes
  mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1;  // Value dB1 =1 dB, dB3 = 3 dB
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
5864 5865
  sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long));
  *sr_ProhibitTimer_r9 = 0;   // SR tx on PUCCH, Value in number of SR period(s). Value 0 = no timer for SR, Value 2= 2*SR
5866
  mac_MainConfig->ext1 = CALLOC(1, sizeof(struct LTE_MAC_MainConfig__ext1));
5867
  mac_MainConfig->ext1->sr_ProhibitTimer_r9 = sr_ProhibitTimer_r9;
5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902
  //sps_RA_ConfigList_rlola = NULL;
#endif
  // Measurement ID list
  MeasId_list = CALLOC(1, sizeof(*MeasId_list));
  memset((void *)MeasId_list, 0, sizeof(*MeasId_list));
  MeasId0 = CALLOC(1, sizeof(*MeasId0));
  MeasId0->measId = 1;
  MeasId0->measObjectId = 1;
  MeasId0->reportConfigId = 1;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId0);
  MeasId1 = CALLOC(1, sizeof(*MeasId1));
  MeasId1->measId = 2;
  MeasId1->measObjectId = 1;
  MeasId1->reportConfigId = 2;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId1);
  MeasId2 = CALLOC(1, sizeof(*MeasId2));
  MeasId2->measId = 3;
  MeasId2->measObjectId = 1;
  MeasId2->reportConfigId = 3;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId2);
  MeasId3 = CALLOC(1, sizeof(*MeasId3));
  MeasId3->measId = 4;
  MeasId3->measObjectId = 1;
  MeasId3->reportConfigId = 4;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId3);
  MeasId4 = CALLOC(1, sizeof(*MeasId4));
  MeasId4->measId = 5;
  MeasId4->measObjectId = 1;
  MeasId4->reportConfigId = 5;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId4);
  MeasId5 = CALLOC(1, sizeof(*MeasId5));
  MeasId5->measId = 6;
  MeasId5->measObjectId = 1;
  MeasId5->reportConfigId = 6;
  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId5);
5903
  //  LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measIdToAddModList = MeasId_list;
5904 5905 5906 5907 5908 5909 5910
  // Add one EUTRA Measurement Object
  MeasObj_list = CALLOC(1, sizeof(*MeasObj_list));
  memset((void *)MeasObj_list, 0, sizeof(*MeasObj_list));
  // Configure MeasObject
  MeasObj = CALLOC(1, sizeof(*MeasObj));
  memset((void *)MeasObj, 0, sizeof(*MeasObj));
  MeasObj->measObjectId = 1;
5911
  MeasObj->measObject.present = LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA;
5912 5913 5914 5915
  MeasObj->measObject.choice.measObjectEUTRA.carrierFreq =
      to_earfcn_DL(RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0],
                   RC.rrc[ctxt_pP->module_id]->configuration.downlink_frequency[0],
                   RC.rrc[ctxt_pP->module_id]->configuration.N_RB_DL[0]);
5916
  MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = LTE_AllowedMeasBandwidth_mbw25;
5917 5918 5919 5920 5921 5922
  MeasObj->measObject.choice.measObjectEUTRA.presenceAntennaPort1 = 1;
  MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf = CALLOC(1, sizeof(uint8_t));
  MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf[0] = 0;
  MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.size = 1;
  MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.bits_unused = 6;
  MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = NULL;   // Default is 15 or 0dB
5923 5924 5925 5926 5927 5928

  if (RC.rrc[ctxt_pP->module_id]->num_neigh_cells > 0) {
    MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList =
      (LTE_CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList));
    CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList;
  }
5929 5930 5931 5932 5933 5934 5935

  if (!ue_context_pP->ue_context.measurement_info) {
    ue_context_pP->ue_context.measurement_info = CALLOC(1,sizeof(*(ue_context_pP->ue_context.measurement_info)));
  }

  //TODO: Assign proper values
  ue_context_pP->ue_context.measurement_info->offsetFreq = 0;
5936
  ue_context_pP->ue_context.measurement_info->cellIndividualOffset[0] = LTE_Q_OffsetRange_dB0;
5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947

  /* TODO: Extend to multiple carriers */
  // Add adjacent cell lists (max 6 per eNB)
  for (i = 0; i < RC.rrc[ctxt_pP->module_id]->num_neigh_cells; i++) {
    CellToAdd = (LTE_CellsToAddMod_t *) CALLOC(1, sizeof(*CellToAdd));
    CellToAdd->cellIndex = i + 1;
    CellToAdd->physCellId = RC.rrc[ctxt_pP->module_id]->neigh_cells_id[i][0];//get_adjacent_cell_id(ctxt_pP->module_id, i);
    CellToAdd->cellIndividualOffset = LTE_Q_OffsetRange_dB0;
    ue_context_pP->ue_context.measurement_info->cellIndividualOffset[i+1] = CellToAdd->cellIndividualOffset;
    ASN_SEQUENCE_ADD(&CellsToAddModList->list, CellToAdd);
  }
5948
  ASN_SEQUENCE_ADD(&MeasObj_list->list, MeasObj);
5949
  //  LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measObjectToAddModList = MeasObj_list;
5950 5951 5952 5953 5954

  if (!ue_context_pP->ue_context.measurement_info->events) {
    ue_context_pP->ue_context.measurement_info->events = CALLOC(1,sizeof(*(ue_context_pP->ue_context.measurement_info->events)));
  }

5955 5956 5957 5958 5959 5960 5961 5962 5963
  // Report Configurations for periodical, A1-A5 events
  ReportConfig_list = CALLOC(1, sizeof(*ReportConfig_list));
  ReportConfig_per = CALLOC(1, sizeof(*ReportConfig_per));
  ReportConfig_A1 = CALLOC(1, sizeof(*ReportConfig_A1));
  ReportConfig_A2 = CALLOC(1, sizeof(*ReportConfig_A2));
  ReportConfig_A3 = CALLOC(1, sizeof(*ReportConfig_A3));
  ReportConfig_A4 = CALLOC(1, sizeof(*ReportConfig_A4));
  ReportConfig_A5 = CALLOC(1, sizeof(*ReportConfig_A5));
  ReportConfig_per->reportConfigId = 1;
5964
  ReportConfig_per->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
5965
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.present =
5966
    LTE_ReportConfigEUTRA__triggerType_PR_periodical;
5967
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.choice.periodical.purpose =
5968 5969 5970
    LTE_ReportConfigEUTRA__triggerType__periodical__purpose_reportStrongestCells;
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
5971
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
5972 5973
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
5974 5975
  ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_per);
  ReportConfig_A1->reportConfigId = 2;
5976
  ReportConfig_A1->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
5977
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.present =
5978
    LTE_ReportConfigEUTRA__triggerType_PR_event;
5979
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
5980
    LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1;
5981
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA1.
5982
  a1_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
5983 5984
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA1.
  a1_Threshold.choice.threshold_RSRP = 10;
5985 5986
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
5987
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
5988 5989
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
5990
  ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A1);
Cedric Roux's avatar
Cedric Roux committed
5991 5992 5993
  //  if (ho_state == 1 /*HO_MEASUREMENT */ ) {
  LOG_I(RRC, "[eNB %d] frame %d: requesting A2, A3, A4, and A5 event reporting\n",
        ctxt_pP->module_id, ctxt_pP->frame);
5994
  ReportConfig_A2->reportConfigId = 3;
5995
  ReportConfig_A2->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
5996
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.present =
5997
    LTE_ReportConfigEUTRA__triggerType_PR_event;
5998
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
5999
    LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2;
Cedric Roux's avatar
Cedric Roux committed
6000
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
6001
  eventA2.a2_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
Cedric Roux's avatar
Cedric Roux committed
6002 6003 6004
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
  eventA2.a2_Threshold.choice.threshold_RSRP = 10;
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
6005
    LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
6006
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
6007
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
6008 6009
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
6010 6011
  ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A2);
  ReportConfig_A3->reportConfigId = 4;
6012
  ReportConfig_A3->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
6013
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.present =
6014
    LTE_ReportConfigEUTRA__triggerType_PR_event;
6015
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
6016
    LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3;
Cedric Roux's avatar
Cedric Roux committed
6017
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset = 0;   //10;
6018 6019
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
  eventA3.reportOnLeave = 1;
Cedric Roux's avatar
Cedric Roux committed
6020
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
6021
    LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
6022
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
6023
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
6024 6025
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
Cedric Roux's avatar
Cedric Roux committed
6026 6027
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis = 0; // FIXME ...hysteresis is of type long!
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger =
6028
    LTE_TimeToTrigger_ms40;
6029 6030
  ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A3);
  ReportConfig_A4->reportConfigId = 5;
6031
  ReportConfig_A4->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
6032
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.present =
6033
    LTE_ReportConfigEUTRA__triggerType_PR_event;
6034
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
6035
    LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4;
Cedric Roux's avatar
Cedric Roux committed
6036
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
6037
  eventA4.a4_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
Cedric Roux's avatar
Cedric Roux committed
6038 6039 6040
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
  eventA4.a4_Threshold.choice.threshold_RSRP = 10;
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
6041
    LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
6042
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
6043
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
6044 6045
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
6046 6047
  ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A4);
  ReportConfig_A5->reportConfigId = 6;
6048
  ReportConfig_A5->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
6049
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.present =
6050
    LTE_ReportConfigEUTRA__triggerType_PR_event;
6051
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
6052
    LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA5;
6053
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
6054
  eventA5.a5_Threshold1.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
6055
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
6056
  eventA5.a5_Threshold2.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
6057 6058 6059 6060
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
  eventA5.a5_Threshold1.choice.threshold_RSRP = 10;
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
  eventA5.a5_Threshold2.choice.threshold_RSRP = 10;
Cedric Roux's avatar
Cedric Roux committed
6061
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
6062
    LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
6063
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
6064
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
6065 6066
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
6067
  ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A5);
Cedric Roux's avatar
Cedric Roux committed
6068
  //  rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list;
6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080

  /* A3 event update */
  if (!ue_context_pP->ue_context.measurement_info->events->a3_event) {
      ue_context_pP->ue_context.measurement_info->events->a3_event = CALLOC(1,sizeof(*(ue_context_pP->ue_context.measurement_info->events->a3_event)));
  }

  ue_context_pP->ue_context.measurement_info->events->a3_event->a3_offset = ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset;
  ue_context_pP->ue_context.measurement_info->events->a3_event->reportOnLeave = ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.reportOnLeave;
  ue_context_pP->ue_context.measurement_info->events->a3_event->hysteresis = ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis;
  ue_context_pP->ue_context.measurement_info->events->a3_event->timeToTrigger = ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger;
  ue_context_pP->ue_context.measurement_info->events->a3_event->maxReportCells = ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.maxReportCells;

6081 6082 6083 6084 6085 6086
#if 0
    /* TODO: set a proper value.
     * 20 means: UE does not report if RSRP of serving cell is higher
     * than -120 dB (see 36.331 5.5.3.1).
     * This is too low for the X2 handover experiment.
     */
Cedric Roux's avatar
Cedric Roux committed
6087 6088
  rsrp = CALLOC(1, sizeof(RSRP_Range_t));
  *rsrp = 20;
6089
#endif
6090
  Sparams = CALLOC(1, sizeof(*Sparams));
6091 6092 6093
  Sparams->present = LTE_MeasConfig__speedStatePars_PR_setup;
  Sparams->choice.setup.timeToTrigger_SF.sf_High = LTE_SpeedStateScaleFactors__sf_Medium_oDot75;
  Sparams->choice.setup.timeToTrigger_SF.sf_Medium = LTE_SpeedStateScaleFactors__sf_High_oDot5;
6094 6095
  Sparams->choice.setup.mobilityStateParameters.n_CellChangeHigh = 10;
  Sparams->choice.setup.mobilityStateParameters.n_CellChangeMedium = 5;
6096 6097
  Sparams->choice.setup.mobilityStateParameters.t_Evaluation = LTE_MobilityStateParameters__t_Evaluation_s60;
  Sparams->choice.setup.mobilityStateParameters.t_HystNormal = LTE_MobilityStateParameters__t_HystNormal_s120;
6098 6099
  quantityConfig = CALLOC(1, sizeof(*quantityConfig));
  memset((void *)quantityConfig, 0, sizeof(*quantityConfig));
6100
  quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(struct LTE_QuantityConfigEUTRA));
6101 6102 6103 6104 6105
  memset((void *)quantityConfig->quantityConfigEUTRA, 0, sizeof(*quantityConfig->quantityConfigEUTRA));
  quantityConfig->quantityConfigCDMA2000 = NULL;
  quantityConfig->quantityConfigGERAN = NULL;
  quantityConfig->quantityConfigUTRA = NULL;
  quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP =
Cedric Roux's avatar
Cedric Roux committed
6106
    CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP)));
6107
  quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ =
Cedric Roux's avatar
Cedric Roux committed
6108
    CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ)));
6109 6110
  *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = LTE_FilterCoefficient_fc4;
  *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = LTE_FilterCoefficient_fc4;
6111 6112 6113 6114

  ue_context_pP->ue_context.measurement_info->filterCoefficientRSRP = *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP;
  ue_context_pP->ue_context.measurement_info->filterCoefficientRSRQ = *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ;

6115
  /* mobilityinfo  */
Cedric Roux's avatar
Cedric Roux committed
6116
  mobilityInfo = ue_context_pP->ue_context.mobilityInfo;
6117

Cedric Roux's avatar
Cedric Roux committed
6118 6119 6120
  if (mobilityInfo) {
    free(mobilityInfo);
  }
6121

6122 6123
  mobilityInfo = CALLOC(1, sizeof(*mobilityInfo));
  memset((void *)mobilityInfo, 0, sizeof(*mobilityInfo));
Cedric Roux's avatar
Cedric Roux committed
6124 6125
  mobilityInfo->targetPhysCellId = RC.rrc[ctxt_pP->module_id]->carrier[0].physCellId;
  //(PhysCellId_t) two_tier_hexagonal_cellIds[ue_context_pP->ue_context.handover_info->modid_t];
Cedric Roux's avatar
Cedric Roux committed
6126
  LOG_D(RRC, "[eNB %d] Frame %d: handover preparation: targetPhysCellId: %ld mod_id: %d ue: %x \n",
6127 6128 6129
        ctxt_pP->module_id,
        ctxt_pP->frame,
        mobilityInfo->targetPhysCellId,
Cedric Roux's avatar
Cedric Roux committed
6130
        ctxt_pP->module_id, // get_adjacent_cell_mod_id(mobilityInfo->targetPhysCellId),
6131
        ue_context_pP->ue_context.rnti);
6132
  mobilityInfo->additionalSpectrumEmission = CALLOC(1, sizeof(*mobilityInfo->additionalSpectrumEmission));
6133
  *mobilityInfo->additionalSpectrumEmission = (LTE_AdditionalSpectrumEmission_t) 1;  //Check this value!
6134
  mobilityInfo->t304 = LTE_MobilityControlInfo__t304_ms200;    // need to configure an appropriate value here
6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146
  // New UE Identity (C-RNTI) to identify an UE uniquely in a cell
  mobilityInfo->newUE_Identity.size = 2;
  mobilityInfo->newUE_Identity.bits_unused = 0;
  mobilityInfo->newUE_Identity.buf = rv;
  mobilityInfo->newUE_Identity.buf[0] = rv[0];
  mobilityInfo->newUE_Identity.buf[1] = rv[1];
  //memset((void *)&mobilityInfo->radioResourceConfigCommon,(void *)&rrc_inst->sib2->radioResourceConfigCommon,sizeof(RadioResourceConfigCommon_t));
  //memset((void *)&mobilityInfo->radioResourceConfigCommon,0,sizeof(RadioResourceConfigCommon_t));
  // Configuring radioResourceConfigCommon
  mobilityInfo->radioResourceConfigCommon.rach_ConfigCommon =
    CALLOC(1, sizeof(*mobilityInfo->radioResourceConfigCommon.rach_ConfigCommon));
  memcpy((void *)mobilityInfo->radioResourceConfigCommon.rach_ConfigCommon,
6147
         (void *)&rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.rach_ConfigCommon, sizeof(LTE_RACH_ConfigCommon_t));
6148 6149 6150
  mobilityInfo->radioResourceConfigCommon.prach_Config.prach_ConfigInfo =
    CALLOC(1, sizeof(*mobilityInfo->radioResourceConfigCommon.prach_Config.prach_ConfigInfo));
  memcpy((void *)mobilityInfo->radioResourceConfigCommon.prach_Config.prach_ConfigInfo,
6151
         (void *)&rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.prach_Config.prach_ConfigInfo,
6152
         sizeof(LTE_PRACH_ConfigInfo_t));
6153
  mobilityInfo->radioResourceConfigCommon.prach_Config.rootSequenceIndex =
6154
    rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.prach_Config.rootSequenceIndex;
6155 6156 6157
  mobilityInfo->radioResourceConfigCommon.pdsch_ConfigCommon =
    CALLOC(1, sizeof(*mobilityInfo->radioResourceConfigCommon.pdsch_ConfigCommon));
  memcpy((void *)mobilityInfo->radioResourceConfigCommon.pdsch_ConfigCommon,
6158
         (void *)&rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.pdsch_ConfigCommon, sizeof(LTE_PDSCH_ConfigCommon_t));
6159
  memcpy((void *)&mobilityInfo->radioResourceConfigCommon.pusch_ConfigCommon,
6160
         (void *)&rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.pusch_ConfigCommon, sizeof(LTE_PUSCH_ConfigCommon_t));
6161 6162 6163 6164
  mobilityInfo->radioResourceConfigCommon.phich_Config = NULL;
  mobilityInfo->radioResourceConfigCommon.pucch_ConfigCommon =
    CALLOC(1, sizeof(*mobilityInfo->radioResourceConfigCommon.pucch_ConfigCommon));
  memcpy((void *)mobilityInfo->radioResourceConfigCommon.pucch_ConfigCommon,
6165
         (void *)&rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.pucch_ConfigCommon, sizeof(LTE_PUCCH_ConfigCommon_t));
6166 6167 6168
  mobilityInfo->radioResourceConfigCommon.soundingRS_UL_ConfigCommon =
    CALLOC(1, sizeof(*mobilityInfo->radioResourceConfigCommon.soundingRS_UL_ConfigCommon));
  memcpy((void *)mobilityInfo->radioResourceConfigCommon.soundingRS_UL_ConfigCommon,
6169
         (void *)&rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon,
6170
         sizeof(LTE_SoundingRS_UL_ConfigCommon_t));
6171 6172 6173
  mobilityInfo->radioResourceConfigCommon.uplinkPowerControlCommon =
    CALLOC(1, sizeof(*mobilityInfo->radioResourceConfigCommon.uplinkPowerControlCommon));
  memcpy((void *)mobilityInfo->radioResourceConfigCommon.uplinkPowerControlCommon,
6174
         (void *)&rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.uplinkPowerControlCommon,
6175
         sizeof(LTE_UplinkPowerControlCommon_t));
6176 6177 6178
  mobilityInfo->radioResourceConfigCommon.antennaInfoCommon = NULL;
  mobilityInfo->radioResourceConfigCommon.p_Max = NULL;   // CALLOC(1,sizeof(*mobilityInfo->radioResourceConfigCommon.p_Max));
  //memcpy((void *)mobilityInfo->radioResourceConfigCommon.p_Max,(void *)rrc_inst->sib1->p_Max,sizeof(P_Max_t));
Cedric Roux's avatar
Cedric Roux committed
6179 6180
  mobilityInfo->radioResourceConfigCommon.tdd_Config = NULL;  //CALLOC(1,sizeof(TDD_Config_t));
  //memcpy((void *)mobilityInfo->radioResourceConfigCommon.tdd_Config,(void *)rrc_inst->sib1->tdd_Config,sizeof(TDD_Config_t));
6181
  mobilityInfo->radioResourceConfigCommon.ul_CyclicPrefixLength =
6182
    rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.ul_CyclicPrefixLength;
6183 6184
  //End of configuration of radioResourceConfigCommon
  mobilityInfo->carrierFreq = CALLOC(1, sizeof(*mobilityInfo->carrierFreq));  //CALLOC(1,sizeof(CarrierFreqEUTRA_t)); 36090
6185 6186 6187 6188
  mobilityInfo->carrierFreq->dl_CarrierFreq =
      to_earfcn_DL(RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0],
                   RC.rrc[ctxt_pP->module_id]->configuration.downlink_frequency[0],
                   RC.rrc[ctxt_pP->module_id]->configuration.N_RB_DL[0]);
6189
  mobilityInfo->carrierFreq->ul_CarrierFreq = NULL;
6190
  mobilityInfo->carrierBandwidth = CALLOC(1, sizeof(
Cedric Roux's avatar
Cedric Roux committed
6191
      *mobilityInfo->carrierBandwidth));    //CALLOC(1,sizeof(struct CarrierBandwidthEUTRA));  AllowedMeasBandwidth_mbw25
6192
  mobilityInfo->carrierBandwidth->dl_Bandwidth = LTE_CarrierBandwidthEUTRA__dl_Bandwidth_n25;
6193 6194
  mobilityInfo->carrierBandwidth->ul_Bandwidth = NULL;
  mobilityInfo->rach_ConfigDedicated = NULL;
Cedric Roux's avatar
Cedric Roux committed
6195
  ue_context_pP->ue_context.mobilityInfo = mobilityInfo;
6196
#if 0
Cedric Roux's avatar
Cedric Roux committed
6197 6198 6199 6200 6201 6202 6203 6204 6205 6206
  LOG_I(RRC,
        "[eNB %d] Frame %d: potential handover preparation: store the information in an intermediate structure in case of failure\n",
        ctxt_pP->module_id, ctxt_pP->frame);
  // store the information in an intermediate structure for Hanodver management
  //rrc_inst->handover_info.as_config.sourceRadioResourceConfig.srb_ToAddModList = CALLOC(1,sizeof());
  ue_context_pP->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_pP->ue_context.handover_info)));
  //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.srb_ToAddModList,(void *)SRB_list,sizeof(SRB_ToAddModList_t));
  ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.srb_ToAddModList = *SRB_configList2;
  //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.drb_ToAddModList,(void *)DRB_list,sizeof(DRB_ToAddModList_t));
  ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToAddModList = *DRB_configList;
6207
  ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToReleaseList = NULL;
Cedric Roux's avatar
Cedric Roux committed
6208 6209
  ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig =
    CALLOC(1, sizeof(*ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6210
  memcpy((void *)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig,
Cedric Roux's avatar
Cedric Roux committed
6211 6212 6213
         (void *)mac_MainConfig, sizeof(MAC_MainConfig_t));
  ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated =
    CALLOC(1, sizeof(PhysicalConfigDedicated_t));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6214
  memcpy((void *)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated,
Cedric Roux's avatar
Cedric Roux committed
6215 6216 6217 6218 6219
         (void *)ue_context_pP->ue_context.physicalConfigDedicated, sizeof(PhysicalConfigDedicated_t));
  ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.sps_Config = NULL;
  //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.sps_Config,(void *)rrc_inst->sps_Config[ue_mod_idP],sizeof(SPS_Config_t));
#endif
  //  }
6220 6221
  securityConfigHO = CALLOC(1, sizeof(*securityConfigHO));
  memset((void *)securityConfigHO, 0, sizeof(*securityConfigHO));
6222
  securityConfigHO->handoverType.present = LTE_SecurityConfigHO__handoverType_PR_intraLTE;
6223 6224 6225 6226 6227
  securityConfigHO->handoverType.choice.intraLTE.securityAlgorithmConfig = NULL; /* TODO: to be checked */
  securityConfigHO->handoverType.choice.intraLTE.keyChangeIndicator = 0;
  securityConfigHO->handoverType.choice.intraLTE.nextHopChainingCount = 0;
#if defined(ENABLE_ITTI)
  /* Initialize NAS list */
6228
  dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList));
6229 6230 6231 6232

  /* Add all NAS PDUs to the list */
  for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) {
    if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) {
6233
      dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t));
6234 6235
      memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t));
      OCTET_STRING_fromBuf(dedicatedInfoNas,
Cedric Roux's avatar
Cedric Roux committed
6236
                           (char *)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer,
6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249
                           ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length);
      ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas);
    }

    /* TODO parameters yet to process ... */
    {
      //      ue_context_pP->ue_context.e_rab[i].param.qos;
      //      ue_context_pP->ue_context.e_rab[i].param.sgw_addr;
      //      ue_context_pP->ue_context.e_rab[i].param.gtp_teid;
    }
    /* TODO should test if e RAB are Ok before! */
    ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE;
    LOG_D(RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n",
Cedric Roux's avatar
Cedric Roux committed
6250
          i, ue_context_pP->ue_context.e_rab[i].status, "E_RAB_STATUS_DONE");
6251 6252 6253 6254 6255 6256 6257 6258 6259
  }

  /* If list is empty free the list and reset the address */
  if (dedicatedInfoNASList->list.count == 0) {
    free(dedicatedInfoNASList);
    dedicatedInfoNASList = NULL;
  }

#endif
Cedric Roux's avatar
Cedric Roux committed
6260

6261 6262
  measurements_enabled = RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]->configuration.enable_x2 ||
                         RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]->configuration.enable_measurement_reports;
Cedric Roux's avatar
Cedric Roux committed
6263

6264 6265 6266 6267
  memset(buffer, 0, RRC_BUF_SIZE);
  char rrc_buf[1000 /* arbitrary, should be big enough, has to be less than size of return buf by a few bits/bytes */];
  int rrc_size;
  rrc_size = do_RRCConnectionReconfiguration(ctxt_pP,
Cedric Roux's avatar
Cedric Roux committed
6268 6269 6270 6271 6272
             (unsigned char *)rrc_buf,
             xid,   //Transaction_id,
             NULL, // SRB_configList
             NULL,
             NULL,  // DRB2_list,
6273 6274
             (struct LTE_SPS_Config *)NULL,   // *sps_Config,
             (struct LTE_PhysicalConfigDedicated *)*physicalConfigDedicated,
Cedric Roux's avatar
Cedric Roux committed
6275 6276 6277
             //#ifdef EXMIMO_IOT
             //                                         NULL, NULL, NULL,NULL,
             //#else
6278 6279 6280 6281
             measurements_enabled ? (LTE_MeasObjectToAddModList_t *)MeasObj_list : NULL,
             measurements_enabled ? (LTE_ReportConfigToAddModList_t *)ReportConfig_list : NULL,
             measurements_enabled ? (LTE_QuantityConfig_t *)quantityConfig : NULL,
             measurements_enabled ? (LTE_MeasIdToAddModList_t *)MeasId_list : NULL,
Cedric Roux's avatar
Cedric Roux committed
6282
             //#endif
6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294
             (LTE_MAC_MainConfig_t *)mac_MainConfig,
             (LTE_MeasGapConfig_t *)NULL,
             (LTE_MobilityControlInfo_t *)mobilityInfo,
             (LTE_SecurityConfigHO_t *)securityConfigHO,
             (struct LTE_MeasConfig__speedStatePars *)Sparams,
             (LTE_RSRP_Range_t *)rsrp,
             (LTE_C_RNTI_t *)cba_RNTI,
             (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)dedicatedInfoNASList,
             (LTE_SL_CommConfig_r12_t *)NULL,
             (LTE_SL_DiscConfig_r12_t *)NULL
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
             , (LTE_SCellToAddMod_r10_t *)NULL
6295
#endif
Cedric Roux's avatar
Cedric Roux committed
6296
                                            );
6297

Cedric Roux's avatar
Cedric Roux committed
6298 6299 6300 6301
  if (rrc_size <= 0) {
    printf("%s:%d: fatal\n", __FILE__, __LINE__);
    abort();
  }
6302

Cedric Roux's avatar
Cedric Roux committed
6303
  char *ho_buf = (char *)buffer;
6304 6305
  int ho_size;
  ho_size = do_HandoverCommand(
Cedric Roux's avatar
Cedric Roux committed
6306 6307 6308
              ho_buf, 1024 /* TODO: this is the value found in struct x2ap_handover_req_ack_s for array rrc_buffer */,
              rrc_buf,
              rrc_size);
6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339
  *_size = size = ho_size;
  LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size,
              "[MSG] RRC Connection Reconfiguration handover\n");
#if defined(ENABLE_ITTI)

  /* Free all NAS PDUs */
  for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) {
    if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) {
      /* Free the NAS PDU buffer and invalidate it */
      free(ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer);
      ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer = NULL;
    }
  }

#endif
  LOG_I(RRC,
        "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration handover (bytes %d, UE id %x)\n",
        ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti);
  LOG_D(RRC,
        "[FRAME %05d][RRC_eNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration handover to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
        ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_eNB_mui, ctxt_pP->module_id, DCCH);
  MSC_LOG_TX_MESSAGE(
    MSC_RRC_ENB,
    MSC_RRC_UE,
    buffer,
    size,
    MSC_AS_TIME_FMT" rrcConnectionReconfiguration handover UE %x MUI %d size %u",
    MSC_AS_TIME_ARGS(ctxt_pP),
    ue_context_pP->ue_context.rnti,
    rrc_eNB_mui,
    size);
6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351

  free(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ);
  quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = NULL;

  free(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP);
  quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = NULL;

  free(quantityConfig->quantityConfigEUTRA);
  quantityConfig->quantityConfigEUTRA = NULL;

  free(quantityConfig);
  quantityConfig = NULL;
6352 6353 6354

  free(securityConfigHO);
  securityConfigHO = NULL;
6355 6356 6357

  free(Sparams);
  Sparams = NULL;
6358 6359 6360
}

void
Cedric Roux's avatar
Cedric Roux committed
6361
rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s *ue_context_p, protocol_ctxt_t *const ctxt_pP) {
6362
  uint16_t                            Idx;
6363
  Idx = DCCH;
6364
#if 1
Cedric Roux's avatar
Cedric Roux committed
6365
  // Activate the radio bearers
6366
  // SRB1
Cedric Roux's avatar
Cedric Roux committed
6367 6368 6369 6370
  ue_context_p->ue_context.Srb1.Active = 1;
  ue_context_p->ue_context.Srb1.Srb_info.Srb_id = Idx;
  memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[0], &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE);
  memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[1], &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6371
  // SRB2
Cedric Roux's avatar
Cedric Roux committed
6372 6373 6374 6375 6376
  ue_context_p->ue_context.Srb2.Active = 1;
  ue_context_p->ue_context.Srb2.Srb_info.Srb_id = Idx;
  memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[0], &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE);
  memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[1], &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE);
#endif
6377
  LOG_I(RRC, "[eNB %d] CALLING RLC CONFIG SRB1 (rbid %d) for UE %x\n",
Cedric Roux's avatar
Cedric Roux committed
6378 6379 6380 6381
        ctxt_pP->module_id, Idx, ue_context_p->ue_context.rnti);
  // Configure PDCP/RLC for the target
  rrc_pdcp_config_asn1_req(ctxt_pP,
                           ue_context_p->ue_context.SRB_configList,
6382 6383
                           (LTE_DRB_ToAddModList_t *) NULL,
                           (LTE_DRB_ToReleaseList_t *) NULL,
Cedric Roux's avatar
Cedric Roux committed
6384 6385 6386 6387
                           0xff,
                           NULL,
                           NULL,
                           NULL
nepes's avatar
nepes committed
6388
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
6389
                           , (LTE_PMCH_InfoList_r9_t *) NULL
winckel's avatar
winckel committed
6390
#endif
Cedric Roux's avatar
Cedric Roux committed
6391 6392 6393
                           , NULL);
  rrc_rlc_config_asn1_req(ctxt_pP,
                          ue_context_p->ue_context.SRB_configList,
6394 6395
                          (LTE_DRB_ToAddModList_t *) NULL,
                          (LTE_DRB_ToReleaseList_t *) NULL
nepes's avatar
nepes committed
6396
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
6397
                          , (LTE_PMCH_InfoList_r9_t *) NULL
6398
                          , 0, 0
Lionel Gauthier's avatar
 
Lionel Gauthier committed
6399
#endif
6400
                         );
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6401

Cedric Roux's avatar
Cedric Roux committed
6402
  if (EPC_MODE_ENABLED) {
6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414
  rrc_eNB_process_security (
    ctxt_pP,
    ue_context_p,
    &ue_context_p->ue_context.security_capabilities);
  process_eNB_security_key (
    ctxt_pP,
    ue_context_p,
    ue_context_p->ue_context.kenb);
  rrc_pdcp_config_security(
    ctxt_pP,
    ue_context_p,
    FALSE);
Cedric Roux's avatar
Cedric Roux committed
6415
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6416

6417 6418
  // Add a new user (called during the HO procedure)
  LOG_I(RRC, "rrc_eNB_target_add_ue_handover module_id %d rnti %d\n", ctxt_pP->module_id, ctxt_pP->rnti);
Cedric Roux's avatar
Cedric Roux committed
6419
  // Configure MAC for the target
6420
  rrc_mac_config_req_eNB(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6421
    ctxt_pP->module_id,
Cedric Roux's avatar
Cedric Roux committed
6422
    ue_context_p->ue_context.primaryCC_id,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6423
    0,0,0,0,0,
6424
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6425
    0,
6426
#endif
Cedric Roux's avatar
Cedric Roux committed
6427
    ue_context_p->ue_context.rnti,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6428 6429
    (LTE_BCCH_BCH_Message_t *) NULL,
    (LTE_RadioResourceConfigCommonSIB_t *) NULL,
6430
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6431
    (LTE_RadioResourceConfigCommonSIB_t *) NULL,
6432
#endif
Cedric Roux's avatar
Cedric Roux committed
6433
    ue_context_p->ue_context.physicalConfigDedicated,
6434
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6435
    (LTE_SCellToAddMod_r10_t *)NULL,
Cedric Roux's avatar
Cedric Roux committed
6436
    //(struct PhysicalConfigDedicatedSCell_r10 *)NULL,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6437 6438
#endif
    (LTE_MeasObjectToAddMod_t **) NULL,
Cedric Roux's avatar
Cedric Roux committed
6439
    ue_context_p->ue_context.mac_MainConfig,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6440
    1,
Cedric Roux's avatar
Cedric Roux committed
6441 6442
    NULL,//SRB1_logicalChannelConfig,
    ue_context_p->ue_context.measGapConfig,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6443
    (LTE_TDD_Config_t *) NULL,
6444 6445
    (LTE_MobilityControlInfo_t *) ue_context_p->ue_context.mobilityInfo,
    (LTE_SchedulingInfoList_t *) NULL,
Cedric Roux's avatar
Cedric Roux committed
6446 6447 6448
    0,
    NULL,
    NULL,
6449
    (LTE_MBSFN_SubframeConfigList_t *) NULL
6450
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6451
    , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL
6452
#endif
6453
#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6454 6455
    ,
    (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL
6456 6457 6458 6459 6460 6461 6462 6463 6464
#endif
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                        ,
                        0,
                        (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL,
                        (LTE_SchedulingInfo_MBMS_r14_t *) NULL,
                        (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
                        (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
                        (LTE_MBSFN_AreaInfoList_r9_t *) NULL
6465
#endif
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6466
  );
6467 6468 6469
//#if 0
//}
//#endif
winckel's avatar
winckel committed
6470
}
6471

6472
//-----------------------------------------------------------------------------
6473
/*
6474
* Process the RRC Connection Reconfiguration Complete from the UE
6475
*/
6476 6477
void
rrc_eNB_process_RRCConnectionReconfigurationComplete(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6478
  const protocol_ctxt_t *const ctxt_pP,
6479
  rrc_eNB_ue_context_t  *ue_context_pP,
6480
  const uint8_t xid
6481 6482
)
//-----------------------------------------------------------------------------
6483
{
OAI-admin's avatar
OAI-admin committed
6484
  int                                 drb_id;
6485 6486 6487 6488 6489
  int                                 oip_ifup = 0;
  int                                 dest_ip_offset = 0;
  uint8_t                            *kRRCenc = NULL;
  uint8_t                            *kRRCint = NULL;
  uint8_t                            *kUPenc = NULL;
6490 6491 6492 6493 6494
  LTE_DRB_ToAddModList_t             *DRB_configList = ue_context_pP->ue_context.DRB_configList2[xid];
  LTE_SRB_ToAddModList_t             *SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid];
  LTE_DRB_ToReleaseList_t            *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid];
  LTE_DRB_Identity_t                 *drb_id_p      = NULL;

6495
  ue_context_pP->ue_context.ue_reestablishment_timer = 0;
6496 6497
  ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // reset rrc inactivity timer

6498 6499 6500
  if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
    /* CDRX: activated if ack was expected */
    int UE_id_mac = find_UE_id(ctxt_pP->module_id, ue_context_pP->ue_context.rnti);
6501 6502 6503 6504
    if (UE_id_mac == -1){
      LOG_E(RRC,PROTOCOL_RRC_CTXT_UE_FMT" rrc_eNB_process_RRCConnectionReconfigurationComplete without UE_id(MAC) rnti %x, let's return\n",PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ue_context_pP->ue_context.rnti);
      return;
    }
6505
    UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id_mac]);
6506 6507 6508 6509 6510 6511 6512
    
    if (UE_scheduling_control->cdrx_waiting_ack == TRUE) {
      UE_scheduling_control->cdrx_waiting_ack = FALSE;
      UE_scheduling_control->cdrx_configured = TRUE;
      LOG_I(RRC, "CDRX configuration activated after RRC Connection Reconfiguration Complete reception\n");
    }
  } // No CDRX with the CU/DU split in this version of the code
6513 6514 6515 6516 6517 6518

  T(T_ENB_RRC_CONNECTION_RECONFIGURATION_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
6519

6520 6521
  /* Derive the keys from kenb */
  if (DRB_configList != NULL) {
6522
    derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm,
6523 6524
                      ue_context_pP->ue_context.kenb,
                      &kUPenc);
6525 6526
  }

6527
  derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm,
6528 6529 6530
                     ue_context_pP->ue_context.kenb,
                     &kRRCenc);

6531
  derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm,
6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547
                     ue_context_pP->ue_context.kenb,
                     &kRRCint);

  /* Refresh SRBs/DRBs */
  MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_PDCP_ENB, NULL, 0, MSC_AS_TIME_FMT" CONFIG_REQ UE %x DRB (security unchanged)",
                     MSC_AS_TIME_ARGS(ctxt_pP),
                     ue_context_pP->ue_context.rnti);

  rrc_pdcp_config_asn1_req(ctxt_pP,
                          SRB_configList, // NULL,
                          DRB_configList,
                          DRB_Release_configList2,
                          0xff, // already configured during the securitymodecommand
                          kRRCenc,
                          kRRCint,
                          kUPenc
6548
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
6549
                          , (LTE_PMCH_InfoList_r9_t *) NULL
6550
#endif
6551 6552 6553 6554 6555 6556 6557
                          , NULL);

  /* Refresh SRBs/DRBs */
  rrc_rlc_config_asn1_req(ctxt_pP,
                          SRB_configList, // NULL,
                          DRB_configList,
                          DRB_Release_configList2
6558
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
6559 6560 6561
                          , (LTE_PMCH_InfoList_r9_t *) NULL,
                          0,
                          0
winckel's avatar
winckel committed
6562
#endif
6563
                          );
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6564

6565
  /* Set the SRB active in UE context */
6566
  if (SRB_configList != NULL) {
6567 6568 6569 6570 6571 6572
    for (int i = 0; (i < SRB_configList->list.count) && (i < 3); i++) {
      if (SRB_configList->list.array[i]->srb_Identity == 1) {
        ue_context_pP->ue_context.Srb1.Active = 1;
      } else if (SRB_configList->list.array[i]->srb_Identity == 2) {
        ue_context_pP->ue_context.Srb2.Active = 1;
        ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = 2;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6573 6574 6575 6576
        LOG_I(RRC,"[eNB %d] Frame  %d CC %d : SRB2 is now active\n",
              ctxt_pP->module_id,
              ctxt_pP->frame,
              ue_context_pP->ue_context.primaryCC_id);
6577
      } else {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6578 6579 6580
        LOG_W(RRC,"[eNB %d] Frame  %d CC %d : invalide SRB identity %ld\n",
              ctxt_pP->module_id,
              ctxt_pP->frame,
Cedric Roux's avatar
Cedric Roux committed
6581
              ue_context_pP->ue_context.primaryCC_id,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6582
              SRB_configList->list.array[i]->srb_Identity);
6583 6584
      }
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6585

6586 6587
    free(SRB_configList);
    ue_context_pP->ue_context.SRB_configList2[xid] = NULL;
6588
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6589

6590
  /* Loop through DRBs and establish if necessary */
6591
  if (DRB_configList != NULL) {
6592
    for (int i = 0; i < DRB_configList->list.count; i++) {  // num max DRB (11-3-8)
6593
      if (DRB_configList->list.array[i]) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6594
        drb_id = (int)DRB_configList->list.array[i]->drb_Identity;
6595 6596

        LOG_I(RRC, "[eNB %d] Frame  %d : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete from UE rnti %x, reconfiguring DRB %d/LCID %d\n",
6597 6598 6599 6600 6601
              ctxt_pP->module_id,
              ctxt_pP->frame,
              ctxt_pP->rnti,
              (int)DRB_configList->list.array[i]->drb_Identity,
              (int)*DRB_configList->list.array[i]->logicalChannelIdentity);
6602 6603 6604

        /* For pre-ci tests */
        LOG_I(RRC, "[eNB %d] Frame  %d : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete from UE %u, reconfiguring DRB %d/LCID %d\n",
6605 6606 6607
              ctxt_pP->module_id,
              ctxt_pP->frame,
              oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid],
6608
              (int)DRB_configList->list.array[i]->drb_Identity,
6609
              (int)*DRB_configList->list.array[i]->logicalChannelIdentity);
6610

6611 6612
        if (ue_context_pP->ue_context.DRB_active[drb_id] == 0) {
          ue_context_pP->ue_context.DRB_active[drb_id] = 1;
6613
          LOG_D(RRC, "[eNB %d] Frame %d: Establish RLC UM Bidirectional, DRB %d Active\n",
6614
                ctxt_pP->module_id, ctxt_pP->frame, (int)DRB_configList->list.array[i]->drb_Identity);
6615

6616
          if (!EPC_MODE_ENABLED && !ENB_NAS_USE_TUN) {
6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642
            LOG_I(OIP, "[eNB %d] trying to bring up the OAI interface oai%d\n",
                  ctxt_pP->module_id,
                  ctxt_pP->module_id);

            oip_ifup = nas_config(ctxt_pP->module_id,   // interface index
                                  ctxt_pP->module_id + 1,   // third octet
                                  ctxt_pP->module_id + 1,   // fourth octet
                                  "oai");

            if (oip_ifup == 0) { // interface is up --> send a config the DRB
              module_id_t ue_module_id;
              dest_ip_offset = 8;
              LOG_I(OIP,
                    "[eNB %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n",
                    ctxt_pP->module_id, ctxt_pP->module_id,
                      (long int)((ue_context_pP->local_uid * LTE_maxDRB) + DRB_configList->list.array[i]->drb_Identity));
              ue_module_id = oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid];
              rb_conf_ipv4(0, //add
                          ue_module_id,  //cx
                          ctxt_pP->module_id,    //inst
                            (ue_module_id * LTE_maxDRB) + DRB_configList->list.array[i]->drb_Identity, // RB
                          0,    //dscp
                          ipv4_address(ctxt_pP->module_id + 1, ctxt_pP->module_id + 1),  //saddr
                          ipv4_address(ctxt_pP->module_id + 1, dest_ip_offset + ue_module_id + 1));  //daddr
              LOG_D(RRC, "[eNB %d] State = Attached (UE rnti %x module id %u)\n",
                    ctxt_pP->module_id, ue_context_pP->ue_context.rnti, ue_module_id);
6643 6644
            } /* oip_ifup */
          } /* !EPC_MODE_ENABLED && ENB_NAS_USE_TUN*/
6645

6646
          LOG_D(RRC,
6647 6648
                PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ  (DRB) ---> MAC_eNB\n",
                PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
6649

6650
          if (DRB_configList->list.array[i]->logicalChannelIdentity) {
6651
            DRB2LCHAN[i] = (uint8_t) * DRB_configList->list.array[i]->logicalChannelIdentity;
6652
          }
6653

6654 6655 6656 6657 6658 6659 6660 6661
	        if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) {
            rrc_mac_config_req_eNB(ctxt_pP->module_id,
                                   ue_context_pP->ue_context.primaryCC_id,
                                   0,
                                   0,
                                   0,
                                   0,
                                   0,
6662
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
6663
                                   0,
6664
#endif
6665 6666 6667
                                   ue_context_pP->ue_context.rnti,
                                   (LTE_BCCH_BCH_Message_t *) NULL,
                                   (LTE_RadioResourceConfigCommonSIB_t *) NULL,
6668
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
6669
                                   (LTE_RadioResourceConfigCommonSIB_t *) NULL,
6670
#endif
6671
                                   ue_context_pP->ue_context.physicalConfigDedicated,
6672
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
6673
                                   (LTE_SCellToAddMod_r10_t *)NULL,
6674
#endif
6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686
                                   (LTE_MeasObjectToAddMod_t **) NULL,
                                   ue_context_pP->ue_context.mac_MainConfig,
                                   DRB2LCHAN[i],
                                   DRB_configList->list.array[i]->logicalChannelConfig,
                                   ue_context_pP->ue_context.measGapConfig,
                                   (LTE_TDD_Config_t *) NULL,
                                   NULL,
                                   (LTE_SchedulingInfoList_t *) NULL,
                                   0,
                                   NULL,
                                   NULL,
                                   (LTE_MBSFN_SubframeConfigList_t *) NULL
6687
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
6688 6689 6690
                                   , 0,
                                   (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
                                   (LTE_PMCH_InfoList_r9_t *) NULL
winckel's avatar
winckel committed
6691
#endif
6692
#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
6693 6694
                                   ,
                                   (LTE_SystemInformationBlockType1_v1310_IEs_t *) NULL
6695 6696 6697 6698 6699 6700 6701 6702 6703
#endif
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                        ,
                        0,
                        (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL,
                        (LTE_SchedulingInfo_MBMS_r14_t *) NULL,
                        (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
                        (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
                        (LTE_MBSFN_AreaInfoList_r9_t *) NULL
6704
#endif
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6705
          );
6706
	 }
6707
        } else {        // remove LCHAN from MAC/PHY
6708
          if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) {
6709
            // DRB has just been removed so remove RLC + PDCP for DRB
6710
            /*      rrc_pdcp_config_req (ctxt_pP->module_id, frameP, 1, CONFIG_ACTION_REMOVE,
6711 6712
               (ue_mod_idP * NB_RB_MAX) + DRB2LCHAN[i],UNDEF_SECURITY_MODE);
             */
6713 6714 6715 6716 6717 6718 6719 6720
            if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
              rrc_rlc_config_req(ctxt_pP,
                                SRB_FLAG_NO,
                                MBMS_FLAG_NO,
                                CONFIG_ACTION_REMOVE,
                                DRB2LCHAN[i],
                                Rlc_info_um);
            }
6721 6722
          }

6723
          ue_context_pP->ue_context.DRB_active[drb_id] = 0;
6724 6725

          LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ  (DRB) ---> MAC_eNB\n",
6726
                PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
6727
          if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) {
6728 6729
            rrc_mac_config_req_eNB(ctxt_pP->module_id,
                                   ue_context_pP->ue_context.primaryCC_id,
6730 6731 6732 6733 6734
                                   0,
                                   0,
                                   0,
                                   0,
                                   0,
6735
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
6736
                                   0,
6737
#endif
6738 6739 6740
                                   ue_context_pP->ue_context.rnti,
                                   (LTE_BCCH_BCH_Message_t *) NULL,
                                   (LTE_RadioResourceConfigCommonSIB_t *) NULL,
6741
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
6742
                                   (LTE_RadioResourceConfigCommonSIB_t *) NULL,
6743
#endif
6744
                                   ue_context_pP->ue_context.physicalConfigDedicated,
6745
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
6746
                                   (LTE_SCellToAddMod_r10_t *) NULL,
6747 6748 6749 6750 6751 6752 6753 6754 6755
#endif
                                   (LTE_MeasObjectToAddMod_t **) NULL,
                                   ue_context_pP->ue_context.mac_MainConfig,
                                   DRB2LCHAN[i],
                                   (LTE_LogicalChannelConfig_t *) NULL,
                                   (LTE_MeasGapConfig_t *) NULL,
                                   (LTE_TDD_Config_t *) NULL,
                                   NULL,
                                   (LTE_SchedulingInfoList_t *) NULL,
6756 6757 6758 6759
                                   0,
                                   NULL,
                                   NULL,
                                   NULL
6760
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
6761 6762 6763 6764
                                   ,
                                   0,
                                   (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
                                   (LTE_PMCH_InfoList_r9_t *) NULL
winckel's avatar
winckel committed
6765
#endif
6766
#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
6767
                                   ,
6768
                                   (LTE_SystemInformationBlockType1_v1310_IEs_t *) NULL
6769 6770 6771 6772 6773 6774 6775 6776 6777
#endif
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                        ,
                        0,
                        (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL,
                        (LTE_SchedulingInfo_MBMS_r14_t *) NULL,
                        (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
                        (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
                        (LTE_MBSFN_AreaInfoList_r9_t *) NULL
6778
#endif
6779
                                   );
6780
          }
6781 6782 6783
        } // end else of if (ue_context_pP->ue_context.DRB_active[drb_id] == 0)
      } // end if (DRB_configList->list.array[i])
    } // end for (int i = 0; i < DRB_configList->list.count; i++)
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6784 6785

    free(DRB_configList);
6786
    ue_context_pP->ue_context.DRB_configList2[xid] = NULL;
6787
  } // end if DRB_configList != NULL
6788

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6789
  if(DRB_Release_configList2 != NULL) {
6790
    for (int i = 0; i < DRB_Release_configList2->list.count; i++) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6791 6792 6793 6794 6795 6796 6797
      if (DRB_Release_configList2->list.array[i]) {
        drb_id_p = DRB_Release_configList2->list.array[i];
        drb_id = *drb_id_p;

        if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) {
          ue_context_pP->ue_context.DRB_active[drb_id] = 0;
        }
6798
      }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6799 6800 6801 6802
    }

    free(DRB_Release_configList2);
    ue_context_pP->ue_context.DRB_Release_configList2[xid] = NULL;
6803
  }
winckel's avatar
winckel committed
6804
}
6805

6806
//-----------------------------------------------------------------------------
6807 6808 6809 6810 6811 6812
void
rrc_eNB_generate_RRCConnectionSetup(
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t  *const ue_context_pP,
  const int                    CC_id
)
6813
//-----------------------------------------------------------------------------
6814
{
6815
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
Ahmed.Elias's avatar
Ahmed.Elias committed
6816 6817
  boolean_t is_mtc = ctxt_pP->brOption;
#endif
6818 6819 6820
  LTE_LogicalChannelConfig_t             *SRB1_logicalChannelConfig;  //,*SRB2_logicalChannelConfig;
  LTE_SRB_ToAddModList_t                **SRB_configList;
  LTE_SRB_ToAddMod_t                     *SRB1_config;
6821

6822
  MessageDef                             *message_p;
6823
     
6824 6825 6826 6827 6828
  T(T_ENB_RRC_CONNECTION_SETUP,
    T_INT(ctxt_pP->module_id),
    T_INT(ctxt_pP->frame),
    T_INT(ctxt_pP->subframe),
    T_INT(ctxt_pP->rnti));
Cedric Roux's avatar
Cedric Roux committed
6829

6830 6831
  eNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; 
  SRB_configList = &ue_p->SRB_configList;
6832

6833
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
6834

6835
  if (is_mtc) {
6836
    ue_p->Srb0.Tx_buffer.payload_size =
6837
      do_RRCConnectionSetup_BR(ctxt_pP,
6838 6839 6840 6841 6842 6843 6844
                                ue_context_pP,
                                CC_id,
                                (uint8_t *) ue_p->Srb0.Tx_buffer.Payload,
                                (const uint8_t) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, //at this point we do not have the UE capability information, so it can only be TM1 or TM2
                                rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),
                                SRB_configList,
                                &ue_context_pP->ue_context.physicalConfigDedicated);
6845
  } else
Ahmed.Elias's avatar
Ahmed.Elias committed
6846 6847
#endif
  {
6848
    ue_p->Srb0.Tx_buffer.payload_size =
6849
      do_RRCConnectionSetup(ctxt_pP,
6850 6851 6852 6853 6854 6855 6856
                            ue_context_pP,
                            CC_id,
                            (uint8_t*) ue_p->Srb0.Tx_buffer.Payload,
                            (uint8_t) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, //at this point we do not have the UE capability information, so it can only be TM1 or TM2
                            rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),
                            SRB_configList,
                            &ue_context_pP->ue_context.physicalConfigDedicated);
6857
  }
6858 6859 6860 6861
  LOG_DUMPMSG(RRC,DEBUG_RRC,
              (char *)(ue_p->Srb0.Tx_buffer.Payload),
              ue_p->Srb0.Tx_buffer.payload_size,
              "[MSG] RRC Connection Setup\n");
6862

6863
  // configure SRB1/SRB2, PhysicalConfigDedicated, MAC_MainConfig for UE
6864 6865 6866 6867 6868
   switch (RC.rrc[ctxt_pP->module_id]->node_type){
    case ngran_eNB_CU    :
    case ngran_ng_eNB_CU :
    case ngran_gNB_CU    :
      // create an ITTI message
6869 6870
      /* TODO: F1 IDs ar missing in RRC */
      message_p = itti_alloc_new_message (TASK_RRC_ENB, F1AP_DL_RRC_MESSAGE);
6871
      F1AP_DL_RRC_MESSAGE (message_p).rrc_container =  (uint8_t*)ue_p->Srb0.Tx_buffer.Payload;
6872

6873
      F1AP_DL_RRC_MESSAGE (message_p).rrc_container_length = ue_p->Srb0.Tx_buffer.payload_size;
6874
      F1AP_DL_RRC_MESSAGE (message_p).gNB_CU_ue_id     = 0;  
6875 6876
      F1AP_DL_RRC_MESSAGE (message_p).gNB_DU_ue_id = 0;
      F1AP_DL_RRC_MESSAGE (message_p).old_gNB_DU_ue_id  = 0xFFFFFFFF; // unknown 
6877
      F1AP_DL_RRC_MESSAGE (message_p).rnti = ue_p->rnti; 
6878 6879 6880
      F1AP_DL_RRC_MESSAGE (message_p).srb_id = CCCH;  
      F1AP_DL_RRC_MESSAGE (message_p).execute_duplication      = 1;
      F1AP_DL_RRC_MESSAGE (message_p).RAT_frequency_priority_information.en_dc      = 0; 
6881
      itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p);
Bing-Kai Hong's avatar
Bing-Kai Hong committed
6882
      LOG_D(RRC, "Send F1AP_DL_RRC_MESSAGE with ITTI\n");
6883 6884 6885 6886
      break;
    case ngran_eNB_DU    :
    case ngran_gNB_DU  :
      // nothing to do for DU 
6887
      AssertFatal(1==0,"nothing to do for DU\n");
6888
      break;
6889 6890 6891 6892
    case ngran_eNB:   
    case ngran_ng_eNB :
    case ngran_gNB  :  
  
6893 6894 6895 6896 6897 6898 6899 6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915
      if (*SRB_configList != NULL) {
        for (int cnt = 0; cnt < (*SRB_configList)->list.count; cnt++) {
          if ((*SRB_configList)->list.array[cnt]->srb_Identity == 1) {
           SRB1_config = (*SRB_configList)->list.array[cnt];

            if (SRB1_config->logicalChannelConfig) {
             if (SRB1_config->logicalChannelConfig->present ==
                  LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) {
                SRB1_logicalChannelConfig = &SRB1_config->logicalChannelConfig->choice.explicitValue;
              } else {
                SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue;
             }
            } else {
              SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue;
           }

           LOG_D(RRC,
                PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ  (SRB1) ---> MAC_eNB\n",
                PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
            if (RC.rrc[ctxt_pP->module_id]->node_type == ngran_eNB) {
             rrc_mac_config_req_eNB(ctxt_pP->module_id,
                                  ue_context_pP->ue_context.primaryCC_id,
                                  0,0,0,0,0,
6916
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
6917
                                   0,
6918
#endif
6919 6920 6921
                                  ue_context_pP->ue_context.rnti,
                                  (LTE_BCCH_BCH_Message_t *) NULL,
                                  (LTE_RadioResourceConfigCommonSIB_t *) NULL,
6922
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
6923
                                  (LTE_RadioResourceConfigCommonSIB_t *) NULL,
6924
#endif
6925
                                  ue_context_pP->ue_context.physicalConfigDedicated,
6926
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
6927 6928
                                   (LTE_SCellToAddMod_r10_t *)NULL,
                                  //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL,
6929
#endif
6930 6931 6932 6933 6934 6935 6936 6937 6938
                                  (LTE_MeasObjectToAddMod_t **) NULL,
                                  ue_context_pP->ue_context.mac_MainConfig,
                                  1,
                                  SRB1_logicalChannelConfig,
                                  ue_context_pP->ue_context.measGapConfig,
                                  (LTE_TDD_Config_t *) NULL,
                                  NULL,
                                  (LTE_SchedulingInfoList_t *) NULL,
                                  0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL
6939
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
6940
                                  , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL
winckel's avatar
winckel committed
6941
#endif
6942
#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
6943 6944
                                   ,
                                  (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL
6945 6946 6947 6948 6949 6950 6951 6952 6953
#endif
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                        ,
                        0,
                        (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL,
                        (LTE_SchedulingInfo_MBMS_r14_t *) NULL,
                        (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
                        (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
                        (LTE_MBSFN_AreaInfoList_r9_t *) NULL
6954
#endif
6955 6956 6957
				 );
	  break;
	}
6958
      }
winckel's avatar
winckel committed
6959
    }
6960

6961 6962
    break;
  default :
6963 6964 6965
    LOG_W(RRC, "Unknown node type %d\n", RC.rrc[ctxt_pP->module_id]->node_type);		
  }
  
6966
  MSC_LOG_TX_MESSAGE(
6967 6968
    MSC_RRC_ENB,
    MSC_RRC_UE,
6969 6970
    ue_p->Srb0.Tx_buffer.Header, // LG WARNING
    ue_p->Srb0.Tx_buffer.payload_size,
6971 6972 6973
    MSC_AS_TIME_FMT" RRCConnectionSetup UE %x size %u",
    MSC_AS_TIME_ARGS(ctxt_pP),
    ue_context_pP->ue_context.rnti,
6974
    ue_p->Srb0.Tx_buffer.payload_size);
6975

6976 6977

  LOG_I(RRC,
6978 6979
        PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCConnectionSetup (bytes %d)\n",
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
6980
        ue_p->Srb0.Tx_buffer.payload_size);
6981

6982
     // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE
6983 6984 6985 6986 6987 6988
    ue_context_pP->ue_context.ue_release_timer = 1;
    // remove UE after 10 frames after RRCConnectionRelease is triggered
    ue_context_pP->ue_context.ue_release_timer_thres = 1000;

  /* init timers */
  ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0;
6989
  }
winckel's avatar
winckel committed
6990
}
6991

6992 6993
void setup_ngran_CU(eNB_RRC_INST *rrc) {

6994
  
6995
}
Lionel Gauthier's avatar
 
Lionel Gauthier committed
6996

6997
//-----------------------------------------------------------------------------
6998
char openair_rrc_eNB_configuration(
6999 7000
  const module_id_t enb_mod_idP,
  RrcConfigurationReq *configuration
7001 7002
)
//-----------------------------------------------------------------------------
winckel's avatar
winckel committed
7003
{
7004
  protocol_ctxt_t ctxt;
7005
  int             CC_id;
7006
  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, enb_mod_idP, ENB_FLAG_YES, NOT_A_RNTI, 0, 0,enb_mod_idP);
7007 7008 7009
  LOG_I(RRC,
        PROTOCOL_RRC_CTXT_FMT" Init...\n",
        PROTOCOL_RRC_CTXT_ARGS(&ctxt));
laurent's avatar
laurent committed
7010
#if OCP_FRAMEWORK
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7011

7012 7013 7014 7015
  while ( RC.rrc[enb_mod_idP] == NULL ) {
    LOG_E(RRC, "RC.rrc not yet initialized, waiting 1 second\n");
    sleep(1);
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7016 7017

#endif
7018
  AssertFatal(RC.rrc[enb_mod_idP] != NULL, "RC.rrc not initialized!");
7019
  AssertFatal(MAX_MOBILES_PER_ENB < (module_id_t)0xFFFFFFFFFFFFFFFF, " variable overflow");
7020
  AssertFatal(configuration!=NULL,"configuration input is null\n");
7021
  RC.rrc[ctxt.module_id]->Nb_ue = 0;
7022

7023 7024
  pthread_mutex_init(&RC.rrc[ctxt.module_id]->cell_info_mutex,NULL);
  RC.rrc[ctxt.module_id]->cell_info_configured = 0;
7025

7026 7027
  uid_linear_allocator_init(&RC.rrc[ctxt.module_id]->uid_allocator);
  RB_INIT(&RC.rrc[ctxt.module_id]->rrc_ue_head);
7028
  //    for (j = 0; j < (MAX_MOBILES_PER_ENB + 1); j++) {
7029
  //        RC.rrc[enb_mod_idP]->Srb2[j].Active = 0;
7030
  //    }
7031 7032
  RC.rrc[ctxt.module_id]->initial_id2_s1ap_ids = hashtable_create (MAX_MOBILES_PER_ENB * 2, NULL, NULL);
  RC.rrc[ctxt.module_id]->s1ap_id2_s1ap_ids    = hashtable_create (MAX_MOBILES_PER_ENB * 2, NULL, NULL);
7033

7034
  /// System Information INIT
7035 7036
  LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Checking release \n",
        PROTOCOL_RRC_CTXT_ARGS(&ctxt));
7037
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
7038 7039
  // can clear it at runtime
  RC.rrc[ctxt.module_id]->carrier[0].MBMS_flag = 0;
7040
  // This has to come from some top-level configuration
7041
  // only CC_id 0 is logged
7042
#if (LTE_RRC_VERSION < MAKE_VERSION(10, 0, 0))
7043
  LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Rel10 RRC detected, MBMS flag %d\n",
Cedric Roux's avatar
Cedric Roux committed
7044 7045 7046
#else
  LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Rel14 RRC detected, MBMS flag %d\n",
#endif
7047
        PROTOCOL_RRC_CTXT_ARGS(&ctxt),
7048
        RC.rrc[ctxt.module_id]->carrier[0].MBMS_flag);
winckel's avatar
winckel committed
7049
#else
7050
  LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Rel8 RRC\n", PROTOCOL_RRC_CTXT_ARGS(&ctxt));
winckel's avatar
winckel committed
7051 7052
#endif
#ifdef CBA
7053

7054 7055
  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
    for (j = 0; j < NUM_MAX_CBA_GROUP; j++) {
7056
      RC.rrc[ctxt.module_id]->carrier[CC_id].cba_rnti[j] = CBA_OFFSET + j;
7057
    }
7058

7059 7060
    if (RC.rrc[ctxt.module_id]->carrier[CC_id].num_active_cba_groups > NUM_MAX_CBA_GROUP) {
      RC.rrc[ctxt.module_id]->carrier[CC_id].num_active_cba_groups = NUM_MAX_CBA_GROUP;
7061
    }
7062

7063 7064 7065
    LOG_D(RRC,
          PROTOCOL_RRC_CTXT_FMT" Initialization of 4 cba_RNTI values (%x %x %x %x) num active groups %d\n",
          PROTOCOL_RRC_CTXT_ARGS(&ctxt),
7066 7067 7068 7069 7070
          enb_mod_idP, RC.rrc[ctxt.module_id]->carrier[CC_id].cba_rnti[0],
          RC.rrc[ctxt.module_id]->carrier[CC_id].cba_rnti[1],
          RC.rrc[ctxt.module_id]->carrier[CC_id].cba_rnti[2],
          RC.rrc[ctxt.module_id]->carrier[CC_id].cba_rnti[3],
          RC.rrc[ctxt.module_id]->carrier[CC_id].num_active_cba_groups);
7071
  }
winckel's avatar
winckel committed
7072
#endif
7073

7074
  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
7075
    init_SI(&ctxt, CC_id, configuration);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7076

7077
    for (int ue_id = 0; ue_id < MAX_MOBILES_PER_ENB; ue_id++) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7078 7079
      RC.rrc[ctxt.module_id]->carrier[CC_id].sizeof_paging[ue_id] = 0;
      RC.rrc[ctxt.module_id]->carrier[CC_id].paging[ue_id] = (uint8_t *) malloc16(256);
7080
    }
7081
  }
7082 7083
  rrc_init_global_param();

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7084
  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
7085
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7086

7087
    switch (RC.rrc[ctxt.module_id]->carrier[CC_id].MBMS_flag) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7088 7089 7090 7091 7092 7093
      case 1:
      case 2:
      case 3:
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Configuring 1 MBSFN sync area\n", PROTOCOL_RRC_CTXT_ARGS(&ctxt));
        RC.rrc[ctxt.module_id]->carrier[CC_id].num_mbsfn_sync_area = 1;
        break;
7094

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7095 7096 7097 7098
      case 4:
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Configuring 2 MBSFN sync area\n", PROTOCOL_RRC_CTXT_ARGS(&ctxt));
        RC.rrc[ctxt.module_id]->carrier[CC_id].num_mbsfn_sync_area = 2;
        break;
7099

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7100 7101 7102
      default:
        RC.rrc[ctxt.module_id]->carrier[CC_id].num_mbsfn_sync_area = 0;
        break;
7103 7104
    }

7105
    // if we are here the RC.rrc[enb_mod_idP]->MBMS_flag > 0,
7106
    /// MCCH INIT
7107
    if (RC.rrc[ctxt.module_id]->carrier[CC_id].MBMS_flag > 0) {
7108 7109 7110 7111
      init_MCCH(ctxt.module_id, CC_id);
      /// MTCH data bearer init
      init_MBMS(ctxt.module_id, CC_id, 0);
    }
7112

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7113
#endif
7114 7115
    openair_rrc_top_init_eNB(RC.rrc[ctxt.module_id]->carrier[CC_id].MBMS_flag,0);
  }
7116
	
7117
  openair_rrc_on(&ctxt);
7118 7119 7120 7121 7122 7123 7124 7125 7126

/*
  RC.rrc[ctxt.module_id]->mcc= rrc_configuration_req->mcc;
  RC.rrc[ctxt.module_id]->mnc= rrc_configuration_req->mnc;
  RC.rrc[ctxt.module_id]->mnc_digit_length= rrc_configuration_req->mnc_digit_length;
  RC.rrc[ctxt.module_id]->tac= rrc_configuration_req->tac;

  LOG_W(RRC, "[inst %d] RRC->MCC/MSG->MCC %d/%d \n", ctxt.module_id, RC.rrc[ctxt.module_id]->mcc, rrc_configuration_req->mcc);
  */
7127
  if (NODE_IS_CU(RC.rrc[ctxt.module_id]->node_type))
7128 7129
  	// msg_p = itti_alloc_new_message (TASK_ENB_APP, F1AP_SCTP_REQ);
    // RCconfig_CU_F1(msg_p, enb_id);
7130 7131
    setup_ngran_CU(RC.rrc[ctxt.module_id]);
	
7132
  return 0;
winckel's avatar
winckel committed
7133
}
7134

winckel's avatar
winckel committed
7135
/*------------------------------------------------------------------------------*/
7136 7137 7138
int
rrc_eNB_decode_ccch(
  protocol_ctxt_t* const ctxt_pP,
Robert Schmidt's avatar
Robert Schmidt committed
7139
  const uint8_t          *buffer,
7140
  int                    buffer_length,
7141
  const int              CC_id
7142 7143
)
//-----------------------------------------------------------------------------
7144
{
7145 7146 7147
  module_id_t                                       Idx;
  asn_dec_rval_t                                    dec_rval;
  LTE_UL_CCCH_Message_t                             *ul_ccch_msg = NULL;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7148 7149
  LTE_RRCConnectionRequest_r8_IEs_t                *rrcConnectionRequest = NULL;
  LTE_RRCConnectionReestablishmentRequest_r8_IEs_t *rrcConnectionReestablishmentRequest = NULL;
7150
  int                                 i, rval;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7151
  struct rrc_eNB_ue_context_s                  *ue_context_p = NULL;
7152
  uint64_t                                      random_value = 0;
7153
  int                                           stmsi_received = 0;
Cedric Roux's avatar
Cedric Roux committed
7154 7155
  T(T_ENB_RRC_UL_CCCH_DATA_IN, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
    T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
7156
  //memset(ul_ccch_msg,0,sizeof(UL_CCCH_Message_t));
7157
  LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Decoding UL CCCH %x.%x.%x.%x.%x.%x (%p)\n",
7158
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
7159 7160 7161 7162 7163 7164
        ((uint8_t*) buffer)[0],
        ((uint8_t *) buffer)[1],
        ((uint8_t *) buffer)[2],
        ((uint8_t *) buffer)[3],
        ((uint8_t *) buffer)[4],
        ((uint8_t *) buffer)[5], (uint8_t *) buffer);
7165 7166
  dec_rval = uper_decode(
               NULL,
7167
               &asn_DEF_LTE_UL_CCCH_Message,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7168
               (void **)&ul_ccch_msg,
7169
               (uint8_t *) buffer,
7170 7171 7172
               100,
               0,
               0);
7173

7174
  for (i = 0; i < 8; i++) {
7175
    LOG_T(RRC, "%x.", ((uint8_t *) & ul_ccch_msg)[i]);
7176
  }
7177 7178

  if (dec_rval.consumed == 0) {
7179 7180 7181
    LOG_E(RRC,
          PROTOCOL_RRC_CTXT_UE_FMT" FATAL Error in receiving CCCH\n",
          PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
7182 7183 7184
    return -1;
  }

7185
  if (ul_ccch_msg->message.present == LTE_UL_CCCH_MessageType_PR_c1) {
7186
    switch (ul_ccch_msg->message.choice.c1.present) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7187 7188 7189 7190 7191
      case LTE_UL_CCCH_MessageType__c1_PR_NOTHING:
        LOG_I(RRC,
              PROTOCOL_RRC_CTXT_FMT" Received PR_NOTHING on UL-CCCH-Message\n",
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP));
        break;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
7192

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7193 7194 7195
      case LTE_UL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentRequest:
        T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_REQUEST, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
          T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
7196
        LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)(buffer), buffer_length,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7197 7198 7199 7200 7201 7202 7203 7204 7205 7206 7207 7208 7209 7210
                    "[MSG] RRC Connection Reestablishment Request\n");
        LOG_D(RRC,
              PROTOCOL_RRC_CTXT_UE_FMT"MAC_eNB--- MAC_DATA_IND (rrcConnectionReestablishmentRequest on SRB0) --> RRC_eNB\n",
              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
        rrcConnectionReestablishmentRequest =
          &ul_ccch_msg->message.choice.c1.choice.rrcConnectionReestablishmentRequest.criticalExtensions.choice.rrcConnectionReestablishmentRequest_r8;
        LOG_I(RRC,
              PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest cause %s\n",
              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
              ((rrcConnectionReestablishmentRequest->reestablishmentCause == LTE_ReestablishmentCause_otherFailure) ?    "Other Failure" :
               (rrcConnectionReestablishmentRequest->reestablishmentCause == LTE_ReestablishmentCause_handoverFailure) ? "Handover Failure" :
               "reconfigurationFailure"));
        {
          uint16_t                          c_rnti = 0;
Cedric Roux's avatar
Cedric Roux committed
7211

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7212 7213 7214 7215 7216 7217 7218 7219 7220
          if (rrcConnectionReestablishmentRequest->ue_Identity.physCellId != RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId) {
            LOG_E(RRC,
                  PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest ue_Identity.physCellId(%ld) is not equal to current physCellId(%d), let's reject the UE\n",
                  PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
                  rrcConnectionReestablishmentRequest->ue_Identity.physCellId,
                  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId);
            rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id);
            break;
          }
7221

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7222
          LOG_D(RRC, "physCellId is %ld\n", rrcConnectionReestablishmentRequest->ue_Identity.physCellId);
7223

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7224 7225 7226 7227
          for (i = 0; i < rrcConnectionReestablishmentRequest->ue_Identity.shortMAC_I.size; i++) {
            LOG_D(RRC, "rrcConnectionReestablishmentRequest->ue_Identity.shortMAC_I.buf[%d] = %x\n",
                  i, rrcConnectionReestablishmentRequest->ue_Identity.shortMAC_I.buf[i]);
          }
7228

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7229 7230 7231 7232 7233 7234 7235 7236
          if (rrcConnectionReestablishmentRequest->ue_Identity.c_RNTI.size == 0 ||
              rrcConnectionReestablishmentRequest->ue_Identity.c_RNTI.size > 2) {
            LOG_E(RRC,
                  PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest c_RNTI range error, let's reject the UE\n",
                  PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
            rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id);
            break;
          }
7237

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7238 7239 7240
          c_rnti = BIT_STRING_to_uint16(&rrcConnectionReestablishmentRequest->ue_Identity.c_RNTI);
          LOG_D(RRC, "c_rnti is %x\n", c_rnti);
          ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt_pP->module_id], c_rnti);
7241

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7242 7243 7244 7245 7246 7247 7248
          if (ue_context_p == NULL) {
            LOG_E(RRC,
                  PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest without UE context, let's reject the UE\n",
                  PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
            rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id);
            break;
          }
7249

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7250
          int UE_id = find_UE_id(ctxt_pP->module_id, c_rnti);
7251

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7252 7253 7254 7255 7256 7257 7258
          if(UE_id == -1) {
            LOG_E(RRC,
                  PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest without UE_id(MAC) rnti %x, let's reject the UE\n",
                  PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),c_rnti);
            rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id);
            break;
          }
7259 7260 7261 7262 7263 7264
      if((RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer > 0) &&
         (RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres > 20)){
         LOG_E(RRC,
               PROTOCOL_RRC_CTXT_UE_FMT" RCConnectionReestablishmentComplete(Previous) don't receive, delete the c-rnti UE\n",
               PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
         RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1000;
7265
         rrc_eNB_previous_SRB2(ue_context_p);
7266
         ue_context_p->ue_context.ue_reestablishment_timer = 0;
7267 7268 7269 7270 7271 7272 7273 7274 7275 7276 7277 7278 7279 7280 7281 7282 7283 7284
      }
      //previous rnti
      rnti_t previous_rnti = 0;
      for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
        if (reestablish_rnti_map[i][1] == c_rnti) {
          previous_rnti = reestablish_rnti_map[i][0];
          break;
        }
      }
      if(previous_rnti != 0){
        UE_id = find_UE_id(ctxt_pP->module_id, previous_rnti);
        if(UE_id == -1){
            LOG_E(RRC,
                  PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReestablishmentRequest without UE_id(MAC) previous rnti %x, let's reject the UE\n",
                  PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),previous_rnti);
            rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id);
            break;
        }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7285 7286 7287 7288 7289 7290
          if((RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer > 0) &&
              (RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres > 20)) {
            LOG_E(RRC,
                  PROTOCOL_RRC_CTXT_UE_FMT" RCConnectionReestablishmentComplete(Previous) don't receive, delete the Previous UE\n",
                  PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
            RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1000;
7291
          rrc_eNB_previous_SRB2(ue_context_p);
7292
          ue_context_p->ue_context.ue_reestablishment_timer = 0;
7293
        }
7294 7295 7296
      }

      //c-plane not end
Haruki NAOI's avatar
Haruki NAOI committed
7297
      if((ue_context_p->ue_context.Status != RRC_RECONFIGURED) && (ue_context_p->ue_context.reestablishment_cause == LTE_ReestablishmentCause_spare1)) {
7298 7299 7300 7301 7302 7303
        LOG_E(RRC,
             PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest (UE %x c-plane is not end), let's reject the UE\n",
             PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),c_rnti);
        rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id);
        break;
      }
7304

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7305 7306 7307 7308 7309 7310 7311 7312 7313 7314 7315 7316 7317 7318 7319
          if(ue_context_p->ue_context.ue_reestablishment_timer > 0) {
            LOG_E(RRC,
                  PROTOCOL_RRC_CTXT_UE_FMT" RRRCConnectionReconfigurationComplete(Previous) don't receive, delete the Previous UE\n",
                  PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
            ue_context_p->ue_context.Status = RRC_RECONFIGURED;
            protocol_ctxt_t  ctxt_old_p;
            PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt_old_p,
                                          ctxt_pP->instance,
                                          ENB_FLAG_YES,
                                          c_rnti,
                                          ctxt_pP->frame,
                                          ctxt_pP->subframe);
            rrc_eNB_process_RRCConnectionReconfigurationComplete(&ctxt_old_p,
                ue_context_p,
                ue_context_p->ue_context.reestablishment_xid);
7320

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7321 7322 7323 7324 7325 7326
            for (uint8_t e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
              if (ue_context_p->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE) {
                ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED;
              } else {
                ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_FAILED;
              }
7327 7328
            }
          }
7329

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7330 7331 7332 7333 7334 7335 7336 7337 7338 7339 7340 7341 7342 7343 7344 7345 7346
          LOG_D(RRC,
                PROTOCOL_RRC_CTXT_UE_FMT" UE context: %p\n",
                PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
                ue_context_p);
          /* reset timers */
          ue_context_p->ue_context.ul_failure_timer = 0;
          ue_context_p->ue_context.ue_release_timer = 0;
          ue_context_p->ue_context.ue_reestablishment_timer = 0;
          ue_context_p->ue_context.ue_release_timer_s1 = 0;
          ue_context_p->ue_context.ue_release_timer_rrc = 0;
          ue_context_p->ue_context.reestablishment_xid = -1;

          // insert C-RNTI to map
          for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
            if (reestablish_rnti_map[i][0] == 0) {
              reestablish_rnti_map[i][0] = ctxt_pP->rnti;
              reestablish_rnti_map[i][1] = c_rnti;
7347 7348
              LOG_D(RRC, "reestablish_rnti_map[%d] [0] %x, [1] %x\n",
                    i, reestablish_rnti_map[i][0], reestablish_rnti_map[i][1]);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7349 7350 7351 7352 7353 7354 7355 7356 7357
              break;
            }
          }

          ue_context_p->ue_context.reestablishment_cause = rrcConnectionReestablishmentRequest->reestablishmentCause;
          LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Accept connection reestablishment request from UE physCellId %ld cause %ld\n",
                PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
                rrcConnectionReestablishmentRequest->ue_Identity.physCellId,
                ue_context_p->ue_context.reestablishment_cause);
7358
#ifndef NO_RRM
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7359
          send_msg(&S_rrc, msg_rrc_MR_attach_ind(ctxt_pP->module_id, Mac_id));
7360
#else
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7361 7362 7363 7364 7365 7366 7367 7368 7369 7370 7371 7372 7373 7374 7375 7376 7377 7378 7379 7380 7381 7382 7383 7384 7385 7386 7387 7388 7389 7390 7391 7392 7393 7394 7395 7396 7397 7398 7399 7400 7401 7402
          ue_context_p->ue_context.primaryCC_id = CC_id;
          //LG COMMENT Idx = (ue_mod_idP * NB_RB_MAX) + DCCH;
          Idx = DCCH;
          // SRB1
          ue_context_p->ue_context.Srb1.Active = 1;
          ue_context_p->ue_context.Srb1.Srb_info.Srb_id = Idx;
          memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[0],
                 &DCCH_LCHAN_DESC,
                 LCHAN_DESC_SIZE);
          memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[1],
                 &DCCH_LCHAN_DESC,
                 LCHAN_DESC_SIZE);
          // SRB2: set  it to go through SRB1 with id 1 (DCCH)
          ue_context_p->ue_context.Srb2.Active = 1;
          ue_context_p->ue_context.Srb2.Srb_info.Srb_id = Idx;
          memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[0],
                 &DCCH_LCHAN_DESC,
                 LCHAN_DESC_SIZE);
          memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[1],
                 &DCCH_LCHAN_DESC,
                 LCHAN_DESC_SIZE);
          rrc_eNB_generate_RRCConnectionReestablishment(ctxt_pP, ue_context_p, CC_id);
          LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT"CALLING RLC CONFIG SRB1 (rbid %d)\n",
                PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
                Idx);
          MSC_LOG_TX_MESSAGE(MSC_RRC_ENB,
                             MSC_PDCP_ENB,
                             NULL,
                             0,
                             MSC_AS_TIME_FMT" CONFIG_REQ UE %x SRB",
                             MSC_AS_TIME_ARGS(ctxt_pP),
                             ue_context_p->ue_context.rnti);
          rrc_pdcp_config_asn1_req(ctxt_pP,
                                   ue_context_p->ue_context.SRB_configList,
                                   (LTE_DRB_ToAddModList_t *) NULL,
                                   (LTE_DRB_ToReleaseList_t *) NULL,
                                   0xff,
                                   NULL,
                                   NULL,
                                   NULL
                                   , (LTE_PMCH_InfoList_r9_t *) NULL
                                   ,NULL);
7403
          if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
7404 7405 7406 7407 7408 7409 7410 7411
            rrc_rlc_config_asn1_req(ctxt_pP,
                                    ue_context_p->ue_context.SRB_configList,
                                    (LTE_DRB_ToAddModList_t *) NULL,
                                    (LTE_DRB_ToReleaseList_t *) NULL
                                    , (LTE_PMCH_InfoList_r9_t *) NULL,
                                    0,0
                                   );
        }
7412
#endif //NO_RRM
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7413 7414
        }
        break;
Cedric Roux's avatar
Cedric Roux committed
7415

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7416 7417 7418
      case LTE_UL_CCCH_MessageType__c1_PR_rrcConnectionRequest:
        T(T_ENB_RRC_CONNECTION_REQUEST, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
          T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
Cedric Roux's avatar
Cedric Roux committed
7419

7420 7421
      LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,
                  buffer_length,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7422 7423 7424 7425 7426 7427 7428
                    "[MSG] RRC Connection Request\n");
        LOG_D(RRC,
              PROTOCOL_RRC_CTXT_UE_FMT"MAC_eNB --- MAC_DATA_IND  (rrcConnectionRequest on SRB0) --> RRC_eNB\n",
              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
        ue_context_p = rrc_eNB_get_ue_context(
                         RC.rrc[ctxt_pP->module_id],
                         ctxt_pP->rnti);
7429

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7430 7431 7432 7433 7434 7435
        if (ue_context_p != NULL) {
          // erase content
          rrc_eNB_free_mem_UE_context(ctxt_pP, ue_context_p);
          MSC_LOG_RX_DISCARDED_MESSAGE(
            MSC_RRC_ENB,
            MSC_RRC_UE,
7436
            buffer,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7437 7438 7439 7440 7441 7442 7443 7444 7445 7446 7447 7448 7449 7450
            dec_rval.consumed,
            MSC_AS_TIME_FMT" LTE_RRCConnectionRequest UE %x size %u (UE already in context)",
            MSC_AS_TIME_ARGS(ctxt_pP),
            ue_context_p->ue_context.rnti,
            dec_rval.consumed);
        } else {
          rrcConnectionRequest = &ul_ccch_msg->message.choice.c1.choice.rrcConnectionRequest.criticalExtensions.choice.rrcConnectionRequest_r8;
          {
            if (LTE_InitialUE_Identity_PR_randomValue == rrcConnectionRequest->ue_Identity.present) {
              if(rrcConnectionRequest->ue_Identity.choice.randomValue.size != 5) {
                LOG_I(RRC, "wrong InitialUE-Identity randomValue size, expected 5, provided %lu",
                      (long unsigned int)rrcConnectionRequest->ue_Identity.choice.randomValue.size);
                return -1;
              }
7451

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7452 7453 7454 7455 7456 7457 7458 7459 7460 7461 7462 7463
              memcpy(((uint8_t *) & random_value) + 3,
                     rrcConnectionRequest->ue_Identity.choice.randomValue.buf,
                     rrcConnectionRequest->ue_Identity.choice.randomValue.size);

              /* if there is already a registered UE (with another RNTI) with this random_value,
               * the current one must be removed from MAC/PHY (zombie UE)
               */
              if ((ue_context_p = rrc_eNB_ue_context_random_exist(ctxt_pP, random_value))) {
                LOG_W(RRC, "new UE rnti %x (coming with random value) is already there as UE %x, removing %x from MAC/PHY\n",
                      ctxt_pP->rnti, ue_context_p->ue_context.rnti, ue_context_p->ue_context.rnti);
                ue_context_p->ue_context.ul_failure_timer = 20000;
              }
7464

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7465
              ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP, random_value);
7466

7467 7468 7469 7470 7471 7472
              ue_context_p->ue_context.Srb0.Srb_id = 0;
              ue_context_p->ue_context.Srb0.Active = 1;
              memcpy(ue_context_p->ue_context.Srb0.Rx_buffer.Payload,
                     buffer,
                     buffer_length);
              ue_context_p->ue_context.Srb0.Rx_buffer.payload_size = buffer_length;
7473

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7474 7475 7476 7477 7478 7479 7480 7481 7482
            } else if (LTE_InitialUE_Identity_PR_s_TMSI == rrcConnectionRequest->ue_Identity.present) {
              /* Save s-TMSI */
              LTE_S_TMSI_t   s_TMSI = rrcConnectionRequest->ue_Identity.choice.s_TMSI;
              mme_code_t mme_code = BIT_STRING_to_uint8(&s_TMSI.mmec);
              m_tmsi_t   m_tmsi   = BIT_STRING_to_uint32(&s_TMSI.m_TMSI);
              random_value = (((uint64_t)mme_code) << 32) | m_tmsi;

              if ((ue_context_p = rrc_eNB_ue_context_stmsi_exist(ctxt_pP, mme_code, m_tmsi))) {
                LOG_I(RRC," S-TMSI exists, ue_context_p %p, old rnti %x => %x\n",ue_context_p,ue_context_p->ue_context.rnti,ctxt_pP->rnti);
7483

7484
                if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
7485 7486 7487 7488 7489 7490 7491 7492 7493 7494 7495
                  rrc_mac_remove_ue(ctxt_pP->module_id, ue_context_p->ue_context.rnti);
                }
                else {
                  MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, F1AP_UE_CONTEXT_RELEASE_CMD);
                  F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = ctxt_pP->rnti;
                  F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK;
                  F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release
                  F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = NULL;
                  F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container_length = 0;
                  itti_send_msg_to_task(TASK_CU_F1, ctxt_pP->module_id, m);
                }
7496

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7497 7498 7499 7500 7501 7502 7503 7504 7505 7506 7507 7508 7509 7510 7511
                stmsi_received=1;
                /* replace rnti in the context */
                /* for that, remove the context from the RB tree */
                RB_REMOVE(rrc_ue_tree_s, &RC.rrc[ctxt_pP->module_id]->rrc_ue_head, ue_context_p);
                /* and insert again, after changing rnti everywhere it has to be changed */
                ue_context_p->ue_id_rnti = ctxt_pP->rnti;
                ue_context_p->ue_context.rnti = ctxt_pP->rnti;
                RB_INSERT(rrc_ue_tree_s, &RC.rrc[ctxt_pP->module_id]->rrc_ue_head, ue_context_p);
                /* reset timers */
                ue_context_p->ue_context.ul_failure_timer = 0;
                ue_context_p->ue_context.ue_release_timer = 0;
                ue_context_p->ue_context.ue_reestablishment_timer = 0;
                ue_context_p->ue_context.ue_release_timer_s1 = 0;
                ue_context_p->ue_context.ue_release_timer_rrc = 0;
                ue_context_p->ue_context.reestablishment_xid = -1;
7512
              } else {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7513 7514 7515 7516 7517 7518 7519 7520 7521 7522 7523 7524 7525 7526 7527
                LOG_I(RRC," S-TMSI doesn't exist, setting Initialue_identity_s_TMSI.m_tmsi to %p => %x\n",ue_context_p,m_tmsi);
                //              ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP, NOT_A_RANDOM_UE_IDENTITY);
                ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP,random_value);

                if (ue_context_p == NULL)
                  LOG_E(RRC, "%s:%d:%s: rrc_eNB_get_next_free_ue_context returned NULL\n", __FILE__, __LINE__, __FUNCTION__);

                if (ue_context_p != NULL) {
                  ue_context_p->ue_context.Initialue_identity_s_TMSI.presence = TRUE;
                  ue_context_p->ue_context.Initialue_identity_s_TMSI.mme_code = mme_code;
                  ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi = m_tmsi;
                } else {
                  /* TODO: do we have to break here? */
                  //break;
                }
7528
              }
gauthier's avatar
gauthier committed
7529

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7530 7531 7532
              MSC_LOG_RX_MESSAGE(
                MSC_RRC_ENB,
                MSC_RRC_UE,
7533
                buffer,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7534 7535 7536 7537 7538 7539 7540 7541 7542 7543 7544 7545 7546 7547 7548 7549 7550
                dec_rval.consumed,
                MSC_AS_TIME_FMT" RRCConnectionRequest UE %x size %u (s-TMSI mmec %u m_TMSI %u random UE id (0x%" PRIx64 ")",
                MSC_AS_TIME_ARGS(ctxt_pP),
                ue_context_p->ue_context.rnti,
                dec_rval.consumed,
                ue_context_p->ue_context.Initialue_identity_s_TMSI.mme_code,
                ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi,
                ue_context_p->ue_context.random_ue_identity);
            } else {
              LOG_E(RRC,
                    PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionRequest without random UE identity or S-TMSI not supported, let's reject the UE\n",
                    PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
              rrc_eNB_generate_RRCConnectionReject(ctxt_pP,
                                                   rrc_eNB_get_ue_context(RC.rrc[ctxt_pP->module_id], ctxt_pP->rnti),
                                                   CC_id);
              break;
            }
7551
          }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7552 7553 7554 7555
          LOG_D(RRC,
                PROTOCOL_RRC_CTXT_UE_FMT" UE context: %p\n",
                PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
                ue_context_p);
gauthier's avatar
gauthier committed
7556

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7557 7558 7559
          if (ue_context_p != NULL) {
            ue_context_p->ue_context.establishment_cause = rrcConnectionRequest->establishmentCause;
            ue_context_p->ue_context.reestablishment_cause = LTE_ReestablishmentCause_spare1;
7560

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7561 7562 7563 7564 7565 7566 7567 7568 7569 7570 7571 7572 7573
            if (stmsi_received==0)
              LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Accept new connection from UE random UE identity (0x%" PRIx64 ") MME code %u TMSI %u cause %ld\n",
                    PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
                    ue_context_p->ue_context.random_ue_identity,
                    ue_context_p->ue_context.Initialue_identity_s_TMSI.mme_code,
                    ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi,
                    ue_context_p->ue_context.establishment_cause);
            else
              LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Accept new connection from UE  MME code %u TMSI %u cause %ld\n",
                    PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
                    ue_context_p->ue_context.Initialue_identity_s_TMSI.mme_code,
                    ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi,
                    ue_context_p->ue_context.establishment_cause);
7574

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7575 7576 7577 7578
            if (stmsi_received == 0)
              RC.rrc[ctxt_pP->module_id]->Nb_ue++;
          } else {
            // no context available
7579 7580
            if (flexran_agent_get_rrc_xface(ctxt_pP->module_id)) {
              flexran_agent_get_rrc_xface(ctxt_pP->module_id)->flexran_agent_notify_ue_state_change(ctxt_pP->module_id,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7581 7582 7583 7584 7585 7586 7587
                  ctxt_pP->rnti,
                  PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
            }

            LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Can't create new context for UE random UE identity (0x%" PRIx64 ")\n",
                  PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
                  random_value);
7588
            if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type))
7589
              rrc_mac_remove_ue(ctxt_pP->module_id,ctxt_pP->rnti);
7590
            else if (NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
7591 7592 7593 7594 7595 7596 7597 7598
              MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, F1AP_UE_CONTEXT_RELEASE_CMD);
              F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = ctxt_pP->rnti;
              F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK;
              F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release
              F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = NULL;
              F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container_length = 0;
              itti_send_msg_to_task(TASK_CU_F1, ctxt_pP->module_id, m);
            }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7599 7600
            return -1;
          }
7601
        }
7602

winckel's avatar
winckel committed
7603
#ifndef NO_RRM
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7604
        send_msg(&S_rrc, msg_rrc_MR_attach_ind(ctxt_pP->module_id, Mac_id));
winckel's avatar
winckel committed
7605
#else
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 7616 7617 7618 7619 7620 7621 7622 7623 7624 7625 7626 7627 7628 7629 7630 7631 7632 7633 7634 7635 7636 7637 7638 7639 7640 7641 7642 7643 7644 7645 7646
        ue_context_p->ue_context.primaryCC_id = CC_id;
        //LG COMMENT Idx = (ue_mod_idP * NB_RB_MAX) + DCCH;
        Idx = DCCH;
        // SRB1
        ue_context_p->ue_context.Srb1.Active = 1;
        ue_context_p->ue_context.Srb1.Srb_info.Srb_id = Idx;
        memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[0],
               &DCCH_LCHAN_DESC,
               LCHAN_DESC_SIZE);
        memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[1],
               &DCCH_LCHAN_DESC,
               LCHAN_DESC_SIZE);
        // SRB2: set  it to go through SRB1 with id 1 (DCCH)
        ue_context_p->ue_context.Srb2.Active = 1;
        ue_context_p->ue_context.Srb2.Srb_info.Srb_id = Idx;
        memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[0],
               &DCCH_LCHAN_DESC,
               LCHAN_DESC_SIZE);
        memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[1],
               &DCCH_LCHAN_DESC,
               LCHAN_DESC_SIZE);
        rrc_eNB_generate_RRCConnectionSetup(ctxt_pP, ue_context_p, CC_id);
        LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT"CALLING RLC CONFIG SRB1 (rbid %d)\n",
              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
              Idx);
        MSC_LOG_TX_MESSAGE(
          MSC_RRC_ENB,
          MSC_PDCP_ENB,
          NULL,
          0,
          MSC_AS_TIME_FMT" CONFIG_REQ UE %x SRB",
          MSC_AS_TIME_ARGS(ctxt_pP),
          ue_context_p->ue_context.rnti);
        rrc_pdcp_config_asn1_req(ctxt_pP,
                                 ue_context_p->ue_context.SRB_configList,
                                 (LTE_DRB_ToAddModList_t *) NULL,
                                 (LTE_DRB_ToReleaseList_t *) NULL,
                                 0xff,
                                 NULL,
                                 NULL,
                                 NULL
7647
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7648
                                 , (LTE_PMCH_InfoList_r9_t *) NULL
7649
#endif
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7650
                                 ,NULL);
7651

7652
        if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
7653 7654 7655 7656
          rrc_rlc_config_asn1_req(ctxt_pP,
                                  ue_context_p->ue_context.SRB_configList,
                                  (LTE_DRB_ToAddModList_t *) NULL,
                                  (LTE_DRB_ToReleaseList_t *) NULL
7657
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
7658 7659
                                  , (LTE_PMCH_InfoList_r9_t *) NULL
                                  , 0, 0
7660
#endif
7661 7662
                                 );
        }
winckel's avatar
winckel committed
7663
#endif //NO_RRM
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7664
        break;
7665

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7666 7667 7668 7669 7670
      default:
        LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Unknown message\n",
              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
        rval = -1;
        break;
winckel's avatar
winckel committed
7671
    }
7672 7673 7674

    rval = 0;
  } else {
7675 7676
    LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT"  Unknown error \n",
          PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
7677 7678 7679 7680
    rval = -1;
  }

  return rval;
7681 7682
}

7683 7684 7685
//-----------------------------------------------------------------------------
int
rrc_eNB_decode_dcch(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7686
  const protocol_ctxt_t *const ctxt_pP,
7687
  const rb_id_t                Srb_id,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7688
  const uint8_t    *const      Rx_sdu,
7689 7690 7691
  const sdu_size_t             sdu_sizeP
)
//-----------------------------------------------------------------------------
7692 7693 7694
{
  asn_dec_rval_t                      dec_rval;
  //UL_DCCH_Message_t uldcchmsg;
7695
  LTE_UL_DCCH_Message_t               *ul_dcch_msg = NULL; //&uldcchmsg;
7696
  int i;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7697 7698
  struct rrc_eNB_ue_context_s        *ue_context_p = NULL;
  MessageDef                         *msg_delete_tunnels_p = NULL;
7699
  uint8_t                             xid;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7700
  int dedicated_DRB=0;
Cedric Roux's avatar
Cedric Roux committed
7701 7702 7703
  T(T_ENB_RRC_UL_DCCH_DATA_IN, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
    T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));

7704
  if ((Srb_id != 1) && (Srb_id != 2)) {
7705 7706 7707
    LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Received message on SRB%d, should not have ...\n",
          PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
          Srb_id);
7708 7709 7710 7711
  } else {
    LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Received message on SRB%d\n",
          PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
          Srb_id);
7712
  }
7713

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7714
  //memset(ul_dcch_msg,0,sizeof(UL_DCCH_Message_t));
7715 7716 7717 7718
  LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Decoding UL-DCCH Message\n",
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
  dec_rval = uper_decode(
               NULL,
7719
               &asn_DEF_LTE_UL_DCCH_Message,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7720
               (void **)&ul_dcch_msg,
7721 7722 7723 7724
               Rx_sdu,
               sdu_sizeP,
               0,
               0);
7725
  {
7726
    for (i = 0; i < sdu_sizeP; i++) {
7727
      LOG_T(RRC, "%x.", Rx_sdu[i]);
7728
    }
winckel's avatar
winckel committed
7729

7730 7731 7732 7733
    LOG_T(RRC, "\n");
  }

  if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
Cedric Roux's avatar
Cedric Roux committed
7734
    LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Failed to decode UL-DCCH (%zu bytes)\n",
7735 7736
          PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
          dec_rval.consumed);
7737 7738
    return -1;
  }
7739

7740
  ue_context_p = rrc_eNB_get_ue_context(
7741
                   RC.rrc[ctxt_pP->module_id],
7742
                   ctxt_pP->rnti);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
7743

7744
  if (ul_dcch_msg->message.present == LTE_UL_DCCH_MessageType_PR_c1) {
7745
    switch (ul_dcch_msg->message.choice.c1.present) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7746
      case LTE_UL_DCCH_MessageType__c1_PR_NOTHING:   /* No components present */
7747
        break;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
7748

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7749
      case LTE_UL_DCCH_MessageType__c1_PR_csfbParametersRequestCDMA2000:
7750
        break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7751 7752 7753 7754 7755 7756 7757 7758 7759 7760 7761 7762 7763 7764 7765 7766

      case LTE_UL_DCCH_MessageType__c1_PR_measurementReport:

        // to avoid segmentation fault
        if(!ue_context_p) {
          LOG_I(RRC, "Processing measurementReport UE %x, ue_context_p is NULL\n", ctxt_pP->rnti);
          break;
        }

        LOG_D(RRC,
              PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND "
              "%d bytes (measurementReport) ---> RRC_eNB\n",
              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
              DCCH,
              sdu_sizeP);
        rrc_eNB_process_MeasurementReport(
7767 7768
          ctxt_pP,
          ue_context_p,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7769 7770 7771 7772 7773 7774 7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 7790 7791 7792 7793 7794 7795 7796 7797 7798 7799 7800 7801 7802 7803
          &ul_dcch_msg->message.choice.c1.choice.measurementReport.
          criticalExtensions.choice.c1.choice.measurementReport_r8.measResults);
        break;

      case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete:

        // to avoid segmentation fault
        if(!ue_context_p) {
          LOG_I(RRC, "Processing LTE_RRCConnectionReconfigurationComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti);
          break;
        }

        LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)(Rx_sdu),sdu_sizeP,
                    "[MSG] RRC Connection Reconfiguration Complete\n");
        MSC_LOG_RX_MESSAGE(
          MSC_RRC_ENB,
          MSC_RRC_UE,
          Rx_sdu,
          sdu_sizeP,
          MSC_AS_TIME_FMT" LTE_RRCConnectionReconfigurationComplete UE %x size %u",
          MSC_AS_TIME_ARGS(ctxt_pP),
          ue_context_p->ue_context.rnti,
          sdu_sizeP);
        LOG_D(RRC,
              PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes "
              "(RRCConnectionReconfigurationComplete) ---> RRC_eNB]\n",
              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
              DCCH,
              sdu_sizeP);

        if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.
            present ==
            LTE_RRCConnectionReconfigurationComplete__criticalExtensions_PR_rrcConnectionReconfigurationComplete_r8) {
          /*NN: revise the condition */
          /*FK: left the condition as is for the case MME is used (S1 mode) but setting  dedicated_DRB = 1 otherwise (noS1 mode) so that no second RRCReconfiguration message activationg more DRB is sent as this causes problems with the nasmesh driver.*/
7804
          int flexran_agent_handover = 0;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7805 7806 7807 7808 7809 7810 7811 7812 7813 7814 7815 7816 7817 7818 7819 7820
          if (EPC_MODE_ENABLED) {
            if (ue_context_p->ue_context.Status == RRC_RECONFIGURED) {
              dedicated_DRB = 1;
              LOG_I(RRC,
                    PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld)\n",
                    PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
              //clear
              int16_t UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti);

              if(UE_id == -1) {
                LOG_E(RRC,
                      PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReconfigurationComplete without rnti %x, fault\n",
                      PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti);
                break;
              }

7821
              AssertFatal(!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type),
7822 7823
                          "CU cannot decode DCCH: no access to RC.mac[]\n");

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7824 7825 7826 7827 7828 7829 7830
              if(RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag == 1) {
                LOG_I(RRC,
                      PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld) C-RNTI Complete\n",
                      PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
                dedicated_DRB = 2;
                RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0;
              }
Cedric Roux's avatar
Cedric Roux committed
7831 7832 7833 7834 7835 7836 7837 7838 7839 7840
            } else if (ue_context_p->ue_context.Status == RRC_HO_EXECUTION) {
              int16_t UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti);

              if(UE_id == -1) {
                LOG_E(RRC,
                      PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReconfigurationComplete without rnti %x, fault\n",
                      PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti);
                break;
              }

7841 7842
              flexran_agent_handover = 1;
              RC.rrc[ctxt_pP->module_id]->Nb_ue++;
Cedric Roux's avatar
Cedric Roux committed
7843 7844 7845
              dedicated_DRB = 3;
              RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0;
              ue_context_p->ue_context.Status = RRC_RECONFIGURED;
luaihui's avatar
luaihui committed
7846 7847 7848
	      if(ue_context_p->ue_context.handover_info){
	        ue_context_p->ue_context.handover_info->state = HO_CONFIGURED;
	      }
Cedric Roux's avatar
Cedric Roux committed
7849 7850 7851
              LOG_I(RRC,
                    PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_HO_EXECUTION (xid %ld)\n",
                    PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7852 7853 7854 7855 7856 7857 7858 7859 7860 7861 7862 7863 7864 7865 7866 7867 7868 7869 7870 7871 7872 7873 7874
            } else {
              dedicated_DRB = 0;
              ue_context_p->ue_context.Status = RRC_RECONFIGURED;
              LOG_I(RRC,
                    PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (default DRB, xid %ld)\n",
                    PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
            }

            ue_context_p->ue_context.reestablishment_xid = -1;
          } else {
            dedicated_DRB = 1;
            ue_context_p->ue_context.Status = RRC_RECONFIGURED;
            LOG_I(RRC,
                  PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld)\n",
                  PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
          }

          rrc_eNB_process_RRCConnectionReconfigurationComplete(
            ctxt_pP,
            ue_context_p,
            ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);

          //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future
7875 7876
          if (flexran_agent_get_rrc_xface(ctxt_pP->module_id)) {
            flexran_agent_get_rrc_xface(ctxt_pP->module_id)->flexran_agent_notify_ue_state_change(ctxt_pP->module_id,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7877
                ue_context_p->ue_id_rnti,
7878
                flexran_agent_handover?PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED:PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_UPDATED);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7879 7880
          }
        }
7881

7882 7883 7884 7885 7886 7887 7888 7889 7890 7891 7892 7893 7894 7895 7896 7897 7898 7899 7900 7901 7902 7903 7904 7905 7906 7907 7908 7909 7910 7911 7912
        if (EPC_MODE_ENABLED) {
          if (dedicated_DRB == 1) {
            //    rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(ctxt_pP,
            //               ue_context_p,
            //               ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
            if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) {
              rrc_eNB_send_S1AP_E_RAB_MODIFY_RESP(ctxt_pP,
                                                  ue_context_p,
                                                  ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
              ue_context_p->ue_context.nb_of_modify_e_rabs = 0;
              ue_context_p->ue_context.nb_of_failed_e_rabs = 0;
              memset(ue_context_p->ue_context.modify_e_rab, 0, sizeof(ue_context_p->ue_context.modify_e_rab));

              for(int i = 0; i < NB_RB_MAX; i++) {
                ue_context_p->ue_context.modify_e_rab[i].xid = -1;
              }
            } else if(ue_context_p->ue_context.e_rab_release_command_flag == 1) {
              xid = ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier;
              ue_context_p->ue_context.e_rab_release_command_flag = 0;
              //gtp tunnel delete
              msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ);
              memset(&GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p)));
              GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;

              for(i = 0; i < NB_RB_MAX; i++) {
                if(xid == ue_context_p->ue_context.e_rab[i].xid) {
                  GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = ue_context_p->ue_context.enb_gtp_ebi[i];
                  ue_context_p->ue_context.enb_gtp_teid[i] = 0;
                  memset(&ue_context_p->ue_context.enb_gtp_addrs[i], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[i]));
                  ue_context_p->ue_context.enb_gtp_ebi[i]  = 0;
                }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7913 7914
              }

7915 7916 7917 7918 7919 7920 7921 7922 7923 7924 7925 7926
              itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->instance, msg_delete_tunnels_p);
              //S1AP_E_RAB_RELEASE_RESPONSE
              rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(ctxt_pP,
                  ue_context_p,
                  xid);
            } else {
              rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(ctxt_pP,
                                                 ue_context_p,
                                                 ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
            }
          } else if(dedicated_DRB == 0) {
            if(ue_context_p->ue_context.reestablishment_cause == LTE_ReestablishmentCause_spare1) {
luaihui's avatar
luaihui committed
7927
              
7928 7929 7930 7931
              rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP,
                  ue_context_p);
            } else {
              ue_context_p->ue_context.reestablishment_cause = LTE_ReestablishmentCause_spare1;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7932

7933 7934 7935 7936 7937 7938 7939 7940 7941
              for (uint8_t e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
                if (ue_context_p->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE) {
                  ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED;
                } else {
                  ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_FAILED;
                }
              }
            }
          } else if(dedicated_DRB == 2) {
7942 7943 7944 7945 7946 7947 7948
            for (uint8_t e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
              if (ue_context_p->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE) {
                ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED;
              } else {
                ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_FAILED;
              }
            }
7949 7950 7951 7952 7953 7954 7955
          } else if(dedicated_DRB == 3) { //x2 path switch
            for (uint8_t e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
              if (ue_context_p->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE) {
                ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED;
              } else {
                ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_FAILED;
              }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7956 7957
            }

7958 7959 7960 7961
            LOG_I(RRC,"issue rrc_eNB_send_PATH_SWITCH_REQ \n");
            rrc_eNB_send_PATH_SWITCH_REQ(ctxt_pP,ue_context_p);
          }
        } /* EPC_MODE_ENABLED */
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7962 7963 7964 7965 7966 7967 7968 7969 7970 7971 7972 7973 7974 7975 7976 7977 7978 7979 7980 7981 7982 7983 7984 7985 7986 7987 7988 7989 7990 7991 7992 7993 7994 7995 7996 7997

        break;

      case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReestablishmentComplete:
        T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
          T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
        LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP,
                    "[MSG] RRC Connection Reestablishment Complete\n");
        MSC_LOG_RX_MESSAGE(
          MSC_RRC_ENB,
          MSC_RRC_UE,
          Rx_sdu,
          sdu_sizeP,
          MSC_AS_TIME_FMT" LTE_RRCConnectionReestablishmentComplete UE %x size %u",
          MSC_AS_TIME_ARGS(ctxt_pP),
          ue_context_p->ue_context.rnti,
          sdu_sizeP);
        LOG_I(RRC,
              PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes "
              "(rrcConnectionReestablishmentComplete) ---> RRC_eNB\n",
              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
              DCCH,
              sdu_sizeP);
        {
          rnti_t reestablish_rnti = 0;

          // select C-RNTI from map
          for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
            if (reestablish_rnti_map[i][0] == ctxt_pP->rnti) {
              reestablish_rnti = reestablish_rnti_map[i][1];
              ue_context_p = rrc_eNB_get_ue_context(
                               RC.rrc[ctxt_pP->module_id],
                               reestablish_rnti);
              // clear currentC-RNTI from map
              reestablish_rnti_map[i][0] = 0;
              reestablish_rnti_map[i][1] = 0;
7998 7999
              LOG_D(RRC, "reestablish_rnti_map[%d] [0] %x, [1] %x\n",
                    i, reestablish_rnti_map[i][0], reestablish_rnti_map[i][1]);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8000 8001 8002 8003 8004 8005 8006 8007 8008 8009
              break;
            }
          }

          if (!ue_context_p) {
            LOG_E(RRC,
                  PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentComplete without UE context, falt\n",
                  PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
            break;
          }
8010

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8011 8012
          //clear
          int UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti);
8013

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8014 8015 8016 8017
          if(UE_id == -1) {
            LOG_E(RRC,
                  PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentComplete without UE_id(MAC) rnti %x, fault\n",
                  PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti);
8018 8019 8020
            break;
          }

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8021
          RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0;
8022
          ue_context_p->ue_context.reestablishment_xid = -1;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8023 8024 8025 8026 8027 8028 8029 8030

          if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.criticalExtensions.present ==
              LTE_RRCConnectionReestablishmentComplete__criticalExtensions_PR_rrcConnectionReestablishmentComplete_r8) {
            rrc_eNB_process_RRCConnectionReestablishmentComplete(ctxt_pP, reestablish_rnti, ue_context_p,
                ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.rrc_TransactionIdentifier,
                &ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.criticalExtensions.choice.rrcConnectionReestablishmentComplete_r8);

            //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future
8031 8032
            if (flexran_agent_get_rrc_xface(ctxt_pP->module_id)) {
              flexran_agent_get_rrc_xface(ctxt_pP->module_id)->flexran_agent_notify_ue_state_change(ctxt_pP->module_id,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8033 8034 8035 8036 8037 8038 8039 8040 8041
                  ue_context_p->ue_id_rnti,
                  PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED);
            }
          }

          //ue_context_p->ue_context.ue_release_timer = 0;
          ue_context_p->ue_context.ue_reestablishment_timer = 1;
          // remove UE after 100 frames after LTE_RRCConnectionReestablishmentRelease is triggered
          ue_context_p->ue_context.ue_reestablishment_timer_thres = 1000;
8042
        }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8043 8044 8045 8046 8047 8048 8049
        break;

      case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionSetupComplete:

        // to avoid segmentation fault
        if(!ue_context_p) {
          LOG_I(RRC, "Processing LTE_RRCConnectionSetupComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti);
8050 8051
          break;
        }
8052

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8053 8054 8055 8056 8057 8058 8059 8060 8061 8062 8063 8064 8065 8066 8067 8068 8069 8070 8071 8072 8073 8074 8075
        LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP,
                    "[MSG] RRC Connection SetupComplete\n");
        MSC_LOG_RX_MESSAGE(
          MSC_RRC_ENB,
          MSC_RRC_UE,
          Rx_sdu,
          sdu_sizeP,
          MSC_AS_TIME_FMT" LTE_RRCConnectionSetupComplete UE %x size %u",
          MSC_AS_TIME_ARGS(ctxt_pP),
          ue_context_p->ue_context.rnti,
          sdu_sizeP);
        LOG_D(RRC,
              PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes "
              "(RRCConnectionSetupComplete) ---> RRC_eNB\n",
              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
              DCCH,
              sdu_sizeP);

        if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionSetupComplete.criticalExtensions.present ==
            LTE_RRCConnectionSetupComplete__criticalExtensions_PR_c1) {
          if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionSetupComplete.criticalExtensions.choice.c1.
              present ==
              LTE_RRCConnectionSetupComplete__criticalExtensions__c1_PR_rrcConnectionSetupComplete_r8) {
8076
            AssertFatal(!NODE_IS_DU(RC.rrc[ctxt_pP->module_id]->node_type),
8077
                        "should not be reached in DU\n");
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8078 8079 8080 8081 8082 8083
            rrc_eNB_process_RRCConnectionSetupComplete(
              ctxt_pP,
              ue_context_p,
              &ul_dcch_msg->message.choice.c1.choice.rrcConnectionSetupComplete.criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8);
            LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_CONNECTED \n",
                  PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
8084

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8085
            //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future
8086 8087
            if (flexran_agent_get_rrc_xface(ctxt_pP->module_id)) {
              flexran_agent_get_rrc_xface(ctxt_pP->module_id)->flexran_agent_notify_ue_state_change(ctxt_pP->module_id,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8088 8089 8090
                  ue_context_p->ue_id_rnti,
                  PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED);
            }
8091 8092
          }
        }
8093

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8094
        ue_context_p->ue_context.ue_release_timer=0;
8095
        break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8096 8097 8098 8099 8100 8101 8102 8103 8104

      case LTE_UL_DCCH_MessageType__c1_PR_securityModeComplete:
        T(T_ENB_RRC_SECURITY_MODE_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
          T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));

        // to avoid segmentation fault
        if(!ue_context_p) {
          LOG_I(RRC, "Processing securityModeComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti);
          break;
8105 8106
        }

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8107 8108 8109 8110 8111 8112 8113 8114 8115 8116 8117 8118 8119 8120 8121 8122 8123 8124 8125 8126 8127 8128 8129 8130 8131
        LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP,
                    "[MSG] RRC Security Mode Complete\n");
        MSC_LOG_RX_MESSAGE(
          MSC_RRC_ENB,
          MSC_RRC_UE,
          Rx_sdu,
          sdu_sizeP,
          MSC_AS_TIME_FMT" securityModeComplete UE %x size %u",
          MSC_AS_TIME_ARGS(ctxt_pP),
          ue_context_p->ue_context.rnti,
          sdu_sizeP);
        LOG_I(RRC,
              PROTOCOL_RRC_CTXT_UE_FMT" received securityModeComplete on UL-DCCH %d from UE\n",
              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
              DCCH);
        LOG_D(RRC,
              PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes "
              "(securityModeComplete) ---> RRC_eNB\n",
              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
              DCCH,
              sdu_sizeP);

        if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
          xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)ul_dcch_msg);
        }
8132

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8133 8134 8135 8136 8137 8138
        // confirm with PDCP about the security mode for DCCH
        //rrc_pdcp_config_req (enb_mod_idP, frameP, 1,CONFIG_ACTION_SET_SECURITY_MODE, (ue_mod_idP * NB_RB_MAX) + DCCH, 0x77);
        // continue the procedure
        rrc_eNB_generate_UECapabilityEnquiry(
          ctxt_pP,
          ue_context_p);
8139
        break;
8140

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8141 8142 8143 8144 8145 8146 8147 8148 8149 8150 8151 8152 8153 8154 8155 8156 8157 8158 8159 8160
      case LTE_UL_DCCH_MessageType__c1_PR_securityModeFailure:
        T(T_ENB_RRC_SECURITY_MODE_FAILURE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
          T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
        LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP,
                    "[MSG] RRC Security Mode Failure\n");
        MSC_LOG_RX_MESSAGE(
          MSC_RRC_ENB,
          MSC_RRC_UE,
          Rx_sdu,
          sdu_sizeP,
          MSC_AS_TIME_FMT" securityModeFailure UE %x size %u",
          MSC_AS_TIME_ARGS(ctxt_pP),
          ue_context_p->ue_context.rnti,
          sdu_sizeP);
        LOG_W(RRC,
              PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes "
              "(securityModeFailure) ---> RRC_eNB\n",
              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
              DCCH,
              sdu_sizeP);
8161

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8162 8163 8164
        if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
          xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)ul_dcch_msg);
        }
8165

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8166 8167 8168 8169 8170
        // cancel the security mode in PDCP
        // followup with the remaining procedure
        //#warning "LG Removed rrc_eNB_generate_UECapabilityEnquiry after receiving securityModeFailure"
        rrc_eNB_generate_UECapabilityEnquiry(ctxt_pP, ue_context_p);
        break;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
8171

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8172 8173 8174
      case LTE_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation:
        T(T_ENB_RRC_UE_CAPABILITY_INFORMATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
          T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
Lionel Gauthier's avatar
 
Lionel Gauthier committed
8175

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 8193 8194 8195 8196 8197 8198 8199 8200 8201 8202
        // to avoid segmentation fault
        if(!ue_context_p) {
          LOG_I(RRC, "Processing ueCapabilityInformation UE %x, ue_context_p is NULL\n", ctxt_pP->rnti);
          break;
        }

        LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP,
                    "[MSG] RRC UECapablility Information\n");
        MSC_LOG_RX_MESSAGE(
          MSC_RRC_ENB,
          MSC_RRC_UE,
          Rx_sdu,
          sdu_sizeP,
          MSC_AS_TIME_FMT" ueCapabilityInformation UE %x size %u",
          MSC_AS_TIME_ARGS(ctxt_pP),
          ue_context_p->ue_context.rnti,
          sdu_sizeP);
        LOG_I(RRC,
              PROTOCOL_RRC_CTXT_UE_FMT" received ueCapabilityInformation on UL-DCCH %d from UE\n",
              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
              DCCH);
        LOG_D(RRC,
              PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes "
              "(UECapabilityInformation) ---> RRC_eNB\n",
              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
              DCCH,
              sdu_sizeP);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
8203

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8204 8205 8206
        if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
          xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)ul_dcch_msg);
        }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
8207

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8208
        LOG_I(RRC, "got UE capabilities for UE %x\n", ctxt_pP->rnti);
8209

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8210 8211 8212 8213 8214 8215
        if (ue_context_p->ue_context.UE_Capability) {
          LOG_I(RRC, "freeing old UE capabilities for UE %x\n", ctxt_pP->rnti);
          ASN_STRUCT_FREE(asn_DEF_LTE_UE_EUTRA_Capability,
                          ue_context_p->ue_context.UE_Capability);
          ue_context_p->ue_context.UE_Capability = 0;
        }
8216

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8217 8218 8219 8220 8221 8222 8223 8224 8225
        dec_rval = uper_decode(NULL,
                               &asn_DEF_LTE_UE_EUTRA_Capability,
                               (void **)&ue_context_p->ue_context.UE_Capability,
                               ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.
                               choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.
                               array[0]->ueCapabilityRAT_Container.buf,
                               ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.
                               choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.
                               array[0]->ueCapabilityRAT_Container.size, 0, 0);
Cedric Roux's avatar
Cedric Roux committed
8226 8227 8228
        ue_context_p->ue_context.UE_Capability_size = ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.
            choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.
            array[0]->ueCapabilityRAT_Container.size;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8229 8230 8231 8232

        if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
          xer_fprint(stdout, &asn_DEF_LTE_UE_EUTRA_Capability, ue_context_p->ue_context.UE_Capability);
        }
8233

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8234 8235 8236 8237 8238 8239 8240 8241
        if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
          LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Failed to decode UE capabilities (%zu bytes)\n",
                PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
                dec_rval.consumed);
          ASN_STRUCT_FREE(asn_DEF_LTE_UE_EUTRA_Capability,
                          ue_context_p->ue_context.UE_Capability);
          ue_context_p->ue_context.UE_Capability = 0;
        }
8242

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8243 8244 8245 8246 8247 8248
        if (EPC_MODE_ENABLED) {
            rrc_eNB_send_S1AP_UE_CAPABILITIES_IND(ctxt_pP,
                                                  ue_context_p,
                                                  ul_dcch_msg);
        } else {
          ue_context_p->ue_context.nb_of_e_rabs = 1;
8249

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8250 8251 8252 8253 8254
          for (i = 0; i < ue_context_p->ue_context.nb_of_e_rabs; i++) {
            ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_NEW;
            ue_context_p->ue_context.e_rab[i].param.e_rab_id = 1+i;
            ue_context_p->ue_context.e_rab[i].param.qos.qci=9;
          }
8255

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8256 8257
          ue_context_p->ue_context.setup_e_rabs =ue_context_p->ue_context.nb_of_e_rabs;
        }
8258

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8259 8260 8261 8262
        rrc_eNB_generate_defaultRRCConnectionReconfiguration(ctxt_pP,
            ue_context_p,
            RC.rrc[ctxt_pP->module_id]->HO_flag);
        break;
8263

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8264 8265 8266 8267
      case LTE_UL_DCCH_MessageType__c1_PR_ulHandoverPreparationTransfer:
        T(T_ENB_RRC_UL_HANDOVER_PREPARATION_TRANSFER, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
          T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
        break;
Cedric Roux's avatar
Cedric Roux committed
8268

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8269 8270 8271
      case LTE_UL_DCCH_MessageType__c1_PR_ulInformationTransfer:
        T(T_ENB_RRC_UL_INFORMATION_TRANSFER, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
          T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
8272

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8273 8274
        // to avoid segmentation fault
        if(!ue_context_p) {
8275 8276
          LOG_I(RRC, "Processing ulInformationTransfer UE %x, ue_context_p is NULL\n", ctxt_pP->rnti);
          break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8277
        }
8278

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8279 8280 8281 8282 8283 8284 8285 8286 8287 8288 8289 8290
        LOG_D(RRC,"[MSG] RRC UL Information Transfer \n");
        LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP,
                    "[MSG] RRC UL Information Transfer \n");
        MSC_LOG_RX_MESSAGE(
          MSC_RRC_ENB,
          MSC_RRC_UE,
          Rx_sdu,
          sdu_sizeP,
          MSC_AS_TIME_FMT" ulInformationTransfer UE %x size %u",
          MSC_AS_TIME_ARGS(ctxt_pP),
          ue_context_p->ue_context.rnti,
          sdu_sizeP);
8291

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8292 8293 8294 8295 8296
        if (EPC_MODE_ENABLED == 1) {
          rrc_eNB_send_S1AP_UPLINK_NAS(ctxt_pP,
                                       ue_context_p,
                                       ul_dcch_msg);
        }
Cedric Roux's avatar
Cedric Roux committed
8297

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8298
        break;
8299

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8300 8301 8302 8303
      case LTE_UL_DCCH_MessageType__c1_PR_counterCheckResponse:
        T(T_ENB_RRC_COUNTER_CHECK_RESPONSE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
          T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
        break;
8304
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
8305

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8306 8307 8308 8309
      case LTE_UL_DCCH_MessageType__c1_PR_ueInformationResponse_r9:
        T(T_ENB_RRC_UE_INFORMATION_RESPONSE_R9, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
          T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
        break;
Cedric Roux's avatar
Cedric Roux committed
8310

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8311 8312 8313 8314
      case LTE_UL_DCCH_MessageType__c1_PR_proximityIndication_r9:
        T(T_ENB_RRC_PROXIMITY_INDICATION_R9, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
          T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
        break;
8315
#endif
8316
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
8317

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8318 8319 8320 8321
      case LTE_UL_DCCH_MessageType__c1_PR_rnReconfigurationComplete_r10:
        T(T_ENB_RRC_RECONFIGURATION_COMPLETE_R10, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
          T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
        break;
winckel's avatar
winckel committed
8322

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8323 8324 8325 8326
      case LTE_UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10:
        T(T_ENB_RRC_MBMS_COUNTING_RESPONSE_R10, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
          T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
        break;
Cedric Roux's avatar
Cedric Roux committed
8327

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8328 8329 8330 8331
      case LTE_UL_DCCH_MessageType__c1_PR_interFreqRSTDMeasurementIndication_r10:
        T(T_ENB_RRC_INTER_FREQ_RSTD_MEASUREMENT_INDICATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
          T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
        break;
8332
#endif
8333

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8334 8335 8336 8337 8338 8339 8340
      default:
        T(T_ENB_RRC_UNKNOW_MESSAGE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
          T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
        LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Unknown message %s:%u\n",
              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
              __FILE__, __LINE__);
        return -1;
winckel's avatar
winckel committed
8341 8342
    }

8343
    return 0;
8344
    //TTN for D2D
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8345
  } else if (ul_dcch_msg->message.present == LTE_UL_DCCH_MessageType_PR_messageClassExtension) {
8346
    LOG_I(RRC, "THINH [LTE_UL_DCCH_MessageType_PR_messageClassExtension]\n");
8347

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8348 8349
    switch (ul_dcch_msg->message.choice.messageClassExtension.present) {
      case LTE_UL_DCCH_MessageType__messageClassExtension_PR_NOTHING: /* No components present */
8350 8351
        break;

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8352 8353
      case LTE_UL_DCCH_MessageType__messageClassExtension_PR_c2: //SidelinkUEInformation
        //case UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12: //SidelinkUEInformation
8354
        LOG_I(RRC,"THINH [LTE_UL_DCCH_MessageType__messageClassExtension_PR_c2]\n");
8355 8356
        LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP,
                    "[MSG] RRC SidelinkUEInformation \n");
8357
        MSC_LOG_RX_MESSAGE(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8358 8359 8360 8361 8362 8363 8364 8365
          MSC_RRC_ENB,
          MSC_RRC_UE,
          Rx_sdu,
          sdu_sizeP,
          MSC_AS_TIME_FMT" SidelinkUEInformation UE %x size %u",
          MSC_AS_TIME_ARGS(ctxt_pP),
          ue_context_p->ue_context.rnti,
          sdu_sizeP);
8366 8367 8368 8369 8370 8371 8372
        LOG_I(RRC,
              PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes "
              "(SidelinkUEInformation) ---> RRC_eNB\n",
              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
              DCCH,
              sdu_sizeP);
        rrc_eNB_process_SidelinkUEInformation(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8373 8374 8375
          ctxt_pP,
          ue_context_p,
          &ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.sidelinkUEInformation_r12);
8376
        break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8377 8378

      default:
8379
        break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8380 8381 8382
    }

    //end TTN
8383
  } else {
8384 8385 8386
    LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Unknown error %s:%u\n",
          PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
          __FILE__, __LINE__);
8387 8388 8389
    return -1;
  }

8390
  return 0;
winckel's avatar
winckel committed
8391 8392
}

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8393 8394
void rrc_eNB_reconfigure_DRBs (const protocol_ctxt_t *const ctxt_pP,
                               rrc_eNB_ue_context_t  *ue_context_pP) {
8395
  int i;
Navid Nikaein's avatar
Navid Nikaein committed
8396
  int e_rab_done=0;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8397 8398

  for (i = 0;
Navid Nikaein's avatar
Navid Nikaein committed
8399
       i < 3;//NB_RB_MAX - 3;  // S1AP_MAX_E_RAB
8400
       i++) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8401
    if ( ue_context_pP->ue_context.e_rab[i].status < E_RAB_STATUS_DONE) {
8402 8403 8404 8405 8406 8407 8408 8409
      ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_NEW;
      ue_context_pP->ue_context.e_rab[i].param.e_rab_id = i + 1;
      ue_context_pP->ue_context.e_rab[i].param.qos.qci = i % 9;
      ue_context_pP->ue_context.e_rab[i].param.qos.allocation_retention_priority.priority_level= i % PRIORITY_LEVEL_LOWEST;
      ue_context_pP->ue_context.e_rab[i].param.qos.allocation_retention_priority.pre_emp_capability= PRE_EMPTION_CAPABILITY_DISABLED;
      ue_context_pP->ue_context.e_rab[i].param.qos.allocation_retention_priority.pre_emp_vulnerability= PRE_EMPTION_VULNERABILITY_DISABLED;
      ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer = NULL;
      ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length = 0;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8410
      //  memset (ue_context_pP->ue_context.e_rab[i].param.sgw_addr.buffer,0,20);
8411 8412 8413
      ue_context_pP->ue_context.e_rab[i].param.sgw_addr.length = 0;
      ue_context_pP->ue_context.e_rab[i].param.gtp_teid=0;
      ue_context_pP->ue_context.nb_of_e_rabs++;
Navid Nikaein's avatar
Navid Nikaein committed
8414
      e_rab_done++;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8415 8416
      LOG_I(RRC,"setting up the dedicated DRBs %d (index %d) status %d \n",
            ue_context_pP->ue_context.e_rab[i].param.e_rab_id, i, ue_context_pP->ue_context.e_rab[i].status);
8417
    }
8418
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8419

Navid Nikaein's avatar
Navid Nikaein committed
8420
  ue_context_pP->ue_context.setup_e_rabs+=e_rab_done;
8421 8422 8423
  rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(ctxt_pP, ue_context_pP, 0);
}

Raymond Knopp's avatar
Raymond Knopp committed
8424
void handle_f1_setup_req(f1ap_setup_req_t *f1_setup_req) { 
8425

8426
  
8427
  LOG_I(RRC,"Received F1 Setup Request from gNB_DU %llu (%s)\n",(unsigned long long int)f1_setup_req->gNB_DU_id,f1_setup_req->gNB_DU_name);
8428
  
8429
  //uint16_t num_cells_to_activate = 0;
8430 8431
  
  int cu_cell_ind=0;
Raymond Knopp's avatar
Raymond Knopp committed
8432

8433 8434 8435
  MessageDef                         *msg_p = NULL;

  //LOG_W(RRC,"num_cells_available %d \n", f1_setup_req->num_cells_available);
8436 8437 8438 8439 8440
  for (int i=0;i<f1_setup_req->num_cells_available;i++) {
    // check that mcc/mnc match and grab MIB/SIB1
    int found_cell=0;
    for (int j=0;j<RC.nb_inst;j++) {
      eNB_RRC_INST *rrc = RC.rrc[j];
Robert Schmidt's avatar
Robert Schmidt committed
8441 8442
      if (rrc->configuration.mcc[0] == f1_setup_req->mcc[i] &&
	  rrc->configuration.mnc[0] == f1_setup_req->mnc[i] &&
8443 8444 8445
	  rrc->nr_cellid == f1_setup_req->nr_cellid[i]) {
        // check that CU rrc instance corresponds to mcc/mnc/cgi (normally cgi should be enough, but just in case)

8446 8447 8448 8449 8450 8451 8452
        rrc->carrier[0].MIB = malloc(f1_setup_req->mib_length[i]);
        rrc->carrier[0].sizeof_MIB = f1_setup_req->mib_length[i];
        LOG_W(RRC, "instance %d mib length %d\n", i, f1_setup_req->mib_length[i]);
        LOG_W(RRC, "instance %d sib1 length %d\n", i, f1_setup_req->sib1_length[i]);
       
        memcpy((void*)rrc->carrier[0].MIB,f1_setup_req->mib[i],f1_setup_req->mib_length[i]);
        asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
8453
                         &asn_DEF_LTE_BCCH_BCH_Message,
8454 8455 8456 8457
        					       (void **)&rrc->carrier[0].mib_DU,
        					       f1_setup_req->mib[i],
        					       f1_setup_req->mib_length[i]);
        AssertFatal(dec_rval.code == RC_OK,
8458
              "[eNB_DU %"PRIu8"] Failed to decode LTE_BCCH_BCH_MESSAGE (%zu bits)\n",
8459 8460
        	    j,
        	    dec_rval.consumed );	
8461 8462
        LTE_BCCH_BCH_Message_t *mib = &rrc->carrier[0].mib;
        LTE_BCCH_BCH_Message_t *mib_DU = rrc->carrier[0].mib_DU;
8463 8464 8465 8466 8467 8468 8469 8470
        mib->message.dl_Bandwidth = mib_DU->message.dl_Bandwidth;
        mib->message.phich_Config.phich_Resource = mib_DU->message.phich_Config.phich_Resource;
        mib->message.phich_Config.phich_Duration = mib_DU->message.phich_Config.phich_Duration;

        rrc->carrier[0].SIB1 = malloc(f1_setup_req->sib1_length[i]);
        rrc->carrier[0].sizeof_SIB1 = f1_setup_req->sib1_length[i];
        memcpy((void*)rrc->carrier[0].SIB1,f1_setup_req->sib1[i],f1_setup_req->sib1_length[i]); 
        dec_rval = uper_decode_complete(NULL,
8471
                &asn_DEF_LTE_BCCH_DL_SCH_Message,
8472 8473 8474 8475
        				(void **)&rrc->carrier[0].siblock1_DU,
        				f1_setup_req->sib1[i],
        				f1_setup_req->sib1_length[i]);
        AssertFatal(dec_rval.code == RC_OK,
8476
              "[eNB_DU %"PRIu8"] Failed to decode LTE_BCCH_DLSCH_MESSAGE (%zu bits)\n",
8477 8478 8479
        	    j,
        	    dec_rval.consumed );	
        // Parse message and extract SystemInformationBlockType1 field
8480 8481 8482 8483 8484
        LTE_BCCH_DL_SCH_Message_t *bcch_message = rrc->carrier[0].siblock1_DU;
        AssertFatal(bcch_message->message.present == LTE_BCCH_DL_SCH_MessageType_PR_c1,
              "bcch_message->message.present != LTE_BCCH_DL_SCH_MessageType_PR_c1\n");
        AssertFatal(bcch_message->message.choice.c1.present == LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1,
              "bcch_message->message.choice.c1.present != LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1\n");
8485 8486 8487 8488 8489 8490 8491 8492
        rrc->carrier[0].sib1 = &bcch_message->message.choice.c1.choice.systemInformationBlockType1;
        rrc->carrier[0].physCellId = f1_setup_req->nr_pci[i];
        // prepare F1_SETUP_RESPONSE

        if (msg_p == NULL) {
          msg_p = itti_alloc_new_message (TASK_CU_F1,F1AP_SETUP_RESP); 						 
        }
        F1AP_SETUP_RESP (msg_p).gNB_CU_name                                = rrc->node_name;
Robert Schmidt's avatar
Robert Schmidt committed
8493 8494 8495
        F1AP_SETUP_RESP (msg_p).mcc[cu_cell_ind]                           = rrc->configuration.mcc[0];
        F1AP_SETUP_RESP (msg_p).mnc[cu_cell_ind]                           = rrc->configuration.mnc[0];
        F1AP_SETUP_RESP (msg_p).mnc_digit_length[cu_cell_ind]              = rrc->configuration.mnc_digit_length[0];
8496
	F1AP_SETUP_RESP (msg_p).nr_cellid[cu_cell_ind]                     = rrc->nr_cellid;
8497 8498 8499 8500 8501
        F1AP_SETUP_RESP (msg_p).nrpci[cu_cell_ind]                         = f1_setup_req->nr_pci[i];
        int num_SI= 0;
        if (rrc->carrier[0].SIB23) {
          F1AP_SETUP_RESP (msg_p).SI_container[cu_cell_ind][num_SI]        = rrc->carrier[0].SIB23;
          F1AP_SETUP_RESP (msg_p).SI_container_length[cu_cell_ind][num_SI] = rrc->carrier[0].sizeof_SIB23;
8502 8503 8504 8505
          //printf("SI %d size %d: ", 0, F1AP_SETUP_RESP(msg_p).SI_container_length[j][num_SI]);
          //for (int n = 0; n < F1AP_SETUP_RESP(msg_p).SI_container_length[j][num_SI]; n++)
          //  printf("%02x ", F1AP_SETUP_RESP(msg_p).SI_container[0][num_SI][n]);
          //printf("\n");
8506 8507 8508
          num_SI++;
        }
        F1AP_SETUP_RESP (msg_p).num_SI[cu_cell_ind] = num_SI;
8509

8510 8511
        cu_cell_ind++;
        found_cell=1;
8512 8513 8514 8515

        F1AP_SETUP_RESP (msg_p).num_cells_to_activate = cu_cell_ind;
        // send ITTI message to F1AP-CU task
        itti_send_msg_to_task (TASK_CU_F1, ENB_MODULE_ID_TO_INSTANCE(j), msg_p);
8516 8517 8518 8519
        break;
      } else {// setup_req mcc/mnc match rrc internal list element
        
        LOG_W(RRC,"[Inst %d] No matching MCC/MNC: rrc->mcc/f1_setup_req->mcc %d/%d rrc->mnc/f1_setup_req->mnc %d/%d \n", 
Robert Schmidt's avatar
Robert Schmidt committed
8520
            j, rrc->configuration.mcc[0], f1_setup_req->mcc[i],rrc->configuration.mnc[0], f1_setup_req->mnc[i]);
8521 8522

      }
8523 8524 8525
    }// for (int j=0;j<RC.nb_inst;j++)
    if (found_cell==0) {
      AssertFatal(1==0,"No cell found\n");
Raymond Knopp's avatar
Raymond Knopp committed
8526
      /*msg_p = itti_alloc_new_message (TASK_CU_F1,F1AP_SETUP_FAILURE); 						 
8527 8528 8529 8530 8531 8532 8533 8534 8535 8536
      F1AP_SETUP_RESP (msg_p).cause                             = rrc->node_name;
      F1AP_SETUP_RESP (msg_p).time_to_wait                      = rrc->node_id;
      F1AP_SETUP_RESP (msg_p).criticality_diagnostics           = rrc->node_name;*/
    }
    // handle other failure cases
  }//for (int i=0;i<f1_setup_req->num_cells_available;i++)
}
 

  // ignore 5GNR fields for now, just take MIB and SIB1
8537 8538
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
laurent's avatar
laurent committed
8539
void rrc_enb_init(void) {
8540
  pthread_mutex_init(&lock_ue_freelist, NULL);
8541 8542
  pthread_mutex_init(&rrc_release_freelist, NULL);
  memset(&rrc_release_info,0,sizeof(RRC_release_list_t));
8543 8544
  rrc_release_info.RRC_release_ctrl = (RRC_release_ctrl_t *)malloc(sizeof(RRC_release_ctrl_t)*NUMBER_OF_UE_MAX);
  memset(rrc_release_info.RRC_release_ctrl,0,sizeof(RRC_release_ctrl_t)*NUMBER_OF_UE_MAX);
laurent's avatar
laurent committed
8545 8546
}

Cedric Roux's avatar
Cedric Roux committed
8547 8548 8549 8550 8551 8552 8553 8554 8555 8556 8557 8558 8559 8560 8561 8562 8563 8564 8565 8566 8567 8568 8569
//-----------------------------------------------------------------------------
int add_ue_to_remove(struct rrc_eNB_ue_context_s **ue_to_be_removed,
                     int removed_ue_count,
                     struct rrc_eNB_ue_context_s *ue_context_p)
{
  int i;

  /* is it already here? */
  for (i = 0; i < removed_ue_count; i++)
    if (ue_to_be_removed[i] == ue_context_p)
      return removed_ue_count;

  if (removed_ue_count == NUMBER_OF_UE_MAX) {
    LOG_E(RRC, "fatal: ue_to_be_removed is full\n");
    exit(1);
  }

  ue_to_be_removed[removed_ue_count] = ue_context_p;
  removed_ue_count++;

  return removed_ue_count;
}

laurent's avatar
laurent committed
8570
//-----------------------------------------------------------------------------
8571 8572 8573 8574 8575 8576
void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id)
{
  int32_t current_timestamp_ms = 0;
  int32_t ref_timestamp_ms = 0;
  struct timeval ts;
  struct rrc_eNB_ue_context_s *ue_context_p = NULL;
Cedric Roux's avatar
Cedric Roux committed
8577 8578 8579
  struct rrc_eNB_ue_context_s *ue_to_be_removed[NUMBER_OF_UE_MAX];
  int removed_ue_count = 0;
  int cur_ue;
8580 8581
#ifdef LOCALIZATION
  double estimated_distance = 0;
8582
  protocol_ctxt_t                     ctxt;
8583
#endif
Cedric Roux's avatar
Cedric Roux committed
8584 8585
  MessageDef *msg;

8586
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_IN);
Cedric Roux's avatar
Cedric Roux committed
8587

8588
  if (RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]->configuration.enable_x2) {
Cedric Roux's avatar
Cedric Roux committed
8589 8590 8591 8592
    /* send a tick to x2ap */
    msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_SUBFRAME_PROCESS);
    itti_send_msg_to_task(TASK_X2AP, ctxt_pP->module_id, msg);

8593
  check_handovers(ctxt_pP); // counter, get the value and aggregate
Cedric Roux's avatar
Cedric Roux committed
8594 8595
  }

8596 8597 8598
  // check for UL failure or for UE to be released
  RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
    ctxt_pP->rnti = ue_context_p->ue_id_rnti;
8599

8600 8601 8602 8603 8604 8605 8606 8607 8608 8609 8610 8611
    if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe == 0)) {
      if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) {
        LOG_I(RRC, "UE rnti %x: S-TMSI %x failure timer %d/8\n",
              ue_context_p->ue_context.rnti,
              ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi,
              ue_context_p->ue_context.ul_failure_timer);
      } else {
        LOG_I(RRC, "UE rnti %x failure timer %d/8\n",
              ue_context_p->ue_context.rnti,
              ue_context_p->ue_context.ul_failure_timer);
      }
    }
8612

8613 8614
    if (ue_context_p->ue_context.ul_failure_timer > 0) {
      ue_context_p->ue_context.ul_failure_timer++;
8615

8616 8617 8618 8619
      if (ue_context_p->ue_context.ul_failure_timer >= 20000) {
        // remove UE after 20 seconds after MAC (or else) has indicated UL failure
        LOG_I(RRC, "Removing UE %x instance, because of uplink failure timer timeout\n",
              ue_context_p->ue_context.rnti);
Cedric Roux's avatar
Cedric Roux committed
8620
        removed_ue_count = add_ue_to_remove(ue_to_be_removed, removed_ue_count, ue_context_p);
8621 8622 8623
        break; // break RB_FOREACH
      }
    }
8624

8625 8626
    if (ue_context_p->ue_context.ue_release_timer_s1 > 0) {
      ue_context_p->ue_context.ue_release_timer_s1++;
8627

8628 8629 8630 8631
      if (ue_context_p->ue_context.ue_release_timer_s1 >= ue_context_p->ue_context.ue_release_timer_thres_s1) {
        LOG_I(RRC, "Removing UE %x instance, because of UE_CONTEXT_RELEASE_COMMAND not received after %d ms from sending request\n",
              ue_context_p->ue_context.rnti,
              ue_context_p->ue_context.ue_release_timer_thres_s1);
8632

8633
        if (EPC_MODE_ENABLED && !NODE_IS_DU(RC.rrc[ctxt_pP->module_id]->node_type))
8634 8635
          rrc_eNB_generate_RRCConnectionRelease(ctxt_pP, ue_context_p);
        else
Cedric Roux's avatar
Cedric Roux committed
8636
          removed_ue_count = add_ue_to_remove(ue_to_be_removed, removed_ue_count, ue_context_p);
8637

8638 8639 8640 8641
        ue_context_p->ue_context.ue_release_timer_s1 = 0;
        break; // break RB_FOREACH
      } // end if timer_s1 timeout
    } // end if timer_s1 > 0 (S1 UE_CONTEXT_RELEASE_REQ ongoing)
Lionel Gauthier's avatar
 
Lionel Gauthier committed
8642

8643 8644
    if (ue_context_p->ue_context.ue_release_timer_rrc > 0) {
      ue_context_p->ue_context.ue_release_timer_rrc++;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8645

8646 8647 8648 8649
      if (ue_context_p->ue_context.ue_release_timer_rrc >= ue_context_p->ue_context.ue_release_timer_thres_rrc) {
        LOG_I(RRC, "Removing UE %x instance after UE_CONTEXT_RELEASE_Complete (ue_release_timer_rrc timeout)\n",
              ue_context_p->ue_context.rnti);
        ue_context_p->ue_context.ue_release_timer_rrc = 0;
Cedric Roux's avatar
Cedric Roux committed
8650
        removed_ue_count = add_ue_to_remove(ue_to_be_removed, removed_ue_count, ue_context_p);
8651
        break; // break RB_FOREACH
8652
      }
8653
    }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
8654

8655 8656
    if (ue_context_p->ue_context.handover_info != NULL) {
      if (ue_context_p->ue_context.handover_info->state == HO_RELEASE) {
Cedric Roux's avatar
Cedric Roux committed
8657
        removed_ue_count = add_ue_to_remove(ue_to_be_removed, removed_ue_count, ue_context_p);
8658 8659 8660
        rrc_eNB_handover_ue_context_release(ctxt_pP, ue_context_p);
        break; //break RB_FOREACH (why to break ?)
      }
Cedric Roux's avatar
Cedric Roux committed
8661 8662 8663 8664 8665 8666 8667 8668
      if (ue_context_p->ue_context.handover_info->state == HO_CANCEL) {
        rrc_eNB_handover_cancel(ctxt_pP, ue_context_p);
        /* freeing handover_info and setting it to NULL to let
         * RRC wait for MME to later on release the UE
         */
        free(ue_context_p->ue_context.handover_info);
        ue_context_p->ue_context.handover_info = NULL;
      }
8669
    }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
8670

8671
    pthread_mutex_lock(&rrc_release_freelist);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
8672

8673 8674
    if (rrc_release_info.num_UEs > 0) {
      uint16_t release_total = 0;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
8675

8676 8677 8678 8679 8680 8681 8682 8683 8684 8685
      for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) {
        if (rrc_release_info.RRC_release_ctrl[release_num].flag > 0) {
          release_total++;
        }

        if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) &&
            (rrc_release_info.RRC_release_ctrl[release_num].rnti == ue_context_p->ue_context.rnti)) {
          ue_context_p->ue_context.ue_release_timer_rrc = 1;
          ue_context_p->ue_context.ue_release_timer_thres_rrc = 100;

8686
          if (EPC_MODE_ENABLED && !NODE_IS_DU(RC.rrc[ctxt_pP->module_id]->node_type)) {
8687
            if (rrc_release_info.RRC_release_ctrl[release_num].flag == 4) { // if timer_s1 == 0
8688 8689
              rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(ctxt_pP->module_id,
                  ue_context_p->ue_context.eNB_ue_s1ap_id);
8690 8691
            }

8692 8693 8694 8695
            rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(ctxt_pP->module_id,
                  ue_context_p);
            // erase data of GTP tunnels in UE context
            for (int e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
8696
              ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0;
8697 8698 8699
              memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab],
                  0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
              ue_context_p->ue_context.enb_gtp_ebi[e_rab]  = 0;
8700 8701 8702
            }

            struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL;
8703 8704
            rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0,
                                                      ue_context_p->ue_context.eNB_ue_s1ap_id);
8705 8706 8707 8708

            if (rrc_ue_s1ap_ids != NULL) {
              rrc_eNB_S1AP_remove_ue_ids(RC.rrc[ctxt_pP->module_id], rrc_ue_s1ap_ids);
            }
8709
          } /* EPC_MODE_ENABLED && !NODE_IS_DU */
8710 8711 8712 8713 8714 8715 8716 8717 8718 8719 8720 8721 8722 8723 8724

          rrc_release_info.RRC_release_ctrl[release_num].flag = 0;
          rrc_release_info.num_UEs--;
          break; // break for (release_num)
        } // end if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) && ...

        if (release_total >= rrc_release_info.num_UEs) {
          break; // break for (release_num)
        }
      } // end for (release_num)
    } // end if (rrc_release_info.num_UEs > 0)

    pthread_mutex_unlock(&rrc_release_freelist);

    if ((ue_context_p->ue_context.ue_rrc_inactivity_timer > 0) && (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0)) {
8725
      ue_context_p->ue_context.ue_rrc_inactivity_timer++;
8726 8727 8728 8729

      if (ue_context_p->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) {
        LOG_I(RRC, "Removing UE %x instance because of rrc_inactivity_timer timeout\n",
              ue_context_p->ue_context.rnti);
Cedric Roux's avatar
Cedric Roux committed
8730
        removed_ue_count = add_ue_to_remove(ue_to_be_removed, removed_ue_count, ue_context_p);
8731 8732 8733 8734 8735 8736 8737 8738 8739 8740 8741
        break; // break RB_FOREACH
      }
    }

    if (ue_context_p->ue_context.ue_reestablishment_timer > 0) {
      ue_context_p->ue_context.ue_reestablishment_timer++;

      if (ue_context_p->ue_context.ue_reestablishment_timer >= ue_context_p->ue_context.ue_reestablishment_timer_thres) {
        LOG_I(RRC, "Removing UE %x instance because of reestablishment_timer timeout\n",
              ue_context_p->ue_context.rnti);
        ue_context_p->ue_context.ul_failure_timer = 20000; // lead to send S1 UE_CONTEXT_RELEASE_REQ
Cedric Roux's avatar
Cedric Roux committed
8742
        removed_ue_count = add_ue_to_remove(ue_to_be_removed, removed_ue_count, ue_context_p);
8743 8744 8745 8746 8747 8748 8749 8750 8751 8752 8753 8754 8755 8756 8757 8758
        ue_context_p->ue_context.ue_reestablishment_timer = 0;
        break; // break RB_FOREACH
      }
    }

    if (ue_context_p->ue_context.ue_release_timer > 0) {
      ue_context_p->ue_context.ue_release_timer++;

      if (ue_context_p->ue_context.ue_release_timer >= ue_context_p->ue_context.ue_release_timer_thres) {
        LOG_I(RRC, "Removing UE %x instance because of RRC Connection Setup timer timeout\n",
              ue_context_p->ue_context.rnti);
        /*
        * TODO: Naming problem here: ue_release_timer seems to have been used when RRC Connection Release was sent.
        * It is no more the case.
        * The timer should be renamed.
        */
Cedric Roux's avatar
Cedric Roux committed
8759
        removed_ue_count = add_ue_to_remove(ue_to_be_removed, removed_ue_count, ue_context_p);
8760 8761 8762 8763 8764 8765
        ue_context_p->ue_context.ue_release_timer = 0;
        break; // break RB_FOREACH
      }
    }
  } // end RB_FOREACH

Cedric Roux's avatar
Cedric Roux committed
8766 8767 8768
  for (cur_ue = 0; cur_ue < removed_ue_count; cur_ue++) {
    if ((ue_to_be_removed[cur_ue]->ue_context.ul_failure_timer >= 20000) ||
        ((ue_to_be_removed[cur_ue]->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) &&
8769
         (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0))) {
Cedric Roux's avatar
Cedric Roux committed
8770 8771 8772 8773
      ue_to_be_removed[cur_ue]->ue_context.ue_release_timer_s1 = 1;
      ue_to_be_removed[cur_ue]->ue_context.ue_release_timer_thres_s1 = 100;
      ue_to_be_removed[cur_ue]->ue_context.ue_release_timer = 0;
      ue_to_be_removed[cur_ue]->ue_context.ue_reestablishment_timer = 0;
8774 8775
    }

Cedric Roux's avatar
Cedric Roux committed
8776
    rrc_eNB_free_UE(ctxt_pP->module_id, ue_to_be_removed[cur_ue]);
8777

Cedric Roux's avatar
Cedric Roux committed
8778 8779
    if (ue_to_be_removed[cur_ue]->ue_context.ul_failure_timer >= 20000) {
      ue_to_be_removed[cur_ue]->ue_context.ul_failure_timer = 0;
8780 8781
    }

Cedric Roux's avatar
Cedric Roux committed
8782
    if ((ue_to_be_removed[cur_ue]->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) &&
8783
        (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0)) {
Cedric Roux's avatar
Cedric Roux committed
8784
      ue_to_be_removed[cur_ue]->ue_context.ue_rrc_inactivity_timer = 0; //reset timer after S1 command UE context release request is sent
8785 8786 8787 8788 8789 8790 8791 8792 8793 8794 8795 8796 8797 8798 8799 8800 8801 8802 8803 8804 8805 8806 8807 8808 8809 8810 8811 8812 8813 8814 8815 8816 8817 8818
    }
  }

#ifdef RRC_LOCALIZATION
  /* for the localization, only primary CC_id might be relevant*/
  gettimeofday(&ts, NULL);
  current_timestamp_ms = ts.tv_sec * 1000 + ts.tv_usec / 1000;
  ref_timestamp_ms = RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms;
  RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
    ctxt = *ctxt_pP;
    ctxt.rnti = ue_context_p->ue_context.rnti;
    estimated_distance = rrc_get_estimated_ue_distance(&ctxt, CC_id, RC.rrc[ctxt_pP->module_id]->loc_type);

    if ((current_timestamp_ms - ref_timestamp_ms > RC.rrc[ctxt_pP->module_id]->aggregation_period_ms) &&
        estimated_distance != -1) {
      LOG_D(LOCALIZE, "RRC [UE/id %d -> eNB/id %d] timestamp %d frame %d estimated r = %f\n",
            ctxt.rnti,
            ctxt_pP->module_id,
            current_timestamp_ms,
            ctxt_pP->frame,
            estimated_distance);
      LOG_D(LOCALIZE, "RRC status %d\n",
            ue_context_p->ue_context.Status);
      push_front(&RC.rrc[ctxt_pP->module_id]->loc_list, estimated_distance);
      RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms = current_timestamp_ms;
    } // end if
  } // end RB_FOREACH
#endif
  (void)ts; /* remove gcc warning "unused variable" */
  (void)ref_timestamp_ms; /* remove gcc warning "unused variable" */
  (void)current_timestamp_ms; /* remove gcc warning "unused variable" */
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_OUT);
}

8819
//-----------------------------------------------------------------------------
laurent's avatar
laurent committed
8820
void *rrc_enb_process_itti_msg(void *notUsed) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8821 8822 8823 8824 8825
  MessageDef                         *msg_p;
  const char                         *msg_name_p;
  instance_t                          instance;
  int                                 result;
  protocol_ctxt_t                     ctxt;
8826

8827
  memset(&ctxt, 0, sizeof(ctxt));
8828

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8829 8830 8831 8832
  // Wait for a message
  itti_receive_msg(TASK_RRC_ENB, &msg_p);
  msg_name_p = ITTI_MSG_NAME(msg_p);
  instance = ITTI_MSG_INSTANCE(msg_p);
8833 8834
  /* RRC_SUBFRAME_PROCESS is sent every subframe, do not log it */
  if (ITTI_MSG_ID(msg_p) != RRC_SUBFRAME_PROCESS)
luaihui's avatar
luaihui committed
8835
    LOG_D(RRC,"Received message %s\n",msg_name_p);
8836

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8837
  switch (ITTI_MSG_ID(msg_p)) {
8838
    case TERMINATE_MESSAGE:
8839
      LOG_W(RRC, " *** Exiting RRC thread\n");
8840 8841 8842 8843 8844 8845 8846
      itti_exit_task();
      break;

    case MESSAGE_TEST:
      LOG_I(RRC, "[eNB %d] Received %s\n", instance, msg_name_p);
      break;

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8847
    /* Messages from MAC */
8848
    case RRC_MAC_CCCH_DATA_IND:
8849
      PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
8850
                                    RRC_MAC_CCCH_DATA_IND(msg_p).enb_index,
8851 8852 8853 8854
                                    ENB_FLAG_YES,
                                    RRC_MAC_CCCH_DATA_IND(msg_p).rnti,
                                    msg_p->ittiMsgHeader.lte_time.frame,
                                    msg_p->ittiMsgHeader.lte_time.slot);
8855

8856
      LOG_I(RRC,"Decoding CCCH : inst %d, CC_id %d, ctxt %p, sib_info_p->Rx_buffer.payload_size %d\n",
Robert Schmidt's avatar
Robert Schmidt committed
8857 8858 8859 8860
            instance,
            RRC_MAC_CCCH_DATA_IND(msg_p).CC_id,
            &ctxt,
            RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8861

8862
      if (RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size >= CCCH_SDU_SIZE) {
8863
        LOG_I(RRC, "CCCH message has size %d > %d\n",
8864
              RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size,CCCH_SDU_SIZE);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8865
        break;
8866
      }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8867

8868 8869 8870 8871
      rrc_eNB_decode_ccch(&ctxt,
                          (uint8_t*)RRC_MAC_CCCH_DATA_IND(msg_p).sdu,
                          RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size,
                          RRC_MAC_CCCH_DATA_IND(msg_p).CC_id);
8872
      break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8873

8874

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8875
    /* Messages from PDCP */
8876
    case RRC_DCCH_DATA_IND:
8877 8878 8879 8880 8881 8882
      PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
                                    instance,
                                    ENB_FLAG_YES,
                                    RRC_DCCH_DATA_IND(msg_p).rnti,
                                    msg_p->ittiMsgHeader.lte_time.frame,
                                    msg_p->ittiMsgHeader.lte_time.slot);
8883
      LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Received on DCCH %d %s\n",
8884 8885 8886 8887 8888 8889
            PROTOCOL_RRC_CTXT_UE_ARGS(&ctxt),
            RRC_DCCH_DATA_IND(msg_p).dcch_index,
            msg_name_p);
      rrc_eNB_decode_dcch(&ctxt,
                          RRC_DCCH_DATA_IND(msg_p).dcch_index,
                          RRC_DCCH_DATA_IND(msg_p).sdu_p,
8890 8891 8892
                          RRC_DCCH_DATA_IND(msg_p).sdu_size);
      // Message buffer has been processed, free it now.
      result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), RRC_DCCH_DATA_IND(msg_p).sdu_p);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8893

8894
      if (result != EXIT_SUCCESS) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8895 8896
        LOG_I(RRC, "Failed to free memory (%d)!\n",result);
        break;
8897
      }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
8898

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8899
      break;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
8900

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8901
    /* Messages from S1AP */
8902 8903 8904
    case S1AP_DOWNLINK_NAS:
      rrc_eNB_process_S1AP_DOWNLINK_NAS(msg_p, msg_name_p, instance, &rrc_eNB_mui);
      break;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
8905

8906 8907 8908
    case S1AP_INITIAL_CONTEXT_SETUP_REQ:
      rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p, msg_name_p, instance);
      break;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
8909

8910 8911 8912
    case S1AP_UE_CTXT_MODIFICATION_REQ:
      rrc_eNB_process_S1AP_UE_CTXT_MODIFICATION_REQ(msg_p, msg_name_p, instance);
      break;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
8913

8914
    case S1AP_PAGING_IND:
8915 8916
      LOG_D(RRC, "[eNB %d] Received Paging message from S1AP: %s\n", instance, msg_name_p);
      rrc_eNB_process_PAGING_IND(msg_p, msg_name_p, instance);
8917
      break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8918 8919

    case S1AP_E_RAB_SETUP_REQ:
8920 8921 8922
      rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(msg_p, msg_name_p, instance);
      LOG_D(RRC, "[eNB %d] Received the message %s\n", instance, msg_name_p);
      break;
8923 8924 8925 8926 8927 8928 8929 8930

    case S1AP_E_RAB_MODIFY_REQ:
      rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(msg_p, msg_name_p, instance);
      break;

    case S1AP_E_RAB_RELEASE_COMMAND:
      rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(msg_p, msg_name_p, instance);
      break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8931

8932 8933 8934
    case S1AP_UE_CONTEXT_RELEASE_REQ:
      rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_REQ(msg_p, msg_name_p, instance);
      break;
8935

8936 8937 8938
    case S1AP_UE_CONTEXT_RELEASE_COMMAND:
      rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND(msg_p, msg_name_p, instance);
      break;
8939

Konstantinos Alexandris's avatar
Konstantinos Alexandris committed
8940 8941
    case GTPV1U_ENB_DELETE_TUNNEL_RESP: {
      rrc_eNB_ue_context_t *ue = rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti);
Lionel Gauthier's avatar
Lionel Gauthier committed
8942

Konstantinos Alexandris's avatar
Konstantinos Alexandris committed
8943 8944
      if (ue != NULL
          && ue->ue_context.ue_release_timer_rrc > 0
Cedric Roux's avatar
Cedric Roux committed
8945 8946 8947
          && (ue->ue_context.handover_info == NULL ||
              (ue->ue_context.handover_info->state != HO_RELEASE &&
               ue->ue_context.handover_info->state != HO_CANCEL))) {
Konstantinos Alexandris's avatar
Konstantinos Alexandris committed
8948
        ue->ue_context.ue_release_timer_rrc = ue->ue_context.ue_release_timer_thres_rrc;
8949
      }
Cedric Roux's avatar
Cedric Roux committed
8950

8951
      break;
Konstantinos Alexandris's avatar
Konstantinos Alexandris committed
8952
    }
Lionel Gauthier's avatar
Lionel Gauthier committed
8953

8954 8955 8956 8957
    case S1AP_PATH_SWITCH_REQ_ACK:
      LOG_I(RRC, "[eNB %d] received path switch ack %s\n", instance, msg_name_p);
      rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK(msg_p, msg_name_p, instance);
      break;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
8958

8959 8960 8961 8962 8963 8964 8965 8966
    case X2AP_SETUP_REQ:
      rrc_eNB_process_x2_setup_request(instance, &X2AP_SETUP_REQ(msg_p));
      break;

    case X2AP_SETUP_RESP:
      rrc_eNB_process_x2_setup_response(instance, &X2AP_SETUP_RESP(msg_p));
      break;

8967
    case X2AP_HANDOVER_REQ:
8968
      LOG_I(RRC, "[eNB %d] target eNB Receives X2 HO Req %s\n", instance, msg_name_p);
8969 8970
      rrc_eNB_process_handoverPreparationInformation(instance, &X2AP_HANDOVER_REQ(msg_p));
      break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8971

8972 8973
    case X2AP_HANDOVER_REQ_ACK: {
      struct rrc_eNB_ue_context_s        *ue_context_p = NULL;
luaihui's avatar
luaihui committed
8974 8975 8976
      x2ap_handover_req_ack_t 			  *x2ap_handover_req_ack = NULL;
      hashtable_rc_t                	  hash_rc      = HASH_TABLE_KEY_NOT_EXISTS;
      gtpv1u_ue_data_t             		  *gtpv1u_ue_data_p = NULL;
8977 8978 8979 8980 8981 8982
      ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], X2AP_HANDOVER_REQ_ACK(msg_p).rnti);
      if (ue_context_p == NULL) {
        /* is it possible? */
        LOG_E(RRC, "could not find UE (rnti %x) while processing X2AP_HANDOVER_REQ_ACK\n",
              X2AP_HANDOVER_REQ_ACK(msg_p).rnti);
        exit(1);
8983
      }
8984
      LOG_I(RRC, "[eNB %d] source eNB receives the X2 HO ACK %s\n", instance, msg_name_p);
8985
      DevAssert(ue_context_p != NULL);
8986

8987
      if (ue_context_p->ue_context.handover_info->state != HO_REQUEST) abort();
luaihui's avatar
luaihui committed
8988 8989 8990 8991 8992 8993 8994 8995 8996 8997 8998 8999 9000 9001 9002 9003 9004 9005 9006 9007 9008 9009 9010 9011 9012 9013 9014 9015 9016 9017 9018 9019 9020 9021
	  
      hash_rc = hashtable_get(RC.gtpv1u_data_g->ue_mapping, ue_context_p->ue_context.rnti, (void**)&gtpv1u_ue_data_p);
      /* set target enb gtp teid */
      if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) {
        LOG_E(RRC, "X2AP_HANDOVER_REQ_ACK func(), hashtable_get failed: while getting ue rnti %x in hashtable ue_mapping\n", ue_context_p->ue_context.rnti);
      } else {
        uint8_t nb_e_rabs_tobesetup = 0;
	ebi_t   eps_bearer_id       = 0;
	int     ip_offset           = 0;
	in_addr_t  in_addr;
	x2ap_handover_req_ack = &X2AP_HANDOVER_REQ_ACK(msg_p);
	nb_e_rabs_tobesetup = x2ap_handover_req_ack->nb_e_rabs_tobesetup;
        ue_context_p->ue_context.nb_x2u_e_rabs = nb_e_rabs_tobesetup;
	for(int i=0; i< nb_e_rabs_tobesetup; i++){
	  ip_offset               = 0;
	  eps_bearer_id = x2ap_handover_req_ack->e_rabs_tobesetup[i].e_rab_id;
          ue_context_p->ue_context.enb_gtp_x2u_ebi[i] = eps_bearer_id;
          ue_context_p->ue_context.enb_gtp_x2u_teid[i] = x2ap_handover_req_ack->e_rabs_tobesetup[i].gtp_teid;
	  gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_teNB = x2ap_handover_req_ack->e_rabs_tobesetup[i].gtp_teid; 
			
	  if ((x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.length == 4) ||
	      (x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.length == 20)) {
	      in_addr = *((in_addr_t*)x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.buffer);
	      ip_offset = 4;
	      gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].tenb_ip_addr = in_addr;
              ue_context_p->ue_context.enb_gtp_x2u_addrs[i] = x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr;
	  }

	  if ((x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.length == 16) ||
	      (x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.length == 20)) {
	      memcpy(gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].tenb_ip6_addr.s6_addr,
		     &x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.buffer[ip_offset],
		     16);
          }
Cedric Roux's avatar
Cedric Roux committed
9022

luaihui's avatar
luaihui committed
9023 9024 9025
        }
      }
	  
9026 9027 9028 9029
      rrc_eNB_process_handoverCommand(instance, ue_context_p, &X2AP_HANDOVER_REQ_ACK(msg_p));
      ue_context_p->ue_context.handover_info->state = HO_PREPARE;
      break;
    }
9030

9031 9032
   case X2AP_UE_CONTEXT_RELEASE: {
      struct rrc_eNB_ue_context_s        *ue_context_p = NULL;
9033 9034
      ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], X2AP_UE_CONTEXT_RELEASE(msg_p).rnti);
      LOG_I(RRC, "[eNB %d] source eNB receives the X2 UE CONTEXT RELEASE %s\n", instance, msg_name_p);
9035 9036 9037
      DevAssert(ue_context_p != NULL);

      if (ue_context_p->ue_context.handover_info->state != HO_COMPLETE) abort();
Lionel Gauthier's avatar
Lionel Gauthier committed
9038

9039 9040 9041 9042
      ue_context_p->ue_context.handover_info->state = HO_RELEASE;
      break;
    }

Cedric Roux's avatar
Cedric Roux committed
9043 9044 9045 9046 9047 9048 9049 9050 9051 9052 9053 9054 9055 9056 9057 9058 9059 9060 9061 9062 9063 9064 9065 9066 9067 9068 9069 9070 9071 9072 9073 9074 9075 9076 9077 9078 9079 9080 9081 9082 9083 9084
   case X2AP_HANDOVER_CANCEL: {
      struct rrc_eNB_ue_context_s        *ue_context_p = NULL;
      char *cause;
      switch (X2AP_HANDOVER_CANCEL(msg_p).cause) {
      case X2AP_T_RELOC_PREP_TIMEOUT:
        cause = "T_RelocPrep timeout";
        break;
      case X2AP_TX2_RELOC_OVERALL_TIMEOUT:
        cause = "Tx2_RelocOverall timeout";
        break;
      default:
        /* cannot come here */
        exit(1);
      }
      ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], X2AP_HANDOVER_CANCEL(msg_p).rnti);
      if (ue_context_p != NULL &&
          ue_context_p->ue_context.handover_info != NULL) {
        LOG_I(RRC, "[eNB %d] eNB receives X2 HANDOVER CANCEL for rnti %x, cause %s [%s]\n",
              instance,
              X2AP_HANDOVER_CANCEL(msg_p).rnti,
              cause,
              msg_name_p);
        if (X2AP_HANDOVER_CANCEL(msg_p).cause == X2AP_T_RELOC_PREP_TIMEOUT) {
          /* for prep timeout, simply return to normal state */
          /* TODO: be sure that it's correct to set Status to RRC_RECONFIGURED */
          ue_context_p->ue_context.Status = RRC_RECONFIGURED;
          /* TODO: be sure free is enough here (check memory leaks) */
          free(ue_context_p->ue_context.handover_info);
          ue_context_p->ue_context.handover_info = NULL;
        } else {
          /* for overall timeout, remove UE entirely */
          ue_context_p->ue_context.handover_info->state = HO_CANCEL;
        }
      } else {
        char *failure_cause;
        if (ue_context_p == NULL)
          failure_cause = "no UE found";
        else
          failure_cause = "UE not in handover";
        LOG_W(RRC, "[eNB %d] cannot process (%s) X2 HANDOVER CANCEL for rnti %x, cause %s, ignoring\n",
              instance, failure_cause, X2AP_HANDOVER_CANCEL(msg_p).rnti, cause);
      }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9085
      break;
Cedric Roux's avatar
Cedric Roux committed
9086
    }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
9087

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9088
    /* Messages from eNB app */
9089
    case RRC_CONFIGURATION_REQ:
9090
      LOG_I(RRC, "[eNB %d] Received %s : %p\n", instance, msg_name_p, &RRC_CONFIGURATION_REQ(msg_p));
9091
      openair_rrc_eNB_configuration(ENB_INSTANCE_TO_MODULE_ID(instance), &RRC_CONFIGURATION_REQ(msg_p));
9092
      break;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
9093

9094
    /* Messages from F1AP task */
Raymond Knopp's avatar
Raymond Knopp committed
9095
    case F1AP_SETUP_REQ:
9096
      AssertFatal(NODE_IS_CU(RC.rrc[instance]->node_type),
9097
		  "should not receive F1AP_SETUP_REQUEST, need call by CU!\n");
Raymond Knopp's avatar
Raymond Knopp committed
9098
      LOG_I(RRC,"[eNB %d] Received %s : %p\n", instance, msg_name_p, &F1AP_SETUP_REQ(msg_p));
9099
      handle_f1_setup_req(&F1AP_SETUP_REQ(msg_p));
9100
      break;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
9101

9102 9103
    case RRC_SUBFRAME_PROCESS:
      rrc_subframe_process(&RRC_SUBFRAME_PROCESS(msg_p).ctxt, RRC_SUBFRAME_PROCESS(msg_p).CC_id);
9104
      break;
9105

9106 9107 9108
    default:
      LOG_E(RRC, "[eNB %d] Received unexpected message %s\n", instance, msg_name_p);
      break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9109
  }
9110

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9111 9112 9113 9114 9115 9116 9117 9118
  result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p);

  if (result != EXIT_SUCCESS) {
    LOG_I(RRC, "Failed to free memory (%d)!\n",result);
  }

  msg_p = NULL;
  return NULL;
laurent's avatar
laurent committed
9119 9120 9121
}

//-----------------------------------------------------------------------------
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9122
void *
laurent's avatar
laurent committed
9123
rrc_enb_task(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9124
  void *args_p
laurent's avatar
laurent committed
9125 9126 9127 9128 9129 9130 9131 9132 9133
)
//-----------------------------------------------------------------------------
{
  rrc_enb_init();
  itti_mark_task_ready(TASK_RRC_ENB);
  LOG_I(RRC,"Entering main loop of RRC message task\n");

  while (1) {
    (void) rrc_enb_process_itti_msg(NULL);
9134
  }
9135
}
winckel's avatar
winckel committed
9136

9137 9138 9139 9140 9141 9142 9143 9144 9145 9146 9147 9148 9149 9150 9151 9152 9153 9154
/*------------------------------------------------------------------------------*/
void
openair_rrc_top_init_eNB(int eMBMS_active,uint8_t HO_active)
//-----------------------------------------------------------------------------
{
  module_id_t         module_id;
  int                 CC_id;
  /* for no gcc warnings */
  (void)CC_id;
  LOG_D(RRC, "[OPENAIR][INIT] Init function start: NB_eNB_INST=%d\n", RC.nb_inst);

  if (RC.nb_inst > 0) {
    LOG_I(RRC,"[eNB] handover active state is %d \n", HO_active);

    for (module_id=0; module_id<NB_eNB_INST; module_id++) {
      RC.rrc[module_id]->HO_flag   = (uint8_t)HO_active;
    }

9155
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
9156 9157 9158 9159 9160 9161 9162 9163 9164 9165 9166 9167 9168 9169 9170 9171 9172
    LOG_I(RRC,"[eNB] eMBMS active state is %d \n", eMBMS_active);

    for (module_id=0; module_id<NB_eNB_INST; module_id++) {
      for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
        RC.rrc[module_id]->carrier[CC_id].MBMS_flag = (uint8_t)eMBMS_active;
      }
    }

#endif
#ifdef CBA

    for (module_id=0; module_id<RC.nb_inst; module_id++) {
      for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
        RC.rrc[module_id]->carrier[CC_id].num_active_cba_groups = cba_group_active;
      }
    }

winckel's avatar
winckel committed
9173
#endif
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9174
  }
9175 9176 9177 9178 9179 9180 9181 9182 9183
}

//-----------------------------------------------------------------------------
void
rrc_top_cleanup_eNB(
  void
)
//-----------------------------------------------------------------------------
{
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9184
  for (int i=0; i<RC.nb_inst; i++) free (RC.rrc[i]);
9185 9186 9187 9188

  free(RC.rrc);
}

9189 9190

//-----------------------------------------------------------------------------
9191 9192 9193
//TTN - for D2D
uint8_t
rrc_eNB_process_SidelinkUEInformation(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9194 9195 9196
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t         *ue_context_pP,
  LTE_SidelinkUEInformation_r12_t *sidelinkUEInformation
9197 9198 9199
)
//-----------------------------------------------------------------------------
{
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9200 9201 9202 9203 9204 9205 9206 9207 9208 9209 9210 9211 9212 9213 9214 9215 9216 9217 9218 9219 9220 9221 9222 9223 9224 9225 9226
  LTE_SL_DestinationInfoList_r12_t  *destinationInfoList;
  int n_destinations = 0;
  int n_discoveryMessages = 0;
  LOG_I(RRC,
        PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing SidelinkUEInformation from UE (SRB1 Active)\n",
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));

  //For SL Communication
  if (sidelinkUEInformation->criticalExtensions.present == LTE_SidelinkUEInformation_r12__criticalExtensions_PR_c1) {
    if (sidelinkUEInformation->criticalExtensions.choice.c1.present == LTE_SidelinkUEInformation_r12__criticalExtensions__c1_PR_sidelinkUEInformation_r12) {
      // express its interest to receive SL communication
      if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commRxInterestedFreq_r12 !=  NULL) {
      }

      // express its interest to transmit  non-relay one-to-many SL communication
      if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12 != NULL) &&
          (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->carrierFreq_r12 != NULL)) {
        n_destinations = sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->destinationInfoList_r12.list.count;
        destinationInfoList = CALLOC(1, sizeof(LTE_SL_DestinationInfoList_r12_t));

        for (int i=0; i< n_destinations; i++ ) {
          //sl_DestinationIdentityList[i] = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->destinationInfoList_r12.list.array[i]);
          ASN_SEQUENCE_ADD(&destinationInfoList->list, sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->destinationInfoList_r12.list.array[i]);
        }

        //generate RRC Reconfiguration
        rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, destinationInfoList, 0);
9227 9228 9229

        free(destinationInfoList);
        destinationInfoList = NULL;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9230 9231 9232 9233 9234 9235 9236 9237 9238 9239 9240 9241 9242 9243 9244 9245 9246 9247
        return 0;
      }

      // express its interest to transmit  non-relay one-to-one SL communication
      if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension != NULL) &&
          (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13 != NULL)) {
        if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->carrierFreq_r12 != NULL) {
          n_destinations = sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->destinationInfoList_r12.list.count;
          destinationInfoList = CALLOC(1, sizeof(LTE_SL_DestinationInfoList_r12_t));

          for (int i=0; i< n_destinations; i++ ) {
            //sl_DestinationIdentityList[i] = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->destinationInfoList_r12.list.array[i]);
            ASN_SEQUENCE_ADD(&destinationInfoList->list,
                             sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->destinationInfoList_r12.list.array[i]);
          }

          //generate RRC Reconfiguration
          rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, destinationInfoList, 0);
9248 9249 9250

          free(destinationInfoList);
          destinationInfoList = NULL;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9251 9252 9253 9254 9255 9256 9257 9258 9259 9260 9261 9262 9263 9264 9265 9266 9267 9268 9269 9270 9271
          return 0;
        }
      }

      // express its interest to transmit relay related one-to-one SL communication
      if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension != NULL) &&
          (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13 != NULL)) {
        if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13->destinationInfoList_r12.list.count
            > 0) {
          n_destinations =
            sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13->destinationInfoList_r12.list.count;
          destinationInfoList = CALLOC(1, sizeof(LTE_SL_DestinationInfoList_r12_t));

          for (int i=0; i< n_destinations; i++ ) {
            //sl_DestinationIdentityList[i] = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13->destinationInfoList_r12.list.array[i]);
            ASN_SEQUENCE_ADD(&destinationInfoList->list,
                             sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13->destinationInfoList_r12.list.array[i]);
          }

          //generate RRC Reconfiguration
          rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, destinationInfoList, 0);
9272 9273 9274

          free(destinationInfoList);
          destinationInfoList = NULL;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9275 9276 9277 9278 9279 9280 9281 9282 9283 9284 9285 9286 9287 9288 9289 9290 9291 9292 9293 9294 9295
          return 0;
        }
      }

      //express its interest to transmit relay related one-to-many SL communication
      if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension != NULL) &&
          (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13 != NULL)) {
        if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12.list.count
            > 0) {
          n_destinations =
            sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12.list.count;
          destinationInfoList = CALLOC(1, sizeof(LTE_SL_DestinationInfoList_r12_t));

          for (int i=0; i< n_destinations; i++ ) {
            //sl_DestinationIdentityList[i] = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12.list.array[i]);
            ASN_SEQUENCE_ADD(&destinationInfoList->list,
                             sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12.list.array[i]);
          }

          //generate RRC Reconfiguration
          rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, destinationInfoList, 0);
9296 9297 9298

          free(destinationInfoList);
          destinationInfoList = NULL;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9299 9300 9301 9302 9303 9304 9305 9306 9307 9308 9309 9310 9311 9312 9313 9314 9315 9316 9317 9318 9319 9320 9321
          return 0;
        }
      }

      //For SL Discovery
      //express its interest to receive SL discovery announcements
      //express its interest to transmit non-PS related discovery announcements
      if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discTxResourceReq_r12 != NULL) {
        n_discoveryMessages = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discTxResourceReq_r12);
        //generate RRC Reconfiguration
        rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, NULL, n_discoveryMessages);
        return 0;
      }

      //express its interest to transmit PS related discovery announcements
      if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension != NULL) &&
          (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->discTxResourceReqPS_r13 !=NULL)) {
        if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->discTxResourceReqPS_r13->discTxResourceReq_r13 > 0) {
          n_discoveryMessages = sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->discTxResourceReqPS_r13->discTxResourceReq_r13;
          //generate RRC Reconfiguration
          rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, NULL, n_discoveryMessages);
          return 0;
        }
9322
      }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9323 9324 9325 9326
    }
  }

  return 0;
9327 9328 9329 9330 9331
}

//-----------------------------------------------------------------------------
int
rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9332 9333
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t *const ue_context_pP,
9334
  LTE_SL_DestinationInfoList_r12_t  *destinationInfoList,
9335 9336 9337 9338 9339
  int n_discoveryMessages
)
//-----------------------------------------------------------------------------
{
  uint8_t                             buffer[RRC_BUF_SIZE];
9340
  uint16_t                            size = 0;
9341 9342 9343 9344 9345
  memset(buffer, 0, RRC_BUF_SIZE);

  // allocate dedicated pools for UE -sl-CommConfig/sl-DiscConfig (sl-V2X-ConfigDedicated)
  //populate dedicated resources for SL communication (sl-CommConfig)
  if ((destinationInfoList != NULL) && (destinationInfoList->list.count > 0)) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9346 9347 9348 9349 9350 9351 9352 9353 9354 9355 9356 9357 9358 9359
    LOG_I(RRC,"[eNB %d] Frame %d, Generate LTE_RRCConnectionReconfiguration_Sidelink (bytes %d, UE id %x), number of destinations %d\n",
          ctxt_pP->module_id,ctxt_pP->frame, size, ue_context_pP->ue_context.rnti,destinationInfoList->list.count );
    //get dedicated resources from available pool and assign to the UE
    LTE_SL_CommConfig_r12_t  sl_CommConfig[destinationInfoList->list.count];
    //get a RP from the available RPs
    sl_CommConfig[0] = rrc_eNB_get_sidelink_commTXPool(ctxt_pP, ue_context_pP, destinationInfoList);
    size = do_RRCConnectionReconfiguration(ctxt_pP,
                                           buffer,
                                           rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),   //Transaction_id
                                           (LTE_SRB_ToAddModList_t *)NULL,
                                           (LTE_DRB_ToAddModList_t *)NULL,
                                           (LTE_DRB_ToReleaseList_t *)NULL, // DRB2_list,
                                           (struct LTE_SPS_Config *)NULL,   // *sps_Config,
                                           NULL, NULL, NULL, NULL,NULL,
Cedric Roux's avatar
Cedric Roux committed
9360
                                           NULL, NULL,  NULL, NULL, NULL, NULL, NULL,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9361 9362 9363 9364 9365 9366 9367 9368
                                           (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)NULL,
                                           (LTE_SL_CommConfig_r12_t *)&sl_CommConfig,
                                           (LTE_SL_DiscConfig_r12_t *)NULL
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                                           , (LTE_SCellToAddMod_r10_t *)NULL
#endif
                                          );
    //
9369
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9370

9371 9372
  //populate dedicated resources for SL discovery (sl-DiscConfig)
  if (n_discoveryMessages > 0) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9373 9374 9375 9376 9377 9378 9379 9380 9381 9382 9383
    LTE_SL_DiscConfig_r12_t sl_DiscConfig[n_discoveryMessages];
    //get a RP from the available RPs
    sl_DiscConfig[0] = rrc_eNB_get_sidelink_discTXPool(ctxt_pP, ue_context_pP, n_discoveryMessages );
    size = do_RRCConnectionReconfiguration(ctxt_pP,
                                           buffer,
                                           rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),   //Transaction_id
                                           (LTE_SRB_ToAddModList_t *)NULL,
                                           (LTE_DRB_ToAddModList_t *)NULL,
                                           (LTE_DRB_ToReleaseList_t *)NULL, // DRB2_list,
                                           (struct LTE_SPS_Config *)NULL,   // *sps_Config,
                                           NULL, NULL, NULL, NULL,NULL,
Cedric Roux's avatar
Cedric Roux committed
9384
                                           NULL, NULL,  NULL, NULL, NULL, NULL, NULL,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9385 9386 9387 9388 9389 9390 9391
                                           (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)NULL,
                                           (LTE_SL_CommConfig_r12_t *)NULL,
                                           (LTE_SL_DiscConfig_r12_t *)&sl_DiscConfig
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                                           , (LTE_SCellToAddMod_r10_t *)NULL
#endif
                                          );
9392 9393
  }

9394
  LOG_I(RRC,"[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration_Sidelink (bytes %d, UE id %x)\n",
9395 9396 9397 9398 9399 9400 9401 9402 9403 9404 9405 9406 9407
        ctxt_pP->module_id,ctxt_pP->frame, size, ue_context_pP->ue_context.rnti);
  rrc_data_req(
    ctxt_pP,
    DCCH,
    rrc_eNB_mui++,
    SDU_CONFIRM_NO,
    size,
    buffer,
    PDCP_TRANSMISSION_MODE_CONTROL);
  // rrc_data_req();
  return size;
}

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9408 9409
LTE_SL_CommConfig_r12_t rrc_eNB_get_sidelink_commTXPool( const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, LTE_SL_DestinationInfoList_r12_t  *destinationInfoList ) {
  // for the moment, use scheduled resource allocation
9410 9411
  LTE_SL_CommConfig_r12_t sl_CommConfig_r12;
  LTE_SL_CommConfig_r12_t  *sl_CommConfig = &sl_CommConfig_r12;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9412
  LTE_SL_CommResourcePool_r12_t    *sc_CommTxConfig;
9413
  memset(sl_CommConfig,0,sizeof(LTE_SL_CommConfig_r12_t));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9414 9415 9416 9417 9418 9419 9420 9421 9422 9423 9424 9425 9426 9427 9428 9429 9430 9431 9432 9433 9434 9435 9436 9437 9438 9439 9440 9441 9442 9443 9444 9445 9446 9447 9448 9449 9450 9451 9452 9453 9454 9455 9456 9457 9458 9459 9460 9461 9462 9463 9464 9465 9466 9467 9468 9469 9470 9471
  sl_CommConfig->commTxResources_r12 = CALLOC(1, sizeof(*sl_CommConfig->commTxResources_r12));
  sl_CommConfig->commTxResources_r12->present = LTE_SL_CommConfig_r12__commTxResources_r12_PR_setup;
  sl_CommConfig->commTxResources_r12->choice.setup.present = LTE_SL_CommConfig_r12__commTxResources_r12__setup_PR_scheduled_r12;
  sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.size = 2;
  sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.buf = CALLOC(1,2);
  sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.buf[0] = 0x00;
  sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.buf[1] = 0x01;//ctxt_pP->rnti;//rnti
  sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.bits_unused = 0;
  sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.mcs_r12 = CALLOC(1,sizeof(*sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.mcs_r12));
  //*sl_CommConfig_test->commTxResources_r12->choice.setup.choice.scheduled_r12.mcs_r12 = 12; //Msc
  sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.mac_MainConfig_r12.retx_BSR_TimerSL = LTE_RetxBSR_Timer_r12_sf320; //MacConfig, for testing only
  //sl_CommConfig_test->commTxResources_r12->choice.setup.choice.scheduled_r12.sc_CommTxConfig_r12;
  sc_CommTxConfig = & sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sc_CommTxConfig_r12;
  sc_CommTxConfig->sc_CP_Len_r12 = LTE_SL_CP_Len_r12_normal;
  sc_CommTxConfig->sc_Period_r12 = LTE_SL_PeriodComm_r12_sf40;
  sc_CommTxConfig->data_CP_Len_r12 = LTE_SL_CP_Len_r12_normal;
  //sc_TF_ResourceConfig_r12
  sc_CommTxConfig->sc_TF_ResourceConfig_r12.prb_Num_r12 = 20;
  sc_CommTxConfig->sc_TF_ResourceConfig_r12.prb_Start_r12 = 5;
  sc_CommTxConfig->sc_TF_ResourceConfig_r12.prb_End_r12 = 44;
  sc_CommTxConfig->sc_TF_ResourceConfig_r12.offsetIndicator_r12.present = LTE_SL_OffsetIndicator_r12_PR_small_r12;
  sc_CommTxConfig->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = 0;
  sc_CommTxConfig->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present = LTE_SubframeBitmapSL_r12_PR_bs40_r12;
  sc_CommTxConfig->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = 5;
  sc_CommTxConfig->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf  = CALLOC(1,5);
  sc_CommTxConfig->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = 0;
  //dataHoppingConfig_r12
  sc_CommTxConfig->dataHoppingConfig_r12.hoppingParameter_r12 = 0;
  sc_CommTxConfig->dataHoppingConfig_r12.numSubbands_r12  = LTE_SL_HoppingConfigComm_r12__numSubbands_r12_ns1;
  sc_CommTxConfig->dataHoppingConfig_r12.rb_Offset_r12 = 0;
  //ue_SelectedResourceConfig_r12
  sc_CommTxConfig->ue_SelectedResourceConfig_r12 = CALLOC (1, sizeof (*sc_CommTxConfig->ue_SelectedResourceConfig_r12));
  sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.prb_Num_r12 = 20;
  sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.prb_Start_r12 = 5;
  sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.prb_End_r12 = 44;
  sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.offsetIndicator_r12.present = LTE_SL_OffsetIndicator_r12_PR_small_r12;
  sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = 0 ;
  sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.present = LTE_SubframeBitmapSL_r12_PR_bs40_r12;
  sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.size = 5;
  sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf  = CALLOC(1,5);
  sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.bits_unused = 0;
  sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[0] = 0xF0;
  sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[1] = 0xFF;
  sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[2] = 0xFF;
  sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[3] = 0xFF;
  sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[4] = 0xFF;
  //rxParametersNCell_r12
  sc_CommTxConfig->rxParametersNCell_r12 = CALLOC (1, sizeof (*sc_CommTxConfig->rxParametersNCell_r12));
  sc_CommTxConfig->rxParametersNCell_r12->tdd_Config_r12 = CALLOC (1, sizeof (*sc_CommTxConfig->rxParametersNCell_r12->tdd_Config_r12 ));
  sc_CommTxConfig->rxParametersNCell_r12->tdd_Config_r12->subframeAssignment = 0 ;
  sc_CommTxConfig->rxParametersNCell_r12->tdd_Config_r12->specialSubframePatterns = 0;
  sc_CommTxConfig->rxParametersNCell_r12->syncConfigIndex_r12 = 0;
  //txParameters_r12
  sc_CommTxConfig->txParameters_r12 = CALLOC (1, sizeof (*sc_CommTxConfig->txParameters_r12));
  sc_CommTxConfig->txParameters_r12->sc_TxParameters_r12.alpha_r12 = LTE_Alpha_r12_al0;
  sc_CommTxConfig->txParameters_r12->sc_TxParameters_r12.p0_r12 = 0;
  sc_CommTxConfig->ext1 = NULL ;
  return *sl_CommConfig;
9472 9473 9474
}


Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9475 9476 9477
LTE_SL_DiscConfig_r12_t rrc_eNB_get_sidelink_discTXPool( const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP,  int n_discoveryMessages ) {
  //TODO
  LTE_SL_DiscConfig_r12_t  sl_DiscConfig;
9478
  memset(&sl_DiscConfig,0,sizeof(LTE_SL_DiscConfig_r12_t));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9479 9480 9481 9482 9483 9484 9485
  sl_DiscConfig.discTxResources_r12 = CALLOC(1,sizeof(*sl_DiscConfig.discTxResources_r12));
  sl_DiscConfig.discTxResources_r12->present = LTE_SL_DiscConfig_r12__discTxResources_r12_PR_setup;
  sl_DiscConfig.discTxResources_r12->choice.setup.present = LTE_SL_DiscConfig_r12__discTxResources_r12__setup_PR_scheduled_r12;
  //sl_DiscConfig.discTxResources_r12->choice.setup.choice.scheduled_r12.discHoppingConfig_r12;
  //sl_DiscConfig.discTxResources_r12->choice.setup.choice.scheduled_r12.discTF_IndexList_r12;
  //sl_DiscConfig.discTxResources_r12->choice.setup.choice.scheduled_r12.discTxConfig_r12;
  return sl_DiscConfig;
9486
}
9487

9488 9489
RRC_status_t
rrc_rx_tx(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
9490
  protocol_ctxt_t *const ctxt_pP,
9491
  const int        CC_id
9492 9493 9494
)
//-----------------------------------------------------------------------------
{
9495 9496 9497 9498 9499
  MessageDef *message_p;
  message_p = itti_alloc_new_message(TASK_RRC_ENB, RRC_SUBFRAME_PROCESS);
  RRC_SUBFRAME_PROCESS(message_p).ctxt  = *ctxt_pP;
  RRC_SUBFRAME_PROCESS(message_p).CC_id = CC_id;
  itti_send_msg_to_task(TASK_RRC_ENB, ctxt_pP->module_id, message_p);
9500
  return RRC_OK;
9501
}