rrc_eNB.c 462 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
#include "oai_asn1.h"
33 34
#include <asn_application.h>
#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 40
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
#include "LAYER2/RLC/rlc.h"
41
#include "LAYER2/MAC/mac_proto.h"
42
#include "common/utils/LOG/log.h"
43
#include "COMMON/mac_rrc_primitives.h"
44
#include "RRC/LTE/MESSAGES/asn1_msg.h"
45 46
#include "LTE_RRCConnectionRequest.h"
#include "LTE_RRCConnectionReestablishmentRequest.h"
47
//#include "ReestablishmentCause.h"
48 49 50 51 52 53
#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"
54
#include "LTE_HandoverPreparationInformation.h"
55
#include "LTE_HandoverCommand.h"
56
#include "rlc.h"
57 58
#include "rrc_eNB_UE_context.h"
#include "platform_types.h"
59 60 61
#include "LTE_SL-CommConfig-r12.h"
#include "LTE_PeriodicBSR-Timer-r12.h"
#include "LTE_RetxBSR-Timer-r12.h"
62 63 64 65 66 67

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

68
#include "common/utils/LOG/vcd_signal_dumper.h"
Cedric Roux's avatar
Cedric Roux committed
69
#include "x2ap_eNB.h"
70

71
#include "T.h"
72
#include "LTE_MeasResults.h"
73

74 75 76 77
#include "RRC/NAS/nas_config.h"
#include "RRC/NAS/rb_config.h"
#include "OCG.h"
#include "OCG_extern.h"
78

79
#include "UTIL/OSA/osa_defs.h"
80

81 82
#include "rrc_eNB_S1AP.h"
#include "rrc_eNB_GTPV1U.h"
83
#include "rrc_eNB_M2AP.h"
84

85
#include "pdcp.h"
86
#include "openair3/ocp-gtpu/gtp_itf.h"
Laurent Thomas's avatar
Laurent Thomas committed
87
#include <openair3/ocp-gtpu/gtp_itf.h>
88

89
#include "intertask_interface.h"
Melissa Elkadi's avatar
Melissa Elkadi committed
90
#include "softmodem-common.h"
91

92
#if ENABLE_RAL
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
93
  #include "rrc_eNB_ral.h"
Lionel Gauthier's avatar
Lionel Gauthier committed
94 95
#endif

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

98
#define ASN_MAX_ENCODE_SIZE 4096
99
#define NUMBEROF_DRBS_TOBE_ADDED 1
s.rampalli's avatar
s.rampalli committed
100
static int encode_CG_ConfigInfo(char *buffer,int buffer_size,rrc_eNB_ue_context_t *const ue_context_pP,int *enc_size);
101

102 103
extern RAN_CONTEXT_t RC;

Lionel Gauthier's avatar
 
Lionel Gauthier committed
104 105
extern eNB_MAC_INST                *eNB_mac_inst;
extern UE_MAC_INST                 *UE_mac_inst;
106

winckel's avatar
RRC:  
winckel committed
107

Lionel Gauthier's avatar
 
Lionel Gauthier committed
108
mui_t                               rrc_eNB_mui = 0;
winckel's avatar
RRC:  
winckel committed
109

110
extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw);
111 112
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);
113
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);
114 115 116
extern int rrc_eNB_generate_RRCConnectionReconfiguration_endc(protocol_ctxt_t *ctxt, rrc_eNB_ue_context_t *ue_context, unsigned char *buffer, int buffer_size, OCTET_STRING_t *scg_group_config,
    OCTET_STRING_t *scg_RB_config);
extern struct rrc_eNB_ue_context_s *get_first_ue_context(eNB_RRC_INST *rrc_instance_pP);
117

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

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

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
132 133 134 135
  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;
  }
136 137
}

138 139 140
//-----------------------------------------------------------------------------
static void
init_SI(
141
  const protocol_ctxt_t *const ctxt_pP,
142
  const int              CC_id,
143
  RrcConfigurationReq *configuration
144
)
145
//-----------------------------------------------------------------------------
146 147
{
  int                                 i;
148
  LTE_SystemInformationBlockType1_v1310_IEs_t *sib1_v13ext=(LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL;
Cedric Roux's avatar
Cedric Roux committed
149
  LOG_D(RRC,"%s()\n\n\n\n",__FUNCTION__);
150

151
  if(configuration->radioresourceconfig[CC_id].mbms_dedicated_serving_cell == true) {
152
    LOG_A(RRC, "Configuring MIB FeMBMS (N_RB_DL %d)\n",
153 154 155 156
          (int)configuration->N_RB_DL[CC_id]);
    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MIB_FeMBMS = (uint8_t *) malloc16(4);
    do_MIB_FeMBMS(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id],
                  configuration->N_RB_DL[CC_id],
157 158
                  0, //additionalNonMBSFN
                  0);
159 160 161 162
    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));
163
    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,
164
        configuration
165 166
                                                                              );
    LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Contents of SIB1-MBMS\n",
167
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)
168 169
         );
    LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS freqBandIndicator_r14 %ld\n",
170
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
171 172
          RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->freqBandIndicator_r14
         );
173

174 175
    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",
176 177 178
            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
            i,
            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->schedulingInfoList_MBMS_r14.list.count);
179 180 181
    }

    LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS SIB13-r14 contents for MBSFN subframe allocation (partial)\n",
182
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)
183
         );
184 185

    for (i = 0; i < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9.list.count; i++) {
186
      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS SIB13-r14 contents for MBSFN sync area %d/%d (partial)\n",
187 188 189
            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);
190
      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS MCCH Repetition Period: %ld (just index number, not real value)\n",
191 192
            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);
193
      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS MCCH Offset: %ld\n",
194 195
            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);
196
      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS MCCH Modification Period: %ld\n",
197 198
            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);
199
      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS MCCH Signalling MCS: %ld\n",
200 201
            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);
202 203 204
      //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);
205

206 207 208 209 210 211
      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"));
      }
212 213 214
    }

    if(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->nonMBSFN_SubframeConfig_r14) {
215 216 217 218 219 220 221 222 223
      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS non MBSFN Subframe Config radioFrameAllocationPeriod-r14 %ld\n",
            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->nonMBSFN_SubframeConfig_r14->radioFrameAllocationPeriod_r14
           );
      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS non MBSFN Subframe Config radioFrameAllocationOffset-r14 %ld\n",
            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",
224 225 226 227
            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.buf);
    }

228
    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].FeMBMS_flag=1;
229 230
    //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");
  }
231

232 233
  eNB_RRC_INST *rrc = RC.rrc[ctxt_pP->module_id];
  rrc_eNB_carrier_data_t *carrier=&rrc->carrier[CC_id];
234
  carrier->MIB = (uint8_t *) malloc16(4);
235 236
  carrier->sizeof_SIB1 = 0;
  carrier->sizeof_SIB23 = 0;
237
  carrier->SIB1 = (uint8_t *) malloc16(32);
238
  AssertFatal(carrier->SIB1!=NULL,PROTOCOL_RRC_CTXT_FMT" init_SI: FATAL, no memory for SIB1 allocated\n",
239
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP));
240
  LOG_I(RRC,"[eNB %d] Node type %d \n ", ctxt_pP->module_id, rrc->node_type);
241

242
  if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) {
243 244 245 246 247 248
    // 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];
249 250
    carrier->eutra_band      = configuration->eutra_band[CC_id];
    carrier->N_RB_DL         = configuration->N_RB_DL[CC_id];
251
    carrier->pbch_repetition = configuration->pbch_repetition[CC_id];
252
    LOG_I(RRC, "configuration->schedulingInfoSIB1_BR_r13[CC_id] %d\n",(int)configuration->schedulingInfoSIB1_BR_r13[CC_id]);
253
    LOG_A(RRC, "Configuring MIB (N_RB_DL %d,phich_Resource %d,phich_Duration %d)\n",
254 255 256
          (int)configuration->N_RB_DL[CC_id],
          (int)configuration->radioresourceconfig[CC_id].phich_resource,
          (int)configuration->radioresourceconfig[CC_id].phich_duration);
257 258 259 260
    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,
261 262 263
                                 0,
                                 configuration->schedulingInfoSIB1_BR_r13[CC_id]
                                );
264 265
    carrier->sizeof_SIB1 = do_SIB1(&rrc->carrier[CC_id],
                                   ctxt_pP->module_id,
266
                                   CC_id,
267
                                   false,
268 269
                                   configuration
                                  );
270
    AssertFatal(carrier->sizeof_SIB1 != 255,"FATAL, RC.rrc[enb_mod_idP].carrier[CC_id].sizeof_SIB1 == 255");
271 272 273 274 275
    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],
276
          ctxt_pP->module_id,
277
          CC_id, true, configuration);
278
    }
279
  }
280

281
  if (!NODE_IS_DU(rrc->node_type)) {
282
    carrier->SIB23 = (uint8_t *) malloc16(64);
283
    AssertFatal(carrier->SIB23!=NULL,"cannot allocate memory for SIB");
284
    carrier->sizeof_SIB23 = do_SIB23(ctxt_pP->module_id,
285
                                     CC_id,
286
                                     false,
287 288
                                     configuration
                                    );
289
    LOG_I(RRC,"do_SIB23, size %d \n ", carrier->sizeof_SIB23);
290
    AssertFatal(carrier->sizeof_SIB23 != 255,"FATAL, RC.rrc[mod].carrier[CC_id].sizeof_SIB23 == 255");
291 292 293 294 295
    carrier->sizeof_SIB23_BR = 0;

    if (configuration->schedulingInfoSIB1_BR_r13[CC_id]>0) {
      carrier->SIB23_BR = (uint8_t *) malloc16(64);
      AssertFatal(carrier->SIB23_BR!=NULL,"cannot allocate memory for SIB");
296
      carrier->sizeof_SIB23_BR = do_SIB23(ctxt_pP->module_id, CC_id, true, configuration);
297 298
    }

299
    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" SIB2/3 Contents (partial)\n",
300
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP));
301
    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.n_SB = %ld\n",
302 303
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
          carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.n_SB);
304
    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.hoppingMode = %ld\n",
305 306
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
          carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode);
307
    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.pusch_HoppingOffset = %ld\n",
308 309
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
          carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset);
310
    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.enable64QAM = %d\n",
311 312
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
          (int)carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM);
313
    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.groupHoppingEnabled = %d\n",
314 315
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
          (int)carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled);
316
    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.groupAssignmentPUSCH = %ld\n",
317 318
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
          carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH);
319
    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.sequenceHoppingEnabled = %d\n",
320 321
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
          (int)carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled);
322
    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.cyclicShift  = %ld\n",
323 324
          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
          carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift);
325

326 327
    if (carrier->MBMS_flag > 0) {
      for (i = 0; i < carrier->sib2->mbsfn_SubframeConfigList->list.count; i++) {
328
        // SIB 2
329
        //   LOG_D(RRC, "[eNB %ld] mbsfn_SubframeConfigList.list.count = %ld\n", enb_mod_idP, RC.rrc[enb_mod_idP].sib2->mbsfn_SubframeConfigList->list.count);
330 331 332 333 334 335 336 337 338 339 340 341 342
        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);
343
      }
344

345 346
      //   SIB13
      for (i = 0; i < carrier->sib13->mbsfn_AreaInfoList_r9.list.count; i++) {
347 348 349 350 351 352 353 354 355 356
        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);
357
      }
358
    } 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));
359

360
    //TTN - SIB 18
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391
    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);
      }
392

393 394 395 396 397
      //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,
398
              carrier->sib19->discConfig_r12->discRxPool_r12.list.count);
399
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 cp_Len_r12: %ld \n",
400 401
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->cp_Len_r12);
402
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 discPeriod_r12: %ld \n",
403 404
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->discPeriod_r12);
405
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 numRetx_r12: %ld \n",
406 407
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->numRetx_r12);
408
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 numRepetition_r12: %ld \n",
409 410
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->numRepetition_r12);
411
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_Num_r12: %ld \n",
412 413
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_Num_r12);
414
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_Start_r12: %ld \n",
415 416
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_Start_r12);
417
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_End_r12: %ld \n",
418 419
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_End_r12);
420
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 offsetIndicator: %ld \n",
421 422
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12);
423
        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 subframeBitmap_choice_bs_buf: %s \n",
424 425
              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf);
426
      }
427
    }
428
  }
429

430
  LOG_D(RRC,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
431 432 433
        PROTOCOL_RRC_CTXT_FMT" RRC_UE --- MAC_CONFIG_REQ (SIB1.tdd & SIB2 params) ---> MAC_UE\n",
        PROTOCOL_RRC_CTXT_ARGS(ctxt_pP));

434
  // LTE-M stuff here (take out CU-DU for now)
435
  if (NODE_IS_MONOLITHIC(rrc->node_type)) {
436
    if ((carrier->mib.message.schedulingInfoSIB1_BR_r13>0) &&
437
        (carrier->sib1_BR!=NULL)) {
438
      AssertFatal(carrier->sib1_BR->nonCriticalExtension!=NULL,
439
                  "sib2_br->nonCriticalExtension is null (v8.9)\n");
440
      AssertFatal(carrier->sib1_BR->nonCriticalExtension->nonCriticalExtension!=NULL,
441
                  "sib2_br->nonCriticalExtension is null (v9.2)\n");
442
      AssertFatal(carrier->sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL,
443
                  "sib2_br->nonCriticalExtension is null (v11.3)\n");
444
      AssertFatal(carrier->sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL,
445
                  "sib2_br->nonCriticalExtension is null (v12.5)\n");
446
      AssertFatal(carrier->sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL,
447
                  "sib2_br->nonCriticalExtension is null (v13.10)\n");
448
      sib1_v13ext = carrier->sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension;
islam.galal's avatar
islam.galal committed
449
      // Basic Asserts for CE_level0 PRACH configuration
450 451
      LTE_RadioResourceConfigCommonSIB_t *radioResourceConfigCommon_BR = &carrier[CC_id].sib2_BR->radioResourceConfigCommon;
      struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach=radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
452
      LTE_PRACH_ParametersListCE_r13_t   *prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13;
islam.galal's avatar
islam.galal committed
453
      AssertFatal(prach_ParametersListCE_r13->list.count>0,"prach_ParametersListCE_r13 is empty\n");
454
      LTE_PRACH_ParametersCE_r13_t *p = prach_ParametersListCE_r13->list.array[0];
islam.galal's avatar
islam.galal committed
455 456
      AssertFatal(p->prach_StartingSubframe_r13 != NULL, "prach_StartingSubframe_r13 celevel0 is null\n");
      AssertFatal((1<<p->numRepetitionPerPreambleAttempt_r13)<=(2<<*p->prach_StartingSubframe_r13),
457 458 459
                  "prachce0->numReptitionPerPreambleAttempt_r13 %d > prach_StartingSubframe_r13 %d\n",
                  1<<p->numRepetitionPerPreambleAttempt_r13,
                  2<<*p->prach_StartingSubframe_r13);
460 461
    }
  }
462

463
  if (NODE_IS_MONOLITHIC(rrc->node_type)) {
464
    LOG_D(RRC, "About to call rrc_mac_config_req_eNB for ngran_eNB\n");
laurent's avatar
laurent committed
465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496
    rrc_mac_config_req_eNB_t tmp = {
        .CC_id = CC_id,
        .physCellId = carrier->physCellId,
        .p_eNB = carrier->p_eNB,
        .Ncp = carrier->Ncp,
        .eutra_band = carrier->sib1->freqBandIndicator,
        .dl_CarrierFreq = carrier->dl_CarrierFreq,
        .pbch_repetition = carrier->pbch_repetition,
        .mib = &carrier->mib,
        .radioResourceConfigCommon = &carrier->sib2->radioResourceConfigCommon,
        .tdd_Config = carrier->sib1->tdd_Config,
        .schedulingInfoList = &carrier->sib1->schedulingInfoList,
        .ul_CarrierFreq = carrier->ul_CarrierFreq,
        .ul_Bandwidth = carrier->sib2->freqInfo.ul_Bandwidth,
        .additionalSpectrumEmission = &carrier->sib2->freqInfo.additionalSpectrumEmission,
        .mbsfn_SubframeConfigList = carrier->sib2->mbsfn_SubframeConfigList,
        .MBMS_Flag = carrier->MBMS_flag,
        .sib1_ext_r13 = sib1_v13ext,
        .FeMBMS_Flag = RC.rrc[ctxt_pP->module_id]->carrier[CC_id].FeMBMS_flag,
        .mib_fembms = &carrier->siblock1_MBMS,
    };
    if (carrier->sib2_BR)
      tmp.LTE_radioResourceConfigCommon_BR = &carrier->sib2_BR->radioResourceConfigCommon;
    if (carrier->sib13)
      tmp.mbsfn_AreaInfoList = &carrier->sib13->mbsfn_AreaInfoList_r9;
    if (carrier->sib1_MBMS) {
      tmp.nonMBSFN_SubframeConfig = carrier->sib1_MBMS->nonMBSFN_SubframeConfig_r14;
      tmp.sib1_mbms_r14_fembms = carrier->sib1_MBMS->systemInformationBlockType13_r14;
      if (carrier->sib1_MBMS->systemInformationBlockType13_r14)
        tmp.mbsfn_AreaInfoList_fembms = &carrier->sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9;
    }
    rrc_mac_config_req_eNB(ctxt_pP->module_id, &tmp);
497
  }
498 499 500

  /* set flag to indicate that cell information is configured. This is required
   * in DU to trigger F1AP_SETUP procedure */
501 502 503
  pthread_mutex_lock(&rrc->cell_info_mutex);
  rrc->cell_info_configured=1;
  pthread_mutex_unlock(&rrc->cell_info_mutex);
504 505
}

winckel's avatar
winckel committed
506
/*------------------------------------------------------------------------------*/
507 508
static void
init_MCCH(
509 510
  module_id_t enb_mod_idP,
  int CC_id
511 512
)
//-----------------------------------------------------------------------------
513 514 515
{
  int                                 sync_area = 0;
  // initialize RRC_eNB_INST MCCH entry
516
  eNB_RRC_INST *rrc = RC.rrc[enb_mod_idP];
517
  RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE =
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
518
    malloc(RC.rrc[enb_mod_idP]->carrier[CC_id].num_mbsfn_sync_area * sizeof(uint8_t *));
Lionel Gauthier's avatar
 
Lionel Gauthier committed
519

520 521 522
  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);
523
    AssertFatal(RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE[sync_area] != NULL,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
524
                "[eNB %d]init_MCCH: FATAL, no memory for MCCH MESSAGE allocated \n", enb_mod_idP);
525
    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
526 527
        sync_area,
        (uint8_t *)RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE[sync_area],
528
        32, /* TODO: what is the actual size of .MCCH_MESSAGE[sync_area]? */
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
529 530
        &RC.rrc[enb_mod_idP]->carrier[CC_id].mcch,
        &RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message);
531
    LOG_I(RRC, "mcch message pointer %p for sync area %d \n",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
532 533
          RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE[sync_area],
          sync_area);
534 535
    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
536
          RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->commonSF_AllocPeriod_r9);
537
    LOG_D(RRC,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
538 539
          "[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);
540
    LOG_D(RRC, "[eNB %d] MBSFN Subframe Pattern: %02x (in hex)\n",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
541 542 543
          enb_mod_idP,
          RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->commonSF_Alloc_r9.list.array[0]->subframeAllocation.
          choice.oneFrame.buf[0]);
544
    AssertFatal(RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] != 255,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
545
                "RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] == 255");
546
    RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESS[sync_area].Active = 1;
547
  }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
548

549
  //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)
550 551
  // ??Configure MCCH logical channel
  // call mac_config_req with appropriate structure from ASN.1 description
552 553
  //  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]);
554
  if (NODE_IS_MONOLITHIC(rrc->node_type)) {
laurent's avatar
laurent committed
555 556 557 558
    rrc_mac_config_req_eNB_t tmp = {0};
    tmp.CC_id = CC_id;
    tmp.pmch_InfoList = &RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9;
    rrc_mac_config_req_eNB(enb_mod_idP, &tmp);
559
  }
560

561
  //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);
562 563
}

564
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
 
Lionel Gauthier committed
565
static void init_MBMS(
566
  module_id_t enb_mod_idP,
567
  int         CC_id,
568 569 570
  frame_t frameP
)
//-----------------------------------------------------------------------------
571 572 573
{
  // init the configuration for MTCH
  protocol_ctxt_t               ctxt;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
574

575
  if (RC.rrc[enb_mod_idP]->carrier[CC_id].MBMS_flag > 0) {
576
    PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, enb_mod_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, 0,enb_mod_idP);
577 578 579
    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
580 581
                             (LTE_SRB_ToAddModList_t *)NULL,   // LTE_SRB_ToAddModList
                             (LTE_DRB_ToAddModList_t *)NULL,   // LTE_DRB_ToAddModList
582
                             (LTE_DRB_ToReleaseList_t *)NULL,
583 584 585 586
                             0,     // security mode
                             NULL,  // key rrc encryption
                             NULL,  // key rrc integrity
                             NULL   // key encryption
587
                             , &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9)
588
                             ,NULL);
589

590
    if (!NODE_IS_CU(RC.rrc[enb_mod_idP]->node_type)) {
591
      rrc_rlc_config_asn1_req(&ctxt,
592 593 594
                              NULL, // LTE_SRB_ToAddModList
                              NULL,   // LTE_DRB_ToAddModList
                              NULL,   // DRB_ToReleaseList
595 596
                              &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9),0, 0
                             );
597
    }
598 599

    //rrc_mac_config_req();
600
  }
601 602
}

603 604 605 606 607 608
//-----------------------------------------------------------------------------
uint8_t
rrc_eNB_get_next_transaction_identifier(
  module_id_t enb_mod_idP
)
//-----------------------------------------------------------------------------
609
{
610 611
  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;
612
  LOG_T(RRC,"generated xid is %d\n",rrc_transaction_identifier[enb_mod_idP]);
613 614 615 616 617
  return rrc_transaction_identifier[enb_mod_idP];
}
/*------------------------------------------------------------------------------*/
/* Functions to handle UE index in eNB UE list */

winckel's avatar
winckel committed
618

619 620 621 622 623 624 625 626 627
////-----------------------------------------------------------------------------
//static module_id_t
//rrc_eNB_get_UE_index(
//                module_id_t enb_mod_idP,
//                uint64_t    UE_identity
//)
////-----------------------------------------------------------------------------
//{
//
628
//    bool      reg = false;
629 630 631 632
//    module_id_t    i;
//
//    AssertFatal(enb_mod_idP < NB_eNB_INST, "eNB index invalid (%d/%d)!", enb_mod_idP, NB_eNB_INST);
//
633
//    for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
634
//        if (RC.rrc[enb_mod_idP]->Info.UE_info[i] == UE_identity) {
635
//            // UE_identity already registered
636
//            reg = true;
637 638 639 640
//            break;
//        }
//    }
//
641
//    if (reg == false) {
642 643 644 645 646 647
//        return (UE_MODULE_INVALID);
//    } else
//        return (i);
//}


648
//-----------------------------------------------------------------------------
gauthier's avatar
gauthier committed
649
// return the ue context if there is already an UE with ue_identityP, NULL otherwise
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
650
static struct rrc_eNB_ue_context_s *
651
rrc_eNB_ue_context_random_exist(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
652
  const protocol_ctxt_t *const ctxt_pP,
653 654 655 656
  const uint64_t               ue_identityP
)
//-----------------------------------------------------------------------------
{
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
657
  struct rrc_eNB_ue_context_s        *ue_context_p = NULL;
658
  RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
659
    if (ue_context_p->ue_context.random_ue_identity == ue_identityP)
gauthier's avatar
gauthier committed
660
      return ue_context_p;
661
  }
gauthier's avatar
gauthier committed
662 663 664 665
  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
666
static struct rrc_eNB_ue_context_s *
gauthier's avatar
gauthier committed
667
rrc_eNB_ue_context_stmsi_exist(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
668
  const protocol_ctxt_t *const ctxt_pP,
gauthier's avatar
gauthier committed
669 670 671 672 673
  const mme_code_t             mme_codeP,
  const m_tmsi_t               m_tmsiP
)
//-----------------------------------------------------------------------------
{
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
674
  struct rrc_eNB_ue_context_s        *ue_context_p = NULL;
675
  RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
kaltenbe's avatar
kaltenbe committed
676
    LOG_I(RRC,"checking for UE S-TMSI %x, mme %x (%p): rnti %x",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
677 678 679
          m_tmsiP, mme_codeP, ue_context_p,
          ue_context_p->ue_context.rnti);

680
    if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == true) {
681
      printf("=> S-TMSI %x, MME %x\n",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
682 683 684
             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
685 686 687
      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
688
    } else
kaltenbe's avatar
kaltenbe committed
689
      printf("\n");
gauthier's avatar
gauthier committed
690 691
  }
  return NULL;
692 693
}

694 695
//-----------------------------------------------------------------------------
// 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
696
static struct rrc_eNB_ue_context_s *
697
rrc_eNB_get_next_free_ue_context(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
698
  const protocol_ctxt_t *const ctxt_pP,
699 700 701 702
  const uint64_t               ue_identityP
)
//-----------------------------------------------------------------------------
{
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
703
  struct rrc_eNB_ue_context_s        *ue_context_p = NULL;
704
  ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid);
705 706

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

709 710 711 712 713
    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;
714
    }
715

716 717
    ue_context_p->ue_id_rnti = ctxt_pP->rntiMaybeUEid; // here ue_id_rnti is just a key, may be something else
    ue_context_p->ue_context.rnti = ctxt_pP->rntiMaybeUEid; // yes duplicate, 1 may be removed
718
    ue_context_p->ue_context.random_ue_identity = ue_identityP;
719
    RB_INSERT(rrc_ue_tree_s, &RC.rrc[ctxt_pP->module_id]->rrc_ue_head, ue_context_p);
720 721 722 723 724 725 726 727 728 729 730
    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;
  }
731

732
  return(ue_context_p);
winckel's avatar
winckel committed
733 734
}

735 736 737
//-----------------------------------------------------------------------------
void
rrc_eNB_free_mem_UE_context(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
738 739
  const protocol_ctxt_t               *const ctxt_pP,
  struct rrc_eNB_ue_context_s         *const ue_context_pP
740
)
741
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
742
{
743 744
  int i;
  LOG_T(RRC,
Cedric Roux's avatar
Cedric Roux committed
745
        PROTOCOL_RRC_CTXT_UE_FMT" Clearing UE context 0x%p (free internal structs)\n",
746 747
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
        ue_context_pP);
748 749
  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]);
750 751

  if (ue_context_pP->ue_context.SRB_configList) {
752
    ASN_STRUCT_FREE(asn_DEF_LTE_SRB_ToAddModList, ue_context_pP->ue_context.SRB_configList);
753 754
    ue_context_pP->ue_context.SRB_configList = NULL;
  }
755

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
756 757 758 759 760
  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;
    }
761 762
  }

763
  if (ue_context_pP->ue_context.DRB_configList) {
764
    ASN_STRUCT_FREE(asn_DEF_LTE_DRB_ToAddModList, ue_context_pP->ue_context.DRB_configList);
765 766
    ue_context_pP->ue_context.DRB_configList = NULL;
  }
767

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
768 769 770 771 772 773 774 775 776 777
  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;
    }
778 779
  }

780
  memset(ue_context_pP->ue_context.DRB_active, 0, sizeof(ue_context_pP->ue_context.DRB_active));
781

782
  if (ue_context_pP->ue_context.physicalConfigDedicated) {
783
    ASN_STRUCT_FREE(asn_DEF_LTE_PhysicalConfigDedicated, ue_context_pP->ue_context.physicalConfigDedicated);
784
    ue_context_pP->ue_context.physicalConfigDedicated = NULL;
785 786
  }

787
  if (ue_context_pP->ue_context.sps_Config) {
788
    ASN_STRUCT_FREE(asn_DEF_LTE_SPS_Config, ue_context_pP->ue_context.sps_Config);
789
    ue_context_pP->ue_context.sps_Config = NULL;
790 791
  }

792 793
  for (i=0; i < MAX_MEAS_OBJ; i++) {
    if (ue_context_pP->ue_context.MeasObj[i] != NULL) {
794
      ASN_STRUCT_FREE(asn_DEF_LTE_MeasObjectToAddMod, ue_context_pP->ue_context.MeasObj[i]);
795 796
      ue_context_pP->ue_context.MeasObj[i] = NULL;
    }
797
  }
798

799 800
  for (i=0; i < MAX_MEAS_CONFIG; i++) {
    if (ue_context_pP->ue_context.ReportConfig[i] != NULL) {
801
      ASN_STRUCT_FREE(asn_DEF_LTE_ReportConfigToAddMod, ue_context_pP->ue_context.ReportConfig[i]);
802 803 804
      ue_context_pP->ue_context.ReportConfig[i] = NULL;
    }
  }
805

806
  if (ue_context_pP->ue_context.QuantityConfig) {
807
    ASN_STRUCT_FREE(asn_DEF_LTE_QuantityConfig, ue_context_pP->ue_context.QuantityConfig);
808 809
    ue_context_pP->ue_context.QuantityConfig = NULL;
  }
810

811
  if (ue_context_pP->ue_context.mac_MainConfig) {
812
    ASN_STRUCT_FREE(asn_DEF_LTE_MAC_MainConfig, ue_context_pP->ue_context.mac_MainConfig);
813 814
    ue_context_pP->ue_context.mac_MainConfig = NULL;
  }
815

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
816 817 818 819 820
  /*  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
821 822
    /* 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
823 824
    ue_context_pP->ue_context.handover_info = NULL;
  }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
825

826 827
  if (ue_context_pP->ue_context.measurement_info) {
    /* TODO: be sure free is enough here (check memory leaks) */
828 829 830 831 832
    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;
      }
833

834 835 836
      free(ue_context_pP->ue_context.measurement_info->events);
      ue_context_pP->ue_context.measurement_info->events = NULL;
    }
837

838 839 840 841
    free(ue_context_pP->ue_context.measurement_info);
    ue_context_pP->ue_context.measurement_info = NULL;
  }

842 843 844 845 846
  //SRB_INFO                           SI;
  //SRB_INFO                           Srb0;
  //SRB_INFO_TABLE_ENTRY               Srb1;
  //SRB_INFO_TABLE_ENTRY               Srb2;
  if (ue_context_pP->ue_context.measConfig) {
847
    ASN_STRUCT_FREE(asn_DEF_LTE_MeasConfig, ue_context_pP->ue_context.measConfig);
848
    ue_context_pP->ue_context.measConfig = NULL;
849
  }
850

851
  if (ue_context_pP->ue_context.measConfig) {
852
    ASN_STRUCT_FREE(asn_DEF_LTE_MeasConfig, ue_context_pP->ue_context.measConfig);
853
    ue_context_pP->ue_context.measConfig = NULL;
854
  }
855

856
#if 0
857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875
  //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;
  //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
876 877
}

878
//-----------------------------------------------------------------------------
879
/*
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
880
* Should be called when UE context in eNB should be released
881
* or when S1 command UE_CONTEXT_RELEASE_REQ should be sent
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
882
*/
883
void
884 885 886
rrc_eNB_free_UE(
  const module_id_t enb_mod_idP,
  const struct rrc_eNB_ue_context_s *const ue_context_pP)
887
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
888
{
889
  rnti_t rnti = ue_context_pP->ue_context.rnti;
890

891
  if (enb_mod_idP >= NB_eNB_INST) {
892
    LOG_E(RRC, "eNB instance invalid (%d/%d) for UE %x!\n",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
893 894 895
          enb_mod_idP,
          NB_eNB_INST,
          rnti);
896
    return;
897
  }
Lionel Gauthier's avatar
Lionel Gauthier committed
898

899 900 901 902 903 904 905 906 907 908
  if(EPC_MODE_ENABLED) {
    if (!NODE_IS_DU(RC.rrc[enb_mod_idP]->node_type)) {
      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
909 910 911 912 913 914
        /* 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;
915
      }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
916

917 918 919 920 921 922 923
      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,
924 925 926
            ue_context_pP,
            S1AP_CAUSE_RADIO_NETWORK,
            20); // send cause 20: user inactivity
927 928
        return;
      }
929
    }
930
  }
931

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
932 933 934
  LOG_W(RRC, "[eNB %d] Removing UE RNTI %x\n",
        enb_mod_idP,
        rnti);
935 936
  // add UE info to freeList
  LOG_I(RRC, "Put UE %x into freeList\n",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
937
        rnti);
938
  put_UE_in_freelist(enb_mod_idP, rnti, 1);
939
}
Raymond Knopp's avatar
 
Raymond Knopp committed
940

941
void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, bool removeFlag) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
942 943
  eNB_MAC_INST                             *eNB_MAC = RC.mac[mod_id];
  pthread_mutex_lock(&lock_ue_freelist);
944
  LOG_I(PHY,"add ue %d in free list, context flag: %d\n", rnti, removeFlag);
laurent's avatar
laurent committed
945 946 947 948 949 950 951 952 953 954 955 956
  int i;
  for (i=0; i < sizeofArray(eNB_MAC->UE_free_ctrl); i++) 
    if (eNB_MAC->UE_free_ctrl[i].rnti == 0)
      break;
  if (i==sizeofArray(eNB_MAC->UE_free_ctrl)) {
    LOG_E(PHY,"List of UE to free is full\n");
    pthread_mutex_unlock(&lock_ue_freelist);
    return;
  }
  eNB_MAC->UE_free_ctrl[i].rnti = rnti;
  eNB_MAC->UE_free_ctrl[i].removeContextFlg = removeFlag;
  eNB_MAC->UE_free_ctrl[i].raFlag = 0;
957 958
  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
959
  pthread_mutex_unlock(&lock_ue_freelist);
960 961
}

962 963 964 965 966
extern int16_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type);
extern int16_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type);
extern void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch);
extern void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch);

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
967 968 969 970 971
void release_UE_in_freeList(module_id_t mod_id) {
  PHY_VARS_eNB                             *eNB_PHY = NULL;
  eNB_MAC_INST                             *eNB_MAC = RC.mac[mod_id];
  pthread_mutex_lock(&lock_ue_freelist);

laurent's avatar
laurent committed
972 973
  for(int ue_num = 0; ue_num < sizeofArray(eNB_MAC->UE_free_ctrl) ; ue_num++) {
    rnti_t rnti = eNB_MAC->UE_free_ctrl[ue_num].rnti;
974 975
    if (!rnti)
      continue;
laurent's avatar
laurent committed
976
      protocol_ctxt_t  ctxt;
977
    PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, rnti, 0, 0, mod_id);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
978

laurent's avatar
laurent committed
979
      for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
980
        eNB_PHY = RC.eNB[mod_id][CC_id];
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
981 982
        int id;
        // clean ULSCH entries for rnti
983
      id = find_ulsch(rnti, eNB_PHY, eNB_MAC->UE_free_ctrl[ue_num].raFlag ? SEARCH_EXIST_RA : SEARCH_EXIST);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
984

985 986
      if (id >= 0)
        clean_eNb_ulsch(eNB_PHY->ulsch[id]);
987

Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
988
        // clean DLSCH entries for rnti
989
      id = find_dlsch(rnti, eNB_PHY, eNB_MAC->UE_free_ctrl[ue_num].raFlag ? SEARCH_EXIST_RA : SEARCH_EXIST);
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
990

991 992
      if (id >= 0)
        clean_eNb_dlsch(eNB_PHY->dlsch[id][0]);
993

Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
994
        // clean UCI entries for rnti
995 996 997 998
      for (int i = 0; i < NUMBER_OF_UCI_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));
999 1000
          }
        }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1001

laurent's avatar
laurent committed
1002 1003
        for(int j = 0; j < 10; j++) {
          nfapi_ul_config_request_body_t *ul_req_tmp  = &eNB_MAC->UL_req_tmp[CC_id][j].ul_config_request_body;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1004

1005
        if (ul_req_tmp) {
laurent's avatar
laurent committed
1006
            int pdu_number = ul_req_tmp->number_of_pdus;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1007

1008 1009 1010 1011 1012 1013
          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)) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1014
                LOG_I(RRC, "remove UE %x from ul_config_pdu_list %d/%d\n", rnti, pdu_index, pdu_number);
1015

1016 1017
              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));
1018
                }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1019 1020

                ul_req_tmp->number_of_pdus--;
1021 1022
              }
            }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1023 1024 1025 1026
          }
        }
      }

1027
      if (!NODE_IS_CU(RC.rrc[mod_id]->node_type)) {
laurent's avatar
laurent committed
1028 1029
	if (!eNB_MAC->UE_free_ctrl[ue_num].raFlag)
	    rrc_mac_remove_ue(mod_id,rnti);
1030 1031
        rrc_rlc_remove_ue(&ctxt);
        pdcp_remove_UE(&ctxt);
1032
      } else {
1033
        MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, 0, F1AP_UE_CONTEXT_RELEASE_CMD);
1034 1035 1036 1037 1038 1039 1040
        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
1041

laurent's avatar
laurent committed
1042 1043
      if(eNB_MAC->UE_free_ctrl[ue_num].removeContextFlg) {
	struct rrc_eNB_ue_context_s *ue_context_pP = rrc_eNB_get_ue_context(RC.rrc[mod_id],rnti);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1044
        if(ue_context_pP) {
laurent's avatar
laurent committed
1045
          LOG_I(PHY, "remove RNTI %04x\n", rnti);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1046 1047
          rrc_eNB_remove_ue_context(&ctxt,RC.rrc[mod_id],
                                    (struct rrc_eNB_ue_context_s *) ue_context_pP);
1048
        }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1049 1050
      }

laurent's avatar
laurent committed
1051 1052
      LOG_I(RRC, "[release_UE_in_freeList] remove UE %x from freeList ra context: %d\n", rnti, eNB_MAC->UE_free_ctrl[ue_num].raFlag);
      eNB_MAC->UE_free_ctrl[ue_num].rnti = 0;
1053
    }
laurent's avatar
laurent committed
1054
  pthread_mutex_unlock(&lock_ue_freelist);
1055 1056
}

1057
int rrc_eNB_previous_SRB2(rrc_eNB_ue_context_t         *ue_context_pP) {
Haruki NAOI's avatar
Haruki NAOI committed
1058
  struct LTE_SRB_ToAddMod                *SRB2_config = NULL;
1059
  uint8_t i;
1060 1061 1062
  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];

1063
  if (*SRB_configList2 != NULL) {
1064
    if((*SRB_configList2)->list.count!=0) {
1065
      LOG_D(RRC, "rrc_eNB_previous_SRB2 SRB_configList2(%p) count is %d\n           SRB_configList2->list.array[0] addr is %p",
1066
            SRB_configList2, (*SRB_configList2)->list.count,  (*SRB_configList2)->list.array[0]);
1067
    }
1068

1069
    for (i = 0; (i < (*SRB_configList2)->list.count) && (i < 3); i++) {
1070
      if ((*SRB_configList2)->list.array[i]->srb_Identity == 2 ) {
1071 1072 1073 1074
        SRB2_config = (*SRB_configList2)->list.array[i];
        break;
      }
    }
1075
  } else {
1076 1077 1078 1079
    LOG_E(RRC, "rrc_eNB_previous_SRB2 SRB_configList2 NULL\n");
  }

  if (SRB2_config != NULL) {
1080
    asn1cSeqAdd(&SRB_configList->list, SRB2_config);
1081
  } else {
1082 1083
    LOG_E(RRC, "rrc_eNB_previous_SRB2 SRB2_config NULL\n");
  }
1084

1085 1086
  return 0;
}
1087
//-----------------------------------------------------------------------------
1088 1089 1090
/*
* Process the rrc connection setup complete message from UE (SRB1 Active)
*/
1091 1092
void
rrc_eNB_process_RRCConnectionSetupComplete(
1093 1094
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t *ue_context_pP,
1095
  LTE_RRCConnectionSetupComplete_r8_IEs_t *rrcConnectionSetupComplete
1096
)
1097
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
1098
{
1099
  LOG_A(RRC, PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing LTE_RRCConnectionSetupComplete from UE (SRB1 Active)\n",
1100
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
1101
  ue_context_pP->ue_context.Srb1.Active = 1;
1102
  ue_context_pP->ue_context.StatusRrc = RRC_CONNECTED;
1103
  ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity timer when UE goes into RRC_CONNECTED
1104
  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->rntiMaybeUEid));
Cedric Roux's avatar
Cedric Roux committed
1105

1106 1107
  if (EPC_MODE_ENABLED == 1) {
    // Forward message to S1AP layer
1108
    rrc_eNB_send_S1AP_NAS_FIRST_REQ(ctxt_pP, ue_context_pP, rrcConnectionSetupComplete);
1109
  } else {
1110
    // RRC loop back (no S1AP), send SecurityModeCommand to UE
1111
    rrc_eNB_generate_SecurityModeCommand(ctxt_pP, ue_context_pP);
1112
  }
winckel's avatar
winckel committed
1113 1114
}

1115 1116 1117
//-----------------------------------------------------------------------------
void
rrc_eNB_generate_SecurityModeCommand(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1118 1119
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t          *const ue_context_pP
1120
)
1121
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
1122
{
1123
  uint8_t                             buffer[100]={0};
1124
  uint8_t                             size;
1125
  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->rntiMaybeUEid));
1126 1127 1128
  size = do_SecurityModeCommand(
           ctxt_pP,
           buffer,
1129
           sizeof(buffer),
1130 1131 1132
           rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),
           ue_context_pP->ue_context.ciphering_algorithm,
           ue_context_pP->ue_context.integrity_algorithm);
1133
  LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Security Mode Command\n");
1134
  LOG_I(RRC,
1135 1136 1137
        PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate SecurityModeCommand (bytes %d)\n",
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
        size);
1138
  LOG_D(RRC,
1139 1140 1141 1142 1143
        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);
1144

1145
  if (!NODE_IS_DU(RC.rrc[ctxt_pP->module_id]->node_type)) {
1146 1147 1148 1149 1150 1151 1152 1153 1154
    LOG_I(RRC,"calling rrc_data_req :securityModeCommand\n");
    rrc_data_req(ctxt_pP,
                 DCCH,
                 rrc_eNB_mui++,
                 SDU_CONFIRM_NO,
                 size,
                 buffer,
                 PDCP_TRANSMISSION_MODE_CONTROL);
  }
1155 1156
}

1157 1158 1159
//-----------------------------------------------------------------------------
void
rrc_eNB_generate_UECapabilityEnquiry(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1160 1161
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t          *const ue_context_pP
1162 1163
)
//-----------------------------------------------------------------------------
1164 1165 1166
{
  uint8_t                             buffer[100];
  uint8_t                             size;
1167
  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->rntiMaybeUEid));
1168
  int16_t eutra_band = RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0];
1169
  uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_gnb_freq_band[0][0];
1170 1171 1172
  size = do_UECapabilityEnquiry(
           ctxt_pP,
           buffer,
1173
           sizeof(buffer),
1174 1175 1176
           rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),
           eutra_band,
           nr_band);
1177
  LOG_I(RRC,
1178 1179 1180
        PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate UECapabilityEnquiry (bytes %d)\n",
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
        size);
1181
  LOG_D(RRC,
1182 1183 1184 1185 1186
        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);
1187
  rrc_data_req(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1188 1189 1190 1191 1192 1193 1194
    ctxt_pP,
    DCCH,
    rrc_eNB_mui++,
    SDU_CONFIRM_NO,
    size,
    buffer,
    PDCP_TRANSMISSION_MODE_CONTROL);
1195 1196
}

1197 1198 1199 1200 1201 1202 1203 1204 1205 1206
//-----------------------------------------------------------------------------
void
rrc_eNB_generate_NR_UECapabilityEnquiry(
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t          *const ue_context_pP
)
//-----------------------------------------------------------------------------
{
  uint8_t                             buffer[100];
  uint8_t                             size;
1207
  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->rntiMaybeUEid));
1208
  int16_t eutra_band = RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0];
1209
  uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_gnb_freq_band[0][0];
1210 1211 1212
  size = do_NR_UECapabilityEnquiry(
           ctxt_pP,
           buffer,
1213
           sizeof(buffer),
1214 1215 1216
           rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),
           eutra_band,
           nr_band);
1217
  LOG_A(RRC,
1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236
        PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate NR UECapabilityEnquiry (bytes %d)\n",
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
        size);
  LOG_D(RRC,
        PROTOCOL_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (NR UECapabilityEnquiry MUI %d) --->[PDCP][RB %02d]\n",
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
        size,
        rrc_eNB_mui,
        DCCH);
  rrc_data_req(
    ctxt_pP,
    DCCH,
    rrc_eNB_mui++,
    SDU_CONFIRM_NO,
    size,
    buffer,
    PDCP_TRANSMISSION_MODE_CONTROL);
}

1237 1238 1239
//-----------------------------------------------------------------------------
void
rrc_eNB_generate_RRCConnectionReject(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1240 1241
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t          *const ue_context_pP,
1242 1243 1244 1245
  const int                    CC_id
)
//-----------------------------------------------------------------------------
{
1246
  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->rntiMaybeUEid));
1247
  eNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
1248
  ue_p->Srb0.Tx_buffer.payload_size =
1249
    do_RRCConnectionReject(ctxt_pP->module_id,
1250
                           (uint8_t *) ue_p->Srb0.Tx_buffer.Payload);
1251
  LOG_DUMPMSG(RRC,DEBUG_RRC,
1252
              (char *)(ue_p->Srb0.Tx_buffer.Payload),
1253
              ue_p->Srb0.Tx_buffer.payload_size,
1254
              "[MSG] RRCConnectionReject\n");
1255
  LOG_I(RRC,
1256
        PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionReject (bytes %d)\n",
1257
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
1258
        ue_p->Srb0.Tx_buffer.payload_size);
1259 1260
}

1261
//-----------------------------------------------------------------------------
1262 1263 1264
/*
 * Generate a RCC Connection Reestablishment after requested
 */
1265
void
1266
rrc_eNB_generate_RRCConnectionReestablishment(
1267 1268 1269
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t  *const ue_context_pP,
  const int             CC_id)
1270 1271
//-----------------------------------------------------------------------------
{
1272 1273 1274 1275 1276 1277 1278
  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;
1279
  uint16_t rnti = ctxt_pP->rntiMaybeUEid;
1280 1281 1282 1283 1284 1285 1286 1287
  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
1288
  ue_context->Srb0.Tx_buffer.payload_size = do_RRCConnectionReestablishment(ctxt_pP,
1289 1290 1291 1292 1293 1294 1295
      ue_context_pP,
      CC_id,
      (uint8_t *) ue_context->Srb0.Tx_buffer.Payload,
      (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));
1296
  LOG_DUMPMSG(RRC, DEBUG_RRC,
OAI-admin's avatar
OAI-admin committed
1297 1298
              (char *)(ue_context->Srb0.Tx_buffer.Payload),
              ue_context->Srb0.Tx_buffer.payload_size,
1299 1300 1301
              "[MSG] RRCConnectionReestablishment \n");

  /* Configure SRB1 for UE */
1302
  if (*SRB_configList != NULL) {
1303
    for (int cnt = 0; cnt < (*SRB_configList)->list.count; cnt++) {
1304 1305
      if ((*SRB_configList)->list.array[cnt]->srb_Identity == 1) {
        SRB1_config = (*SRB_configList)->list.array[cnt];
1306

1307
        if (SRB1_config->logicalChannelConfig) {
1308 1309
          if (SRB1_config->logicalChannelConfig->present == LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) {
            SRB1_logicalChannelConfig = &(SRB1_config->logicalChannelConfig->choice.explicitValue);
1310
          } else {
1311
            SRB1_logicalChannelConfig = &(SRB1_logicalChannelConfig_defaultValue);
1312 1313
          }
        } else {
1314
          SRB1_logicalChannelConfig = &(SRB1_logicalChannelConfig_defaultValue);
1315
        }
1316

1317
        LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ  (SRB1) ---> MAC_eNB\n",
1318
              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
1319

1320
        if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) {
laurent's avatar
laurent committed
1321 1322 1323 1324 1325 1326 1327 1328
          rrc_mac_config_req_eNB_t tmp = {0};
          tmp.CC_id = ue_context->primaryCC_id;
          tmp.physicalConfigDedicated = ue_context->physicalConfigDedicated;
          tmp.mac_MainConfig = ue_context->mac_MainConfig;
          tmp.logicalChannelIdentity = 1;
          tmp.logicalChannelConfig = SRB1_logicalChannelConfig;
          tmp.measGapConfig = ue_context->measGapConfig;
          rrc_mac_config_req_eNB(module_id, &tmp);
1329 1330
          break;
        }
1331 1332 1333
      }  // if ((*SRB_configList)->list.array[cnt]->srb_Identity == 1)
    }  // for (int cnt = 0; cnt < (*SRB_configList)->list.count; cnt++)
  }  // if (*SRB_configList != NULL)
1334

1335
  LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionReestablishment (bytes %d)\n",
1336
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
OAI-admin's avatar
OAI-admin committed
1337
        ue_context->Srb0.Tx_buffer.payload_size);
1338 1339 1340 1341
  UE_id = find_UE_id(module_id, rnti);

  if (UE_id != -1) {
    /* Activate reject timer, if RRCComplete not received after 10 frames, reject UE */
1342
    RC.mac[module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1;
1343
    /* Reject UE after 10 frames, LTE_RRCConnectionReestablishmentReject is triggered */
1344
    RC.mac[module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 100;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1345
  } else {
1346 1347 1348
    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);
1349
  }
1350 1351
}

1352 1353
//-----------------------------------------------------------------------------
void
1354
rrc_eNB_process_RRCConnectionReestablishmentComplete(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1355
  const protocol_ctxt_t *const ctxt_pP,
Cedric Roux's avatar
Cedric Roux committed
1356
  const rnti_t reestablish_rnti,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1357
  rrc_eNB_ue_context_t         *ue_context_pP,
1358
  const uint8_t xid,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1359
  LTE_RRCConnectionReestablishmentComplete_r8_IEs_t *LTE_RRCConnectionReestablishmentComplete
1360 1361
)
//-----------------------------------------------------------------------------
1362
{
1363
  LOG_I(RRC,
1364
        PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, processing LTE_RRCConnectionReestablishmentComplete from UE (SRB1 Active)\n",
1365
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
1366
  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->rntiMaybeUEid));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1367 1368 1369 1370
  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;
1371 1372
  struct LTE_SRB_ToAddMod                *SRB2_config = NULL;
  struct LTE_DRB_ToAddMod                *DRB_config = NULL;
1373
  int i = 0;
1374 1375
  uint8_t                             buffer[RRC_BUF_SIZE];
  uint16_t                            size;
1376 1377 1378 1379
  LTE_MeasObjectToAddModList_t       *MeasObj_list                     = NULL;
  LTE_MeasObjectToAddMod_t           *MeasObj                          = NULL;
  LTE_ReportConfigToAddModList_t     *ReportConfig_list                = NULL;
  LTE_ReportConfigToAddMod_t         *ReportConfig_per, *ReportConfig_A1,
1380
                                     *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5;
1381 1382 1383 1384 1385 1386 1387 1388 1389
  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;
1390 1391
  /* for no gcc warnings */
  (void)dedicatedInfoNas;
1392
  LTE_C_RNTI_t                           *cba_RNTI                         = NULL;
1393
  int                                    measurements_enabled;
1394
  uint8_t next_xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id);
1395
  int ret = 0;
1396
  ue_context_pP->ue_context.StatusRrc = RRC_CONNECTED;
1397
  ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED
1398
  ue_context_pP->ue_context.reestablishment_xid = next_xid;
1399
  SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid];
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1400

1401 1402
  // get old configuration of SRB2
  if (*SRB_configList2 != NULL) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1403
    if((*SRB_configList2)->list.count!=0) {
1404
      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
1405
            SRB_configList2, (*SRB_configList2)->list.count,  (*SRB_configList2)->list.array[0]);
1406
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1407

1408
    for (i = 0; (i < (*SRB_configList2)->list.count) && (i < 3); i++) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1409
      if ((*SRB_configList2)->list.array[i]->srb_Identity == 2 ) {
1410 1411 1412 1413 1414 1415
        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
1416

frtabu's avatar
frtabu committed
1417 1418
  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
1419

frtabu's avatar
frtabu committed
1420 1421 1422
  if (*SRB_configList2) {
    free(*SRB_configList2);
    LOG_D(RRC, "free(ue_context_pP->ue_context.SRB_configList2[%d])\n", next_xid);
1423
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1424

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

1427 1428
  if (SRB2_config != NULL) {
    // Add SRB2 to SRB configuration list
1429 1430
    asn1cSeqAdd(&SRB_configList->list, SRB2_config);
    asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config);
1431
    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
1432
          SRB2_config->srb_Identity);
1433
    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
1434
          SRB2_config->srb_Identity, next_xid);
1435 1436 1437 1438
  } else {
    // SRB configuration list only contains SRB1.
    LOG_W(RRC,"SRB2 configuration does not exist in SRB configuration list\n");
  }
1439

frtabu's avatar
frtabu committed
1440 1441 1442
  if (*DRB_configList2) {
    free(*DRB_configList2);
    LOG_D(RRC, "free(ue_context_pP->ue_context.DRB_configList2[%d])\n", next_xid);
1443
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1444

1445
  *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
1446

1447 1448
  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
1449

1450 1451
    for (i = 0; (i < DRB_configList->list.count) && (i < 3); i++) {
      DRB_config = DRB_configList->list.array[i];
1452
      // Add DRB to DRB configuration list, for LTE_RRCConnectionReconfigurationComplete
1453
      asn1cSeqAdd(&(*DRB_configList2)->list, DRB_config);
1454
    }
1455
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1456

1457 1458
  ue_context_pP->ue_context.Srb1.Active = 1;
  //ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = 2;
1459 1460

  if (EPC_MODE_ENABLED) {
1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471
    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) {
1472
        rrc_ue_s1ap_ids_p->ue_rnti = ctxt_pP->rntiMaybeUEid;
1473
      }
1474
    }
Navid Nikaein's avatar
Navid Nikaein committed
1475

1476 1477
    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);
1478

1479
      if  (h_rc == HASH_TABLE_OK) {
1480
        rrc_ue_s1ap_ids_p->ue_rnti = ctxt_pP->rntiMaybeUEid;
1481
      }
1482
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1483

1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496
    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++;
      }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1497
    }
1498

1499
    create_tunnel_req.rnti = ctxt_pP->rntiMaybeUEid; // warning put zero above
1500
    create_tunnel_req.num_tunnels    = j;
1501
    ret = gtpv1u_update_s1u_tunnel(
1502 1503 1504 1505
            ctxt_pP->instance,
            &create_tunnel_req,
            reestablish_rnti);

1506 1507
    if ( ret != 0 ) {
      LOG_E(RRC,"gtpv1u_update_s1u_tunnel failed,start to release UE %x\n",reestablish_rnti);
1508

1509 1510
      // update s1u tunnel failed,reset rnti?
      if (eNB_ue_s1ap_id > 0) {
1511 1512
        h_rc = hashtable_get(rrc_instance_p->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void **)&rrc_ue_s1ap_ids_p);

1513 1514 1515 1516
        if (h_rc == HASH_TABLE_OK ) {
          rrc_ue_s1ap_ids_p->ue_rnti = reestablish_rnti;
        }
      }
1517

1518
      if (ue_initial_id != 0) {
1519 1520
        h_rc = hashtable_get(rrc_instance_p->initial_id2_s1ap_ids, (hash_key_t)ue_initial_id, (void **)&rrc_ue_s1ap_ids_p);

1521 1522 1523 1524
        if (h_rc == HASH_TABLE_OK ) {
          rrc_ue_s1ap_ids_p->ue_rnti = reestablish_rnti;
        }
      }
1525

1526 1527 1528 1529 1530 1531 1532
      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;
1533
      put_UE_in_freelist(ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid, 0);
1534 1535
      return;
    }
1536 1537
  } /* EPC_MODE_ENABLED */

1538
  /* Update RNTI in ue_context */
1539 1540
  ue_context_pP->ue_id_rnti = ctxt_pP->rntiMaybeUEid; // here ue_id_rnti is just a key, may be something else
  ue_context_pP->ue_context.rnti = ctxt_pP->rntiMaybeUEid;
1541 1542

  if (EPC_MODE_ENABLED) {
1543
    uint8_t send_security_mode_command = false;
1544 1545 1546 1547 1548
    rrc_pdcp_config_security(
      ctxt_pP,
      ue_context_pP,
      send_security_mode_command);
    LOG_D(RRC, "set security successfully \n");
1549 1550
  }

1551 1552 1553 1554 1555 1556 1557
  // 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;
1558
  asn1cSeqAdd(&MeasId_list->list, MeasId0);
1559 1560 1561 1562
  MeasId1 = CALLOC(1, sizeof(*MeasId1));
  MeasId1->measId = 2;
  MeasId1->measObjectId = 1;
  MeasId1->reportConfigId = 2;
1563
  asn1cSeqAdd(&MeasId_list->list, MeasId1);
1564 1565 1566 1567
  MeasId2 = CALLOC(1, sizeof(*MeasId2));
  MeasId2->measId = 3;
  MeasId2->measObjectId = 1;
  MeasId2->reportConfigId = 3;
1568
  asn1cSeqAdd(&MeasId_list->list, MeasId2);
1569 1570 1571 1572
  MeasId3 = CALLOC(1, sizeof(*MeasId3));
  MeasId3->measId = 4;
  MeasId3->measObjectId = 1;
  MeasId3->reportConfigId = 4;
1573
  asn1cSeqAdd(&MeasId_list->list, MeasId3);
1574 1575 1576 1577
  MeasId4 = CALLOC(1, sizeof(*MeasId4));
  MeasId4->measId = 5;
  MeasId4->measObjectId = 1;
  MeasId4->reportConfigId = 5;
1578
  asn1cSeqAdd(&MeasId_list->list, MeasId4);
1579 1580 1581 1582
  MeasId5 = CALLOC(1, sizeof(*MeasId5));
  MeasId5->measId = 6;
  MeasId5->measObjectId = 1;
  MeasId5->reportConfigId = 6;
1583
  asn1cSeqAdd(&MeasId_list->list, MeasId5);
1584
  //  LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measIdToAddModList = MeasId_list;
1585 1586 1587 1588 1589 1590 1591
  // 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;
1592
  MeasObj->measObject.present = LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA;
1593 1594
  MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 3350; //band 7, 2.68GHz
  //MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 36090; //band 33, 1.909GHz
1595
  MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = LTE_AllowedMeasBandwidth_mbw25;
1596 1597 1598 1599 1600 1601 1602
  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 =
1603
    (LTE_CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList));
1604 1605 1606 1607
  CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList;

  // Add adjacent cell lists (6 per eNB)
  for (i = 0; i < 6; i++) {
1608
    CellToAdd = (LTE_CellsToAddMod_t *) CALLOC(1, sizeof(*CellToAdd));
1609 1610
    CellToAdd->cellIndex = i + 1;
    CellToAdd->physCellId = get_adjacent_cell_id(ctxt_pP->module_id, i);
1611
    CellToAdd->cellIndividualOffset = LTE_Q_OffsetRange_dB0;
1612
    asn1cSeqAdd(&CellsToAddModList->list, CellToAdd);
1613 1614
  }

1615
  asn1cSeqAdd(&MeasObj_list->list, MeasObj);
1616
  //  LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measObjectToAddModList = MeasObj_list;
1617 1618 1619 1620 1621 1622 1623 1624 1625
  // 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;
1626
  ReportConfig_per->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
1627
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.present =
1628
    LTE_ReportConfigEUTRA__triggerType_PR_periodical;
1629
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.choice.periodical.purpose =
1630 1631 1632
    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;
1633
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
1634 1635
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
1636
  asn1cSeqAdd(&ReportConfig_list->list, ReportConfig_per);
1637
  ReportConfig_A1->reportConfigId = 2;
1638
  ReportConfig_A1->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
1639
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.present =
1640
    LTE_ReportConfigEUTRA__triggerType_PR_event;
1641
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
1642
    LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1;
1643
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA1.
1644
  a1_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
1645 1646
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA1.
  a1_Threshold.choice.threshold_RSRP = 10;
1647 1648
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
1649
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
1650 1651
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
1652
  asn1cSeqAdd(&ReportConfig_list->list, ReportConfig_A1);
1653

1654
  if (RC.rrc[ctxt_pP->module_id]->HO_flag == 1 /*HO_MEASUREMENT */ ) {
1655 1656 1657
    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;
1658
    ReportConfig_A2->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
1659
    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.present =
1660
      LTE_ReportConfigEUTRA__triggerType_PR_event;
1661
    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
1662
      LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2;
1663
    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
1664
    eventA2.a2_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
1665 1666 1667
    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
    eventA2.a2_Threshold.choice.threshold_RSRP = 10;
    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
1668 1669
      LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
1670
    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
1671 1672
    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
1673
    asn1cSeqAdd(&ReportConfig_list->list, ReportConfig_A2);
1674
    ReportConfig_A3->reportConfigId = 4;
1675
    ReportConfig_A3->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
1676
    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.present =
1677
      LTE_ReportConfigEUTRA__triggerType_PR_event;
1678
    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
1679
      LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3;
1680 1681 1682 1683
    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 =
1684 1685
      LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
1686
    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
1687 1688
    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
1689 1690
    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 =
1691
      LTE_TimeToTrigger_ms40;
1692
    asn1cSeqAdd(&ReportConfig_list->list, ReportConfig_A3);
1693
    ReportConfig_A4->reportConfigId = 5;
1694
    ReportConfig_A4->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
1695
    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.present =
1696
      LTE_ReportConfigEUTRA__triggerType_PR_event;
1697
    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
1698
      LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4;
1699
    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
1700
    eventA4.a4_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
1701 1702 1703
    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
    eventA4.a4_Threshold.choice.threshold_RSRP = 10;
    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
1704 1705
      LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
1706
    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
1707 1708
    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
1709
    asn1cSeqAdd(&ReportConfig_list->list, ReportConfig_A4);
1710
    ReportConfig_A5->reportConfigId = 6;
1711
    ReportConfig_A5->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
1712
    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.present =
1713
      LTE_ReportConfigEUTRA__triggerType_PR_event;
1714
    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
1715
      LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA5;
1716
    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
1717
    eventA5.a5_Threshold1.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
1718
    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
1719
    eventA5.a5_Threshold2.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
1720 1721 1722 1723 1724
    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 =
1725 1726
      LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
1727
    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
1728 1729
    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
1730
    asn1cSeqAdd(&ReportConfig_list->list, ReportConfig_A5);
1731
    //  LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list;
1732 1733 1734 1735 1736 1737
#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.
     */
1738
    rsrp = CALLOC(1, sizeof(LTE_RSRP_Range_t));
1739
    *rsrp = 20;
1740
#endif
1741
    Sparams = CALLOC(1, sizeof(*Sparams));
1742 1743 1744
    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;
1745 1746
    Sparams->choice.setup.mobilityStateParameters.n_CellChangeHigh = 10;
    Sparams->choice.setup.mobilityStateParameters.n_CellChangeMedium = 5;
1747 1748
    Sparams->choice.setup.mobilityStateParameters.t_Evaluation = LTE_MobilityStateParameters__t_Evaluation_s60;
    Sparams->choice.setup.mobilityStateParameters.t_HystNormal = LTE_MobilityStateParameters__t_HystNormal_s120;
1749 1750
    quantityConfig = CALLOC(1, sizeof(*quantityConfig));
    memset((void *)quantityConfig, 0, sizeof(*quantityConfig));
1751
    quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(struct LTE_QuantityConfigEUTRA));
1752 1753 1754 1755 1756 1757 1758 1759
    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)));
1760 1761
    *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = LTE_FilterCoefficient_fc4;
    *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = LTE_FilterCoefficient_fc4;
1762 1763 1764 1765 1766 1767
    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)));
1768
    //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.srb_ToAddModList,(void *)SRB_list,sizeof(LTE_SRB_ToAddModList_t));
1769
    ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.srb_ToAddModList = *SRB_configList2;
1770
    //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.drb_ToAddModList,(void *)DRB_list,sizeof(LTE_DRB_ToAddModList_t));
1771 1772 1773 1774
    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
1775
    memcpy((void *)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig,
1776
           (void *)ue_context_pP->ue_context.mac_MainConfig, sizeof(LTE_MAC_MainConfig_t));
1777
    ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated =
1778
      CALLOC(1, sizeof(LTE_PhysicalConfigDedicated_t));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1779 1780
    memcpy((void *)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated,
           (void *)ue_context_pP->ue_context.physicalConfigDedicated, sizeof(LTE_PhysicalConfigDedicated_t));
1781 1782 1783 1784 1785
    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));
  }

  /* Initialize NAS list */
1786
  dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList));
1787 1788 1789 1790

  /* 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) {
1791
      dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t));
1792 1793
      memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t));
      OCTET_STRING_fromBuf(dedicatedInfoNas,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1794
                           (char *)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer,
1795
                           ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length);
1796
      LOG_D(RRC, "Add LTE_DedicatedInfoNAS(%d) to LTE_DedicatedInfoNASList\n", i);
1797
      asn1cSeqAdd(&dedicatedInfoNASList->list, dedicatedInfoNas);
1798 1799 1800 1801 1802 1803 1804 1805 1806 1807
    }

    /* 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;
1808
    ue_context_pP->ue_context.e_rab[i].xid    = xid;
1809
    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
1810
          i, ue_context_pP->ue_context.e_rab[i].status, "E_RAB_STATUS_DONE");
1811 1812 1813 1814 1815 1816 1817 1818
  }

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

1819 1820
  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;
1821
  // send LTE_RRCConnectionReconfiguration
1822
  memset(buffer, 0, sizeof(buffer));
1823 1824
  size = do_RRCConnectionReconfiguration(ctxt_pP,
                                         buffer,
1825
                                         sizeof(buffer),
1826
                                         next_xid,   //Transaction_id,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1827 1828 1829 1830 1831
                                         (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,
1832 1833 1834
                                         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
1835
                                         (LTE_MeasIdToAddModList_t *)NULL,
1836
                                         //#endif
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1837 1838 1839
                                         (LTE_MAC_MainConfig_t *)ue_context_pP->ue_context.mac_MainConfig,
                                         (LTE_MeasGapConfig_t *)NULL,
                                         (LTE_MobilityControlInfo_t *)NULL,
1840
                                         (LTE_SecurityConfigHO_t *)NULL,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1841 1842 1843 1844 1845
                                         (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,
1846 1847
                                         (LTE_SL_DiscConfig_r12_t *)NULL,
                                         (LTE_SCellToAddMod_r10_t *)NULL
1848
                                        );
1849 1850
  LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size,
              "[MSG] RRC Connection Reconfiguration\n");
1851 1852 1853 1854 1855 1856 1857 1858 1859 1860

  /* 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
1861
  if(size==65535) {
1862 1863 1864
    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
1865
  } else {
1866
    LOG_I(RRC,
1867
          "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE id %x)\n",
1868 1869 1870 1871 1872
          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);
    rrc_data_req(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1873 1874 1875 1876 1877 1878 1879
      ctxt_pP,
      DCCH,
      rrc_eNB_mui++,
      SDU_CONFIRM_NO,
      size,
      buffer,
      PDCP_TRANSMISSION_MODE_CONTROL);
1880
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1881

1882
  // delete UE data of prior RNTI.  UE use current RNTI.
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920
  //  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);
1921 1922 1923
  // 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);
1924 1925 1926 1927 1928
}

//-----------------------------------------------------------------------------
void
rrc_eNB_generate_RRCConnectionReestablishmentReject(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1929 1930
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t          *const ue_context_pP,
1931 1932 1933 1934
  const int                    CC_id
)
//-----------------------------------------------------------------------------
{
1935
  if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
1936
    int UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1937

1938
    if(UE_id != -1) {
1939 1940
      RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1;
      RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 20;
1941
    } else {
1942
      LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT " Generating LTE_RRCConnectionReestablishmentReject without UE_id(MAC) rnti %lx\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), ctxt_pP->rntiMaybeUEid);
1943
    }
1944
  }
1945

1946
  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->rntiMaybeUEid));
1947
  eNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
1948
  ue_p->Srb0.Tx_buffer.payload_size =
1949
    do_RRCConnectionReestablishmentReject(ctxt_pP->module_id,
1950
                                          (uint8_t *) ue_p->Srb0.Tx_buffer.Payload);
1951
  LOG_DUMPMSG(RRC,DEBUG_RRC,
1952 1953
              (char *)(ue_p->Srb0.Tx_buffer.Payload),
              ue_p->Srb0.Tx_buffer.payload_size,
1954
              "[MSG] RRCConnectionReestablishmentReject\n");
1955
  LOG_I(RRC,
1956
        PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionReestablishmentReject (bytes %d)\n",
1957
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
1958
        ue_p->Srb0.Tx_buffer.payload_size);
1959
}
1960
#if 0
1961
void rrc_generate_SgNBReleaseRequest(
1962
  const protocol_ctxt_t *const ctxt_pP,
1963 1964 1965 1966 1967
  rrc_eNB_ue_context_t *const ue_context_pP
)
//-----------------------------------------------------------------------------
{
  MessageDef      *msg;
1968
  msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_ENDC_SGNB_RELEASE_REQ);
1969
  memset(&(X2AP_ENDC_SGNB_RELEASE_REQ(msg)), 0, sizeof(x2ap_ENDC_sgnb_release_req_t));
1970 1971 1972 1973
  // X2AP_ENDC_SGNB_RELEASE_REQ(msg).MeNB_ue_x2_id = ;
  // X2AP_ENDC_SGNB_RELEASE_REQ(msg).SgNB_ue_x2_id = ;
  // X2AP_ENDC_SGNB_RELEASE_REQ(msg).cause = ;
  // X2AP_ENDC_SGNB_RELEASE_REQ(msg).target_physCellId = ;
1974
  LOG_I(RRC,
1975
        "[eNB %d] frame %d UE rnti %x transmitting sgnb release request to sgnb \n",
1976
        ctxt_pP->module_id,ctxt_pP->frame,ctxt_pP->rntiMaybeUEid);
1977 1978 1979 1980
  itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), msg);
  return;
}
#endif
1981
//-----------------------------------------------------------------------------
1982 1983 1984 1985
/*
* Generate the RRC Connection Release to UE.
* If received, UE should switch to RRC_IDLE mode.
*/
1986 1987
void
rrc_eNB_generate_RRCConnectionRelease(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1988 1989
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t *const ue_context_pP
1990 1991 1992
)
//-----------------------------------------------------------------------------
{
1993
  uint8_t buffer[RRC_BUF_SIZE]={0};
1994
  uint16_t size = 0;
1995
  int release_num;
1996
  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->rntiMaybeUEid));
1997
#if 0
1998 1999

  if(ue_context_pP != NULL) {
2000
    if(ue_context_pP->ue_context.StatusRrc == RRC_NR_NSA) {
2001 2002
      //rrc_eNB_generate_SgNBReleaseRequest(ctxt_pP,ue_context_pP);
    }
2003
  }
2004

2005
#endif
2006 2007
  size = do_RRCConnectionRelease(ctxt_pP->module_id, buffer, sizeof(buffer),
                                 rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id));
2008 2009
  ue_context_pP->ue_context.ue_reestablishment_timer = 0;
  ue_context_pP->ue_context.ue_release_timer = 0;
2010
  ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0;
2011
  LOG_I(RRC,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2012
        PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate RRCConnectionRelease (bytes %d)\n",
2013 2014 2015 2016 2017 2018 2019 2020
        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);
2021
  pthread_mutex_lock(&rrc_release_freelist);
2022

2023
  for (release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) {
2024 2025
    if (rrc_release_info.RRC_release_ctrl[release_num].flag == 0) {
      if (ue_context_pP->ue_context.ue_release_timer_s1 > 0) {
2026
        rrc_release_info.RRC_release_ctrl[release_num].flag = 1;
2027
      } else {
2028 2029
        rrc_release_info.RRC_release_ctrl[release_num].flag = 2;
      }
2030

2031
      rrc_release_info.RRC_release_ctrl[release_num].rnti = ctxt_pP->rntiMaybeUEid;
2032 2033
      rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui = rrc_eNB_mui;
      rrc_release_info.num_UEs++;
2034
      LOG_D(RRC, "Generate DLSCH Release send: index %d rnti %lx mui %d flag %d \n", release_num, ctxt_pP->rntiMaybeUEid, rrc_eNB_mui, rrc_release_info.RRC_release_ctrl[release_num].flag);
2035 2036 2037
      break;
    }
  }
2038

2039 2040 2041 2042 2043 2044
  /* TODO: what to do if RRC_release_ctrl is full? For now, exit. */
  if (release_num == NUMBER_OF_UE_MAX) {
    LOG_E(RRC, "fatal: rrc_release_info.RRC_release_ctrl is full\n");
    exit(1);
  }

2045
  pthread_mutex_unlock(&rrc_release_freelist);
2046

2047
  if (NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
2048
    MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, 0, F1AP_UE_CONTEXT_RELEASE_CMD);
2049
    F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = ctxt_pP->rntiMaybeUEid;
2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063
    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);
  }
2064 2065
}

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2066
uint8_t qci_to_priority[9]= {2,4,3,5,1,6,7,8,9};
2067 2068 2069 2070

// 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
2071 2072 2073 2074
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
                                                      )
2075 2076 2077 2078 2079
//-----------------------------------------------------------------------------
{
  uint8_t                             buffer[RRC_BUF_SIZE];
  uint16_t                            size;
  int i;
2080 2081 2082 2083 2084 2085 2086
  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
2087
    *DRB_ul_SpecificParameters        = NULL;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2088 2089 2090
  //  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;
2091
  //DRB_ToAddModList_t**                RRC_DRB_configList=&ue_context_pP->ue_context.DRB_configList;
2092 2093
  struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL;
  LTE_DedicatedInfoNAS_t                 *dedicatedInfoNas                 = NULL;
2094 2095 2096
  /* for no gcc warnings */
  (void)dedicatedInfoNas;
  long  *logicalchannelgroup_drb;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2097
  //  int drb_identity_index=0;
2098 2099
  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
2100

2101 2102 2103
  if (*DRB_configList2) {
    free(*DRB_configList2);
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2104

2105
  //*DRB_configList = CALLOC(1, sizeof(*DRB_configList));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2106
  *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
2107
  /* Initialize NAS list */
2108
  dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList));
2109 2110
  int e_rab_done=0;

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2111 2112 2113 2114 2115
  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;
2116
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2117

2118 2119
    // 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
2120
      //      drb_identity_index++;
2121 2122 2123
      continue;
    }

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2124
    DRB_config = CALLOC(1, sizeof(*DRB_config));
2125 2126
    DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long));
    // allowed value 5..15, value : x+4
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2127 2128 2129
    *(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;
2130 2131 2132 2133 2134 2135 2136 2137
    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));
2138
    *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity;
2139 2140 2141
    DRB_pdcp_config->rlc_AM = NULL;
    DRB_pdcp_config->rlc_UM = NULL;

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2142
    switch (ue_context_pP->ue_context.e_rab[i].param.qos.qci) {
2143 2144 2145 2146
      /*
       * type: realtime data with medium packer error rate
       * action: swtich to RLC UM
       */
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165
      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;

2166 2167 2168 2169
      /*
       * type: non-realtime data with low packer error rate
       * action: swtich to RLC AM
       */
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185
      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;
2186
        PDCP_rlc_AM->statusReportRequired = false;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2187 2188 2189 2190 2191 2192 2193
        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++;
2194 2195 2196 2197 2198 2199
        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
2200
        continue;
2201 2202
    }

2203
    DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed;
2204 2205 2206 2207 2208
    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;

2209
    if (ue_context_pP->ue_context.e_rab[i].param.qos.qci < 9 )
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2210
      DRB_ul_SpecificParameters->priority = qci_to_priority[ue_context_pP->ue_context.e_rab[i].param.qos.qci-1] + 3;
2211
    // ue_context_pP->ue_context.e_rab[i].param.qos.allocation_retention_priority.priority_level;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2212
    else
2213 2214
      DRB_ul_SpecificParameters->priority= 4;

2215
    DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2216
    //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
2217
    DRB_ul_SpecificParameters->bucketSizeDuration =
2218
      LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
2219 2220 2221
    logicalchannelgroup_drb = CALLOC(1, sizeof(long));
    *logicalchannelgroup_drb = 1;//(i+1) % 3;
    DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb;
2222 2223
    asn1cSeqAdd(&DRB_configList->list, DRB_config);
    asn1cSeqAdd(&(*DRB_configList2)->list, DRB_config);
2224 2225
    //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
2226 2227 2228 2229 2230 2231 2232
          *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
         );
2233
    e_rab_done++;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2234
    ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE;
2235 2236 2237
    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
2238 2239 2240 2241 2242
        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);
2243
        asn1cSeqAdd(&dedicatedInfoNASList->list, dedicatedInfoNas);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2244 2245 2246
        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");
2247
      }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2248

2249 2250
      /* TODO parameters yet to process ... */
      {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2251 2252 2253
        //      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;
2254 2255 2256 2257 2258 2259 2260 2261 2262 2263
      }
    }
  }

  /* 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
2264
    }
2265 2266 2267 2268
  } else {
    LOG_W(RRC,"dedlicated NAS list is empty\n");
  }

2269
  memset(buffer, 0, sizeof(buffer));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2270 2271
  size = do_RRCConnectionReconfiguration(ctxt_pP,
                                         buffer,
2272
                                         sizeof(buffer),
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2273 2274 2275 2276 2277 2278
                                         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
2279
                                         NULL, NULL,  NULL, NULL, NULL, NULL, NULL,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2280 2281
                                         (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)dedicatedInfoNASList,
                                         (LTE_SL_CommConfig_r12_t *)NULL,
2282 2283
                                         (LTE_SL_DiscConfig_r12_t *)NULL,
                                         (LTE_SCellToAddMod_r10_t *)NULL
2284
                                        );
2285
  LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Connection Reconfiguration\n");
2286 2287 2288 2289 2290 2291 2292 2293 2294 2295

  /* 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
2296
  LOG_I(RRC,
2297
        "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE RNTI %x)\n",
2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311
        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);
  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
2312 2313 2314 2315
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
                                                    )
2316 2317 2318 2319 2320
//-----------------------------------------------------------------------------
{
  uint8_t                             buffer[RRC_BUF_SIZE];
  uint16_t                            size;
  int i, j;
2321 2322 2323 2324 2325 2326 2327
  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
2328 2329 2330
    *DRB_ul_SpecificParameters        = NULL;
  LTE_DRB_ToAddModList_t                 *DRB_configList = ue_context_pP->ue_context.DRB_configList;
  LTE_DRB_ToAddModList_t                *DRB_configList2 = NULL;
2331 2332
  struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL;
  LTE_DedicatedInfoNAS_t                 *dedicatedInfoNas                 = NULL;
2333 2334 2335 2336 2337
  /* 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 */
2338
  dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList));
2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354

  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
2355

2356 2357 2358 2359 2360 2361 2362
    // 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
2363

2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375
    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;
2376
    *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2377

2378
    switch (ue_context_pP->ue_context.modify_e_rab[i].param.qos.qci) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401
      /*
       * 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;
        }
2402

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443
        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;
2444
        PDCP_rlc_AM->statusReportRequired = false;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2445 2446 2447 2448 2449 2450 2451 2452 2453 2454
        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;
2455 2456
    }

2457
    DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed;
2458 2459 2460 2461 2462 2463
    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
2464 2465
      DRB_ul_SpecificParameters->priority= 4;

2466
    DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8;
2467
    DRB_ul_SpecificParameters->bucketSizeDuration =
2468
      LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
2469
    asn1cSeqAdd(&(DRB_configList2)->list, DRB_config);
2470
    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
2471 2472 2473 2474 2475 2476 2477
          *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
         );
2478 2479 2480
    //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;
2481
    {
2482
      if (ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.buffer != NULL) {
2483
        dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t));
2484 2485
        memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t));
        OCTET_STRING_fromBuf(dedicatedInfoNas,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2486 2487
                             (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);
2488
        asn1cSeqAdd(&dedicatedInfoNASList->list, dedicatedInfoNas);
2489
        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
2490
      } else {
2491
        LOG_W(RRC, "Not received activate dedicated EPS bearer context request\n");
2492
      }
2493 2494
    }
  }
2495 2496 2497 2498 2499 2500 2501

  /* 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");
2502
    }
2503 2504 2505 2506
  } else {
    LOG_W(RRC,"dedlicated NAS list is empty\n");
  }

2507
  memset(buffer, 0, sizeof(buffer));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2508
  size = do_RRCConnectionReconfiguration(ctxt_pP,
2509
                                         buffer, sizeof(buffer),
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2510 2511 2512 2513 2514 2515
                                         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
2516
                                         NULL, NULL,  NULL, NULL, NULL, NULL, NULL,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2517 2518
                                         (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)dedicatedInfoNASList,
                                         (LTE_SL_CommConfig_r12_t *)NULL,
2519 2520
                                         (LTE_SL_DiscConfig_r12_t *)NULL,
                                         (LTE_SCellToAddMod_r10_t *)NULL
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2521
                                        );
2522 2523
  LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size,
              "[MSG] RRC Connection Reconfiguration\n");
2524 2525

  /* Free all NAS PDUs */
2526 2527
  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) {
2528
      /* Free the NAS PDU buffer and invalidate it */
2529 2530
      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;
2531 2532 2533
    }
  }

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2534
  LOG_I(RRC,
2535
        "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE RNTI %x)\n",
2536 2537 2538 2539
        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);
2540
  rrc_data_req(
2541 2542 2543 2544 2545 2546 2547
    ctxt_pP,
    DCCH,
    rrc_eNB_mui++,
    SDU_CONFIRM_NO,
    size,
    buffer,
    PDCP_TRANSMISSION_MODE_CONTROL);
2548 2549 2550 2551 2552
  return 0;
}

//-----------------------------------------------------------------------------
void
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2553 2554 2555 2556 2557
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)
2558 2559
//-----------------------------------------------------------------------------
{
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2560 2561 2562 2563 2564 2565 2566
  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];
2567

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2568 2569 2570 2571 2572 2573 2574 2575 2576 2577
  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;
2578
      asn1cSeqAdd(&(*DRB_Release_configList2)->list, DRB_release);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2579
      //free(DRB_release);
2580
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2581
  }
2582

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2583 2584 2585 2586 2587 2588 2589 2590 2591
  /* 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);
2592
    asn1cSeqAdd(&dedicatedInfoNASList->list, dedicatedInfoNas);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2593 2594 2595 2596 2597
    LOG_I(RRC,"add NAS info with size %d\n",nas_length);
  } else {
    LOG_W(RRC,"dedlicated NAS list is empty\n");
  }

2598
  memset(buffer, 0, sizeof(buffer));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2599 2600
  size = do_RRCConnectionReconfiguration(ctxt_pP,
                                         buffer,
2601
                                         sizeof(buffer),
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617
                                         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
2618
                                         NULL,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2619 2620
                                         (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)dedicatedInfoNASList,
                                         (LTE_SL_CommConfig_r12_t *)NULL,
2621 2622
                                         (LTE_SL_DiscConfig_r12_t *)NULL,
                                         (LTE_SCellToAddMod_r10_t *)NULL
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2623 2624 2625 2626 2627
                                        );
  ue_context_pP->ue_context.e_rab_release_command_flag = 1;
  LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size,
              "[MSG] RRC Connection Reconfiguration\n");

2628 2629
  /* Free all NAS PDUs */
  if (nas_length > 0) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2630 2631
    /* Free the NAS PDU buffer and invalidate it */
    free(nas_buffer);
2632 2633 2634
  }

  LOG_I(RRC,
2635
        "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE RNTI %x)\n",
2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647
        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);
  rrc_data_req(
    ctxt_pP,
    DCCH,
    rrc_eNB_mui++,
    SDU_CONFIRM_NO,
    size,
    buffer,
    PDCP_TRANSMISSION_MODE_CONTROL);
2648
}
2649

2650
//-----------------------------------------------------------------------------
2651 2652 2653 2654
/*
 * Generate the basic (first) RRC Connection Reconfiguration (non BR UE)
 */
void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP,
Robert Schmidt's avatar
Robert Schmidt committed
2655
    rrc_eNB_ue_context_t  *const ue_context_pP,
2656
    const uint8_t                ho_state)
2657
//-----------------------------------------------------------------------------
2658
{
2659 2660 2661 2662 2663
  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
2664
  struct LTE_PhysicalConfigDedicated    **physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated;
2665 2666 2667 2668
  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
2669 2670
    *SRB2_ul_SpecificParameters       = NULL;
  LTE_SRB_ToAddModList_t                 *SRB_configList = ue_context_pP->ue_context.SRB_configList;
2671
  LTE_SRB_ToAddModList_t                 **SRB_configList2                 = NULL;
2672 2673 2674 2675 2676 2677 2678
  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
2679 2680
    *DRB_ul_SpecificParameters        = NULL;
  LTE_DRB_ToAddModList_t                **DRB_configList = &ue_context_pP->ue_context.DRB_configList;
2681
  LTE_DRB_ToAddModList_t                **DRB_configList2                  = NULL;
2682 2683 2684
  LTE_MAC_MainConfig_t                   *mac_MainConfig                   = NULL;
  LTE_MeasObjectToAddModList_t           *MeasObj_list                     = NULL;
  LTE_MeasObjectToAddMod_t               *MeasObj                          = NULL;
Robert Schmidt's avatar
Robert Schmidt committed
2685
  LTE_MeasObjectToAddMod_t               *MeasObj2                         = NULL;
2686
  LTE_ReportConfigToAddModList_t         *ReportConfig_list                = NULL;
2687 2688
  LTE_ReportConfigToAddMod_t             *ReportConfig_per, *ReportConfig_A1,
                                         *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5;
Robert Schmidt's avatar
Robert Schmidt committed
2689
  LTE_ReportConfigToAddMod_t             *ReportConfig_NR                  = NULL;
2690
  LTE_MeasIdToAddModList_t               *MeasId_list                      = NULL;
2691
  LTE_MeasIdToAddMod_t                   *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5;
Robert Schmidt's avatar
Robert Schmidt committed
2692
  LTE_MeasIdToAddMod_t                   *MeasId6;
2693 2694 2695 2696 2697
  long                                   *sr_ProhibitTimer_r9              = NULL;
  long                                   *logicalchannelgroup              = NULL;
  long                                   *logicalchannelgroup_drb          = NULL;
  long                                   *maxHARQ_Tx                       = NULL;
  long                                   *periodicBSR_Timer                = NULL;
2698 2699 2700 2701 2702 2703 2704
  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;
2705 2706
  /* For no gcc warnings */
  (void) dedicatedInfoNas;
2707
  LTE_C_RNTI_t                           *cba_RNTI                         = NULL;
2708
  int                                    measurements_enabled;
2709
  uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id);   //Transaction_id,
Robert Schmidt's avatar
Robert Schmidt committed
2710 2711
  uint8_t cc_id = ue_context_pP->ue_context.primaryCC_id;
  LTE_UE_EUTRA_Capability_t *UEcap = ue_context_pP->ue_context.UE_Capability;
2712
  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->rntiMaybeUEid));
2713 2714
  /* Configure SRB2 */
  SRB_configList2 = &(ue_context_pP->ue_context.SRB_configList2[xid]);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2715

2716 2717 2718
  if (*SRB_configList2) {
    free(*SRB_configList2);
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2719

2720 2721
  *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
  memset(*SRB_configList2, 0, sizeof(**SRB_configList2));
2722 2723 2724 2725
  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;
2726 2727 2728 2729 2730 2731 2732 2733
  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;
2734 2735
  SRB2_lchan_config = CALLOC(1, sizeof(*SRB2_lchan_config));
  SRB2_config->logicalChannelConfig = SRB2_lchan_config;
2736
  SRB2_lchan_config->present = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue;
2737
  SRB2_ul_SpecificParameters = CALLOC(1, sizeof(*SRB2_ul_SpecificParameters));
2738
  SRB2_ul_SpecificParameters->priority = 3; // let some priority for SRB1 and dedicated DRBs
2739 2740 2741
  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 */
2742 2743 2744 2745
  logicalchannelgroup = CALLOC(1, sizeof(long));
  *logicalchannelgroup = 0;
  SRB2_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup;
  SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters = SRB2_ul_SpecificParameters;
2746 2747
  asn1cSeqAdd(&SRB_configList->list, SRB2_config); // this list has the configuration for SRB1 and SRB2
  asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config); // this list has only the configuration for SRB2
2748 2749

  /* Configure DRB */
2750
  // list for all the configured DRB
2751 2752 2753
  if (*DRB_configList) {
    free(*DRB_configList);
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2754

2755
  *DRB_configList = CALLOC(1, sizeof(**DRB_configList));
2756
  memset(*DRB_configList, 0, sizeof(**DRB_configList));
2757
  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
2758

2759 2760 2761
  if (*DRB_configList2) {
    free(*DRB_configList2);
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2762

2763 2764
  *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
  memset(*DRB_configList2, 0, sizeof(**DRB_configList2));
2765 2766 2767 2768
  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
2769
  DRB_config->drb_Identity = (LTE_DRB_Identity_t) 1;  // (ue_mod_idP+1); //allowed values 1..32, value: x
2770 2771 2772 2773
  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;
2774
#ifdef RRC_DEFAULT_RAB_IS_AM
2775 2776 2777 2778 2779 2780 2781
  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;
2782
#else
2783 2784 2785 2786
  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;
2787 2788 2789 2790
#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));
2791
  *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity;
2792 2793
  DRB_pdcp_config->rlc_AM = NULL;
  DRB_pdcp_config->rlc_UM = NULL;
2794
  /* Avoid gcc warnings */
Cedric Roux's avatar
Cedric Roux committed
2795
  (void)PDCP_rlc_AM;
Cedric Roux's avatar
Cedric Roux committed
2796
  (void)PDCP_rlc_UM;
Robert Schmidt's avatar
Robert Schmidt committed
2797
#ifdef RRC_DEFAULT_RAB_IS_AM
2798 2799
  PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM));
  DRB_pdcp_config->rlc_AM = PDCP_rlc_AM;
Robert Schmidt's avatar
Robert Schmidt committed
2800
  PDCP_rlc_AM->statusReportRequired = false;
2801
#else
2802 2803
  PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM));
  DRB_pdcp_config->rlc_UM = PDCP_rlc_UM;
2804
  PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits;
2805
#endif
2806
  DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed;
2807 2808 2809 2810
  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;
2811 2812 2813
  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;
2814 2815 2816 2817
  // 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;
2818 2819
  asn1cSeqAdd(&(*DRB_configList)->list, DRB_config);
  asn1cSeqAdd(&(*DRB_configList2)->list, DRB_config);
2820 2821
  /* MAC Main Config */
  // The different parts of MAC main config are set below
2822
  mac_MainConfig = CALLOC(1, sizeof(*mac_MainConfig));
Robert Schmidt's avatar
Robert Schmidt committed
2823
  ue_context_pP->ue_context.mac_MainConfig = mac_MainConfig;
2824 2825
  mac_MainConfig->ul_SCH_Config = CALLOC(1, sizeof(*mac_MainConfig->ul_SCH_Config));
  maxHARQ_Tx = CALLOC(1, sizeof(long));
2826
  *maxHARQ_Tx = LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5;
2827
  mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx;
2828
  /* BSR reconfiguration */
2829
  periodicBSR_Timer = CALLOC(1, sizeof(long));
2830
  *periodicBSR_Timer = LTE_PeriodicBSR_Timer_r12_sf64; //LTE_PeriodicBSR_Timer_r12_infinity; // LTE_PeriodicBSR_Timer_r12_sf64; // LTE_PeriodicBSR_Timer_r12_sf20
2831
  mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer;
2832
  mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; // LTE_RetxBSR_Timer_r12_sf320; // LTE_RetxBSR_Timer_r12_sf5120
2833
  mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE
2834
  mac_MainConfig->timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_infinity;
2835
  /* PHR reconfiguration */
2836
  mac_MainConfig->phr_Config = CALLOC(1, sizeof(*mac_MainConfig->phr_Config));
2837
  mac_MainConfig->phr_Config->present = LTE_MAC_MainConfig__phr_Config_PR_setup;
2838 2839 2840 2841
  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
2842
  mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB3;  // Value dB1 =1 dB, dB3 = 3 dB
2843 2844 2845 2846 2847
  /* CDRX Configuration */
  mac_MainConfig->drx_Config = NULL;
  rnti_t rnti = ue_context_pP->ue_id_rnti;
  module_id_t module_id = ctxt_pP->module_id;
  LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n");
2848

2849 2850 2851
  /* Process the IE drx_Config */
  if (NODE_IS_MONOLITHIC(rrc_inst->node_type)) {
    mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE
2852

2853 2854 2855 2856
    if (mac_MainConfig->drx_Config == NULL) {
      LOG_W(RRC, "drx_Configuration parameter is NULL, cannot configure local UE parameters or CDRX is deactivated\n");
    } else {
      /* Send DRX configuration to MAC task to configure timers of local UE context */
2857 2858
      rrc_mac_drx_config_req_t req = {.rnti = rnti, .drx_Configuration = mac_MainConfig->drx_Config};
      eNB_Config_Local_DRX(module_id, &req);
2859
      LOG_D(RRC, "DRX configured in MAC Main Configuration for RRC Connection Reconfiguration\n");
2860 2861 2862
    }
  }

2863
  /* End of CDRX configuration */
2864
  sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long));
2865
  *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
2866
  mac_MainConfig->ext1 = CALLOC(1, sizeof(struct LTE_MAC_MainConfig__ext1));
2867
  mac_MainConfig->ext1->sr_ProhibitTimer_r9 = sr_ProhibitTimer_r9;
2868

2869 2870 2871
  // change the transmission mode for the primary component carrier
  // TODO: add codebook subset restriction here
  // TODO: change TM for secondary CC in SCelltoaddmodlist
2872
  if (*physicalConfigDedicated) {
2873
    if ((*physicalConfigDedicated)->antennaInfo) {
2874 2875
      (*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);
2876

2877
      if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm3) {
2878 2879 2880 2881 2882 2883 2884 2885
        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
          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;
2886
      } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm4) {
2887 2888 2889 2890 2891 2892 2893 2894
        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
          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;
2895
      } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm5) {
2896 2897 2898 2899 2900 2901 2902 2903
        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
          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;
2904
      } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm6) {
2905 2906 2907 2908 2909 2910 2911 2912
        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
          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;
2913
      }
2914
    } else {
2915 2916
      LOG_E(RRC,"antenna_info not present in physical_config_dedicated. Not reconfiguring!\n");
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2917

2918
    /* CSI RRC Reconfiguration */
2919 2920 2921 2922
    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)) {
2923
        // feedback mode needs to be set as well
2924
        // TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable
2925 2926
        LOG_I(RRC, "Setting cqi reporting mode to rm31 (hardcoded)\n");
        *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic) = LTE_CQI_ReportModeAperiodic_rm31; // HLC CQI, single PMI
2927
      }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2928
    } else {
2929 2930
      LOG_E(RRC,"cqi_ReportConfig not present in physical_config_dedicated. Not reconfiguring!\n");
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2931
  } else {
2932
    LOG_E(RRC,"physical_config_dedicated not present in LTE_RRCConnectionReconfiguration. Not reconfiguring!\n");
2933
  }
2934

2935 2936 2937 2938 2939 2940 2941
  // 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;
2942
  asn1cSeqAdd(&MeasId_list->list, MeasId0);
2943 2944 2945 2946
  MeasId1 = CALLOC(1, sizeof(*MeasId1));
  MeasId1->measId = 2;
  MeasId1->measObjectId = 1;
  MeasId1->reportConfigId = 2;
2947
  asn1cSeqAdd(&MeasId_list->list, MeasId1);
2948 2949 2950 2951
  MeasId2 = CALLOC(1, sizeof(*MeasId2));
  MeasId2->measId = 3;
  MeasId2->measObjectId = 1;
  MeasId2->reportConfigId = 3;
2952
  asn1cSeqAdd(&MeasId_list->list, MeasId2);
2953 2954 2955 2956
  MeasId3 = CALLOC(1, sizeof(*MeasId3));
  MeasId3->measId = 4;
  MeasId3->measObjectId = 1;
  MeasId3->reportConfigId = 4;
2957
  asn1cSeqAdd(&MeasId_list->list, MeasId3);
2958 2959 2960 2961
  MeasId4 = CALLOC(1, sizeof(*MeasId4));
  MeasId4->measId = 5;
  MeasId4->measObjectId = 1;
  MeasId4->reportConfigId = 5;
2962
  asn1cSeqAdd(&MeasId_list->list, MeasId4);
2963 2964 2965 2966
  MeasId5 = CALLOC(1, sizeof(*MeasId5));
  MeasId5->measId = 6;
  MeasId5->measObjectId = 1;
  MeasId5->reportConfigId = 6;
2967
  asn1cSeqAdd(&MeasId_list->list, MeasId5);
Robert Schmidt's avatar
Robert Schmidt committed
2968 2969 2970 2971 2972 2973 2974 2975 2976

  if (ue_context_pP->ue_context.does_nr) {
    MeasId6 = calloc(1, sizeof(LTE_MeasIdToAddMod_t));

    if (MeasId6 == NULL) exit(1);

    MeasId6->measId = 7;
    MeasId6->measObjectId = 2;
    MeasId6->reportConfigId = 7;
2977
    asn1cSeqAdd(&MeasId_list->list, MeasId6);
Robert Schmidt's avatar
Robert Schmidt committed
2978 2979
  }

2980 2981
  //  LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measIdToAddModList = MeasId_list;
  // Add one EUTRA Measurement Object
2982 2983
  MeasObj_list = CALLOC(1, sizeof(*MeasObj_list));
  memset((void *)MeasObj_list, 0, sizeof(*MeasObj_list));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
2984
  // Configure MeasObject
2985 2986 2987
  MeasObj = CALLOC(1, sizeof(*MeasObj));
  memset((void *)MeasObj, 0, sizeof(*MeasObj));
  MeasObj->measObjectId = 1;
2988
  MeasObj->measObject.present = LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA;
2989
  MeasObj->measObject.choice.measObjectEUTRA.carrierFreq =
2990 2991 2992
    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]);
2993
  MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = LTE_AllowedMeasBandwidth_mbw25;
2994 2995 2996 2997 2998 2999
  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
3000

3001 3002 3003 3004 3005 3006
  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;
  }

Robert Schmidt's avatar
Robert Schmidt committed
3007 3008 3009 3010 3011 3012 3013 3014
  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;
  ue_context_pP->ue_context.measurement_info->cellIndividualOffset[0] = LTE_Q_OffsetRange_dB0;

3015 3016 3017
  /* 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++) {
3018
    CellToAdd = (LTE_CellsToAddMod_t *) CALLOC(1, sizeof(*CellToAdd));
3019
    CellToAdd->cellIndex = i + 1;
3020
    CellToAdd->physCellId = RC.rrc[ctxt_pP->module_id]->neigh_cells_id[i][0];//get_adjacent_cell_id(ctxt_pP->module_id, i);
Robert Schmidt's avatar
Robert Schmidt committed
3021 3022
    CellToAdd->cellIndividualOffset = LTE_Q_OffsetRange_dB0;
    ue_context_pP->ue_context.measurement_info->cellIndividualOffset[i+1] = CellToAdd->cellIndividualOffset;
3023
    asn1cSeqAdd(&CellsToAddModList->list, CellToAdd);
3024
  }
3025

3026
  asn1cSeqAdd(&MeasObj_list->list, MeasObj);
3027
  //  LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measObjectToAddModList = MeasObj_list;
Robert Schmidt's avatar
Robert Schmidt committed
3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059

  if (ue_context_pP->ue_context.does_nr) {
    MeasObj2 = calloc(1, sizeof(LTE_MeasObjectToAddMod_t));

    if (MeasObj2 == NULL) exit(1);

    MeasObj2->measObjectId = 2;
    MeasObj2->measObject.present = LTE_MeasObjectToAddMod__measObject_PR_measObjectNR_r15;
    MeasObj2->measObject.choice.measObjectNR_r15.carrierFreq_r15 = rrc_inst->nr_scg_ssb_freq; //641272; //634000; //(634000 = 3.51GHz) (640000 = 3.6GHz) (641272 = 3619.08MHz = 3600 + 30/1000*106*12/2) (642256 is for 3.6GHz and absoluteFrequencySSB = 642016)
    MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.periodicityAndOffset_r15.present = LTE_MTC_SSB_NR_r15__periodicityAndOffset_r15_PR_sf20_r15;
    MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.periodicityAndOffset_r15.choice.sf20_r15 = 0;
    MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.ssb_Duration_r15 = LTE_MTC_SSB_NR_r15__ssb_Duration_r15_sf4;

    if (rrc_inst->nr_scg_ssb_freq > 2016666) //FR2
      MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15 = LTE_RS_ConfigSSB_NR_r15__subcarrierSpacingSSB_r15_kHz120;
    else
      MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15 = LTE_RS_ConfigSSB_NR_r15__subcarrierSpacingSSB_r15_kHz30;      
    MeasObj2->measObject.choice.measObjectNR_r15.quantityConfigSet_r15 = 1;
    MeasObj2->measObject.choice.measObjectNR_r15.ext1 = calloc(1, sizeof(struct LTE_MeasObjectNR_r15__ext1));

    if (MeasObj2->measObject.choice.measObjectNR_r15.ext1 == NULL) exit(1);

    MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15 = calloc(1, sizeof(struct LTE_MeasObjectNR_r15__ext1__bandNR_r15));

    if (MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15 == NULL) exit(1);

    MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15->present = LTE_MeasObjectNR_r15__ext1__bandNR_r15_PR_setup;
    if (rrc_inst->nr_scg_ssb_freq > 2016666) //FR2
      MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15->choice.setup = 261;
    else 
      MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15->choice.setup = 78;

3060
    asn1cSeqAdd(&MeasObj_list->list, MeasObj2);
Robert Schmidt's avatar
Robert Schmidt committed
3061 3062 3063 3064 3065 3066
  }

  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)));
  }

3067
  // Report Configurations for periodical, A1-A5 events
3068 3069
  ReportConfig_list = CALLOC(1, sizeof(*ReportConfig_list));
  ReportConfig_per = CALLOC(1, sizeof(*ReportConfig_per));
3070 3071 3072 3073 3074
  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));
Robert Schmidt's avatar
Robert Schmidt committed
3075 3076 3077 3078 3079

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

3080
  ReportConfig_per->reportConfigId = 1;
3081
  ReportConfig_per->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3082 3083 3084 3085 3086 3087 3088
  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;
3089 3090
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
3091
  asn1cSeqAdd(&ReportConfig_list->list, ReportConfig_per);
3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106
  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;
3107
  asn1cSeqAdd(&ReportConfig_list->list, ReportConfig_A1);
3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126
  //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;
3127
  asn1cSeqAdd(&ReportConfig_list->list, ReportConfig_A2);
3128 3129 3130 3131 3132 3133
  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;
Robert Schmidt's avatar
Robert Schmidt committed
3134
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset = 0;   //10;
3135
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
Robert Schmidt's avatar
Robert Schmidt committed
3136
  eventA3.reportOnLeave = 1;
3137 3138 3139
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
    LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
Robert Schmidt's avatar
Robert Schmidt committed
3140
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
3141 3142
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
Robert Schmidt's avatar
Robert Schmidt committed
3143
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis = 0; // FIXME ...hysteresis is of type long!
3144
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger =
Robert Schmidt's avatar
Robert Schmidt committed
3145
    LTE_TimeToTrigger_ms40;
3146
  asn1cSeqAdd(&ReportConfig_list->list, ReportConfig_A3);
3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162
  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;
3163
  asn1cSeqAdd(&ReportConfig_list->list, ReportConfig_A4);
3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183
  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;
3184
  asn1cSeqAdd(&ReportConfig_list->list, ReportConfig_A5);
Robert Schmidt's avatar
Robert Schmidt committed
3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210

  if (ue_context_pP->ue_context.does_nr) {
    LOG_I(RRC,"Configuring measurement for NR cell\n");
    ReportConfig_NR->reportConfigId = 7;
    ReportConfig_NR->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigInterRAT;
    ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.present = LTE_ReportConfigInterRAT__triggerType_PR_event;
    ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.eventId.present = LTE_ReportConfigInterRAT__triggerType__event__eventId_PR_eventB1_NR_r15;
    ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.eventId.choice.eventB1_NR_r15.b1_ThresholdNR_r15.present = LTE_ThresholdNR_r15_PR_nr_RSRP_r15;
    ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.eventId.choice.eventB1_NR_r15.b1_ThresholdNR_r15.choice.nr_RSRP_r15 = 0;
    ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.eventId.choice.eventB1_NR_r15.reportOnLeave_r15 = false;
    ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.hysteresis = 2;
    ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.timeToTrigger = LTE_TimeToTrigger_ms80;
    ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.maxReportCells = 4;
    ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.reportInterval = LTE_ReportInterval_ms120;
    ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.reportAmount = LTE_ReportConfigInterRAT__reportAmount_infinity;
    ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7 = calloc(1, sizeof(struct LTE_ReportConfigInterRAT__ext7));

    if (ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7 == NULL) exit(1);

    ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15 = calloc(1, sizeof(struct LTE_ReportQuantityNR_r15));

    if (ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15 == NULL) exit(1);

    ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_rsrp = true;
    ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_rsrq = true;
    ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_sinr = true;
3211
    asn1cSeqAdd(&ReportConfig_list->list, ReportConfig_NR);
Robert Schmidt's avatar
Robert Schmidt committed
3212 3213 3214
    LOG_A(RRC, "Generating RRCCConnectionReconfigurationRequest (NRUE Measurement Report Request).\n");
  }

3215
  //  LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list;
Robert Schmidt's avatar
Robert Schmidt committed
3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226

  /* 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;
3227
#if 0
3228 3229 3230 3231 3232
  /* 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.
   */
3233 3234
  rsrp = CALLOC(1, sizeof(LTE_RSRP_Range_t));
  *rsrp = 20;
3235
#endif
3236 3237 3238 3239 3240 3241 3242 3243
  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
3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254
  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)));
Robert Schmidt's avatar
Robert Schmidt committed
3255 3256 3257 3258
  *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = LTE_FilterCoefficient_fc4;
  *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = LTE_FilterCoefficient_fc4;
  ue_context_pP->ue_context.measurement_info->filterCoefficientRSRP = *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP;
  ue_context_pP->ue_context.measurement_info->filterCoefficientRSRQ = *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ;
3259
  /* Initialize NAS list */
3260
  dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList));
3261 3262

  /* Add all NAS PDUs to the list */
3263 3264
  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) {
3265
      dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t));
3266
      memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3267 3268
      OCTET_STRING_fromBuf(dedicatedInfoNas,
                           (char *)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer,
3269
                           ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length);
3270
      asn1cSeqAdd(&dedicatedInfoNASList->list, dedicatedInfoNas);
3271
    }
3272

3273
    /* TODO parameters yet to process ... */
3274 3275 3276 3277 3278 3279
    {
      //      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! */
3280
    ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3281 3282
    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");
3283 3284 3285 3286 3287 3288 3289 3290
  }

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

3291 3292
  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;
3293
  memset(buffer, 0, sizeof(buffer));
3294 3295
  size = do_RRCConnectionReconfiguration(ctxt_pP,
                                         buffer,
3296
                                         sizeof(buffer),
3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315
                                         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,
3316 3317
                                         (LTE_SL_DiscConfig_r12_t *) NULL,
                                         (LTE_SCellToAddMod_r10_t *) NULL
3318
                                        );
3319
  LOG_DUMPMSG(RRC, DEBUG_RRC,(char *)buffer, size, "[MSG] RRC Connection Reconfiguration\n");
3320 3321

  /* Free all NAS PDUs */
3322 3323
  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) {
3324
      /* Free the NAS PDU buffer and invalidate it */
3325 3326
      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;
3327
    }
3328 3329
  }

3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349
  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);
  rrc_data_req(ctxt_pP,
               DCCH,
               rrc_eNB_mui++,
               SDU_CONFIRM_NO,
               size,
               buffer,
               PDCP_TRANSMISSION_MODE_CONTROL);
Robert Schmidt's avatar
Robert Schmidt committed
3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375
  /* Refresh SRBs/DRBs */
  rrc_pdcp_config_asn1_req(ctxt_pP,
                           *SRB_configList2, // NULL,
                           *DRB_configList,
                           NULL,
                           0xff, // already configured during the securitymodecommand
                           NULL,
                           NULL,
                           NULL
                           , (LTE_PMCH_InfoList_r9_t *) NULL
                           , NULL);

  /* Refresh SRBs/DRBs */
  if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
    rrc_rlc_config_asn1_req(ctxt_pP,
                            *SRB_configList2, // NULL,
                            *DRB_configList,
                            NULL
                            , (LTE_PMCH_InfoList_r9_t *) NULL,
                            0,
                            0
                           );
  }

  free(Sparams);
  Sparams = NULL;
3376 3377
  free(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP);
  quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = NULL;
Robert Schmidt's avatar
Robert Schmidt committed
3378 3379
  free(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ);
  quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = NULL;
3380 3381
  free(quantityConfig->quantityConfigEUTRA);
  quantityConfig->quantityConfigEUTRA = NULL;
3382 3383
  free(quantityConfig);
  quantityConfig = NULL;
winckel's avatar
winckel committed
3384
}
3385

3386 3387 3388
//-----------------------------------------------------------------------------
int
rrc_eNB_generate_RRCConnectionReconfiguration_SCell(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3389 3390
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t *const ue_context_pP,
3391 3392 3393
  uint32_t dl_CarrierFreq_r10
)
//-----------------------------------------------------------------------------
3394
{
3395 3396 3397
  uint8_t size;
  uint8_t buffer[100];
  uint8_t sCellIndexToAdd = 0; //one SCell so far
3398 3399 3400

  //   uint8_t sCellIndexToAdd;
  //   sCellIndexToAdd = rrc_find_free_SCell_index(enb_mod_idP, ue_mod_idP, 1);
3401
  //  if (RC.rrc[enb_mod_idP]->sCell_config[ue_mod_idP][sCellIndexToAdd] ) {
3402 3403
  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;
3404
  } else {
3405 3406
    LOG_E(RRC,"Scell not configured!\n");
    return(-1);
3407 3408
  }

3409
  size = do_RRCConnectionReconfiguration(ctxt_pP,
3410
                                         buffer,
3411
                                         sizeof(buffer),
3412
                                         rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),//Transaction_id,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424
                                         (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,
3425
                                         (LTE_SecurityConfigHO_t *)NULL,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3426 3427 3428 3429 3430
                                         (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,
3431 3432
                                         (LTE_SL_DiscConfig_r12_t *)NULL,
                                         ue_context_pP->ue_context.sCell_config
3433
                                        );
3434
  LOG_I(RRC,"[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE id %x)\n",
3435
        ctxt_pP->module_id,ctxt_pP->frame, size, ue_context_pP->ue_context.rnti);
3436
  rrc_data_req(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3437 3438 3439 3440 3441 3442 3443
    ctxt_pP,
    DCCH,
    rrc_eNB_mui++,
    SDU_CONFIRM_NO,
    size,
    buffer,
    PDCP_TRANSMISSION_MODE_CONTROL);
3444 3445 3446 3447
  return(0);
}


s.rampalli's avatar
s.rampalli committed
3448 3449

//-----------------------------------------------------------------------------
3450 3451 3452
/**
 * @fn    :encode_CG_ConfigInfo
 * @param   :enc_buf to store the encoded bits
s.rampalli's avatar
s.rampalli committed
3453 3454
 * @param   :ue_context_pP ue context used to fill CG-ConfigInfo
 * @param   :enc_size to store thre size of encoded size
3455
 *      this api is to fill and encode CG-ConfigInfo
s.rampalli's avatar
s.rampalli committed
3456 3457 3458 3459 3460 3461 3462 3463 3464 3465
 */
static int encode_CG_ConfigInfo(
  char *buffer,
  int buffer_size,
  rrc_eNB_ue_context_t *const ue_context_pP,
  int *enc_size
) {
  struct NR_CG_ConfigInfo *cg_configinfo = NULL;
  struct NR_RadioBearerConfig *rb_config = NULL;
  asn_enc_rval_t enc_rval;
3466
  char temp_buff[ASN_MAX_ENCODE_SIZE];
3467 3468 3469
  NR_UE_CapabilityRAT_ContainerList_t *ue_cap_rat_container_list = NULL;
  NR_UE_CapabilityRAT_Container_t *ue_cap_rat_container_MRDC = NULL;
  NR_UE_CapabilityRAT_Container_t *ue_cap_rat_container_nr = NULL;
3470
  int RAT_Container_count = 0;
s.rampalli's avatar
s.rampalli committed
3471 3472 3473 3474

  cg_configinfo = calloc(1,sizeof(struct NR_CG_ConfigInfo));
  AssertFatal(cg_configinfo != NULL,"failed to allocate memory for cg_configinfo");
  cg_configinfo->criticalExtensions.present = NR_CG_ConfigInfo__criticalExtensions_PR_c1;
3475 3476
  cg_configinfo->criticalExtensions.choice.c1
    = calloc(1, sizeof(struct NR_CG_ConfigInfo__criticalExtensions__c1));
s.rampalli's avatar
s.rampalli committed
3477
  AssertFatal(cg_configinfo->criticalExtensions.choice.c1 != NULL,
3478 3479 3480 3481 3482
              "failed to allocate memory for cg_configinfo->criticalExtensions.choice.c1");
  cg_configinfo->criticalExtensions.choice.c1->present
    = NR_CG_ConfigInfo__criticalExtensions__c1_PR_cg_ConfigInfo;
  cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo
    = calloc(1,sizeof(struct NR_CG_ConfigInfo_IEs));
s.rampalli's avatar
s.rampalli committed
3483
  AssertFatal(cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo != NULL,
3484 3485 3486 3487 3488 3489 3490
              "failed to allocate memory for cg_configinfo_IEs");
  if(ue_context_pP->ue_context.UE_Capability_MRDC) {
    RAT_Container_count++;
    enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UE_MRDC_Capability,NULL,
                                     (void *)ue_context_pP->ue_context.UE_Capability_MRDC,temp_buff,ASN_MAX_ENCODE_SIZE);
    AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n",
                enc_rval.failed_type->name, enc_rval.encoded);
3491 3492 3493 3494
    ue_cap_rat_container_MRDC = calloc(1, sizeof(*ue_cap_rat_container_MRDC));
    AssertFatal(ue_cap_rat_container_MRDC != NULL,"failed to allocate memory for ue_cap_rat_container_MRDC");
    ue_cap_rat_container_MRDC->rat_Type = NR_RAT_Type_eutra_nr;
    OCTET_STRING_fromBuf(&ue_cap_rat_container_MRDC->ue_CapabilityRAT_Container,
3495 3496 3497 3498 3499 3500 3501 3502 3503 3504
                         (const char *)temp_buff,(enc_rval.encoded+7)>>3);
    memset((void *)temp_buff,0,sizeof(temp_buff));
  }

  if(ue_context_pP->ue_context.UE_Capability_nr) {
    RAT_Container_count++;
    enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UE_NR_Capability,NULL,
                                     (void *)ue_context_pP->ue_context.UE_Capability_nr,temp_buff,ASN_MAX_ENCODE_SIZE);
    AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n",
                enc_rval.failed_type->name, enc_rval.encoded);
3505 3506 3507 3508
    ue_cap_rat_container_nr = calloc(1, sizeof(*ue_cap_rat_container_nr));
    AssertFatal(ue_cap_rat_container_nr != NULL,"failed to allocate memory for ue_cap_rat_container_nr");
    ue_cap_rat_container_nr->rat_Type = NR_RAT_Type_nr;
    OCTET_STRING_fromBuf(&ue_cap_rat_container_nr->ue_CapabilityRAT_Container,
3509 3510 3511 3512
                         (const char *)temp_buff,(enc_rval.encoded+7)>>3);
    memset((void *)temp_buff,0,sizeof(temp_buff));
  }

3513 3514 3515 3516 3517
  if (RAT_Container_count) {
    cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->ue_CapabilityInfo = calloc(1,sizeof( OCTET_STRING_t));
    AssertFatal(cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo-> ue_CapabilityInfo != NULL, "failed to allocate memory for ue_capabilityinfo");
    ue_cap_rat_container_list = calloc(1,sizeof(NR_UE_CapabilityRAT_ContainerList_t));
    if (ue_cap_rat_container_MRDC != NULL)
3518
      asn1cSeqAdd(&ue_cap_rat_container_list->list, ue_cap_rat_container_MRDC);
3519
    if (ue_cap_rat_container_nr != NULL)
3520
      asn1cSeqAdd(&ue_cap_rat_container_list->list, ue_cap_rat_container_nr);
3521 3522 3523 3524 3525 3526
    enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UE_CapabilityRAT_ContainerList,NULL,
                                     (void *)ue_cap_rat_container_list,temp_buff,ASN_MAX_ENCODE_SIZE);
    AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n",
                enc_rval.failed_type->name, enc_rval.encoded);
    OCTET_STRING_fromBuf(cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->ue_CapabilityInfo,
                         (const char *)temp_buff, (enc_rval.encoded+7)>>3);
3527 3528 3529 3530 3531 3532
  }

  // this xer_fprint can be enabled for additional debugging messages
  // xer_fprint(stdout,&asn_DEF_NR_CG_ConfigInfo,(void *)cg_configinfo);
  enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_ConfigInfo,NULL,(void *)cg_configinfo,
                                   buffer,buffer_size);
s.rampalli's avatar
s.rampalli committed
3533
  AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
3534
               enc_rval.failed_type->name, enc_rval.encoded);
s.rampalli's avatar
s.rampalli committed
3535
  *enc_size = (enc_rval.encoded+7)/8;
3536 3537
  ASN_STRUCT_FREE(asn_DEF_NR_RadioBearerConfig,rb_config);
  ASN_STRUCT_FREE(asn_DEF_NR_CG_ConfigInfo,cg_configinfo);
3538
  ASN_STRUCT_FREE(asn_DEF_NR_UE_CapabilityRAT_ContainerList,ue_cap_rat_container_list);
s.rampalli's avatar
s.rampalli committed
3539 3540 3541 3542 3543 3544 3545 3546 3547
  return RRC_OK;
}
//-----------------------------------------------------------------------------






3548 3549 3550
//-----------------------------------------------------------------------------
void
rrc_eNB_process_MeasurementReport(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3551 3552 3553
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t         *ue_context_pP,
  const LTE_MeasResults_t   *const measResults2
3554 3555
)
//-----------------------------------------------------------------------------
3556
{
3557 3558
  int i=0;
  int neighboring_cells=-1;
3559 3560
  int ncell_index = 0;
  long ncell_max = -150;
3561 3562
  uint32_t earfcn_dl;
  uint8_t KeNB_star[32] = { 0 };
s.rampalli's avatar
s.rampalli committed
3563
  char enc_buf[ASN_MAX_ENCODE_SIZE] = {0};
3564
  int enc_size = 0;
3565
  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->rntiMaybeUEid));
Cedric Roux's avatar
Cedric Roux committed
3566

3567 3568
  if (measResults2 == NULL )
    return;
3569

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3570 3571 3572 3573
  if (measResults2->measId > 0 ) {
    if (ue_context_pP->ue_context.measResults == NULL) {
      ue_context_pP->ue_context.measResults = CALLOC(1, sizeof(LTE_MeasResults_t));
    }
3574

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3575
    ue_context_pP->ue_context.measResults->measId=measResults2->measId;
Cedric Roux's avatar
Cedric Roux committed
3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602

    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;

3603 3604 3605 3606
      case 7:
        LOG_D(RRC, "NR event frame %d subframe %d\n", ctxt_pP->frame, ctxt_pP->subframe);
        break;

Cedric Roux's avatar
Cedric Roux committed
3607 3608 3609 3610 3611
      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
3612 3613
    ue_context_pP->ue_context.measResults->measResultPCell.rsrpResult=measResults2->measResultPCell.rsrpResult;
    ue_context_pP->ue_context.measResults->measResultPCell.rsrqResult=measResults2->measResultPCell.rsrqResult;
3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627
    LOG_D(RRC,
          "[eNB %d]Frame %d: UE %lx (Measurement Id %d): RSRP of Source %ld\n",
          ctxt_pP->module_id,
          ctxt_pP->frame,
          ctxt_pP->rntiMaybeUEid,
          (int)measResults2->measId,
          ue_context_pP->ue_context.measResults->measResultPCell.rsrpResult - 140);
    LOG_D(RRC,
          "[eNB %d]Frame %d: UE %lx (Measurement Id %d): RSRQ of Source %ld\n",
          ctxt_pP->module_id,
          ctxt_pP->frame,
          ctxt_pP->rntiMaybeUEid,
          (int)measResults2->measId,
          ue_context_pP->ue_context.measResults->measResultPCell.rsrqResult / 2 - 20);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3628 3629
  }

3630 3631
  /* TODO: improve NR triggering */
  if (measResults2->measId == 7) {
3632
    if ((ue_context_pP->ue_context.StatusRrc != RRC_NR_NSA) && (ue_context_pP->ue_context.StatusRrc != RRC_NR_NSA_RECONFIGURED)) {
3633
      MessageDef      *msg;
3634
      ue_context_pP->ue_context.StatusRrc = RRC_NR_NSA;
Cedric Roux's avatar
Cedric Roux committed
3635 3636
      ue_context_pP->ue_context.gnb_rnti = -1;         // set when receiving X2AP_ENDC_SGNB_ADDITION_REQ_ACK
      ue_context_pP->ue_context.gnb_x2_assoc_id = -1;  // set when receiving X2AP_ENDC_SGNB_ADDITION_REQ_ACK
3637

3638
      if(is_en_dc_supported(ue_context_pP->ue_context.UE_Capability)) {
Raymond Knopp's avatar
Raymond Knopp committed
3639 3640 3641

        AssertFatal(measResults2->measResultNeighCells!=NULL,"no measResultNeighCells, shouldn't happen!\n");
        AssertFatal(measResults2->measResultNeighCells->present==LTE_MeasResults__measResultNeighCells_PR_measResultNeighCellListNR_r15,"field is not LTE_MeasResults__measResultNeighCells_PR_measResultNeighCellListNR_r15");
3642 3643 3644 3645
        /** to add gNB as Secondary node CG-ConfigInfo to be added as per 36.423 r15 **/
        if(encode_CG_ConfigInfo(enc_buf,sizeof(enc_buf),ue_context_pP,&enc_size) == RRC_OK)
          LOG_I(RRC,"CG-ConfigInfo encoded successfully\n");

3646
        msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_ENDC_SGNB_ADDITION_REQ);
3647
        memset(&(X2AP_ENDC_SGNB_ADDITION_REQ(msg)), 0, sizeof(x2ap_ENDC_sgnb_addition_req_t));
3648

3649
        X2AP_ENDC_SGNB_ADDITION_REQ(msg).rnti = ctxt_pP->rntiMaybeUEid;
3650 3651 3652 3653 3654 3655

        X2AP_ENDC_SGNB_ADDITION_REQ(msg).security_capabilities.encryption_algorithms = ue_context_pP->ue_context.nr_security.ciphering_algorithms;
        X2AP_ENDC_SGNB_ADDITION_REQ(msg).security_capabilities.integrity_algorithms = ue_context_pP->ue_context.nr_security.integrity_algorithms;

        memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).kgnb, ue_context_pP->ue_context.nr_security.kgNB, 32);

3656 3657
        memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer,enc_buf,enc_size);
        X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer_size = enc_size;
3658

3659
        X2AP_ENDC_SGNB_ADDITION_REQ(msg).target_physCellId
3660
          //= measResults2->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0]->pci_r15;
3661
          = measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]->physCellId;
3662

3663
        X2AP_ENDC_SGNB_ADDITION_REQ(msg).target_physCellId = 0;
3664 3665 3666 3667 3668 3669 3670
        //For the moment we have a single E-RAB which will be the one to be added to the gNB
        //Not sure how to select bearers to be added if there are multiple.
        X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded = 1;

        for (int e_rab=0; e_rab < X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded; e_rab++) {
          X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id;
          X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].gtp_teid = ue_context_pP->ue_context.e_rab[e_rab].param.gtp_teid;
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
3671
          X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].drb_ID = ue_context_pP->ue_context.DRB_configList->list.array[e_rab]->drb_Identity;
3672 3673 3674 3675 3676
          memcpy(&X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].sgw_addr,
                 &ue_context_pP->ue_context.e_rab[e_rab].param.sgw_addr,
                 sizeof(transport_layer_addr_t));
        }

3677
        LOG_A(RRC, "[eNB %d] frame %d subframe %d: UE rnti %lx switching to NSA mode\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->subframe, ctxt_pP->rntiMaybeUEid);
3678 3679
        itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), msg);
        return;
3680
      }
3681
    }
3682 3683 3684 3685

    if (!ue_context_pP->ue_context.measResults->measResultNeighCells) {
      ue_context_pP->ue_context.measResults->measResultNeighCells = calloc(1,sizeof(*ue_context_pP->ue_context.measResults->measResultNeighCells));
      ue_context_pP->ue_context.measResults->measResultNeighCells->present = LTE_MeasResults__measResultNeighCells_PR_measResultNeighCellListNR_r15;
3686 3687
      ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array = calloc(1, sizeof(*ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array));
      ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0] = calloc(1, sizeof(*ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0]));
3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707
      ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.count = 1;
    }
    struct LTE_MeasResultCellNR_r15 *ueCtxtMeasResultCellNR_r15 = ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0];
    const struct LTE_MeasResultCellNR_r15 *measNeighCellNR0 = measResults2->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0];
    ueCtxtMeasResultCellNR_r15->pci_r15 = measNeighCellNR0->pci_r15;
    if (!ueCtxtMeasResultCellNR_r15->measResultCell_r15.rsrpResult_r15)
      ueCtxtMeasResultCellNR_r15->measResultCell_r15.rsrpResult_r15 = calloc(1, sizeof(*ueCtxtMeasResultCellNR_r15->measResultCell_r15.rsrpResult_r15));
    if (!ueCtxtMeasResultCellNR_r15->measResultCell_r15.rsrqResult_r15)
      ueCtxtMeasResultCellNR_r15->measResultCell_r15.rsrqResult_r15 = calloc(1, sizeof(*ueCtxtMeasResultCellNR_r15->measResultCell_r15.rsrqResult_r15));
    *ueCtxtMeasResultCellNR_r15->measResultCell_r15.rsrpResult_r15 = *measNeighCellNR0->measResultCell_r15.rsrpResult_r15;
    *ueCtxtMeasResultCellNR_r15->measResultCell_r15.rsrqResult_r15 = *measNeighCellNR0->measResultCell_r15.rsrqResult_r15;
    if (measNeighCellNR0->measResultRS_IndexList_r15) {
       if (!ueCtxtMeasResultCellNR_r15->measResultRS_IndexList_r15) {
          ueCtxtMeasResultCellNR_r15->measResultRS_IndexList_r15 = calloc(1,sizeof(*ueCtxtMeasResultCellNR_r15->measResultRS_IndexList_r15));
          ueCtxtMeasResultCellNR_r15->measResultRS_IndexList_r15->list.array = calloc(1, sizeof(ueCtxtMeasResultCellNR_r15->measResultRS_IndexList_r15->list.array));
          ueCtxtMeasResultCellNR_r15->measResultRS_IndexList_r15->list.array[0] = calloc(1, sizeof(*ueCtxtMeasResultCellNR_r15->measResultRS_IndexList_r15->list.array));
          ueCtxtMeasResultCellNR_r15->measResultRS_IndexList_r15->list.count = 1;
       }
      ueCtxtMeasResultCellNR_r15->measResultRS_IndexList_r15->list.array[0]->ssb_Index_r15 = measNeighCellNR0->measResultRS_IndexList_r15->list.array[0]->ssb_Index_r15;
    }
3708 3709
  }

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3710 3711 3712 3713 3714 3715 3716
  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
3717
      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
3718
    }
3719 3720 3721 3722
    if (!ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array) {
        ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array =
        calloc(neighboring_cells, sizeof(*ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array));
    }
3723

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3724
    for (i=0; i < neighboring_cells; i++) {
Cedric Roux's avatar
Cedric Roux committed
3725 3726
      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);
3727
        asn1cSeqAdd(&ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list,measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i]);
Cedric Roux's avatar
Cedric Roux committed
3728 3729 3730 3731
      }

      ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->physCellId =
        measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->physCellId;
3732 3733 3734 3735 3736

      if (!ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult)
        ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult = calloc(1, sizeof(*ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult));
      if (!ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrqResult)
        ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrqResult = calloc(1, sizeof(*ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrqResult));
Cedric Roux's avatar
Cedric Roux committed
3737 3738 3739 3740
      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
3741 3742
      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
3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760
      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
3761 3762 3763
    }
  }

3764 3765 3766
  /* Decide whether to trigger HO or not */
  if (!(measResults2->measId == 4))
    return;
Cedric Roux's avatar
Cedric Roux committed
3767

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

3772 3773 3774
  if (RC.rrc[ctxt_pP->module_id]->x2_ho_net_control)
    return;

3775
  LOG_D(RRC, "A3 event is triggered...\n");
3776

3777
  /* if the UE is not in handover mode, start handover procedure */
3778
  if (ue_context_pP->ue_context.StatusRrc != RRC_HO_EXECUTION) {
3779 3780 3781 3782
    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)));
3783
    ue_context_pP->ue_context.StatusRrc = RRC_HO_EXECUTION;
3784 3785
    ue_context_pP->ue_context.handover_info->state = HO_REQUEST;
    /* HO Preparation message */
3786
    msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_HANDOVER_REQ);
3787
    rrc_eNB_generate_HandoverPreparationInformation(
Cedric Roux's avatar
Cedric Roux committed
3788 3789 3790
      ue_context_pP,
      X2AP_HANDOVER_REQ(msg).rrc_buffer,
      &X2AP_HANDOVER_REQ(msg).rrc_buffer_size);
3791
    X2AP_HANDOVER_REQ(msg).rnti = ctxt_pP->rntiMaybeUEid;
3792
    X2AP_HANDOVER_REQ(msg).target_physCellId = measResults2->measResultNeighCells->choice.
Cedric Roux's avatar
Cedric Roux committed
3793
        measResultListEUTRA.list.array[ncell_index]->physCellId;
3794 3795 3796 3797 3798 3799 3800 3801
    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;
3802 3803
    // 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,
3804
                                       RC.rrc[ctxt_pP->module_id]->carrier[0].N_RB_DL);
3805 3806
    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);
3807 3808 3809 3810
    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
3811 3812 3813 3814 3815 3816 3817 3818
    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;
3819 3820 3821 3822 3823 3824 3825 3826 3827
    }

    /* 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 {
3828
    LOG_D(RRC, "[eNB %d] Frame %d: Ignoring MeasReport from UE %lx as Handover is in progress... \n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rntiMaybeUEid);
3829
  }
3830 3831
}

3832

3833 3834 3835
//-----------------------------------------------------------------------------
void
rrc_eNB_generate_HandoverPreparationInformation(
3836
  //const protocol_ctxt_t* const ctxt_pP,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3837
  rrc_eNB_ue_context_t *const ue_context_pP,
Cedric Roux's avatar
Cedric Roux committed
3838
  uint8_t                     *buffer,
3839
  int                          *_size
Cedric Roux's avatar
Cedric Roux committed
3840
) {
3841
  memset(buffer, 0, 8192);
Cedric Roux's avatar
Cedric Roux committed
3842
  char *ho_buf = (char *) buffer;
3843
  int ho_size;
3844
  ho_size = do_HandoverPreparation(ho_buf, 8192, ue_context_pP->ue_context.UE_Capability, ue_context_pP->ue_context.UE_Capability_size);
3845
  *_size = ho_size;
3846 3847
}

3848 3849
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) {
3850 3851
    LOG_E(RRC, "Error: number of neighbouring cells is exceeded \n");
    return;
3852 3853 3854
  }

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

3859
  RC.rrc[mod_id]->num_neigh_cells++;
3860
  RC.rrc[mod_id]->num_neigh_cells_cc[RC.rrc[mod_id]->num_neigh_cells-1] = m->num_cc;
3861

3862 3863 3864 3865 3866 3867 3868
  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) {
3869 3870
    LOG_E(RRC, "Error: number of neighbouring cells is exceeded \n");
    return;
3871 3872 3873
  }

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

3878
  RC.rrc[mod_id]->num_neigh_cells++;
3879
  RC.rrc[mod_id]->num_neigh_cells_cc[RC.rrc[mod_id]->num_neigh_cells-1] = m->num_cc;
3880

3881 3882 3883 3884 3885
  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
3886
void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_req_t *m) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
3887
  struct rrc_eNB_ue_context_s        *ue_context_target_p = NULL;
3888 3889 3890 3891
  /* TODO: get proper UE rnti */
  int rnti = taus() & 0xffff;
  int i;
  //global_rnti = rnti;
3892 3893 3894
  LTE_HandoverPreparationInformation_t *ho = NULL;
  LTE_HandoverPreparationInformation_r8_IEs_t *ho_info;
  asn_dec_rval_t                      dec_rval;
3895
  ue_context_target_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
3896

3897 3898 3899 3900
  if (ue_context_target_p != NULL) {
    LOG_E(RRC, "\nError in obtaining free UE id in target eNB for handover \n");
    return;
  }
3901

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

3904 3905 3906 3907 3908 3909 3910 3911 3912 3913
  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)));
3914
  //ue_context_target_p->ue_context.StatusRrc = RRC_HO_EXECUTION;
luaihui's avatar
luaihui committed
3915
  //ue_context_target_p->ue_context.handover_info->state = HO_ACK;
3916 3917
  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;
3918 3919 3920 3921 3922 3923 3924
  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;
  dec_rval = uper_decode(NULL,
3925
                         &asn_DEF_LTE_HandoverPreparationInformation,
3926 3927 3928 3929
                         (void **)&ho,
                         m->rrc_buffer,
                         m->rrc_buffer_size, 0, 0);

3930 3931 3932
  if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
    xer_fprint(stdout, &asn_DEF_LTE_HandoverPreparationInformation, ho);
  }
3933

3934
  if (dec_rval.code != RC_OK ||
3935 3936
      ho->criticalExtensions.present != LTE_HandoverPreparationInformation__criticalExtensions_PR_c1 ||
      ho->criticalExtensions.choice.c1.present != LTE_HandoverPreparationInformation__criticalExtensions__c1_PR_handoverPreparationInformation_r8) {
3937 3938 3939 3940 3941 3942 3943 3944
    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);
3945
    ASN_STRUCT_FREE(asn_DEF_LTE_UE_EUTRA_Capability,
3946 3947 3948 3949 3950
                    ue_context_target_p->ue_context.UE_Capability);
    ue_context_target_p->ue_context.UE_Capability = 0;
  }

  dec_rval = uper_decode(NULL,
3951
                         &asn_DEF_LTE_UE_EUTRA_Capability,
3952 3953 3954 3955 3956 3957
                         (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) ) {
3958
    xer_fprint(stdout, &asn_DEF_LTE_UE_EUTRA_Capability, ue_context_target_p->ue_context.UE_Capability);
3959 3960 3961
  }

  if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
3962 3963 3964 3965
    LOG_E(RRC, "Failed to decode UE capabilities (%zu bytes)\n", dec_rval.consumed);
    ASN_STRUCT_FREE(asn_DEF_LTE_UE_EUTRA_Capability,
                    ue_context_target_p->ue_context.UE_Capability);
    ue_context_target_p->ue_context.UE_Capability = 0;
3966
  }
3967

3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978
  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
3979 3980 3981 3982 3983 3984 3985
    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);
3986
  }
luaihui's avatar
luaihui committed
3987

3988
  rrc_eNB_process_X2AP_TUNNEL_SETUP_REQ(mod_id, ue_context_target_p);
3989
  ue_context_target_p->ue_context.StatusRrc = RRC_HO_EXECUTION;
luaihui's avatar
luaihui committed
3990
  ue_context_target_p->ue_context.handover_info->state = HO_ACK;
3991 3992
}

3993
void rrc_eNB_process_handoverCommand(
Cedric Roux's avatar
Cedric Roux committed
3994 3995 3996
  int                         mod_id,
  struct rrc_eNB_ue_context_s *ue_context,
  x2ap_handover_req_ack_t     *m) {
3997
  asn_dec_rval_t dec_rval;
3998
  LTE_HandoverCommand_t *ho = NULL;
3999 4000
  dec_rval = uper_decode(
               NULL,
4001
               &asn_DEF_LTE_HandoverCommand,
Cedric Roux's avatar
Cedric Roux committed
4002
               (void **)&ho,
4003 4004 4005 4006 4007 4008
               m->rrc_buffer,
               m->rrc_buffer_size,
               0,
               0);

  if (dec_rval.code != RC_OK ||
4009 4010
      ho->criticalExtensions.present != LTE_HandoverCommand__criticalExtensions_PR_c1 ||
      ho->criticalExtensions.choice.c1.present != LTE_HandoverCommand__criticalExtensions__c1_PR_handoverCommand_r8) {
4011 4012 4013 4014 4015 4016 4017
    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
4018 4019 4020 4021
  if (size > RRC_BUF_SIZE) {
    printf("%s:%d: fatal\n", __FILE__, __LINE__);
    abort();
  }
4022 4023 4024

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

4027
void rrc_eNB_handover_ue_context_release(
4028 4029
  protocol_ctxt_t *const ctxt_pP,
  struct rrc_eNB_ue_context_s *ue_context_p) {
4030 4031 4032
  int e_rab = 0;
  //MessageDef *msg_release_p = NULL;
  uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id;
4033
  //msg_release_p = itti_alloc_new_message(TASK_RRC_ENB, 0, S1AP_UE_CONTEXT_RELEASE);
4034 4035
  //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);
4036 4037 4038
  gtpv1u_enb_delete_tunnel_req_t delete_tunnels={0};
  delete_tunnels.rnti = ue_context_p->ue_context.rnti;
  delete_tunnels.from_gnb = 0;
4039 4040

  for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
4041
    delete_tunnels.eps_bearer_id[delete_tunnels.num_erab++] =
4042 4043 4044 4045 4046 4047 4048
      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;
  }

4049
  gtpv1u_delete_s1u_tunnel(ctxt_pP->module_id, &delete_tunnels);
4050 4051 4052 4053 4054 4055
  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
4056
}
Cedric Roux's avatar
Cedric Roux committed
4057 4058 4059

/* This function may be incorrect. */
void rrc_eNB_handover_cancel(
4060 4061
  protocol_ctxt_t              *const ctxt_pP,
  struct rrc_eNB_ue_context_s  *ue_context_p) {
Cedric Roux's avatar
Cedric Roux committed
4062 4063 4064 4065
  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);
}
4066 4067 4068

void
check_handovers(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4069
  protocol_ctxt_t *const ctxt_pP
4070
)
4071
//-----------------------------------------------------------------------------
4072
{
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4073
  struct rrc_eNB_ue_context_s        *ue_context_p;
4074
  RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
4075
    ctxt_pP->rntiMaybeUEid = ue_context_p->ue_id_rnti;
4076

4077
    if (ue_context_p->ue_context.StatusRrc == RRC_HO_EXECUTION && ue_context_p->ue_context.handover_info != NULL) {
4078 4079
      /* in the source, UE in HO_PREPARE mode */
      if (ue_context_p->ue_context.handover_info->state == HO_PREPARE) {
4080
        LOG_D(RRC, "[eNB %d] Frame %d: Incoming handover detected for new UE_id %lx) \n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rntiMaybeUEid);
4081 4082
        // source eNB generates rrcconnectionreconfiguration to prepare the HO
        LOG_I(RRC,
Cedric Roux's avatar
Cedric Roux committed
4083 4084
              "[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);
4085
        rrc_data_req(
4086
          ctxt_pP,
4087 4088 4089 4090 4091
          DCCH,
          rrc_eNB_mui++,
          SDU_CONFIRM_NO,
          ue_context_p->ue_context.handover_info->size,
          ue_context_p->ue_context.handover_info->buf,
4092
          PDCP_TRANSMISSION_MODE_CONTROL);
4093
        ue_context_p->ue_context.handover_info->state = HO_COMPLETE;
Cedric Roux's avatar
Cedric Roux committed
4094
        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);
4095
      }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4096

4097 4098 4099 4100
      /* 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
4101
        ue_context_p->ue_context.handover_info->state = HO_FORWARDING;
4102
        msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_HANDOVER_REQ_ACK);
4103 4104
        rrc_eNB_generate_HO_RRCConnectionReconfiguration(ctxt_pP, ue_context_p,
            X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer,
4105
            sizeof(X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer),
Cedric Roux's avatar
Cedric Roux committed
4106
            &X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer_size);
4107
        rrc_eNB_configure_rbs_handover(ue_context_p,ctxt_pP);
4108 4109 4110
        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;
4111 4112 4113
        /* 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
4114
        for (int i=0; i<ue_context_p->ue_context.setup_e_rabs; i++) {
luaihui's avatar
luaihui committed
4115
          /* set gtpv teid info */
4116
          X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].e_rab_id = ue_context_p->ue_context.e_rab[i].param.e_rab_id;
4117
          X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].gtp_teid = ue_context_p->ue_context.enb_gtp_x2u_teid[i];
luaihui's avatar
luaihui committed
4118
          X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr = ue_context_p->ue_context.enb_gtp_x2u_addrs[i];
4119
        }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4120

4121
        itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), msg);
Cedric Roux's avatar
Cedric Roux committed
4122
        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);
4123
      }
winckel's avatar
winckel committed
4124
    }
luaihui's avatar
luaihui committed
4125

4126
    if (ue_context_p->ue_context.StatusRrc == RRC_RECONFIGURED
4127 4128 4129
        && ue_context_p->ue_context.handover_info != NULL &&
        ue_context_p->ue_context.handover_info->forwarding_state == FORWARDING_NO_EMPTY ) {
      MessageDef   *msg_p;
4130
      bool result;
luaihui's avatar
luaihui committed
4131 4132 4133 4134
      protocol_ctxt_t  ctxt;

      do {
        // Checks if a message has been sent to PDCP sub-task
4135
        itti_poll_msg (TASK_DATA_FORWARDING, &msg_p);
luaihui's avatar
luaihui committed
4136

4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147
        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);
4148
              LOG_D(RRC, PROTOCOL_CTXT_FMT"[check_handovers]Received %s from %s: instance %ld, rb_id %ld, muiP %d, confirmP %d, mode %d\n",
4149 4150 4151
                    PROTOCOL_CTXT_ARGS(&ctxt),
                    ITTI_MSG_NAME (msg_p),
                    ITTI_MSG_ORIGIN_NAME(msg_p),
4152
                    ITTI_MSG_DESTINATION_INSTANCE (msg_p),
4153 4154 4155 4156
                    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);
laurent's avatar
laurent committed
4157
              LOG_I(RRC, "Before calling pdcp_data_req from check_handovers! GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id: %ld \n", GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id);
4158 4159 4160 4161 4162 4163 4164 4165 4166 4167
              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, NULL, NULL
                                     );

4168
              if (result != true) {
4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189
                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;
luaihui's avatar
luaihui committed
4190 4191
    }

4192
    if( ue_context_p->ue_context.StatusRrc == RRC_RECONFIGURED &&
4193 4194 4195 4196 4197 4198
        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;
luaihui's avatar
luaihui committed
4199 4200 4201 4202 4203 4204 4205
      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) {
4206 4207 4208 4209 4210 4211 4212 4213 4214 4215
          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);
4216
              LOG_I(RRC, PROTOCOL_CTXT_FMT"[check_handovers]Received %s from %s: instance %ld, rb_id %ld, muiP %d, confirmP %d, mode %d\n",
4217 4218 4219
                    PROTOCOL_CTXT_ARGS(&ctxt),
                    ITTI_MSG_NAME (msg_p),
                    ITTI_MSG_ORIGIN_NAME(msg_p),
4220
                    ITTI_MSG_DESTINATION_INSTANCE (msg_p),
4221 4222 4223 4224
                    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);
laurent's avatar
laurent committed
4225
              LOG_D(RRC, "Before calling pdcp_data_req from check_handovers! GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id: %ld \n", GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id);
4226 4227 4228 4229 4230 4231 4232 4233 4234
              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, NULL, NULL
                                     );
luaihui's avatar
luaihui committed
4235

4236
              if (result != true) {
4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249
                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;
luaihui's avatar
luaihui committed
4250 4251 4252 4253 4254 4255 4256 4257 4258
          }

          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;
4259
    }
4260
  }
4261
}
winckel's avatar
RRC:  
winckel committed
4262

4263
void
Cedric Roux's avatar
Cedric Roux committed
4264 4265 4266
rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP,
    rrc_eNB_ue_context_t  *const ue_context_pP,
    uint8_t               *buffer,
4267
    size_t                 buffer_size,
Cedric Roux's avatar
Cedric Roux committed
4268 4269 4270
    int                    *_size
    //const uint8_t        ho_state
                                                )
4271
//-----------------------------------------------------------------------------
4272
{
4273
  uint16_t                            size;
4274 4275 4276
  int                                 i;
  uint8_t                             rv[2];
  // configure SRB1/SRB2, PhysicalConfigDedicated, MAC_MainConfig for UE
Cedric Roux's avatar
Cedric Roux committed
4277
  eNB_RRC_INST                       *rrc_inst = RC.rrc[ctxt_pP->module_id];
4278
  struct LTE_PhysicalConfigDedicated **physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated;
4279
  // phy config dedicated
4280
  LTE_PhysicalConfigDedicated_t      *physicalConfigDedicated2;
4281
  // srb 1: for HO
4282 4283 4284 4285
  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
4286
    *SRB1_ul_SpecificParameters       = NULL;
4287 4288 4289 4290
  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
4291
    *SRB2_ul_SpecificParameters       = NULL;
4292 4293 4294 4295 4296 4297 4298 4299 4300
  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
4301
    *DRB_ul_SpecificParameters        = NULL;
4302 4303 4304 4305 4306 4307 4308
  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,
4309
                                     *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5;
4310 4311
  LTE_MeasIdToAddModList_t           *MeasId_list                      = NULL;
  LTE_MeasIdToAddMod_t               *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5;
4312
  long                               *sr_ProhibitTimer_r9              = NULL;
4313 4314
  long                               *logicalchannelgroup, *logicalchannelgroup_drb;
  long                               *maxHARQ_Tx, *periodicBSR_Timer;
4315 4316 4317 4318 4319
  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;
4320 4321
  LTE_CellsToAddMod_t                *CellToAdd                        = NULL;
  LTE_CellsToAddModList_t            *CellsToAddModList                = NULL;
4322 4323
  struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL;
  LTE_DedicatedInfoNAS_t             *dedicatedInfoNas                 = NULL;
4324 4325
  /* for no gcc warnings */
  (void)dedicatedInfoNas;
4326
  LTE_C_RNTI_t                       *cba_RNTI                         = NULL;
4327
  int                                measurements_enabled;
4328
  uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id);   //Transaction_id,
4329
  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->rntiMaybeUEid));
4330 4331 4332 4333
  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",
4334
        ctxt_pP->module_id, ctxt_pP->frame);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
4335

4336 4337
  if (SRB_configList) {
    free(SRB_configList);
4338
  }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
4339

4340 4341
  SRB_configList = CALLOC(1, sizeof(*SRB_configList));
  memset(SRB_configList, 0, sizeof(*SRB_configList));
4342 4343 4344 4345
  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;
4346 4347 4348 4349 4350 4351 4352 4353
  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;
4354 4355
  SRB1_lchan_config = CALLOC(1, sizeof(*SRB1_lchan_config));
  SRB1_config->logicalChannelConfig = SRB1_lchan_config;
4356
  SRB1_lchan_config->present = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue;
4357 4358 4359 4360 4361
  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 =
4362
    LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
4363 4364
  //assign_enum(&SRB1_ul_SpecificParameters->bucketSizeDuration,LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50);
  SRB1_ul_SpecificParameters->bucketSizeDuration =
4365
    LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
4366 4367 4368
  logicalchannelgroup = CALLOC(1, sizeof(long));
  *logicalchannelgroup = 0;
  SRB1_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup;
4369
  asn1cSeqAdd(&SRB_configList->list, SRB1_config);
4370 4371 4372 4373
  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
4374

4375 4376 4377
  if (*SRB_configList2) {
    free(*SRB_configList2);
  }
Cedric Roux's avatar
Cedric Roux committed
4378

4379 4380 4381 4382 4383 4384
  *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;
4385 4386 4387 4388 4389 4390 4391 4392
  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;
4393 4394
  SRB2_lchan_config = CALLOC(1, sizeof(*SRB2_lchan_config));
  SRB2_config->logicalChannelConfig = SRB2_lchan_config;
4395
  SRB2_lchan_config->present = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue;
4396 4397 4398
  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 =
4399
    LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
4400
  SRB2_ul_SpecificParameters->bucketSizeDuration =
4401
    LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
4402 4403 4404 4405 4406 4407
  // 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
4408
  asn1cSeqAdd(&SRB_configList->list, SRB2_config);
4409
  // this list has only the configuration for SRB2
4410
  asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config);
4411 4412 4413 4414 4415 4416 4417

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

4419 4420 4421 4422
  *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
4423

4424 4425 4426
  if (*DRB_configList2) {
    free(*DRB_configList2);
  }
Cedric Roux's avatar
Cedric Roux committed
4427

4428 4429 4430 4431 4432 4433 4434 4435
  *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
4436
  DRB_config->drb_Identity = (LTE_DRB_Identity_t) 1;  // (ue_mod_idP+1); //allowed values 1..32, value: x
4437 4438 4439 4440 4441
  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
4442 4443 4444 4445 4446 4447 4448
  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;
4449
#else
4450 4451 4452 4453
  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;
4454 4455 4456 4457
#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));
4458
  *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity;
4459 4460 4461 4462 4463
  DRB_pdcp_config->rlc_AM = NULL;
  DRB_pdcp_config->rlc_UM = NULL;
  /* avoid gcc warnings */
  (void)PDCP_rlc_AM;
  (void)PDCP_rlc_UM;
Robert Schmidt's avatar
Robert Schmidt committed
4464
#ifdef RRC_DEFAULT_RAB_IS_AM
4465 4466
  PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM));
  DRB_pdcp_config->rlc_AM = PDCP_rlc_AM;
4467
  PDCP_rlc_AM->statusReportRequired = 0; // FALSE
4468 4469 4470
#else
  PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM));
  DRB_pdcp_config->rlc_UM = PDCP_rlc_UM;
4471
  PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits;
4472
#endif
4473
  DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed;
4474 4475 4476 4477 4478
  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
4479
  DRB_ul_SpecificParameters->prioritisedBitRate =LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ;
Cedric Roux's avatar
Cedric Roux committed
4480
  //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
4481
  DRB_ul_SpecificParameters->bucketSizeDuration =
4482
    LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
4483 4484 4485 4486
  // 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;
4487 4488
  asn1cSeqAdd(&(*DRB_configList)->list, DRB_config);
  asn1cSeqAdd(&(*DRB_configList2)->list, DRB_config);
4489 4490 4491 4492 4493
  //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));
4494
  *maxHARQ_Tx = LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5;
4495 4496
  mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx;
  periodicBSR_Timer = CALLOC(1, sizeof(long));
4497
  *periodicBSR_Timer = LTE_PeriodicBSR_Timer_r12_sf64;
4498
  mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer;
4499
  mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320;
4500
  mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE
4501
  mac_MainConfig->timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_infinity;
4502 4503
  mac_MainConfig->drx_Config = NULL;
  mac_MainConfig->phr_Config = CALLOC(1, sizeof(*mac_MainConfig->phr_Config));
4504 4505 4506 4507
  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
4508 4509
  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
4510
  mac_MainConfig->ext1 = CALLOC(1, sizeof(struct LTE_MAC_MainConfig__ext1));
4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522
  mac_MainConfig->ext1->sr_ProhibitTimer_r9 = sr_ProhibitTimer_r9;
  //sps_RA_ConfigList_rlola = NULL;

  //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) {
4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537
  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));
4538
  physicalConfigDedicated2->soundingRS_UL_ConfigDedicated = NULL; //CALLOC(1,sizeof(*physicalConfigDedicated2->soundingRS_UL_ConfigDedicated));
4539 4540 4541 4542 4543 4544
  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);
4545
  physicalConfigDedicated2->pdsch_ConfigDedicated->p_a = LTE_PDSCH_ConfigDedicated__p_a_dB0;
4546 4547
  // PUCCH
  physicalConfigDedicated2->pucch_ConfigDedicated->ackNackRepetition.present =
4548
    LTE_PUCCH_ConfigDedicated__ackNackRepetition_PR_release;
4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559
  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 =
4560
    LTE_UplinkPowerControlDedicated__deltaMCS_Enabled_en1;
4561 4562 4563 4564 4565 4566
  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
4567
  *physicalConfigDedicated2->uplinkPowerControlDedicated->filterCoefficient = LTE_FilterCoefficient_fc4;  // fc4 dB
4568
  // TPC-PDCCH-Config
4569 4570
  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;
4571 4572 4573 4574
  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;
4575
  physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_RNTI.buf[1] = 0x34 + ue_context_pP->local_uid;
4576
  physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_RNTI.bits_unused = 0;
4577 4578
  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;
4579 4580 4581 4582
  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;
4583
  physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.buf[1] = 0x34 + ue_context_pP->local_uid;
4584 4585 4586
  physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.bits_unused = 0;
  //AntennaInfoDedicated
  physicalConfigDedicated2->antennaInfo = CALLOC(1, sizeof(*physicalConfigDedicated2->antennaInfo));
4587
  physicalConfigDedicated2->antennaInfo->present = LTE_PhysicalConfigDedicated__antennaInfo_PR_explicitValue;
4588
  //if ((*physicalConfigDedicated)->antennaInfo) {
Cedric Roux's avatar
Cedric Roux committed
4589 4590
  (*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
4591

Cedric Roux's avatar
Cedric Roux committed
4592
  if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm3) {
Cedric Roux's avatar
Cedric Roux committed
4593
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
4594
      CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
Cedric Roux's avatar
Cedric Roux committed
4595
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
4596
      LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm3;
Cedric Roux's avatar
Cedric Roux committed
4597 4598 4599 4600
    (*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
4601
  } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm4) {
Cedric Roux's avatar
Cedric Roux committed
4602
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
4603
      CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
Cedric Roux's avatar
Cedric Roux committed
4604
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
4605
      LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm4;
Cedric Roux's avatar
Cedric Roux committed
4606 4607 4608 4609
    (*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
4610
  } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm5) {
Cedric Roux's avatar
Cedric Roux committed
4611
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
4612
      CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
Cedric Roux's avatar
Cedric Roux committed
4613
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
4614
      LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm5;
Cedric Roux's avatar
Cedric Roux committed
4615 4616 4617 4618
    (*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
4619
  } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm6) {
Cedric Roux's avatar
Cedric Roux committed
4620
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
4621
      CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
Cedric Roux's avatar
Cedric Roux committed
4622
    (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
4623
      LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm6;
Cedric Roux's avatar
Cedric Roux committed
4624 4625 4626 4627 4628
    (*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;
  }
4629

4630
  physicalConfigDedicated2->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.present =
4631
    LTE_AntennaInfoDedicated__ue_TransmitAntennaSelection_PR_release;
4632
  physicalConfigDedicated2->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.release = 0;
4633 4634
  //}
  //else {
Cedric Roux's avatar
Cedric Roux committed
4635
  //LOG_E(RRC,"antenna_info not present in physical_config_dedicated. Not reconfiguring!\n");
4636 4637
  //}
  // CQI ReportConfig
Cedric Roux's avatar
Cedric Roux committed
4638 4639 4640 4641 4642
  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));
4643
  physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->present =  LTE_CQI_ReportPeriodic_PR_release;
4644 4645

  //if ((*physicalConfigDedicated)->cqi_ReportConfig) {
Cedric Roux's avatar
Cedric Roux committed
4646 4647 4648
  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
4649 4650 4651
    //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");
4652
    *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportModeAperiodic_rm31;
Cedric Roux's avatar
Cedric Roux committed
4653
  } else {
4654
    *physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic= LTE_CQI_ReportModeAperiodic_rm30;
Cedric Roux's avatar
Cedric Roux committed
4655 4656
  }

4657 4658
  //}
  //else {
Cedric Roux's avatar
Cedric Roux committed
4659
  //LOG_E(RRC,"cqi_ReportConfig not present in physical_config_dedicated. Not reconfiguring!\n");
4660
  //}
4661
  // SchedulingRequestConfig
4662
  physicalConfigDedicated2->schedulingRequestConfig->present = LTE_SchedulingRequestConfig_PR_setup;
4663
  physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = ue_context_pP->local_uid;
4664

4665
  if (rrc_inst->carrier[0].sib1->tdd_Config==NULL) {  // FDD
4666 4667
    physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 5 + (ue_context_pP->local_uid %
        10);   // Isr = 5 (every 10 subframes, offset=2+UE_id mod3)
4668
  } else {
4669
    switch (rrc_inst->carrier[0].sib1->tdd_Config->subframeAssignment) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4670 4671 4672 4673
      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;
4674

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4675 4676 4677 4678
      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;
4679

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4680 4681 4682 4683
      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;
4684

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
4685 4686 4687
      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
4688
    }
4689
  }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
4690

4691 4692 4693 4694
  //  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 =
Raymond Knopp's avatar
Raymond Knopp committed
4695
    LTE_SchedulingRequestConfig__setup__dsr_TransMax_n64;
4696
  LOG_D(RRC,
4697 4698
        "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);
laurent's avatar
laurent committed
4699 4700 4701 4702 4703 4704 4705 4706
  rrc_mac_config_req_eNB_t tmp = {0};
  tmp.CC_id = ue_context_pP->ue_context.primaryCC_id;
  tmp.rnti = ue_context_pP->ue_context.rnti;
  tmp.physicalConfigDedicated = ue_context_pP->ue_context.physicalConfigDedicated;
  tmp.mac_MainConfig = ue_context_pP->ue_context.mac_MainConfig;
  tmp.logicalChannelIdentity = 1;
  tmp.measGapConfig = ue_context_pP->ue_context.measGapConfig;
  rrc_mac_config_req_eNB(ctxt_pP->module_id, &tmp);
4707 4708 4709 4710 4711 4712 4713 4714
  // 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;
4715 4716 4717 4718 4719 4720 4721 4722
  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;
4723 4724
  SRB2_lchan_config = CALLOC(1, sizeof(*SRB2_lchan_config));
  SRB2_config->logicalChannelConfig = SRB2_lchan_config;
4725
  SRB2_lchan_config->present = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue;
4726 4727 4728
  SRB2_ul_SpecificParameters = CALLOC(1, sizeof(*SRB2_ul_SpecificParameters));
  SRB2_ul_SpecificParameters->priority = 1;
  SRB2_ul_SpecificParameters->prioritisedBitRate =
4729
    LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
4730
  SRB2_ul_SpecificParameters->bucketSizeDuration =
4731
    LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
4732 4733 4734 4735 4736
  // 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;
4737 4738
  asn1cSeqAdd(&SRB_configList->list, SRB2_config);
  asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config);
4739 4740 4741 4742
  // Configure target eNB DRB
  DRB_configList2 = CALLOC(1, sizeof(*DRB_configList2));
  /// DRB
  DRB_config = CALLOC(1, sizeof(*DRB_config));
4743
  //DRB_config->drb_Identity = (LTE_DRB_Identity_t) 1; //allowed values 1..32
4744
  // NN: this is the 1st DRB for this ue, so set it to 1
4745
  DRB_config->drb_Identity = (LTE_DRB_Identity_t) 1;  // (ue_mod_idP+1); //allowed values 1..32
4746 4747 4748 4749
  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;
4750 4751 4752 4753
  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;
4754 4755 4756 4757 4758 4759
  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;
4760 4761
  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;
4762 4763 4764 4765 4766 4767
  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 =
4768
    LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
4769
  DRB_ul_SpecificParameters->bucketSizeDuration =
4770
    LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
4771 4772 4773 4774
  // 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;
4775
  asn1cSeqAdd(&(*DRB_configList2)->list, DRB_config);
4776
  mac_MainConfig = CALLOC(1, sizeof(*mac_MainConfig));
4777
  ue_context_pP->ue_context.mac_MainConfig = mac_MainConfig;
4778 4779
  mac_MainConfig->ul_SCH_Config = CALLOC(1, sizeof(*mac_MainConfig->ul_SCH_Config));
  maxHARQ_Tx = CALLOC(1, sizeof(long));
4780
  *maxHARQ_Tx = LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5;
4781 4782
  mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx;
  periodicBSR_Timer = CALLOC(1, sizeof(long));
4783
  *periodicBSR_Timer = LTE_PeriodicBSR_Timer_r12_sf64;
4784
  mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer;
4785
  mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320;
4786 4787 4788
  mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE
  mac_MainConfig->drx_Config = NULL;
  mac_MainConfig->phr_Config = CALLOC(1, sizeof(*mac_MainConfig->phr_Config));
4789 4790 4791 4792
  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
4793 4794
  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
4795
  mac_MainConfig->ext1 = CALLOC(1, sizeof(struct LTE_MAC_MainConfig__ext1));
4796
  mac_MainConfig->ext1->sr_ProhibitTimer_r9 = sr_ProhibitTimer_r9;
4797 4798 4799 4800 4801 4802 4803
  // 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;
4804
  asn1cSeqAdd(&MeasId_list->list, MeasId0);
4805 4806 4807 4808
  MeasId1 = CALLOC(1, sizeof(*MeasId1));
  MeasId1->measId = 2;
  MeasId1->measObjectId = 1;
  MeasId1->reportConfigId = 2;
4809
  asn1cSeqAdd(&MeasId_list->list, MeasId1);
4810 4811 4812 4813
  MeasId2 = CALLOC(1, sizeof(*MeasId2));
  MeasId2->measId = 3;
  MeasId2->measObjectId = 1;
  MeasId2->reportConfigId = 3;
4814
  asn1cSeqAdd(&MeasId_list->list, MeasId2);
4815 4816 4817 4818
  MeasId3 = CALLOC(1, sizeof(*MeasId3));
  MeasId3->measId = 4;
  MeasId3->measObjectId = 1;
  MeasId3->reportConfigId = 4;
4819
  asn1cSeqAdd(&MeasId_list->list, MeasId3);
4820 4821 4822 4823
  MeasId4 = CALLOC(1, sizeof(*MeasId4));
  MeasId4->measId = 5;
  MeasId4->measObjectId = 1;
  MeasId4->reportConfigId = 5;
4824
  asn1cSeqAdd(&MeasId_list->list, MeasId4);
4825 4826 4827 4828
  MeasId5 = CALLOC(1, sizeof(*MeasId5));
  MeasId5->measId = 6;
  MeasId5->measObjectId = 1;
  MeasId5->reportConfigId = 6;
4829
  asn1cSeqAdd(&MeasId_list->list, MeasId5);
4830
  //  LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measIdToAddModList = MeasId_list;
4831 4832 4833 4834 4835 4836 4837
  // 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;
4838
  MeasObj->measObject.present = LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA;
4839
  MeasObj->measObject.choice.measObjectEUTRA.carrierFreq =
4840 4841 4842
    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]);
4843
  MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = LTE_AllowedMeasBandwidth_mbw25;
4844 4845 4846 4847 4848 4849
  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
4850 4851 4852 4853 4854 4855

  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;
  }
4856 4857 4858 4859 4860 4861 4862

  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;
4863
  ue_context_pP->ue_context.measurement_info->cellIndividualOffset[0] = LTE_Q_OffsetRange_dB0;
4864 4865 4866 4867 4868 4869 4870 4871 4872

  /* 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;
4873
    asn1cSeqAdd(&CellsToAddModList->list, CellToAdd);
4874
  }
4875

4876
  asn1cSeqAdd(&MeasObj_list->list, MeasObj);
4877
  //  LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measObjectToAddModList = MeasObj_list;
4878 4879 4880 4881 4882

  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)));
  }

4883 4884 4885 4886 4887 4888 4889 4890 4891
  // 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;
4892
  ReportConfig_per->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
4893
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.present =
4894
    LTE_ReportConfigEUTRA__triggerType_PR_periodical;
4895
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.choice.periodical.purpose =
4896 4897 4898
    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;
4899
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
4900 4901
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
4902
  asn1cSeqAdd(&ReportConfig_list->list, ReportConfig_per);
4903
  ReportConfig_A1->reportConfigId = 2;
4904
  ReportConfig_A1->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
4905
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.present =
4906
    LTE_ReportConfigEUTRA__triggerType_PR_event;
4907
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
4908
    LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1;
4909
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA1.
4910
  a1_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
4911 4912
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA1.
  a1_Threshold.choice.threshold_RSRP = 10;
4913 4914
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
4915
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
4916 4917
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
4918
  asn1cSeqAdd(&ReportConfig_list->list, ReportConfig_A1);
Cedric Roux's avatar
Cedric Roux committed
4919 4920 4921
  //  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);
4922
  ReportConfig_A2->reportConfigId = 3;
4923
  ReportConfig_A2->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
4924
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.present =
4925
    LTE_ReportConfigEUTRA__triggerType_PR_event;
4926
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
4927
    LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2;
Cedric Roux's avatar
Cedric Roux committed
4928
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
4929
  eventA2.a2_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
Cedric Roux's avatar
Cedric Roux committed
4930 4931 4932
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
  eventA2.a2_Threshold.choice.threshold_RSRP = 10;
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
4933
    LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
4934
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
4935
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
4936 4937
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
4938
  asn1cSeqAdd(&ReportConfig_list->list, ReportConfig_A2);
4939
  ReportConfig_A3->reportConfigId = 4;
4940
  ReportConfig_A3->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
4941
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.present =
4942
    LTE_ReportConfigEUTRA__triggerType_PR_event;
4943
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
4944
    LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3;
Cedric Roux's avatar
Cedric Roux committed
4945
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset = 0;   //10;
4946 4947
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
  eventA3.reportOnLeave = 1;
Cedric Roux's avatar
Cedric Roux committed
4948
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
4949
    LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
4950
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
4951
  ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
4952 4953
  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
4954 4955
  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 =
4956
    LTE_TimeToTrigger_ms40;
4957
  asn1cSeqAdd(&ReportConfig_list->list, ReportConfig_A3);
4958
  ReportConfig_A4->reportConfigId = 5;
4959
  ReportConfig_A4->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
4960
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.present =
4961
    LTE_ReportConfigEUTRA__triggerType_PR_event;
4962
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
4963
    LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4;
Cedric Roux's avatar
Cedric Roux committed
4964
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
4965
  eventA4.a4_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
Cedric Roux's avatar
Cedric Roux committed
4966 4967 4968
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
  eventA4.a4_Threshold.choice.threshold_RSRP = 10;
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
4969
    LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
4970
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
4971
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
4972 4973
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
4974
  asn1cSeqAdd(&ReportConfig_list->list, ReportConfig_A4);
4975
  ReportConfig_A5->reportConfigId = 6;
4976
  ReportConfig_A5->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
4977
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.present =
4978
    LTE_ReportConfigEUTRA__triggerType_PR_event;
4979
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
4980
    LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA5;
4981
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
4982
  eventA5.a5_Threshold1.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
4983
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
4984
  eventA5.a5_Threshold2.present = LTE_ThresholdEUTRA_PR_threshold_RSRP;
4985 4986 4987 4988
  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
4989
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
4990
    LTE_ReportConfigEUTRA__triggerQuantity_rsrp;
4991
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both;
4992
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
4993 4994
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
  ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
4995
  asn1cSeqAdd(&ReportConfig_list->list, ReportConfig_A5);
Cedric Roux's avatar
Cedric Roux committed
4996
  //  rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list;
4997 4998 4999

  /* A3 event update */
  if (!ue_context_pP->ue_context.measurement_info->events->a3_event) {
5000
    ue_context_pP->ue_context.measurement_info->events->a3_event = CALLOC(1,sizeof(*(ue_context_pP->ue_context.measurement_info->events->a3_event)));
5001 5002 5003 5004 5005 5006 5007
  }

  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;
5008
#if 0
5009 5010 5011 5012 5013
  /* 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
5014 5015
  rsrp = CALLOC(1, sizeof(RSRP_Range_t));
  *rsrp = 20;
5016
#endif
5017
  Sparams = CALLOC(1, sizeof(*Sparams));
5018 5019 5020
  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;
5021 5022
  Sparams->choice.setup.mobilityStateParameters.n_CellChangeHigh = 10;
  Sparams->choice.setup.mobilityStateParameters.n_CellChangeMedium = 5;
5023 5024
  Sparams->choice.setup.mobilityStateParameters.t_Evaluation = LTE_MobilityStateParameters__t_Evaluation_s60;
  Sparams->choice.setup.mobilityStateParameters.t_HystNormal = LTE_MobilityStateParameters__t_HystNormal_s120;
5025 5026
  quantityConfig = CALLOC(1, sizeof(*quantityConfig));
  memset((void *)quantityConfig, 0, sizeof(*quantityConfig));
5027
  quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(struct LTE_QuantityConfigEUTRA));
5028 5029 5030 5031 5032
  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
5033
    CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP)));
5034
  quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ =
Cedric Roux's avatar
Cedric Roux committed
5035
    CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ)));
5036 5037
  *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = LTE_FilterCoefficient_fc4;
  *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = LTE_FilterCoefficient_fc4;
5038 5039
  ue_context_pP->ue_context.measurement_info->filterCoefficientRSRP = *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP;
  ue_context_pP->ue_context.measurement_info->filterCoefficientRSRQ = *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ;
5040
  /* mobilityinfo  */
Cedric Roux's avatar
Cedric Roux committed
5041
  mobilityInfo = ue_context_pP->ue_context.mobilityInfo;
5042

Cedric Roux's avatar
Cedric Roux committed
5043 5044 5045
  if (mobilityInfo) {
    free(mobilityInfo);
  }
5046

5047 5048
  mobilityInfo = CALLOC(1, sizeof(*mobilityInfo));
  memset((void *)mobilityInfo, 0, sizeof(*mobilityInfo));
Cedric Roux's avatar
Cedric Roux committed
5049
  mobilityInfo->targetPhysCellId = RC.rrc[ctxt_pP->module_id]->carrier[0].physCellId;
Cedric Roux's avatar
Cedric Roux committed
5050
  LOG_D(RRC, "[eNB %d] Frame %d: handover preparation: targetPhysCellId: %ld mod_id: %d ue: %x \n",
5051 5052 5053
        ctxt_pP->module_id,
        ctxt_pP->frame,
        mobilityInfo->targetPhysCellId,
Cedric Roux's avatar
Cedric Roux committed
5054
        ctxt_pP->module_id, // get_adjacent_cell_mod_id(mobilityInfo->targetPhysCellId),
5055
        ue_context_pP->ue_context.rnti);
5056
  mobilityInfo->additionalSpectrumEmission = CALLOC(1, sizeof(*mobilityInfo->additionalSpectrumEmission));
5057
  *mobilityInfo->additionalSpectrumEmission = (LTE_AdditionalSpectrumEmission_t) 1;  //Check this value!
5058
  mobilityInfo->t304 = LTE_MobilityControlInfo__t304_ms200;    // need to configure an appropriate value here
5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070
  // 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,
5071
         (void *)&rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.rach_ConfigCommon, sizeof(LTE_RACH_ConfigCommon_t));
5072 5073 5074
  mobilityInfo->radioResourceConfigCommon.prach_Config.prach_ConfigInfo =
    CALLOC(1, sizeof(*mobilityInfo->radioResourceConfigCommon.prach_Config.prach_ConfigInfo));
  memcpy((void *)mobilityInfo->radioResourceConfigCommon.prach_Config.prach_ConfigInfo,
5075
         (void *)&rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.prach_Config.prach_ConfigInfo,
5076
         sizeof(LTE_PRACH_ConfigInfo_t));
5077
  mobilityInfo->radioResourceConfigCommon.prach_Config.rootSequenceIndex =
5078
    rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.prach_Config.rootSequenceIndex;
5079 5080 5081
  mobilityInfo->radioResourceConfigCommon.pdsch_ConfigCommon =
    CALLOC(1, sizeof(*mobilityInfo->radioResourceConfigCommon.pdsch_ConfigCommon));
  memcpy((void *)mobilityInfo->radioResourceConfigCommon.pdsch_ConfigCommon,
5082
         (void *)&rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.pdsch_ConfigCommon, sizeof(LTE_PDSCH_ConfigCommon_t));
5083
  memcpy((void *)&mobilityInfo->radioResourceConfigCommon.pusch_ConfigCommon,
5084
         (void *)&rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.pusch_ConfigCommon, sizeof(LTE_PUSCH_ConfigCommon_t));
5085 5086 5087 5088
  mobilityInfo->radioResourceConfigCommon.phich_Config = NULL;
  mobilityInfo->radioResourceConfigCommon.pucch_ConfigCommon =
    CALLOC(1, sizeof(*mobilityInfo->radioResourceConfigCommon.pucch_ConfigCommon));
  memcpy((void *)mobilityInfo->radioResourceConfigCommon.pucch_ConfigCommon,
5089
         (void *)&rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.pucch_ConfigCommon, sizeof(LTE_PUCCH_ConfigCommon_t));
5090 5091 5092
  mobilityInfo->radioResourceConfigCommon.soundingRS_UL_ConfigCommon =
    CALLOC(1, sizeof(*mobilityInfo->radioResourceConfigCommon.soundingRS_UL_ConfigCommon));
  memcpy((void *)mobilityInfo->radioResourceConfigCommon.soundingRS_UL_ConfigCommon,
5093
         (void *)&rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon,
5094
         sizeof(LTE_SoundingRS_UL_ConfigCommon_t));
5095 5096 5097
  mobilityInfo->radioResourceConfigCommon.uplinkPowerControlCommon =
    CALLOC(1, sizeof(*mobilityInfo->radioResourceConfigCommon.uplinkPowerControlCommon));
  memcpy((void *)mobilityInfo->radioResourceConfigCommon.uplinkPowerControlCommon,
5098
         (void *)&rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.uplinkPowerControlCommon,
5099
         sizeof(LTE_UplinkPowerControlCommon_t));
5100 5101 5102
  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
5103 5104
  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));
5105
  mobilityInfo->radioResourceConfigCommon.ul_CyclicPrefixLength =
5106
    rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.ul_CyclicPrefixLength;
5107 5108
  //End of configuration of radioResourceConfigCommon
  mobilityInfo->carrierFreq = CALLOC(1, sizeof(*mobilityInfo->carrierFreq));  //CALLOC(1,sizeof(CarrierFreqEUTRA_t)); 36090
5109
  mobilityInfo->carrierFreq->dl_CarrierFreq =
5110 5111 5112
    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]);
5113
  mobilityInfo->carrierFreq->ul_CarrierFreq = NULL;
5114
  mobilityInfo->carrierBandwidth = CALLOC(1, sizeof(
Cedric Roux's avatar
Cedric Roux committed
5115
      *mobilityInfo->carrierBandwidth));    //CALLOC(1,sizeof(struct CarrierBandwidthEUTRA));  AllowedMeasBandwidth_mbw25
5116
  mobilityInfo->carrierBandwidth->dl_Bandwidth = LTE_CarrierBandwidthEUTRA__dl_Bandwidth_n25;
5117 5118
  mobilityInfo->carrierBandwidth->ul_Bandwidth = NULL;
  mobilityInfo->rach_ConfigDedicated = NULL;
Cedric Roux's avatar
Cedric Roux committed
5119
  ue_context_pP->ue_context.mobilityInfo = mobilityInfo;
5120
#if 0
Cedric Roux's avatar
Cedric Roux committed
5121 5122 5123 5124 5125 5126 5127 5128 5129 5130
  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;
5131
  ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToReleaseList = NULL;
Cedric Roux's avatar
Cedric Roux committed
5132 5133
  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
5134
  memcpy((void *)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig,
Cedric Roux's avatar
Cedric Roux committed
5135 5136 5137
         (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
5138
  memcpy((void *)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated,
Cedric Roux's avatar
Cedric Roux committed
5139 5140 5141 5142 5143
         (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
  //  }
5144 5145
  securityConfigHO = CALLOC(1, sizeof(*securityConfigHO));
  memset((void *)securityConfigHO, 0, sizeof(*securityConfigHO));
5146
  securityConfigHO->handoverType.present = LTE_SecurityConfigHO__handoverType_PR_intraLTE;
5147 5148 5149 5150
  securityConfigHO->handoverType.choice.intraLTE.securityAlgorithmConfig = NULL; /* TODO: to be checked */
  securityConfigHO->handoverType.choice.intraLTE.keyChangeIndicator = 0;
  securityConfigHO->handoverType.choice.intraLTE.nextHopChainingCount = 0;
  /* Initialize NAS list */
5151
  dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList));
5152 5153 5154 5155

  /* 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) {
5156
      dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t));
5157 5158
      memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t));
      OCTET_STRING_fromBuf(dedicatedInfoNas,
Cedric Roux's avatar
Cedric Roux committed
5159
                           (char *)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer,
5160
                           ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length);
5161
      asn1cSeqAdd(&dedicatedInfoNASList->list, dedicatedInfoNas);
5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172
    }

    /* 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
5173
          i, ue_context_pP->ue_context.e_rab[i].status, "E_RAB_STATUS_DONE");
5174 5175 5176 5177 5178 5179 5180 5181
  }

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

5182 5183
  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;
5184
  memset(buffer, 0, buffer_size);
5185 5186 5187
  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
5188
             (unsigned char *)rrc_buf,
5189
             sizeof(rrc_buf),
Cedric Roux's avatar
Cedric Roux committed
5190 5191 5192 5193
             xid,   //Transaction_id,
             NULL, // SRB_configList
             NULL,
             NULL,  // DRB2_list,
5194 5195
             (struct LTE_SPS_Config *)NULL,   // *sps_Config,
             (struct LTE_PhysicalConfigDedicated *)*physicalConfigDedicated,
5196 5197 5198 5199
             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
5200
             //#endif
5201 5202 5203 5204 5205 5206 5207 5208 5209
             (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,
5210 5211
             (LTE_SL_DiscConfig_r12_t *)NULL,
             (LTE_SCellToAddMod_r10_t *)NULL
Cedric Roux's avatar
Cedric Roux committed
5212
                                            );
5213

Cedric Roux's avatar
Cedric Roux committed
5214 5215 5216 5217
  if (rrc_size <= 0) {
    printf("%s:%d: fatal\n", __FILE__, __LINE__);
    abort();
  }
5218

Cedric Roux's avatar
Cedric Roux committed
5219
  char *ho_buf = (char *)buffer;
5220 5221
  int ho_size;
  ho_size = do_HandoverCommand(
5222
              ho_buf, buffer_size,
Cedric Roux's avatar
Cedric Roux committed
5223 5224
              rrc_buf,
              rrc_size);
5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236
  *_size = size = ho_size;
  LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size,
              "[MSG] RRC Connection Reconfiguration handover\n");

  /* 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;
    }
  }
5237

5238 5239 5240 5241 5242 5243
  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);
5244 5245
  /* Refresh SRBs/DRBs */
  rrc_pdcp_config_asn1_req(ctxt_pP,
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
5246 5247 5248 5249 5250 5251 5252 5253 5254
                           *SRB_configList2, // NULL,
                           *DRB_configList,
                           NULL,
                           0xff, // already configured during the securitymodecommand
                           NULL,
                           NULL,
                           NULL
                           , (LTE_PMCH_InfoList_r9_t *) NULL
                           , NULL);
5255 5256

  /* Refresh SRBs/DRBs */
Cedric Roux's avatar
Cedric Roux committed
5257 5258 5259 5260 5261 5262 5263 5264
  if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
    rrc_rlc_config_asn1_req(ctxt_pP,
                            *SRB_configList2, // NULL,
                            *DRB_configList,
                            NULL
                            , (LTE_PMCH_InfoList_r9_t *) NULL,
                            0,
                            0
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
5265
                           );
Cedric Roux's avatar
Cedric Roux committed
5266
  }
5267

5268 5269 5270 5271 5272 5273 5274 5275
  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;
5276 5277
  free(securityConfigHO);
  securityConfigHO = NULL;
5278 5279
  free(Sparams);
  Sparams = NULL;
5280 5281 5282
}

void
Cedric Roux's avatar
Cedric Roux committed
5283
rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s *ue_context_p, protocol_ctxt_t *const ctxt_pP) {
5284
  uint16_t                            Idx;
5285
  Idx = DCCH;
5286
#if 1
Cedric Roux's avatar
Cedric Roux committed
5287
  // Activate the radio bearers
5288
  // SRB1
Cedric Roux's avatar
Cedric Roux committed
5289 5290 5291 5292
  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
5293
  // SRB2
Cedric Roux's avatar
Cedric Roux committed
5294 5295 5296 5297 5298
  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
5299
  LOG_I(RRC, "[eNB %d] CALLING RLC CONFIG SRB1 (rbid %d) for UE %x\n",
Cedric Roux's avatar
Cedric Roux committed
5300 5301 5302 5303
        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,
5304 5305
                           (LTE_DRB_ToAddModList_t *) NULL,
                           (LTE_DRB_ToReleaseList_t *) NULL,
Cedric Roux's avatar
Cedric Roux committed
5306 5307 5308
                           0xff,
                           NULL,
                           NULL,
5309 5310
                           NULL,
                           (LTE_PMCH_InfoList_r9_t *) NULL, NULL);
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
5311

Cedric Roux's avatar
Cedric Roux committed
5312 5313 5314 5315 5316 5317 5318 5319
  if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
    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
                           );
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5320

Cedric Roux's avatar
Cedric Roux committed
5321
  if (EPC_MODE_ENABLED) {
5322 5323 5324 5325 5326 5327 5328 5329
    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);
5330
    rrc_pdcp_config_security(ctxt_pP, ue_context_p, false);
Cedric Roux's avatar
Cedric Roux committed
5331
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5332

5333
  // Add a new user (called during the HO procedure)
5334
  LOG_I(RRC, "rrc_eNB_target_add_ue_handover module_id %d rnti %lx\n", ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid);
Cedric Roux's avatar
Cedric Roux committed
5335
  // Configure MAC for the target
laurent's avatar
laurent committed
5336 5337 5338 5339 5340 5341 5342 5343 5344
  rrc_mac_config_req_eNB_t tmp = {0};
  tmp.CC_id = ue_context_p->ue_context.primaryCC_id;
  tmp.rnti = ue_context_p->ue_context.rnti;
  tmp.physicalConfigDedicated = ue_context_p->ue_context.physicalConfigDedicated;
  tmp.mac_MainConfig = ue_context_p->ue_context.mac_MainConfig;
  tmp.logicalChannelIdentity = 1;
  tmp.measGapConfig = ue_context_p->ue_context.measGapConfig;
  tmp.mobilityControlInfo = ue_context_p->ue_context.mobilityInfo;
  rrc_mac_config_req_eNB(ctxt_pP->module_id, &tmp);
winckel's avatar
winckel committed
5345
}
5346

5347
//-----------------------------------------------------------------------------
5348
/*
5349
* Process the RRC Connection Reconfiguration Complete from the UE
5350
*/
5351 5352
void
rrc_eNB_process_RRCConnectionReconfigurationComplete(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5353
  const protocol_ctxt_t *const ctxt_pP,
5354
  rrc_eNB_ue_context_t  *ue_context_pP,
5355
  const uint8_t xid
5356 5357
)
//-----------------------------------------------------------------------------
5358
{
OAI-admin's avatar
OAI-admin committed
5359
  int                                 drb_id;
5360 5361 5362 5363 5364
  int                                 oip_ifup = 0;
  int                                 dest_ip_offset = 0;
  uint8_t                            *kRRCenc = NULL;
  uint8_t                            *kRRCint = NULL;
  uint8_t                            *kUPenc = NULL;
5365 5366 5367 5368
  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;
5369
  ue_context_pP->ue_context.ue_reestablishment_timer = 0;
5370
  ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // reset rrc inactivity timer
5371 5372 5373 5374 5375 5376
  /* CDRX: activated when RRC Connection Reconfiguration Complete is received */
  rnti_t rnti = ue_context_pP->ue_id_rnti;
  module_id_t module_id = ctxt_pP->module_id;

  if (NODE_IS_MONOLITHIC(RC.rrc[module_id]->node_type)) {
    int UE_id_mac = find_UE_id(module_id, rnti);
5377

5378
    if (UE_id_mac == -1) {
5379
      LOG_E(RRC, "Can't find UE_id(MAC) of UE rnti %x\n", rnti);
5380 5381
      return;
    }
5382

5383
    UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[module_id]->UE_info.UE_sched_ctrl[UE_id_mac]);
5384

5385 5386 5387
    if (UE_scheduling_control->cdrx_waiting_ack == true) {
      UE_scheduling_control->cdrx_waiting_ack = false;
      UE_scheduling_control->cdrx_configured = true; // Set to TRUE when RRC Connection Reconfiguration is received
5388 5389
      LOG_I(RRC, "CDRX configuration activated after RRC Connection Reconfiguration Complete reception\n");
    }
5390
  }
5391

5392
  /* End of CDRX processing */
5393
  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->rntiMaybeUEid));
winckel's avatar
winckel committed
5394

5395 5396
  /* Derive the keys from kenb */
  if (DRB_configList != NULL) {
5397
    derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm,
5398 5399
                      ue_context_pP->ue_context.kenb,
                      &kUPenc);
5400 5401
  }

5402
  derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm,
5403 5404
                     ue_context_pP->ue_context.kenb,
                     &kRRCenc);
5405
  derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm,
5406 5407 5408 5409
                     ue_context_pP->ue_context.kenb,
                     &kRRCint);
  /* Refresh SRBs/DRBs */
  rrc_pdcp_config_asn1_req(ctxt_pP,
5410 5411 5412 5413 5414 5415 5416 5417 5418
                           SRB_configList, // NULL,
                           DRB_configList,
                           DRB_Release_configList2,
                           0xff, // already configured during the securitymodecommand
                           kRRCenc,
                           kRRCint,
                           kUPenc,
                           (LTE_PMCH_InfoList_r9_t *) NULL,
                           NULL);
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
5419

5420
  /* Refresh SRBs/DRBs */
Cedric Roux's avatar
Cedric Roux committed
5421 5422 5423 5424 5425 5426 5427 5428
  if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
    rrc_rlc_config_asn1_req(ctxt_pP,
                            SRB_configList, // NULL,
                            DRB_configList,
                            DRB_Release_configList2,
                            (LTE_PMCH_InfoList_r9_t *) NULL,
                            0,
                            0
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
5429
                           );
Cedric Roux's avatar
Cedric Roux committed
5430
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5431

5432
  /* Set the SRB active in UE context */
5433
  if (SRB_configList != NULL) {
5434 5435 5436 5437 5438 5439
    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
5440 5441 5442 5443
        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);
5444
      } else {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5445 5446 5447
        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
5448
              ue_context_pP->ue_context.primaryCC_id,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5449
              SRB_configList->list.array[i]->srb_Identity);
5450 5451
      }
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5452

5453 5454
    free(SRB_configList);
    ue_context_pP->ue_context.SRB_configList2[xid] = NULL;
5455
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5456

5457
  /* Loop through DRBs and establish if necessary */
5458
  if (DRB_configList != NULL) {
5459
    for (int i = 0; i < DRB_configList->list.count; i++) {  // num max DRB (11-3-8)
5460
      if (DRB_configList->list.array[i]) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5461
        drb_id = (int)DRB_configList->list.array[i]->drb_Identity;
5462 5463
        LOG_I(RRC,
              "[eNB %d] Frame  %d : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete from UE rnti %lx, reconfiguring DRB %d/LCID %d\n",
5464 5465
              ctxt_pP->module_id,
              ctxt_pP->frame,
5466
              ctxt_pP->rntiMaybeUEid,
5467 5468
              (int)DRB_configList->list.array[i]->drb_Identity,
              (int)*DRB_configList->list.array[i]->logicalChannelIdentity);
5469
        /* For pre-ci tests */
Laurent OpenCells's avatar
Laurent OpenCells committed
5470
        LOG_I(RRC, "[eNB %d] Frame  %d : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete, reconfiguring DRB %d/LCID %d\n",
5471 5472
              ctxt_pP->module_id,
              ctxt_pP->frame,
5473
              (int)DRB_configList->list.array[i]->drb_Identity,
5474
              (int)*DRB_configList->list.array[i]->logicalChannelIdentity);
5475

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

5481
          if (!EPC_MODE_ENABLED && !ENB_NAS_USE_TUN) {
5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495
            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,
5496
                    (long int)((ue_context_pP->local_uid * LTE_maxDRB) + DRB_configList->list.array[i]->drb_Identity));
Laurent OpenCells's avatar
Laurent OpenCells committed
5497
              ue_module_id = 0; // Was oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid];
5498
              rb_conf_ipv4(0, //add
5499 5500 5501 5502 5503 5504
                           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
5505 5506
              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);
5507 5508
            } /* oip_ifup */
          } /* !EPC_MODE_ENABLED && ENB_NAS_USE_TUN*/
5509

5510
          LOG_D(RRC,
5511 5512
                PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ  (DRB) ---> MAC_eNB\n",
                PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
5513

5514
          if (DRB_configList->list.array[i]->logicalChannelIdentity) {
5515
            DRB2LCHAN[i] = (uint8_t) * DRB_configList->list.array[i]->logicalChannelIdentity;
5516
          }
5517

5518
          if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) {
laurent's avatar
laurent committed
5519 5520 5521 5522 5523 5524 5525 5526 5527
            rrc_mac_config_req_eNB_t tmp = {0};
            tmp.CC_id = ue_context_pP->ue_context.primaryCC_id;
            tmp.rnti = ue_context_pP->ue_context.rnti;
            tmp.physicalConfigDedicated = ue_context_pP->ue_context.physicalConfigDedicated;
            tmp.mac_MainConfig = ue_context_pP->ue_context.mac_MainConfig;
            tmp.logicalChannelIdentity = DRB2LCHAN[i];
            tmp.logicalChannelConfig = DRB_configList->list.array[i]->logicalChannelConfig;
            tmp.measGapConfig = ue_context_pP->ue_context.measGapConfig;
            rrc_mac_config_req_eNB(ctxt_pP->module_id, &tmp);
5528
          }
5529
        } else {        // remove LCHAN from MAC/PHY
5530
          if (DRB_configList->list.array[i]->logicalChannelIdentity) {
5531
            DRB2LCHAN[i] = (uint8_t) * DRB_configList->list.array[i]->logicalChannelIdentity;
5532 5533
          }

5534
          LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ  (DRB) ---> MAC_eNB\n",
5535
                PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
5536

5537
          if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) {
laurent's avatar
laurent committed
5538 5539 5540 5541 5542 5543 5544
            rrc_mac_config_req_eNB_t tmp = {0};
            tmp.CC_id = ue_context_pP->ue_context.primaryCC_id;
            tmp.rnti = ue_context_pP->ue_context.rnti;
            tmp.physicalConfigDedicated = ue_context_pP->ue_context.physicalConfigDedicated;
            tmp.mac_MainConfig = ue_context_pP->ue_context.mac_MainConfig;
            tmp.logicalChannelIdentity = DRB2LCHAN[i];
            rrc_mac_config_req_eNB(ctxt_pP->module_id, &tmp);
5545
          }
5546 5547 5548
        } // 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
5549 5550

    free(DRB_configList);
5551
    ue_context_pP->ue_context.DRB_configList2[xid] = NULL;
5552
  } // end if DRB_configList != NULL
5553

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5554
  if(DRB_Release_configList2 != NULL) {
5555
    for (int i = 0; i < DRB_Release_configList2->list.count; i++) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5556 5557 5558 5559 5560 5561 5562
      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;
        }
5563
      }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5564 5565 5566 5567
    }

    free(DRB_Release_configList2);
    ue_context_pP->ue_context.DRB_Release_configList2[xid] = NULL;
5568
  }
5569 5570 5571 5572 5573 5574 5575 5576 5577

  /* let's request NR capabilities if the UE supports NR
   * maybe not the right place/time to request
   */
  if (ue_context_pP->ue_context.does_nr &&
      !ue_context_pP->ue_context.nr_capabilities_requested) {
    ue_context_pP->ue_context.nr_capabilities_requested = 1;
    rrc_eNB_generate_NR_UECapabilityEnquiry(ctxt_pP, ue_context_pP);
  }
winckel's avatar
winckel committed
5578
}
5579

5580
//-----------------------------------------------------------------------------
5581 5582 5583 5584 5585 5586
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
)
5587
//-----------------------------------------------------------------------------
5588
{
5589
  bool is_mtc = ctxt_pP->brOption;
5590 5591 5592
  LTE_LogicalChannelConfig_t             *SRB1_logicalChannelConfig;  //,*SRB2_logicalChannelConfig;
  LTE_SRB_ToAddModList_t                **SRB_configList;
  LTE_SRB_ToAddMod_t                     *SRB1_config;
5593
  MessageDef                             *message_p;
5594
  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->rntiMaybeUEid));
5595
  eNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
5596
  SRB_configList = &ue_p->SRB_configList;
5597

5598
  if (is_mtc) {
5599
    ue_p->Srb0.Tx_buffer.payload_size =
5600
      do_RRCConnectionSetup_BR(ctxt_pP,
5601 5602 5603 5604 5605 5606 5607 5608
                               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);
  } else {
5609
    ue_p->Srb0.Tx_buffer.payload_size =
5610
      do_RRCConnectionSetup(ctxt_pP,
5611 5612
                            ue_context_pP,
                            CC_id,
5613
                            (uint8_t *) ue_p->Srb0.Tx_buffer.Payload,
5614 5615 5616 5617
                            (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);
5618
  }
5619

5620 5621 5622 5623
  LOG_DUMPMSG(RRC,DEBUG_RRC,
              (char *)(ue_p->Srb0.Tx_buffer.Payload),
              ue_p->Srb0.Tx_buffer.payload_size,
              "[MSG] RRC Connection Setup\n");
5624

5625
  // configure SRB1/SRB2, PhysicalConfigDedicated, MAC_MainConfig for UE
5626
  switch (RC.rrc[ctxt_pP->module_id]->node_type) {
5627 5628 5629
    case ngran_eNB_CU    :
    case ngran_ng_eNB_CU :
    case ngran_gNB_CU    :
5630
    case ngran_gNB_CUCP  :
5631
      // create an ITTI message
5632
      /* TODO: F1 IDs ar missing in RRC */
5633
      message_p = itti_alloc_new_message (TASK_RRC_ENB, 0, F1AP_DL_RRC_MESSAGE);
5634
      F1AP_DL_RRC_MESSAGE (message_p).rrc_container =  (uint8_t *)ue_p->Srb0.Tx_buffer.Payload;
5635
      F1AP_DL_RRC_MESSAGE (message_p).rrc_container_length = ue_p->Srb0.Tx_buffer.payload_size;
5636
      F1AP_DL_RRC_MESSAGE (message_p).gNB_CU_ue_id     = 0;
5637
      F1AP_DL_RRC_MESSAGE (message_p).gNB_DU_ue_id = 0;
5638 5639 5640
      F1AP_DL_RRC_MESSAGE (message_p).old_gNB_DU_ue_id  = 0xFFFFFFFF; // unknown
      F1AP_DL_RRC_MESSAGE (message_p).rnti = ue_p->rnti;
      F1AP_DL_RRC_MESSAGE (message_p).srb_id = CCCH;
5641
      F1AP_DL_RRC_MESSAGE (message_p).execute_duplication      = 1;
5642
      F1AP_DL_RRC_MESSAGE (message_p).RAT_frequency_priority_information.en_dc      = 0;
5643
      itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p);
Bing-Kai Hong's avatar
Bing-Kai Hong committed
5644
      LOG_D(RRC, "Send F1AP_DL_RRC_MESSAGE with ITTI\n");
5645
      break;
5646

5647 5648
    case ngran_eNB_DU    :
    case ngran_gNB_DU  :
5649
      // nothing to do for DU
5650
      AssertFatal(1==0,"nothing to do for DU\n");
5651
      break;
5652 5653

    case ngran_eNB:
5654
    case ngran_ng_eNB :
5655
    case ngran_gNB  :
5656 5657 5658
      if (*SRB_configList != NULL) {
        for (int cnt = 0; cnt < (*SRB_configList)->list.count; cnt++) {
          if ((*SRB_configList)->list.array[cnt]->srb_Identity == 1) {
5659
            SRB1_config = (*SRB_configList)->list.array[cnt];
5660 5661

            if (SRB1_config->logicalChannelConfig) {
5662
              if (SRB1_config->logicalChannelConfig->present ==
5663 5664 5665 5666
                  LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) {
                SRB1_logicalChannelConfig = &SRB1_config->logicalChannelConfig->choice.explicitValue;
              } else {
                SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue;
5667
              }
5668 5669
            } else {
              SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue;
5670 5671 5672 5673 5674
            }

            LOG_D(RRC,
                  PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ  (SRB1) ---> MAC_eNB\n",
                  PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
5675 5676

            if (RC.rrc[ctxt_pP->module_id]->node_type == ngran_eNB) {
laurent's avatar
laurent committed
5677 5678 5679 5680 5681 5682 5683 5684 5685
              rrc_mac_config_req_eNB_t tmp = {0};
              tmp.CC_id = ue_context_pP->ue_context.primaryCC_id;
              tmp.rnti = ue_context_pP->ue_context.rnti;
              tmp.physicalConfigDedicated = ue_context_pP->ue_context.physicalConfigDedicated;
              tmp.mac_MainConfig = ue_context_pP->ue_context.mac_MainConfig;
              tmp.logicalChannelIdentity = 1;
              tmp.logicalChannelConfig = SRB1_logicalChannelConfig;
              tmp.measGapConfig = ue_context_pP->ue_context.measGapConfig;
              rrc_mac_config_req_eNB(ctxt_pP->module_id, &tmp);
5686 5687 5688 5689
              break;
            }
          }
        }
5690

5691
        break;
5692

5693 5694 5695
      default :
        LOG_W(RRC, "Unknown node type %d\n", RC.rrc[ctxt_pP->module_id]->node_type);
      }
5696

5697 5698 5699 5700 5701 5702 5703 5704 5705 5706
      LOG_I(RRC,
            PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCConnectionSetup (bytes %d)\n",
            PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
            ue_p->Srb0.Tx_buffer.payload_size);
      // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE
      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;
5707
  }
winckel's avatar
winckel committed
5708
}
5709

Cedric Roux's avatar
Cedric Roux committed
5710 5711 5712 5713 5714 5715 5716
//-----------------------------------------------------------------------------
void rrc_eNB_process_reconfiguration_complete_endc(const protocol_ctxt_t *const ctxt_pP,
        rrc_eNB_ue_context_t *const ue_context_p)
//-----------------------------------------------------------------------------
{
  MessageDef *msg_p;

5717
  msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, X2AP_ENDC_SGNB_RECONF_COMPLETE);
Cedric Roux's avatar
Cedric Roux committed
5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735

  /* MeNB_ue_x2_id is unknown, set to 0.
   * This is not correct but X2 id in the eNB is only 12 bits,
   * so unfortunately we can't use rnti.
   * To be corrected if needed.
   * As of today, when stopping t_dc_prep we remove the UE
   * from X2. To keep the id until the 'reconfiguration complete' message is received
   * needs a rethink/rewrite of this logic. For simplicity, let's
   * keep it as is. The only problem we can get is if/when we
   * interoperate with a non-OAI gNB. The OAI gNB does not
   * care about MeNB_ue_x2_id.
   */
  X2AP_ENDC_SGNB_RECONF_COMPLETE(msg_p).MeNB_ue_x2_id   = 0;
  X2AP_ENDC_SGNB_RECONF_COMPLETE(msg_p).SgNB_ue_x2_id   = ue_context_p->ue_context.gnb_rnti;
  X2AP_ENDC_SGNB_RECONF_COMPLETE(msg_p).gnb_x2_assoc_id = ue_context_p->ue_context.gnb_x2_assoc_id;
  itti_send_msg_to_task (TASK_X2AP, ctxt_pP->instance, msg_p);
}

5736 5737
void setup_ngran_CU(eNB_RRC_INST *rrc) {
}
Lionel Gauthier's avatar
 
Lionel Gauthier committed
5738

5739
//-----------------------------------------------------------------------------
5740
char openair_rrc_eNB_configuration(
5741 5742
  const module_id_t enb_mod_idP,
  RrcConfigurationReq *configuration
5743 5744
)
//-----------------------------------------------------------------------------
winckel's avatar
winckel committed
5745
{
5746
  protocol_ctxt_t ctxt;
5747
  int             CC_id;
5748
  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, enb_mod_idP, ENB_FLAG_YES, NOT_A_RNTI, 0, 0,enb_mod_idP);
5749 5750 5751
  LOG_I(RRC,
        PROTOCOL_RRC_CTXT_FMT" Init...\n",
        PROTOCOL_RRC_CTXT_ARGS(&ctxt));
5752
  AssertFatal(RC.rrc[enb_mod_idP] != NULL, "RC.rrc not initialized!");
5753
  AssertFatal(MAX_MOBILES_PER_ENB < (module_id_t)0xFFFFFFFFFFFFFFFF, " variable overflow");
5754
  AssertFatal(configuration!=NULL,"configuration input is null\n");
5755
  RC.rrc[ctxt.module_id]->Nb_ue = 0;
5756 5757
  pthread_mutex_init(&RC.rrc[ctxt.module_id]->cell_info_mutex,NULL);
  RC.rrc[ctxt.module_id]->cell_info_configured = 0;
5758 5759
  uid_linear_allocator_init(&RC.rrc[ctxt.module_id]->uid_allocator);
  RB_INIT(&RC.rrc[ctxt.module_id]->rrc_ue_head);
5760
  //    for (j = 0; j < (MAX_MOBILES_PER_ENB + 1); j++) {
5761
  //        RC.rrc[enb_mod_idP]->Srb2[j].Active = 0;
5762
  //    }
5763 5764
  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);
5765
  /// System Information INIT
5766 5767
  LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Checking release \n",
        PROTOCOL_RRC_CTXT_ARGS(&ctxt));
5768 5769
  // can clear it at runtime
  RC.rrc[ctxt.module_id]->carrier[0].MBMS_flag = 0;
5770
  // This has to come from some top-level configuration
5771
  // only CC_id 0 is logged
Cedric Roux's avatar
Cedric Roux committed
5772
  LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Rel14 RRC detected, MBMS flag %d\n",
5773
        PROTOCOL_RRC_CTXT_ARGS(&ctxt),
5774
        RC.rrc[ctxt.module_id]->carrier[0].MBMS_flag);
5775

5776
  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
5777
    init_SI(&ctxt, CC_id, configuration);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5778

5779
    for (int ue_id = 0; ue_id < MAX_MOBILES_PER_ENB; ue_id++) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5780 5781
      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);
5782
    }
5783
  }
5784

5785 5786
  rrc_init_global_param();

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5787
  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
5788
    switch (RC.rrc[ctxt.module_id]->carrier[CC_id].MBMS_flag) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5789 5790 5791 5792 5793 5794
      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;
5795

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5796 5797 5798 5799
      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;
5800

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5801 5802 5803
      default:
        RC.rrc[ctxt.module_id]->carrier[CC_id].num_mbsfn_sync_area = 0;
        break;
5804 5805
    }

5806
    // if we are here the RC.rrc[enb_mod_idP]->MBMS_flag > 0,
5807
    /// MCCH INIT
5808
    if (RC.rrc[ctxt.module_id]->carrier[CC_id].MBMS_flag > 0) {
5809 5810 5811 5812
      init_MCCH(ctxt.module_id, CC_id);
      /// MTCH data bearer init
      init_MBMS(ctxt.module_id, CC_id, 0);
    }
5813

5814 5815
    openair_rrc_top_init_eNB(RC.rrc[ctxt.module_id]->carrier[CC_id].MBMS_flag,0);
  }
5816

5817 5818
  RC.rrc[ctxt.module_id]->nr_scg_ssb_freq = configuration->nr_scg_ssb_freq;

5819
  openair_rrc_on(&ctxt);
5820

5821 5822 5823 5824 5825
  /*
    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;
5826

5827 5828
    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);
    */
5829
  if (NODE_IS_CU(RC.rrc[ctxt.module_id]->node_type))
5830
    // msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, F1AP_SCTP_REQ);
5831
    // RCconfig_CU_F1(msg_p, enb_id);
5832
    setup_ngran_CU(RC.rrc[ctxt.module_id]);
5833

5834
  return 0;
winckel's avatar
winckel committed
5835
}
5836

5837
static
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
5838 5839
void rrc_eNB_generate_RRCConnectionReestablishmentReject_unknown_UE(protocol_ctxt_t *const ctxt_pP,
    const int CC_id) {
5840
  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP, ctxt_pP->rntiMaybeUEid);
5841 5842 5843 5844 5845 5846
  rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP,
      ue_context_p,
      CC_id);
  ue_context_p->ue_context.ul_failure_timer = 500;  // 500 milliseconds to send the message and remove temporary entry
}

winckel's avatar
winckel committed
5847
/*------------------------------------------------------------------------------*/
5848 5849
int
rrc_eNB_decode_ccch(
5850
  protocol_ctxt_t *const ctxt_pP,
Robert Schmidt's avatar
Robert Schmidt committed
5851
  const uint8_t          *buffer,
5852
  int                    buffer_length,
5853
  const int              CC_id
5854 5855
)
//-----------------------------------------------------------------------------
5856
{
5857 5858 5859
  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
5860 5861
  LTE_RRCConnectionRequest_r8_IEs_t                *rrcConnectionRequest = NULL;
  LTE_RRCConnectionReestablishmentRequest_r8_IEs_t *rrcConnectionReestablishmentRequest = NULL;
5862
  int                                 i, rval;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5863
  struct rrc_eNB_ue_context_s                  *ue_context_p = NULL;
5864
  uint64_t                                      random_value = 0;
5865
  int                                           stmsi_received = 0;
5866
  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->rntiMaybeUEid));
5867
  //memset(ul_ccch_msg,0,sizeof(UL_CCCH_Message_t));
5868
  LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Decoding UL CCCH %x.%x.%x.%x.%x.%x (%p)\n",
5869
        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
5870
        ((uint8_t *) buffer)[0],
5871 5872 5873 5874 5875
        ((uint8_t *) buffer)[1],
        ((uint8_t *) buffer)[2],
        ((uint8_t *) buffer)[3],
        ((uint8_t *) buffer)[4],
        ((uint8_t *) buffer)[5], (uint8_t *) buffer);
5876 5877
  dec_rval = uper_decode(
               NULL,
5878
               &asn_DEF_LTE_UL_CCCH_Message,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5879
               (void **)&ul_ccch_msg,
5880
               (uint8_t *) buffer,
5881 5882 5883
               100,
               0,
               0);
5884

5885
  for (i = 0; i < 8; i++) {
5886
    LOG_T(RRC, "%x.", ((uint8_t *) & ul_ccch_msg)[i]);
5887
  }
5888 5889

  if (dec_rval.consumed == 0) {
5890 5891 5892
    LOG_E(RRC,
          PROTOCOL_RRC_CTXT_UE_FMT" FATAL Error in receiving CCCH\n",
          PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
5893 5894 5895
    return -1;
  }

5896
  if (ul_ccch_msg->message.present == LTE_UL_CCCH_MessageType_PR_c1) {
5897
    switch (ul_ccch_msg->message.choice.c1.present) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5898 5899 5900 5901 5902
      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
5903

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5904
      case LTE_UL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentRequest:
5905
        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->rntiMaybeUEid));
5906
        LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)(buffer), buffer_length,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920
                    "[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
5921

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5922
          if (rrcConnectionReestablishmentRequest->ue_Identity.physCellId != RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId) {
5923
            /* UE was moving from previous cell so quickly that RRCConnectionReestablishment for previous cell was recieved in this cell */
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5924 5925 5926 5927 5928
            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);
5929 5930
            rrc_eNB_generate_RRCConnectionReestablishmentReject_unknown_UE(ctxt_pP,
                CC_id);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5931 5932
            break;
          }
5933

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

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5936 5937 5938 5939
          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]);
          }
5940

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5941 5942
          if (rrcConnectionReestablishmentRequest->ue_Identity.c_RNTI.size == 0 ||
              rrcConnectionReestablishmentRequest->ue_Identity.c_RNTI.size > 2) {
5943
            /* c_RNTI range error should not happen */
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5944 5945 5946
            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));
5947 5948
            rrc_eNB_generate_RRCConnectionReestablishmentReject_unknown_UE(ctxt_pP,
                CC_id);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5949 5950
            break;
          }
5951

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5952
          c_rnti = BIT_STRING_to_uint16(&rrcConnectionReestablishmentRequest->ue_Identity.c_RNTI);
laurent's avatar
laurent committed
5953
          LOG_I(RRC, "reestablishment, previous c_rnti is %x (new is %lx)\n", c_rnti, ctxt_pP->rntiMaybeUEid);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5954
          ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt_pP->module_id], c_rnti);
5955

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5956 5957 5958 5959
          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));
5960 5961
            rrc_eNB_generate_RRCConnectionReestablishmentReject_unknown_UE(ctxt_pP,
                CC_id);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5962 5963
            break;
          }
5964

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

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5967 5968 5969 5970 5971 5972 5973
          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;
          }
5974

5975 5976
          if((RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer > 0) &&
              (RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres > 20)) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5977
            LOG_E(RRC,
5978
                  PROTOCOL_RRC_CTXT_UE_FMT" RCConnectionReestablishmentComplete(Previous) don't receive, delete the c-rnti UE\n",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
5979
                  PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
5980
            RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1000;
5981 5982 5983
            rrc_eNB_previous_SRB2(ue_context_p);
            ue_context_p->ue_context.ue_reestablishment_timer = 0;
          }
5984

5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005
          //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;
            }

6006 6007
            if((RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer > 0) &&
                (RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres > 20)) {
6008
              LOG_E(RRC,
6009
                    PROTOCOL_RRC_CTXT_UE_FMT " RCConnectionReestablishmentComplete not received, but we get a new RRCConnectionReestablishmentRequest, we delete the Previous UE\n",
6010
                    PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
6011
              RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1000;
6012 6013 6014 6015 6016 6017
              rrc_eNB_previous_SRB2(ue_context_p);
              ue_context_p->ue_context.ue_reestablishment_timer = 0;
            }
          }

          //c-plane not end
6018
          if((ue_context_p->ue_context.StatusRrc != RRC_RECONFIGURED) && (ue_context_p->ue_context.reestablishment_cause == LTE_ReestablishmentCause_spare1)) {
6019 6020 6021 6022 6023 6024
            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;
          }
6025

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6026 6027
          if(ue_context_p->ue_context.ue_reestablishment_timer > 0) {
            LOG_E(RRC,
6028
                  PROTOCOL_RRC_CTXT_UE_FMT " RRRCConnectionReconfigurationComplete not received, delete the Previous UE,\nprevious Status %d, new Status RRC_RECONFIGURED\n",
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
6029
                  PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
6030
                  ue_context_p->ue_context.StatusRrc);
6031
            ue_context_p->ue_context.StatusRrc = RRC_RECONFIGURED;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6032 6033 6034 6035 6036 6037 6038 6039 6040 6041
            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);
6042

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6043 6044 6045 6046 6047 6048
            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;
              }
6049 6050
            }
          }
6051

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066
          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) {
6067
              reestablish_rnti_map[i][0] = ctxt_pP->rntiMaybeUEid;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6068
              reestablish_rnti_map[i][1] = c_rnti;
6069 6070
              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
6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114
              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);
          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);
          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);
6115

6116
          if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
6117 6118 6119 6120 6121 6122 6123
            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
                                   );
6124 6125
          }

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6126 6127
        }
        break;
Cedric Roux's avatar
Cedric Roux committed
6128

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6129
      case LTE_UL_CCCH_MessageType__c1_PR_rrcConnectionRequest:
6130
        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->rntiMaybeUEid));
6131 6132
        LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,
                    buffer_length,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6133 6134 6135 6136
                    "[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));
6137
        ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid);
6138

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150
        if (ue_context_p != NULL) {
          // erase content
          rrc_eNB_free_mem_UE_context(ctxt_pP, ue_context_p);
        } 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;
              }
6151

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6152 6153 6154 6155 6156 6157 6158 6159
              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))) {
6160 6161 6162 6163 6164
                LOG_W(RRC,
                      "new UE rnti %lx (coming with random value) is already there as UE %x, removing %x from MAC/PHY\n",
                      ctxt_pP->rntiMaybeUEid,
                      ue_context_p->ue_context.rnti,
                      ue_context_p->ue_context.rnti);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6165 6166
                ue_context_p->ue_context.ul_failure_timer = 20000;
              }
6167

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6168
              ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP, random_value);
6169 6170 6171 6172 6173 6174
              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;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6175 6176 6177 6178 6179 6180 6181 6182
            } 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))) {
6183
                LOG_I(RRC, " S-TMSI exists, ue_context_p %p, old rnti %x => %lx\n", ue_context_p, ue_context_p->ue_context.rnti, ctxt_pP->rntiMaybeUEid);
6184

6185
                if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
laurent's avatar
laurent committed
6186
		  LOG_I(PHY, "remove RNTI %04x\n", ue_context_p->ue_context.rnti);
6187
                  rrc_mac_remove_ue(ctxt_pP->module_id, ue_context_p->ue_context.rnti);
6188
                } else {
6189
                  MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, 0, F1AP_UE_CONTEXT_RELEASE_CMD);
6190
                  F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = ctxt_pP->rntiMaybeUEid;
6191 6192 6193 6194 6195 6196
                  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);
                }
6197

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6198 6199 6200 6201 6202
                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 */
6203 6204
                ue_context_p->ue_id_rnti = ctxt_pP->rntiMaybeUEid;
                ue_context_p->ue_context.rnti = ctxt_pP->rntiMaybeUEid;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6205 6206 6207 6208 6209 6210 6211 6212
                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;
6213
              } else {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6214 6215 6216 6217 6218 6219 6220 6221
                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) {
6222
                  ue_context_p->ue_context.Initialue_identity_s_TMSI.presence = true;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6223 6224 6225 6226 6227 6228
                  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;
                }
6229
              }
gauthier's avatar
gauthier committed
6230

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6231 6232 6233 6234
            } 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));
6235
              rrc_eNB_generate_RRCConnectionReject(ctxt_pP, rrc_eNB_get_ue_context(RC.rrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid), CC_id);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6236 6237
              break;
            }
6238
          }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6239 6240 6241 6242
          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
6243

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6244 6245 6246
          if (ue_context_p != NULL) {
            ue_context_p->ue_context.establishment_cause = rrcConnectionRequest->establishmentCause;
            ue_context_p->ue_context.reestablishment_cause = LTE_ReestablishmentCause_spare1;
6247

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260
            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);
6261

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6262 6263 6264 6265 6266 6267 6268
            if (stmsi_received == 0)
              RC.rrc[ctxt_pP->module_id]->Nb_ue++;
          } else {
            // no context available
            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);
6269

6270
            if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type))
6271
              rrc_mac_remove_ue(ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid);
6272
            else if (NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
6273
              MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, 0, F1AP_UE_CONTEXT_RELEASE_CMD);
6274
              F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = ctxt_pP->rntiMaybeUEid;
6275 6276 6277 6278 6279 6280
              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);
            }
6281

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6282 6283
            return -1;
          }
6284
        }
6285

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317
        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);
        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,
6318 6319
                                 NULL,
                                 (LTE_PMCH_InfoList_r9_t *) NULL,NULL);
6320

6321
        if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
6322 6323 6324
          rrc_rlc_config_asn1_req(ctxt_pP,
                                  ue_context_p->ue_context.SRB_configList,
                                  (LTE_DRB_ToAddModList_t *) NULL,
6325 6326
                                  (LTE_DRB_ToReleaseList_t *) NULL,
                                  (LTE_PMCH_InfoList_r9_t *) NULL, 0, 0
6327 6328
                                 );
        }
6329

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6330
        break;
6331

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6332 6333 6334 6335 6336
      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
6337
    }
6338 6339 6340

    rval = 0;
  } else {
6341 6342
    LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT"  Unknown error \n",
          PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
6343 6344 6345 6346
    rval = -1;
  }

  return rval;
6347 6348
}

Raymond Knopp's avatar
Raymond Knopp committed
6349 6350
#define NCE nonCriticalExtension

6351
static void
Raymond Knopp's avatar
Raymond Knopp committed
6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386
get_ue_Category(
  LTE_UE_EUTRA_Capability_t *c,
  long *catDL,
  long *catUL
)
{
  if (c != NULL) { // v8.6
     *catDL=c->ue_Category; *catUL=c->ue_Category;
     struct LTE_UE_EUTRA_Capability_v920_IEs *c92=c->NCE;
     if (c92 != NULL) { // v9.2
        struct LTE_UE_EUTRA_Capability_v940_IEs *c94=c92->NCE;
        if (c94 != NULL) { // v9.4
           struct LTE_UE_EUTRA_Capability_v1020_IEs *c102=c94->NCE;
           if (c102 != NULL) { // v10.2
              if (c102->ue_Category_v1020) {*catDL=*c102->ue_Category_v1020;*catUL=*c102->ue_Category_v1020;}
              struct LTE_UE_EUTRA_Capability_v1060_IEs *c106=c102->NCE;
                 if (c106 != NULL) { // v10.6
                    struct LTE_UE_EUTRA_Capability_v1090_IEs *c109=c106->NCE;
                    if (c109 != NULL) { // v10.9
                       struct LTE_UE_EUTRA_Capability_v1130_IEs *c113=c109->NCE;
                       if (c113 != NULL) { // v11.3
                          struct LTE_UE_EUTRA_Capability_v1170_IEs *c117=c113->NCE;
                          if (c117 != NULL) { // v11.7
                             if (c117->ue_Category_v1170) {*catDL=*c117->ue_Category_v1170;
                             struct LTE_UE_EUTRA_Capability_v1180_IEs *c118=c117->NCE;
                             if (c118 != NULL) { // v11.8
                                struct LTE_UE_EUTRA_Capability_v11a0_IEs *c11a=c118->NCE;
                                if (c11a != NULL) { // v11.a
                                   if (c11a->ue_Category_v11a0) {*catDL=*c11a->ue_Category_v11a0;*catUL=*c11a->ue_Category_v11a0;}
                                   struct LTE_UE_EUTRA_Capability_v1250_IEs *c125=c11a->NCE;
                                   if (c125 != NULL) { // v12.5
                                      if (c125->ue_CategoryDL_r12) *catDL=*c125->ue_CategoryDL_r12;
                                      if (c125->ue_CategoryUL_r12) *catUL=*c125->ue_CategoryUL_r12;
                                      struct LTE_UE_EUTRA_Capability_v1260_IEs *c126=c125->NCE;
                                      if (c126 != NULL) { // v12.6
6387
                                         if (c126->ue_CategoryDL_v1260) *catDL=*c126->ue_CategoryDL_v1260;
Raymond Knopp's avatar
Raymond Knopp committed
6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415
                                         struct LTE_UE_EUTRA_Capability_v1270_IEs *c127=c126->NCE;
                                         if (c127 != NULL) { // v12.7
                                            struct LTE_UE_EUTRA_Capability_v1280_IEs *c128=c127->NCE;
                                            if (c128 != NULL) { // v12.8
                                               struct LTE_UE_EUTRA_Capability_v1310_IEs *c131=c128->NCE;
                                               if (c131 != NULL) { // v13.1
                                                  if (c131->ue_CategoryDL_v1310 && *c131->ue_CategoryDL_v1310 == 0) *catDL=17;
                                                  if (c131->ue_CategoryDL_v1310 && *c131->ue_CategoryDL_v1310 == 1) *catDL=-1;
                                                  if (c131->ue_CategoryUL_v1310 && *c131->ue_CategoryUL_v1310 == 0) *catUL=14;
                                                  if (c131->ue_CategoryUL_v1310 && *c131->ue_CategoryUL_v1310 == 1) *catUL=-1;
                                                  struct LTE_UE_EUTRA_Capability_v1320_IEs *c132=c131->NCE;
                                                  if (c132 != NULL) { //v13.2
                                                     struct LTE_UE_EUTRA_Capability_v1330_IEs *c133=c132->NCE;
                                                     if (c133 != NULL) { // v13.3
                                                        if (c133->ue_CategoryDL_v1330) *catDL=*c133->ue_CategoryDL_v1330;
                                                        struct LTE_UE_EUTRA_Capability_v1340_IEs *c134=c133->NCE;
                                                        if (c134 != NULL) { // v13.4
                                                           if (c134->ue_CategoryUL_v1340) *catUL=*c134->ue_CategoryUL_v1340;
                                                           struct LTE_UE_EUTRA_Capability_v1350_IEs *c135=c134->NCE;
                                                           if (c135 != NULL) { // v13.5
                                                              if (c135->ue_CategoryDL_v1350) *catDL=99; // Cat 1Bis
                                                              if (c135->ue_CategoryUL_v1350) *catUL=99; // Cat 1Bis
                                                              struct LTE_UE_EUTRA_Capability_v1360_IEs *c136=c135->NCE;
                                                              if (c136 != NULL) { // v13.6
                                                                 struct LTE_UE_EUTRA_Capability_v1430_IEs *c143=c136->NCE;
                                                                 if (c143 != NULL) { // v14.3
                                                                    if (c143->ue_CategoryDL_v1430 && *c143->ue_CategoryDL_v1430 == LTE_UE_EUTRA_Capability_v1430_IEs__ue_CategoryDL_v1430_m2) *catDL=-2;
                                                                    if (c143->ue_CategoryUL_v1430 && *c143->ue_CategoryUL_v1430 == LTE_UE_EUTRA_Capability_v1430_IEs__ue_CategoryDL_v1430_m2) *catUL=-2;
Raymond Knopp's avatar
Raymond Knopp committed
6416
                                                                    if (c143->ue_CategoryUL_v1430) *catUL=16+*c143->ue_CategoryUL_v1430;
Raymond Knopp's avatar
Raymond Knopp committed
6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476
                                                                    if (c143->ue_CategoryUL_v1430b)*catUL=21;
                                                                    struct LTE_UE_EUTRA_Capability_v1440_IEs *c144=c143->NCE;
                                                                    if (c144 != NULL) { // v14.4
                                                                       struct LTE_UE_EUTRA_Capability_v1450_IEs *c145=c144->NCE;
                                                                       if (c145 != NULL) { // v14.5
                                                                          if (c145->ue_CategoryDL_v1450) *catDL=*c145->ue_CategoryDL_v1450;
                                                                          struct LTE_UE_EUTRA_Capability_v1460_IEs *c146=c145->NCE;
                                                                          if (c146 != NULL) { // v14.6
                                                                             if (c146->ue_CategoryDL_v1460) *catDL=*c146->ue_CategoryDL_v1460;
                                                                             struct LTE_UE_EUTRA_Capability_v1510_IEs *c151=c146->NCE;
                                                                             if (c151 != NULL) { // v15.1
                                                                                struct LTE_UE_EUTRA_Capability_v1520_IEs *c152=c151->NCE;
                                                                                if (c152 != NULL) { // v15.20
                                                                                   struct LTE_UE_EUTRA_Capability_v1530_IEs *c153=c152->NCE;
                                                                                   if (c153 != NULL) { // v15.30
                                                                                      if (c153->ue_CategoryDL_v1530) *catDL=*c153->ue_CategoryDL_v1530;
                                                                                      if (c153->ue_CategoryUL_v1530) *catUL=*c153->ue_CategoryUL_v1530;
                                                                                   }
                                                                                }
                                                                             }
                                                                          }
                                                                       }
                                                                    }
                                                                 }
                                                              }
                                                           }
                                                        }
                                                     }
                                                  }
                                               }
                                            }
                                         }
                                      }
                                   }
                                }
                             }
                          }
                       }
                    }
                 }
              }
           }
        }
     }
  }
}

static int
is_ul_64QAM_supported(
  LTE_UE_EUTRA_Capability_t *c
)
//-----------------------------------------------------------------------------
{
  return c != NULL  // R8
         && c->NCE != NULL // R92
         && c->NCE->NCE != NULL // R94
         && c->NCE->NCE->NCE != NULL // R102
         && c->NCE->NCE->NCE->NCE != NULL // R106
         && c->NCE->NCE->NCE->NCE->NCE != NULL // R109
         && c->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R113
6477
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R117
Raymond Knopp's avatar
Raymond Knopp committed
6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R118
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R11a
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R125
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1250 != NULL
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1250->supportedBandListEUTRA_v1250 != NULL
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1250->supportedBandListEUTRA_v1250->list.array != NULL
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1250->supportedBandListEUTRA_v1250->list.array[0]->ul_64QAM_r12 != NULL
         && *c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1250->supportedBandListEUTRA_v1250->list.array[0]->ul_64QAM_r12==LTE_SupportedBandEUTRA_v1250__ul_64QAM_r12_supported;
}

static int
is_dl_256QAM_supported(
  LTE_UE_EUTRA_Capability_t *c
)
6492
//-----------------------------------------------------------------------------
Raymond Knopp's avatar
Raymond Knopp committed
6493 6494 6495 6496 6497 6498 6499 6500
{
  return c != NULL  // R8
         && c->NCE != NULL // R92
         && c->NCE->NCE != NULL // R94
         && c->NCE->NCE->NCE != NULL // R102
         && c->NCE->NCE->NCE->NCE != NULL // R106
         && c->NCE->NCE->NCE->NCE->NCE != NULL // R109
         && c->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R113
6501
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R117
Raymond Knopp's avatar
Raymond Knopp committed
6502 6503 6504
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R118
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R11a
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R125
6505
	 && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1250 != NULL
Raymond Knopp's avatar
Raymond Knopp committed
6506 6507 6508 6509 6510 6511 6512 6513 6514
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1250->supportedBandListEUTRA_v1250 != NULL
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1250->supportedBandListEUTRA_v1250->list.array != NULL
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1250->supportedBandListEUTRA_v1250->list.array[0]->dl_256QAM_r12 != NULL
         && *c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1250->supportedBandListEUTRA_v1250->list.array[0]->dl_256QAM_r12==LTE_SupportedBandEUTRA_v1250__dl_256QAM_r12_supported;

}
static int
is_ul_256QAM_supported(
  LTE_UE_EUTRA_Capability_t *c
6515
)
6516
//-----------------------------------------------------------------------------
Raymond Knopp's avatar
Raymond Knopp committed
6517 6518 6519 6520 6521 6522 6523 6524
{
  return c != NULL  // R8
         && c->NCE != NULL // R92
         && c->NCE->NCE != NULL // R94
         && c->NCE->NCE->NCE != NULL // R102
         && c->NCE->NCE->NCE->NCE != NULL // R106
         && c->NCE->NCE->NCE->NCE->NCE != NULL // R109
         && c->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R113
6525
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R117
Raymond Knopp's avatar
Raymond Knopp committed
6526 6527 6528 6529 6530 6531
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R118
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R11a
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R125
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R126
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // 127
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // 128
6532
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //131
Raymond Knopp's avatar
Raymond Knopp committed
6533 6534 6535 6536 6537 6538 6539 6540
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //132
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //133
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //134
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //135
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //136
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //143
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1430 != NULL
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1430->supportedBandCombination_v1430 != NULL
6541
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1430->supportedBandCombination_v1430->list.array != NULL
Raymond Knopp's avatar
Raymond Knopp committed
6542 6543 6544 6545 6546 6547
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1430->supportedBandCombination_v1430->list.array[0]->bandParameterList_v1430 != NULL
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1430->supportedBandCombination_v1430->list.array[0]->bandParameterList_v1430->list.array != NULL
         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1430->supportedBandCombination_v1430->list.array[0]->bandParameterList_v1430->list.array[0]->ul_256QAM_r14!=NULL
         && *c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1430->supportedBandCombination_v1430->list.array[0]->bandParameterList_v1430->list.array[0]->ul_256QAM_r14==LTE_BandParameters_v1430__ul_256QAM_r14_supported;
}

6548 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564
int to_nr_rsrpq(long rsrpq_result,int nr_band) {

    switch(nr_band) {
      case 1:  // A
      case 70:
      case 74:
      case 34:
      case 38:
      case 39:
      case 40:
      case 50:
      case 51:
       return((rsrpq_result*10)-1180);
      case 66:  // B
       return((rsrpq_result*10)-1175);
      case 77:  // C
      case 78:
6565
      case 79:
6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586
       return((rsrpq_result*10)-1170);
      case 28:  // D
       return((rsrpq_result*10)-1165);
      case 2:
      case 5:
      case 7:
      case 41:  // E
       return((rsrpq_result*10)-1160);
      case 3:   // G
      case 8:
      case 12:
      case 20:
      case 71:
       return((rsrpq_result*10)-1150);
      case 25:  // H
       return((rsrpq_result*10)-1145);
      default:
       AssertFatal(1==0,"Illegal NR band %d\n",nr_band);
    }
}

6587 6588 6589
//-----------------------------------------------------------------------------
int
rrc_eNB_decode_dcch(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6590
  const protocol_ctxt_t *const ctxt_pP,
6591
  const rb_id_t                Srb_id,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6592
  const uint8_t    *const      Rx_sdu,
6593 6594 6595
  const sdu_size_t             sdu_sizeP
)
//-----------------------------------------------------------------------------
6596 6597 6598
{
  asn_dec_rval_t                      dec_rval;
  //UL_DCCH_Message_t uldcchmsg;
6599
  LTE_UL_DCCH_Message_t               *ul_dcch_msg = NULL; //&uldcchmsg;
6600
  int i;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6601
  struct rrc_eNB_ue_context_s        *ue_context_p = NULL;
6602
  uint8_t                             xid;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6603
  int dedicated_DRB=0;
6604
  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->rntiMaybeUEid));
Cedric Roux's avatar
Cedric Roux committed
6605

6606
  if ((Srb_id != 1) && (Srb_id != 2)) {
laurent's avatar
laurent committed
6607
    LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Received message on SRB%ld, should not have ...\n",
6608 6609
          PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
          Srb_id);
6610
  } else {
laurent's avatar
laurent committed
6611
    LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Received message on SRB%ld\n",
6612 6613
          PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
          Srb_id);
6614
  }
6615

6616 6617 6618 6619
  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,
6620
               &asn_DEF_LTE_UL_DCCH_Message,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6621
               (void **)&ul_dcch_msg,
6622 6623 6624 6625
               Rx_sdu,
               sdu_sizeP,
               0,
               0);
6626
  {
6627
    for (i = 0; i < sdu_sizeP; i++) {
6628
      LOG_T(RRC, "%x.", Rx_sdu[i]);
6629
    }
winckel's avatar
winckel committed
6630

6631 6632 6633 6634
    LOG_T(RRC, "\n");
  }

  if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
Cedric Roux's avatar
Cedric Roux committed
6635
    LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Failed to decode UL-DCCH (%zu bytes)\n",
6636 6637
          PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
          dec_rval.consumed);
6638 6639
    return -1;
  }
6640

6641
  ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
6642

6643
  if (ul_dcch_msg->message.present == LTE_UL_DCCH_MessageType_PR_c1) {
6644
    switch (ul_dcch_msg->message.choice.c1.present) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6645
      case LTE_UL_DCCH_MessageType__c1_PR_NOTHING:   /* No components present */
6646
        break;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
6647

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6648
      case LTE_UL_DCCH_MessageType__c1_PR_csfbParametersRequestCDMA2000:
6649
        break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6650 6651 6652 6653 6654

      case LTE_UL_DCCH_MessageType__c1_PR_measurementReport:

        // to avoid segmentation fault
        if(!ue_context_p) {
6655
          LOG_I(RRC, "Processing measurementReport UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6656 6657 6658 6659 6660 6661 6662 6663 6664 6665
          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(
6666 6667
          ctxt_pP,
          ue_context_p,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6668 6669 6670 6671 6672 6673 6674 6675
          &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) {
6676
          LOG_I(RRC, "Processing LTE_RRCConnectionReconfigurationComplete UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 6693
          break;
        }

        LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)(Rx_sdu),sdu_sizeP,
                    "[MSG] RRC Connection Reconfiguration Complete\n");
        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.*/
6694

6695
          if (EPC_MODE_ENABLED || get_softmodem_params()->emulate_l1) {
6696
            if (ue_context_p->ue_context.StatusRrc == RRC_RECONFIGURED) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6697 6698 6699 6700 6701
              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
6702
              int16_t UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6703 6704

              if(UE_id == -1) {
6705
                LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT " RRCConnectionReconfigurationComplete without rnti %lx, fault\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), ctxt_pP->rntiMaybeUEid);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6706 6707 6708
                break;
              }

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

6712
              if(RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag == 1) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6713 6714 6715 6716
                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;
6717
                RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6718
              }
6719
            } else if (ue_context_p->ue_context.StatusRrc == RRC_HO_EXECUTION) {
6720
              int16_t UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid);
Cedric Roux's avatar
Cedric Roux committed
6721 6722

              if(UE_id == -1) {
6723
                LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT " RRCConnectionReconfigurationComplete without rnti %lx, fault\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), ctxt_pP->rntiMaybeUEid);
Cedric Roux's avatar
Cedric Roux committed
6724 6725 6726
                break;
              }

6727
              RC.rrc[ctxt_pP->module_id]->Nb_ue++;
Cedric Roux's avatar
Cedric Roux committed
6728
              dedicated_DRB = 3;
6729
              RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0;
6730
              ue_context_p->ue_context.StatusRrc = RRC_RECONFIGURED;
6731 6732 6733 6734 6735

              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
6736 6737 6738
              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);
6739
            } else if(ue_context_p->ue_context.StatusRrc == RRC_NR_NSA) {
6740 6741
              //Looking for a condition to trigger S1AP E-RAB-Modification-indication, based on the reception of RRCConnectionReconfigurationComplete
              //including NR specific elements.
6742
              if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
6743
                  nonCriticalExtension!=NULL) {
6744
                if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
6745
                    nonCriticalExtension->nonCriticalExtension!=NULL) {
6746
                  if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
6747
                      nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL) {
6748
                    if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
6749 6750 6751 6752 6753 6754 6755 6756
                        nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL) {
                      if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
                          nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL) {
                        if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
                            nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL) {
                          if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
                              nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension
                              ->scg_ConfigResponseNR_r15!=NULL) {
6757
                            dedicated_DRB = -1;     /* put a value that does not run anything below */
6758
                            ue_context_p->ue_context.StatusRrc = RRC_NR_NSA_RECONFIGURED;
6759 6760
                            /*Trigger E-RAB Modification Indication */
                            rrc_eNB_send_E_RAB_Modification_Indication(ctxt_pP, ue_context_p);
Cedric Roux's avatar
Cedric Roux committed
6761 6762
                            /* send reconfiguration complete to gNB */
                            rrc_eNB_process_reconfiguration_complete_endc(ctxt_pP, ue_context_p);
6763
                            LOG_A(RRC, "Sent rrcReconfigurationComplete to gNB\n");
6764
                          }
6765 6766 6767 6768 6769 6770
                        }
                      }
                    }
                  }
                }
              }
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
6771
            } else {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6772
              dedicated_DRB = 0;
6773
              ue_context_p->ue_context.StatusRrc = RRC_RECONFIGURED;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6774 6775 6776 6777 6778 6779 6780 6781
              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;
6782
            ue_context_p->ue_context.StatusRrc = RRC_RECONFIGURED;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6783 6784 6785 6786 6787 6788 6789 6790 6791 6792
            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);
        }
6793

6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 6805 6806 6807 6808 6809 6810 6811 6812 6813
        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
6814 6815 6816
              gtpv1u_enb_delete_tunnel_req_t delete_tunnels={0};
              delete_tunnels.rnti = ue_context_p->ue_context.rnti;
              delete_tunnels.from_gnb = 0;
6817 6818 6819

              for(i = 0; i < NB_RB_MAX; i++) {
                if(xid == ue_context_p->ue_context.e_rab[i].xid) {
6820
                  delete_tunnels.eps_bearer_id[delete_tunnels.num_erab++] = ue_context_p->ue_context.enb_gtp_ebi[i];
6821 6822 6823 6824
                  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
6825
              }
6826
	      gtpv1u_delete_s1u_tunnel(ctxt_pP->instance, &delete_tunnels);
6827 6828 6829 6830 6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841
              //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) {
              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
6842

6843 6844 6845 6846 6847 6848 6849 6850 6851
              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) {
6852 6853 6854 6855 6856 6857 6858
            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;
              }
            }
6859 6860 6861 6862 6863 6864 6865
          } 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
6866 6867
            }

6868 6869 6870 6871
            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
6872 6873 6874 6875

        break;

      case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReestablishmentComplete:
6876
        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->rntiMaybeUEid));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6877 6878 6879 6880 6881 6882 6883 6884 6885 6886 6887 6888 6889
        LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP,
                    "[MSG] RRC Connection Reestablishment Complete\n");
        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++) {
6890
            if (reestablish_rnti_map[i][0] == ctxt_pP->rntiMaybeUEid) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6891 6892 6893 6894 6895 6896 6897
              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;
6898 6899
              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
6900 6901 6902 6903 6904 6905 6906 6907 6908 6909
              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;
          }
6910

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6911
          //clear
6912
          int UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid);
6913

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6914
          if(UE_id == -1) {
6915
            LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT " LTE_RRCConnectionReestablishmentComplete without UE_id(MAC) rnti %lx, fault\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), ctxt_pP->rntiMaybeUEid);
6916 6917 6918
            break;
          }

6919
          RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0;
6920
          ue_context_p->ue_context.reestablishment_xid = -1;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6921 6922 6923 6924 6925 6926 6927 6928 6929 6930 6931 6932

          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);
          }

          //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;
6933
        }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6934 6935 6936 6937 6938 6939
        break;

      case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionSetupComplete:

        // to avoid segmentation fault
        if(!ue_context_p) {
6940
          LOG_I(RRC, "Processing LTE_RRCConnectionSetupComplete UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid);
6941 6942
          break;
        }
6943

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6944 6945 6946 6947 6948 6949 6950 6951 6952 6953 6954 6955 6956 6957
        LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP,
                    "[MSG] RRC Connection SetupComplete\n");
        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) {
6958
            AssertFatal(!NODE_IS_DU(RC.rrc[ctxt_pP->module_id]->node_type),
6959
                        "should not be reached in DU\n");
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6960 6961 6962 6963 6964 6965
            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));
6966 6967
          }
        }
6968

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6969
        ue_context_p->ue_context.ue_release_timer=0;
6970
        break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6971 6972

      case LTE_UL_DCCH_MessageType__c1_PR_securityModeComplete:
6973
        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->rntiMaybeUEid));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6974 6975 6976

        // to avoid segmentation fault
        if(!ue_context_p) {
6977
          LOG_I(RRC, "Processing securityModeComplete UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6978
          break;
6979 6980
        }

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 6994 6995 6996
        LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP,
                    "[MSG] RRC Security Mode Complete\n");
        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);
        }
6997

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
6998 6999 7000 7001 7002 7003
        // 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);
7004
        break;
7005

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7006
      case LTE_UL_DCCH_MessageType__c1_PR_securityModeFailure:
7007
        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->rntiMaybeUEid));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7008 7009 7010 7011 7012 7013 7014 7015
        LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP,
                    "[MSG] RRC Security Mode Failure\n");
        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);
7016

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7017 7018 7019
        if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
          xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)ul_dcch_msg);
        }
7020

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7021 7022 7023 7024 7025
        // 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
7026

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7027
      case LTE_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation:
7028
        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->rntiMaybeUEid));
Lionel Gauthier's avatar
 
Lionel Gauthier committed
7029

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7030 7031
        // to avoid segmentation fault
        if(!ue_context_p) {
7032
          LOG_I(RRC, "Processing ueCapabilityInformation UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7033 7034 7035 7036 7037 7038 7039 7040 7041 7042 7043 7044 7045 7046 7047
          break;
        }

        LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP,
                    "[MSG] RRC UECapablility Information\n");
        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
7048

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7049 7050 7051
        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
7052

7053
        LOG_A(RRC, "got UE capabilities for UE %lx\n", ctxt_pP->rntiMaybeUEid);
7054 7055 7056
        int eutra_index = -1;

        for (i = 0; i < ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.count; i++) {
7057 7058
          if (ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[i]->rat_Type ==
              LTE_RAT_Type_nr) {
7059
            LOG_A(RRC, "got nrUE capabilities for UE %lx\n", ctxt_pP->rntiMaybeUEid);
7060 7061 7062 7063
            if(ue_context_p->ue_context.UE_Capability_nr) {
              ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr);
              ue_context_p->ue_context.UE_Capability_nr = 0;
            }
Raymond Knopp's avatar
Raymond Knopp committed
7064
            LOG_I(RRC,"Received NR_UE_Capabilities\n");
7065 7066 7067 7068 7069 7070 7071 7072 7073 7074 7075 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088
            dec_rval = uper_decode(NULL,
                                   &asn_DEF_NR_UE_NR_Capability,
                                   (void **)&ue_context_p->ue_context.UE_Capability_nr,
                                   ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[i]->ueCapabilityRAT_Container.buf,
                                   ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[i]->ueCapabilityRAT_Container.size,
                                   0, 0);

            if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
              xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, ue_context_p->ue_context.UE_Capability_nr);
            }

            if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
              LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Failed to decode nr UE capabilities (%zu bytes)\n",
                    PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),dec_rval.consumed);
              ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr);
              ue_context_p->ue_context.UE_Capability_nr = 0;
            }

            ue_context_p->ue_context.UE_NR_Capability_size =
              ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[i]->ueCapabilityRAT_Container.size;
          }

          if (ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[i]->rat_Type ==
              LTE_RAT_Type_eutra_nr) {
Raymond Knopp's avatar
Raymond Knopp committed
7089 7090
            LOG_I(RRC,"Received UE_Capabilities_MRDC\n");

7091 7092 7093 7094 7095 7096 7097 7098 7099 7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115 7116 7117 7118 7119
            if(ue_context_p->ue_context.UE_Capability_MRDC) {
              ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC);
              ue_context_p->ue_context.UE_Capability_MRDC = 0;
            }

            dec_rval = uper_decode(NULL,
                                   &asn_DEF_NR_UE_MRDC_Capability,
                                   (void **)&ue_context_p->ue_context.UE_Capability_MRDC,
                                   ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[i]->ueCapabilityRAT_Container.buf,
                                   ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[i]->ueCapabilityRAT_Container.size,
                                   0, 0);

            if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
              xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, ue_context_p->ue_context.UE_Capability_MRDC);
            }

            if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
              LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Failed to decode MRDC UE capabilities (%zu bytes)\n",
                    PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),dec_rval.consumed);
              ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC);
              ue_context_p->ue_context.UE_Capability_MRDC = 0;
            }

            ue_context_p->ue_context.UE_MRDC_Capability_size =
              ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[i]->ueCapabilityRAT_Container.size;
          }

          if (ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[i]->rat_Type ==
              LTE_RAT_Type_eutra) {
7120 7121 7122 7123
            if (eutra_index != -1) {
              LOG_E(RRC, "fatal: more than 1 eutra capability\n");
              exit(1);
            }
7124

7125 7126
            eutra_index = i;
          }
7127 7128 7129 7130 7131 7132
        }

        /* do nothing if no EUTRA capabilities (TODO: may be NR capabilities, to be processed somehow) */
        if (eutra_index == -1)
          break;

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7133
        if (ue_context_p->ue_context.UE_Capability) {
7134
          LOG_I(RRC, "freeing old UE capabilities for UE %lx\n", ctxt_pP->rntiMaybeUEid);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7135 7136 7137 7138
          ASN_STRUCT_FREE(asn_DEF_LTE_UE_EUTRA_Capability,
                          ue_context_p->ue_context.UE_Capability);
          ue_context_p->ue_context.UE_Capability = 0;
        }
7139

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7140 7141 7142
        dec_rval = uper_decode(NULL,
                               &asn_DEF_LTE_UE_EUTRA_Capability,
                               (void **)&ue_context_p->ue_context.UE_Capability,
7143 7144 7145
                               ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[eutra_index]->ueCapabilityRAT_Container.buf,
                               ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[eutra_index]->ueCapabilityRAT_Container.size,
                               0, 0);
7146 7147
        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[eutra_index]->ueCapabilityRAT_Container.size;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7148 7149 7150 7151

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

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7153 7154 7155 7156 7157 7158 7159 7160
        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;
        }
7161

7162 7163 7164
        if (dec_rval.code == RC_OK) {
          /* do NR only if at least one gNB connected */
          if (RC.rrc[ctxt_pP->module_id]->num_gnb_cells != 0)
7165 7166 7167 7168 7169
          {
            allocate_en_DC_r15(ue_context_p->ue_context.UE_Capability);
            if (!is_en_dc_supported(ue_context_p->ue_context.UE_Capability)){
                    LOG_E(RRC, "We did not properly allocate en_DC_r15 for UE_EUTRA_Capability\n");
            }
7170
            ue_context_p->ue_context.does_nr = is_en_dc_supported(ue_context_p->ue_context.UE_Capability);
7171
          }
7172 7173 7174
          else
            ue_context_p->ue_context.does_nr = 0;
        }
7175

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7176
        if (EPC_MODE_ENABLED) {
7177 7178 7179
          rrc_eNB_send_S1AP_UE_CAPABILITIES_IND(ctxt_pP,
                                                ue_context_p,
                                                ul_dcch_msg);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7180 7181
        } else {
          ue_context_p->ue_context.nb_of_e_rabs = 1;
7182

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7183 7184 7185 7186 7187
          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;
          }
7188

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7189 7190
          ue_context_p->ue_context.setup_e_rabs =ue_context_p->ue_context.nb_of_e_rabs;
        }
7191

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7192 7193 7194 7195
        rrc_eNB_generate_defaultRRCConnectionReconfiguration(ctxt_pP,
            ue_context_p,
            RC.rrc[ctxt_pP->module_id]->HO_flag);
        break;
7196

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7197
      case LTE_UL_DCCH_MessageType__c1_PR_ulHandoverPreparationTransfer:
7198
        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->rntiMaybeUEid));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7199
        break;
Cedric Roux's avatar
Cedric Roux committed
7200

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7201
      case LTE_UL_DCCH_MessageType__c1_PR_ulInformationTransfer:
7202
        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->rntiMaybeUEid));
7203

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7204 7205
        // to avoid segmentation fault
        if(!ue_context_p) {
7206
          LOG_I(RRC, "Processing ulInformationTransfer UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid);
7207
          break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7208
        }
7209

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7210 7211 7212
        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");
7213

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7214 7215 7216 7217 7218
        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
7219

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7220
        break;
7221

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7222
      case LTE_UL_DCCH_MessageType__c1_PR_counterCheckResponse:
7223
        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->rntiMaybeUEid));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7224
        break;
7225

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7226
      case LTE_UL_DCCH_MessageType__c1_PR_ueInformationResponse_r9:
7227
        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->rntiMaybeUEid));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7228
        break;
Cedric Roux's avatar
Cedric Roux committed
7229

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7230
      case LTE_UL_DCCH_MessageType__c1_PR_proximityIndication_r9:
7231
        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->rntiMaybeUEid));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7232
        break;
7233

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7234
      case LTE_UL_DCCH_MessageType__c1_PR_rnReconfigurationComplete_r10:
7235
        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->rntiMaybeUEid));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7236
        break;
winckel's avatar
winckel committed
7237

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7238
      case LTE_UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10:
7239
        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->rntiMaybeUEid));
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
7240
        LOG_E(RRC, "THINH [LTE_UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10]\n");
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7241
        break;
Cedric Roux's avatar
Cedric Roux committed
7242

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7243
      case LTE_UL_DCCH_MessageType__c1_PR_interFreqRSTDMeasurementIndication_r10:
7244
        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->rntiMaybeUEid));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7245
        break;
7246

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7247
      default:
7248
        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->rntiMaybeUEid));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7249 7250 7251 7252
        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
7253 7254
    }

7255
    return 0;
7256
    //TTN for D2D
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7257
  } else if (ul_dcch_msg->message.present == LTE_UL_DCCH_MessageType_PR_messageClassExtension) {
7258
    LOG_I(RRC, "[LTE_UL_DCCH_MessageType_PR_messageClassExtension]\n");
7259

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7260 7261
    switch (ul_dcch_msg->message.choice.messageClassExtension.present) {
      case LTE_UL_DCCH_MessageType__messageClassExtension_PR_NOTHING: /* No components present */
7262 7263
        break;

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7264
      case LTE_UL_DCCH_MessageType__messageClassExtension_PR_c2: //SidelinkUEInformation
7265
        if(ul_dcch_msg->message.choice.messageClassExtension.choice.c2.present ==
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
7266
            LTE_UL_DCCH_MessageType__messageClassExtension__c2_PR_scgFailureInformationNR_r15) {
7267
          if (ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.scgFailureInformationNR_r15.
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
7268
              criticalExtensions.present == LTE_SCGFailureInformationNR_r15__criticalExtensions_PR_c1) {
7269
            if (ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.scgFailureInformationNR_r15.criticalExtensions.
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
7270
                choice.c1.present == LTE_SCGFailureInformationNR_r15__criticalExtensions__c1_PR_scgFailureInformationNR_r15) {
7271
              if (ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.scgFailureInformationNR_r15.criticalExtensions.
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
7272
                  choice.c1.choice.scgFailureInformationNR_r15.failureReportSCG_NR_r15!=NULL) {
7273
                LOG_E(RRC, "Received NR scgFailureInformation from UE, failure type: %ld \n",
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
7274 7275
                      ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.scgFailureInformationNR_r15.criticalExtensions.
                      choice.c1.choice.scgFailureInformationNR_r15.failureReportSCG_NR_r15->failureType_r15);
7276
                xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)ul_dcch_msg);
Cedric Roux's avatar
Cedric Roux committed
7277 7278 7279 7280 7281 7282 7283 7284 7285 7286 7287

                /* TODO: scg failure indication, what to do? Let's remove the UE for now.
                 * We could re-establish DRB?
                 * Also, the way to remove is to start ue_release_timer_rrc and
                 * send RRCConnectionRelease to the UE, maybe it's not good/correct.
                 */
                if (ue_context_p != NULL) {
                  ue_context_p->ue_context.ue_release_timer_thres_rrc = 100;
                  ue_context_p->ue_context.ue_release_timer_rrc = 1;
                  rrc_eNB_generate_RRCConnectionRelease(ctxt_pP, ue_context_p);
                }
7288 7289 7290
              }
            }
          }
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
7291
        } else if(ul_dcch_msg->message.choice.messageClassExtension.choice.c2.present == LTE_UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12) {
7292 7293 7294
          //case UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12: //SidelinkUEInformation
          LOG_I(RRC,"THINH [LTE_UL_DCCH_MessageType__messageClassExtension_PR_c2]\n");
          LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP,
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
7295 7296 7297 7298 7299 7300 7301
                      "[MSG] RRC SidelinkUEInformation \n");
          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);
7302 7303 7304 7305
          rrc_eNB_process_SidelinkUEInformation(
            ctxt_pP,
            ue_context_p,
            &ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.sidelinkUEInformation_r12);
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
7306 7307
        }

7308
        break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7309 7310

      default:
7311
        break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7312 7313 7314
    }

    //end TTN
7315
  } else {
7316 7317 7318
    LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Unknown error %s:%u\n",
          PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
          __FILE__, __LINE__);
7319 7320 7321
    return -1;
  }

7322
  return 0;
winckel's avatar
winckel committed
7323 7324
}

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7325 7326
void rrc_eNB_reconfigure_DRBs (const protocol_ctxt_t *const ctxt_pP,
                               rrc_eNB_ue_context_t  *ue_context_pP) {
7327
  int i;
Navid Nikaein's avatar
Navid Nikaein committed
7328
  int e_rab_done=0;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7329 7330

  for (i = 0;
Navid Nikaein's avatar
Navid Nikaein committed
7331
       i < 3;//NB_RB_MAX - 3;  // S1AP_MAX_E_RAB
7332
       i++) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7333
    if ( ue_context_pP->ue_context.e_rab[i].status < E_RAB_STATUS_DONE) {
7334 7335 7336 7337 7338 7339 7340 7341
      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
7342
      //  memset (ue_context_pP->ue_context.e_rab[i].param.sgw_addr.buffer,0,20);
7343 7344 7345
      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
7346
      e_rab_done++;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7347 7348
      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);
7349
    }
7350
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
7351

Navid Nikaein's avatar
Navid Nikaein committed
7352
  ue_context_pP->ue_context.setup_e_rabs+=e_rab_done;
7353 7354 7355
  rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(ctxt_pP, ue_context_pP, 0);
}

7356
void handle_f1_setup_req(f1ap_setup_req_t *f1_setup_req) {
7357
  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);
7358
  //uint16_t num_cells_to_activate = 0;
7359
  int cu_cell_ind=0;
7360 7361 7362
  MessageDef                         *msg_p = NULL;

  //LOG_W(RRC,"num_cells_available %d \n", f1_setup_req->num_cells_available);
7363
  for (int i=0; i<f1_setup_req->num_cells_available; i++) {
7364 7365
    // check that mcc/mnc match and grab MIB/SIB1
    int found_cell=0;
7366 7367

    for (int j=0; j<RC.nb_inst; j++) {
7368
      eNB_RRC_INST *rrc = RC.rrc[j];
7369

7370 7371 7372
      if (rrc->configuration.mcc[0] == f1_setup_req->cell[i].mcc &&
          rrc->configuration.mnc[0] == f1_setup_req->cell[i].mnc &&
          rrc->nr_cellid == f1_setup_req->cell[i].nr_cellid) {
7373
        // check that CU rrc instance corresponds to mcc/mnc/cgi (normally cgi should be enough, but just in case)
7374 7375 7376 7377
        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]);
7378
        memcpy((void *)rrc->carrier[0].MIB,f1_setup_req->mib[i],f1_setup_req->mib_length[i]);
7379
        asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
7380 7381 7382 7383
                                  &asn_DEF_LTE_BCCH_BCH_Message,
                                  (void **)&rrc->carrier[0].mib_DU,
                                  f1_setup_req->mib[i],
                                  f1_setup_req->mib_length[i]);
7384
        AssertFatal(dec_rval.code == RC_OK,
7385 7386 7387
                    "[eNB_DU %"PRIu8"] Failed to decode LTE_BCCH_BCH_MESSAGE (%zu bits)\n",
                    j,
                    dec_rval.consumed );
7388 7389
        LTE_BCCH_BCH_Message_t *mib = &rrc->carrier[0].mib;
        LTE_BCCH_BCH_Message_t *mib_DU = rrc->carrier[0].mib_DU;
7390 7391 7392 7393 7394
        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];
7395
        memcpy((void *)rrc->carrier[0].SIB1,f1_setup_req->sib1[i],f1_setup_req->sib1_length[i]);
7396
        dec_rval = uper_decode_complete(NULL,
7397 7398 7399 7400
                                        &asn_DEF_LTE_BCCH_DL_SCH_Message,
                                        (void **)&rrc->carrier[0].siblock1_DU,
                                        f1_setup_req->sib1[i],
                                        f1_setup_req->sib1_length[i]);
7401
        AssertFatal(dec_rval.code == RC_OK,
7402 7403 7404
                    "[eNB_DU %"PRIu8"] Failed to decode LTE_BCCH_DLSCH_MESSAGE (%zu bits)\n",
                    j,
                    dec_rval.consumed );
7405
        // Parse message and extract SystemInformationBlockType1 field
7406 7407
        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,
7408
                    "bcch_message->message.present != LTE_BCCH_DL_SCH_MessageType_PR_c1\n");
7409
        AssertFatal(bcch_message->message.choice.c1.present == LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1,
7410
                    "bcch_message->message.choice.c1.present != LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1\n");
7411
        rrc->carrier[0].sib1 = &bcch_message->message.choice.c1.choice.systemInformationBlockType1;
7412
        rrc->carrier[0].physCellId = f1_setup_req->cell[i].nr_pci;
7413 7414 7415
        // prepare F1_SETUP_RESPONSE

        if (msg_p == NULL) {
7416
          msg_p = itti_alloc_new_message (TASK_CU_F1, 0,F1AP_SETUP_RESP);
7417
        }
7418

7419
        F1AP_SETUP_RESP (msg_p).gNB_CU_name                                = rrc->node_name;
7420 7421 7422 7423
        F1AP_SETUP_RESP (msg_p).cells_to_activate[cu_cell_ind].mcc                           = rrc->configuration.mcc[0];
        F1AP_SETUP_RESP (msg_p).cells_to_activate[cu_cell_ind].mnc                           = rrc->configuration.mnc[0];
        F1AP_SETUP_RESP (msg_p).cells_to_activate[cu_cell_ind].mnc_digit_length              = rrc->configuration.mnc_digit_length[0];
        F1AP_SETUP_RESP (msg_p).cells_to_activate[cu_cell_ind].nr_cellid                     = rrc->nr_cellid;
7424
        F1AP_SETUP_RESP (msg_p).cells_to_activate[cu_cell_ind].nrpci                         = f1_setup_req->cell[i].nr_pci;
7425 7426
        int num_SI= 0;
        if (rrc->carrier[0].SIB23) {
rmagueta's avatar
rmagueta committed
7427 7428
          F1AP_SETUP_RESP (msg_p).cells_to_activate[cu_cell_ind].SI_container[2+num_SI]        = rrc->carrier[0].SIB23;
          F1AP_SETUP_RESP (msg_p).cells_to_activate[cu_cell_ind].SI_container_length[2+num_SI] = rrc->carrier[0].sizeof_SIB23;
luis_pereira87's avatar
luis_pereira87 committed
7429 7430 7431
          //printf("SI %d size %d: ", 0, F1AP_SETUP_RESP (msg_p).cells_to_activate[cu_cell_ind].SI_container_length[2+num_SI]);
          //for (int n = 0; n < F1AP_SETUP_RESP (msg_p).cells_to_activate[cu_cell_ind].SI_container_length[2+num_SI]; n++)
          //  printf("%02x ", F1AP_SETUP_RESP (msg_p).cells_to_activate[cu_cell_ind].SI_container[2+num_SI][n]);
7432
          //printf("\n");
7433 7434
          num_SI++;
        }
7435

7436
        F1AP_SETUP_RESP (msg_p).cells_to_activate[cu_cell_ind].num_SI = num_SI;
7437 7438
        cu_cell_ind++;
        found_cell=1;
7439 7440 7441
        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);
7442 7443
        break;
      } else {// setup_req mcc/mnc match rrc internal list element
7444
        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",
7445
              j, rrc->configuration.mcc[0], f1_setup_req->cell[i].mcc,rrc->configuration.mnc[0], f1_setup_req->cell[i].mnc);
7446
      }
7447
    }// for (int j=0;j<RC.nb_inst;j++)
7448

7449 7450
    if (found_cell==0) {
      AssertFatal(1==0,"No cell found\n");
7451
      /*msg_p = itti_alloc_new_message (TASK_CU_F1, 0,F1AP_SETUP_FAILURE);
7452 7453 7454 7455
      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;*/
    }
7456

7457 7458 7459 7460
    // handle other failure cases
  }//for (int i=0;i<f1_setup_req->num_cells_available;i++)
}

7461 7462

// ignore 5GNR fields for now, just take MIB and SIB1
7463 7464
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
laurent's avatar
laurent committed
7465
void rrc_enb_init(void) {
7466
  pthread_mutex_init(&lock_ue_freelist, NULL);
7467 7468
  pthread_mutex_init(&rrc_release_freelist, NULL);
  memset(&rrc_release_info,0,sizeof(RRC_release_list_t));
laurent's avatar
laurent committed
7469 7470
}

7471 7472
//-----------------------------------------------------------------------------
void process_successful_rlc_sdu_indication(int instance,
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
7473 7474
    int rnti,
    int message_id) {
7475 7476 7477 7478 7479 7480 7481 7482 7483 7484 7485 7486 7487 7488 7489 7490 7491 7492 7493 7494 7495 7496 7497 7498 7499 7500 7501 7502 7503 7504 7505 7506 7507 7508 7509 7510 7511 7512 7513 7514 7515 7516 7517 7518 7519 7520 7521
  int release_num;
  int release_total;
  RRC_release_ctrl_t *release_ctrl;
  /* Check if the message sent was RRC Connection Release.
   * If yes then continue the release process.
   */
  pthread_mutex_lock(&rrc_release_freelist);

  if (rrc_release_info.num_UEs > 0) {
    release_total = 0;

    for (release_num = 0, release_ctrl = &rrc_release_info.RRC_release_ctrl[0];
         release_num < NUMBER_OF_UE_MAX;
         release_num++, release_ctrl++) {
      if(release_ctrl->flag > 0) {
        release_total++;
      } else {
        continue;
      }

      if (release_ctrl->flag == 1 && release_ctrl->rnti == rnti && release_ctrl->rrc_eNB_mui == message_id) {
        release_ctrl->flag = 3;
        LOG_D(MAC,"DLSCH Release send:index %d rnti %x mui %d flag 1->3\n",
              release_num,
              rnti,
              message_id);
        break;
      }

      if (release_ctrl->flag == 2 && release_ctrl->rnti == rnti && release_ctrl->rrc_eNB_mui == message_id) {
        release_ctrl->flag = 4;
        LOG_D(MAC, "DLSCH Release send:index %d rnti %x mui %d flag 2->4\n",
              release_num,
              rnti,
              message_id);
        break;
      }

      if(release_total >= rrc_release_info.num_UEs)
        break;
    }
  }

  pthread_mutex_unlock(&rrc_release_freelist);
}

//-----------------------------------------------------------------------------
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
7522
void process_unsuccessful_rlc_sdu_indication(int instance, int rnti) {
7523 7524 7525 7526 7527 7528 7529 7530 7531 7532 7533 7534 7535 7536 7537 7538 7539 7540 7541 7542 7543 7544 7545 7546 7547 7548 7549 7550 7551 7552 7553 7554 7555 7556 7557 7558 7559 7560 7561 7562 7563 7564 7565 7566 7567 7568 7569 7570 7571 7572 7573 7574 7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 7589 7590 7591 7592 7593
  int release_num;
  int release_total;
  RRC_release_ctrl_t *release_ctrl;
  /* radio link failure detected by RLC layer, remove UE properly */
  pthread_mutex_lock(&rrc_release_freelist);

  /* first, check if the rnti is in the list rrc_release_info.RRC_release_ctrl */

  if (rrc_release_info.num_UEs > 0) {
    release_total = 0;

    for (release_num = 0, release_ctrl = &rrc_release_info.RRC_release_ctrl[0];
         release_num < NUMBER_OF_UE_MAX;
         release_num++, release_ctrl++) {
      if(release_ctrl->flag > 0) {
        release_total++;
      } else {
        continue;
      }

      if (release_ctrl->flag == 1 && release_ctrl->rnti == rnti) {
        release_ctrl->flag = 3;
        LOG_D(MAC,"DLSCH Release send:index %d rnti %x flag 1->3\n",
              release_num,
              rnti);
        goto done;
      }

      if (release_ctrl->flag == 2 && release_ctrl->rnti == rnti) {
        release_ctrl->flag = 4;
        LOG_D(MAC, "DLSCH Release send:index %d rnti %x flag 2->4\n",
              release_num,
              rnti);
        goto done;
      }

      if(release_total >= rrc_release_info.num_UEs)
        break;
    }
  }

  /* it's not in the list, put it with flag = 4 */
  for (release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) {
    if (rrc_release_info.RRC_release_ctrl[release_num].flag == 0) {
      rrc_release_info.RRC_release_ctrl[release_num].flag = 4;
      rrc_release_info.RRC_release_ctrl[release_num].rnti = rnti;
      rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui = -1;     /* not defined */
      rrc_release_info.num_UEs++;
      LOG_D(RRC, "radio link failure detected: index %d rnti %x flag %d \n",
            release_num,
            rnti,
            rrc_release_info.RRC_release_ctrl[release_num].flag);
      break;
    }
  }

  /* TODO: what to do if rrc_release_info.RRC_release_ctrl is full? */
  if (release_num == NUMBER_OF_UE_MAX) {
    LOG_E(RRC, "fatal: radio link failure: rrc_release_info.RRC_release_ctrl is full\n");
    exit(1);
  }

done:
  pthread_mutex_unlock(&rrc_release_freelist);
}

//-----------------------------------------------------------------------------
void process_rlc_sdu_indication(int instance,
                                int rnti,
                                int is_successful,
                                int srb_id,
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
7594
                                int message_id) {
7595 7596 7597 7598 7599 7600
  if (is_successful)
    process_successful_rlc_sdu_indication(instance, rnti, message_id);
  else
    process_unsuccessful_rlc_sdu_indication(instance, rnti);
}

Cedric Roux's avatar
Cedric Roux committed
7601 7602 7603
//-----------------------------------------------------------------------------
int add_ue_to_remove(struct rrc_eNB_ue_context_s **ue_to_be_removed,
                     int removed_ue_count,
7604
                     struct rrc_eNB_ue_context_s *ue_context_p) {
Cedric Roux's avatar
Cedric Roux committed
7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 7616 7617 7618 7619 7620 7621
  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
7622
//-----------------------------------------------------------------------------
7623
void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
7624 7625 7626 7627
  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
7628 7629 7630
  struct rrc_eNB_ue_context_s *ue_to_be_removed[NUMBER_OF_UE_MAX];
  int removed_ue_count = 0;
  int cur_ue;
Cedric Roux's avatar
Cedric Roux committed
7631
  MessageDef *msg;
7632
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_IN);
Cedric Roux's avatar
Cedric Roux committed
7633

7634
  if (RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]->configuration.enable_x2) {
Cedric Roux's avatar
Cedric Roux committed
7635
    /* send a tick to x2ap */
7636
    msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_SUBFRAME_PROCESS);
Cedric Roux's avatar
Cedric Roux committed
7637
    itti_send_msg_to_task(TASK_X2AP, ctxt_pP->module_id, msg);
7638
    check_handovers(ctxt_pP); // counter, get the value and aggregate
Cedric Roux's avatar
Cedric Roux committed
7639 7640
  }

7641
  // check for UL failure or for UE to be released
7642
  FILE *fd=NULL;
7643
  if ((ctxt_pP->frame&127) == 0 && ctxt_pP->subframe ==0)
Raymond Knopp's avatar
Raymond Knopp committed
7644 7645
    fd=fopen("RRC_stats.log","w+");

7646
  RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
7647
    ctxt_pP->rntiMaybeUEid = ue_context_p->ue_id_rnti;
7648

Raymond Knopp's avatar
Raymond Knopp committed
7649 7650
    if ((ctxt_pP->frame&127) == 0 && ctxt_pP->subframe ==0) {
      if (fd) {
7651
        if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == true) {
Raymond Knopp's avatar
Raymond Knopp committed
7652 7653 7654 7655 7656 7657 7658 7659 7660 7661 7662 7663 7664 7665 7666 7667 7668 7669 7670 7671
          fprintf(fd,"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 {
          fprintf(fd,"RRC UE rnti %x failure timer %d/8\n",
                ue_context_p->ue_context.rnti,
                ue_context_p->ue_context.ul_failure_timer);
        }

        if (ue_context_p->ue_context.UE_Capability) {
          long catDL,catUL;
          get_ue_Category(ue_context_p->ue_context.UE_Capability,&catDL,&catUL);
          fprintf(fd,"RRC UE cap: CatDL %ld, CatUL %ld, 64QAM UL %s, 256 QAM DL %s, 256 QAM UL %s, ENDC %s,\n",
                catDL,catUL,
		is_ul_64QAM_supported(ue_context_p->ue_context.UE_Capability) == 1 ? "yes" : "no",
		is_dl_256QAM_supported(ue_context_p->ue_context.UE_Capability) == 1 ? "yes" : "no",
                is_ul_256QAM_supported(ue_context_p->ue_context.UE_Capability) == 1 ? "yes" : "no",
                is_en_dc_supported(ue_context_p->ue_context.UE_Capability) == 1 ? "yes" : "no");
        }
Raymond Knopp's avatar
Raymond Knopp committed
7672 7673 7674
        if (ue_context_p->ue_context.measResults) {
           fprintf(fd, "RRC PCell RSRP %ld, RSRQ %ld\n", ue_context_p->ue_context.measResults->measResultPCell.rsrpResult-140,
                                                         ue_context_p->ue_context.measResults->measResultPCell.rsrqResult/2 - 20);
7675 7676
          if (ue_context_p->ue_context.measResults->measResultNeighCells &&
              ue_context_p->ue_context.measResults->measResultNeighCells->present == LTE_MeasResults__measResultNeighCells_PR_measResultNeighCellListNR_r15) {
Raymond Knopp's avatar
Raymond Knopp committed
7677 7678 7679

            fprintf(fd,"NR_pci %ld\n",ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0]->pci_r15);
            if(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0]->measResultCell_r15.rsrpResult_r15)
7680
              fprintf(fd,"NR_rsrp %f dB\n",to_nr_rsrpq(*ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0]->measResultCell_r15.rsrpResult_r15,RC.rrc[ctxt_pP->module_id]->nr_gnb_freq_band[0][0])/10.0);
7681
            if (ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0]->measResultCell_r15.rsrqResult_r15)
7682
              fprintf(fd,"NR_rsrq %f dB\n",to_nr_rsrpq(*ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0]->measResultCell_r15.rsrqResult_r15,RC.rrc[ctxt_pP->module_id]->nr_gnb_freq_band[0][0])/10.0);
7683
            if (ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0]->measResultRS_IndexList_r15)
Raymond Knopp's avatar
Raymond Knopp committed
7684 7685
              fprintf(fd,"NR_ssb_index %ld\n",ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0]->measResultRS_IndexList_r15->list.array[0]->ssb_Index_r15);
           }
Raymond Knopp's avatar
Raymond Knopp committed
7686
        }
7687 7688 7689 7690
      }
    }
    if (ue_context_p->ue_context.ul_failure_timer > 0) {
      ue_context_p->ue_context.ul_failure_timer++;
7691

7692 7693 7694 7695
      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
7696
        removed_ue_count = add_ue_to_remove(ue_to_be_removed, removed_ue_count, ue_context_p);
7697 7698 7699
        break; // break RB_FOREACH
      }
    }
7700

7701 7702
    if (ue_context_p->ue_context.ue_release_timer_s1 > 0) {
      ue_context_p->ue_context.ue_release_timer_s1++;
7703

7704 7705 7706 7707
      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);
7708

7709
        if (EPC_MODE_ENABLED && !NODE_IS_DU(RC.rrc[ctxt_pP->module_id]->node_type))
7710 7711
          rrc_eNB_generate_RRCConnectionRelease(ctxt_pP, ue_context_p);
        else
Cedric Roux's avatar
Cedric Roux committed
7712
          removed_ue_count = add_ue_to_remove(ue_to_be_removed, removed_ue_count, ue_context_p);
7713

7714 7715 7716 7717
        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
7718

7719 7720
    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
7721

7722 7723 7724 7725
      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
7726
        removed_ue_count = add_ue_to_remove(ue_to_be_removed, removed_ue_count, ue_context_p);
7727
        break; // break RB_FOREACH
7728
      }
7729
    }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
7730

7731 7732
    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
7733
        removed_ue_count = add_ue_to_remove(ue_to_be_removed, removed_ue_count, ue_context_p);
7734 7735 7736
        rrc_eNB_handover_ue_context_release(ctxt_pP, ue_context_p);
        break; //break RB_FOREACH (why to break ?)
      }
7737

Cedric Roux's avatar
Cedric Roux committed
7738 7739 7740 7741 7742 7743 7744 7745
      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;
      }
7746
    }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
7747

7748
    pthread_mutex_lock(&rrc_release_freelist);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
7749

7750 7751
    if (rrc_release_info.num_UEs > 0) {
      uint16_t release_total = 0;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
7752

7753 7754 7755 7756 7757 7758 7759 7760 7761 7762
      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;

7763
          if (EPC_MODE_ENABLED && !NODE_IS_DU(RC.rrc[ctxt_pP->module_id]->node_type)) {
7764
            if (rrc_release_info.RRC_release_ctrl[release_num].flag == 4) { // if timer_s1 == 0
7765 7766
              rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(ctxt_pP->module_id,
                  ue_context_p->ue_context.eNB_ue_s1ap_id);
7767 7768
            }

7769
            rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(ctxt_pP->module_id,
7770 7771
                ue_context_p);

7772 7773
            // 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++) {
7774
              ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0;
7775
              memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab],
7776
                     0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
7777
              ue_context_p->ue_context.enb_gtp_ebi[e_rab]  = 0;
7778 7779 7780
            }

            struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL;
7781

7782
            rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0,
7783
                              ue_context_p->ue_context.eNB_ue_s1ap_id);
7784 7785 7786 7787

            if (rrc_ue_s1ap_ids != NULL) {
              rrc_eNB_S1AP_remove_ue_ids(RC.rrc[ctxt_pP->module_id], rrc_ue_s1ap_ids);
            }
7788
          } /* EPC_MODE_ENABLED && !NODE_IS_DU */
7789 7790 7791 7792 7793 7794 7795 7796 7797 7798 7799 7800 7801 7802 7803

          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)) {
7804
      ue_context_p->ue_context.ue_rrc_inactivity_timer++;
7805 7806 7807 7808

      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
7809
        removed_ue_count = add_ue_to_remove(ue_to_be_removed, removed_ue_count, ue_context_p);
7810 7811 7812 7813 7814 7815 7816 7817 7818 7819 7820
        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
7821
        removed_ue_count = add_ue_to_remove(ue_to_be_removed, removed_ue_count, ue_context_p);
7822 7823 7824 7825 7826 7827 7828 7829 7830 7831 7832 7833 7834 7835 7836 7837
        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
7838
        removed_ue_count = add_ue_to_remove(ue_to_be_removed, removed_ue_count, ue_context_p);
7839 7840 7841 7842 7843 7844
        ue_context_p->ue_context.ue_release_timer = 0;
        break; // break RB_FOREACH
      }
    }
  } // end RB_FOREACH

Cedric Roux's avatar
Cedric Roux committed
7845 7846 7847
  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) &&
7848
         (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0))) {
Cedric Roux's avatar
Cedric Roux committed
7849 7850 7851 7852
      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;
7853 7854
    }

Cedric Roux's avatar
Cedric Roux committed
7855
    /* remove UE from gNB if UE is in NSA mode */
7856 7857
    if (ue_to_be_removed[cur_ue]->ue_context.StatusRrc == RRC_NR_NSA ||
        ue_to_be_removed[cur_ue]->ue_context.StatusRrc == RRC_NR_NSA_RECONFIGURED) {
Cedric Roux's avatar
Cedric Roux committed
7858
      MessageDef *message_p;
7859
      message_p = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_ENDC_SGNB_RELEASE_REQUEST);
Cedric Roux's avatar
Cedric Roux committed
7860 7861 7862 7863 7864
      X2AP_ENDC_SGNB_RELEASE_REQUEST(message_p).rnti = ue_to_be_removed[cur_ue]->ue_context.gnb_rnti;
      X2AP_ENDC_SGNB_RELEASE_REQUEST(message_p).assoc_id = ue_to_be_removed[cur_ue]->ue_context.gnb_x2_assoc_id;
      X2AP_ENDC_SGNB_RELEASE_REQUEST(message_p).cause = X2AP_CAUSE_RADIO_CONNECTION_WITH_UE_LOST;
      itti_send_msg_to_task(TASK_X2AP, ctxt_pP->module_id, message_p);
      /* set state to RRC_NR_NSA_DELETED to avoid sending X2AP_ENDC_SGNB_RELEASE_REQUEST again later */
7865
      ue_to_be_removed[cur_ue]->ue_context.StatusRrc = RRC_NR_NSA_DELETED;
Cedric Roux's avatar
Cedric Roux committed
7866 7867
    }

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

Cedric Roux's avatar
Cedric Roux committed
7870 7871
    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;
7872 7873
    }

Cedric Roux's avatar
Cedric Roux committed
7874
    if ((ue_to_be_removed[cur_ue]->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) &&
7875
        (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0)) {
Cedric Roux's avatar
Cedric Roux committed
7876
      ue_to_be_removed[cur_ue]->ue_context.ue_rrc_inactivity_timer = 0; //reset timer after S1 command UE context release request is sent
7877 7878 7879
    }
  }

Raymond Knopp's avatar
Raymond Knopp committed
7880 7881 7882
  if (fd!=NULL) fclose(fd);


7883 7884 7885 7886 7887 7888
  (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);
}

7889
void rrc_eNB_process_ENDC_x2_setup_request(int mod_id, x2ap_ENDC_setup_req_t *m) {
7890 7891
  if (RC.rrc[mod_id]->num_gnb_cells >= MAX_NUM_GNB_CELLs) {
    LOG_E(RRC, "Error: number of gNB cells is exceeded\n");
7892 7893 7894 7895
    return;
  }

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

7900 7901
  RC.rrc[mod_id]->num_gnb_cells++;
  RC.rrc[mod_id]->num_gnb_cells_cc[RC.rrc[mod_id]->num_gnb_cells-1] = m->num_cc;
7902 7903

  for (int i=0; i<m->num_cc; i++) {
7904 7905
    RC.rrc[mod_id]->gnb_cells_id[RC.rrc[mod_id]->num_gnb_cells-1][i] = m->Nid_cell[i];
    RC.rrc[mod_id]->nr_gnb_freq_band[RC.rrc[mod_id]->num_gnb_cells-1][i] = m->servedNrCell_band[i];
7906 7907 7908 7909
  }

}

7910
void rrc_eNB_process_AdditionResponseInformation(const module_id_t enb_mod_idP, x2ap_ENDC_sgnb_addition_req_ACK_t *m) {
7911 7912 7913 7914
  NR_CG_Config_t *CG_Config = NULL;
  {
    int i;
    printf("%d: ", m->rrc_buffer_size);
7915

7916
    for (i=0; i<m->rrc_buffer_size; i++) printf("%2.2x", (unsigned char)m->rrc_buffer[i]);
7917

7918 7919 7920 7921 7922 7923 7924
    printf("\n");
  }
  asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
                            &asn_DEF_NR_CG_Config,
                            (void **)&CG_Config,
                            (uint8_t *)m->rrc_buffer,
                            (int) m->rrc_buffer_size);//m->rrc_buffer_size);
7925

7926 7927 7928 7929 7930 7931
  if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
    AssertFatal(1==0,"NR_UL_DCCH_MESSAGE decode error\n");
    // free the memory
    SEQUENCE_free( &asn_DEF_NR_CG_Config, CG_Config, 1 );
    return;
  }
7932

7933 7934 7935 7936 7937 7938
  xer_fprint(stdout,&asn_DEF_NR_CG_Config, CG_Config);
  // recreate enough of X2 EN-DC Container
  AssertFatal(CG_Config->criticalExtensions.choice.c1->present == NR_CG_Config__criticalExtensions__c1_PR_cg_Config,
              "CG_Config not present\n");
  OCTET_STRING_t *scg_CellGroupConfig = NULL;
  OCTET_STRING_t *nr1_conf = NULL;
7939

7940 7941 7942 7943 7944 7945 7946
  if(CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig) {
    scg_CellGroupConfig = CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig;
#ifdef DEBUG_SCG_CONFIG
    {
      int size_s = CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig->size;
      int i;
      LOG_I(RRC, "Dumping scg_CellGroupConfig: %d", size_s);
7947

7948
      for (i=0; i<size_s; i++) printf("%2.2x", (unsigned char)CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig->buf[i]);
7949

7950 7951 7952 7953 7954 7955 7956
      printf("\n");
    }
#endif
  } else {
    LOG_W(RRC, "SCG Cell group configuration is not present in the Addition Response message \n");
    return;
  }
7957

7958 7959
  if(CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config) {
    nr1_conf = CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config;
7960
#ifdef DEBUG_SCG_CONFIG
7961 7962 7963 7964
    {
      int size_s = CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config->size;
      int i;
      LOG_I(RRC, "Dumping scg_RB_Config: %d", size_s);
7965

7966 7967 7968
      for (i=0; i<size_s; i++) printf("%2.2x", (unsigned char)CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config->buf[i]);

      printf("\n");
7969
    }
7970
#endif
7971 7972 7973 7974
  } else {
    LOG_W(RRC, "SCG RB configuration is not present in the Addition Response message \n");
    return;
  }
7975

Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
7976 7977 7978 7979 7980 7981 7982 7983
  protocol_ctxt_t ctxt;
  rrc_eNB_ue_context_t *ue_context;
  unsigned char buffer[8192];
  int size;
  ue_context = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], m->rnti);

  if (ue_context) {
    ue_context->ue_context.nb_of_modify_endc_e_rabs = m->nb_e_rabs_admitted_tobeadded;
Cedric Roux's avatar
Cedric Roux committed
7984 7985 7986 7987

    ue_context->ue_context.gnb_rnti = m->SgNB_ue_x2_id;
    ue_context->ue_context.gnb_x2_assoc_id = m->gnb_x2_assoc_id;

Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
7988 7989 7990 7991 7992 7993 7994 7995 7996 7997 7998 7999 8000 8001
    int j=0;

    while(j < m->nb_e_rabs_admitted_tobeadded) {
      for (int e_rab_idx=0; e_rab_idx<ue_context->ue_context.setup_e_rabs; e_rab_idx++) {
        //Update ue_context information with gNB's address and new GTP tunnel ID
        if( ue_context->ue_context.e_rab[e_rab_idx].param.e_rab_id == m->e_rabs_admitted_tobeadded[j].e_rab_id) {
          memcpy(ue_context->ue_context.gnb_gtp_endc_addrs[e_rab_idx].buffer,
                 m->e_rabs_admitted_tobeadded[j].gnb_addr.buffer,
                 m->e_rabs_admitted_tobeadded[j].gnb_addr.length);
          ue_context->ue_context.gnb_gtp_endc_addrs[e_rab_idx].length = m->e_rabs_admitted_tobeadded[j].gnb_addr.length;
          ue_context->ue_context.gnb_gtp_endc_teid[e_rab_idx] = m->e_rabs_admitted_tobeadded[j].gtp_teid;
          ue_context->ue_context.e_rab[e_rab_idx].status = E_RAB_STATUS_TOMODIFY;
          break;
        }
8002
      }
8003

Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
8004
      j++;
8005
    }
8006

Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
8007 8008 8009 8010 8011 8012 8013 8014 8015 8016 8017 8018 8019 8020 8021 8022
    PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
                                  0,
                                  ENB_FLAG_YES,
                                  m->rnti,
                                  0, 0);
    size = rrc_eNB_generate_RRCConnectionReconfiguration_endc(&ctxt, ue_context, buffer, 8192, scg_CellGroupConfig, nr1_conf);
    rrc_data_req(&ctxt,
                 DCCH,
                 rrc_eNB_mui++,
                 SDU_CONFIRM_NO,
                 size,
                 buffer,
                 PDCP_TRANSMISSION_MODE_CONTROL);
  } else {
    LOG_E(F1AP, "no ue_context for RNTI %x, acknowledging release\n", m->rnti);
  }
8023 8024
}

Cedric Roux's avatar
Cedric Roux committed
8025 8026 8027 8028 8029 8030 8031 8032 8033 8034
void rrc_eNB_process_ENDC_DC_prep_timeout(module_id_t module_id, x2ap_ENDC_dc_prep_timeout_t *m)
{
  rrc_eNB_ue_context_t *ue_context;

  ue_context = rrc_eNB_get_ue_context(RC.rrc[module_id], m->rnti);
  if (ue_context == NULL) {
    LOG_E(RRC, "receiving DC prep timeout for unknown UE rnti %d\n", m->rnti);
    return;
  }

8035
  if (ue_context->ue_context.StatusRrc != RRC_NR_NSA) {
Cedric Roux's avatar
Cedric Roux committed
8036 8037 8038 8039 8040
    LOG_E(RRC, "receiving DC prep timeout for UE rnti %d not in state RRC_NR_NSA\n", m->rnti);
    return;
  }

  LOG_I(RRC, "DC prep timeout for UE rnti %d, put back to RRC_RECONFIGURED mode\n", m->rnti);
8041
  ue_context->ue_context.StatusRrc = RRC_RECONFIGURED;
Cedric Roux's avatar
Cedric Roux committed
8042 8043 8044 8045 8046 8047 8048 8049 8050 8051 8052 8053 8054 8055 8056 8057 8058 8059 8060 8061
}

void rrc_eNB_process_ENDC_sgNB_release_required(module_id_t module_id, x2ap_ENDC_sgnb_release_required_t *m)
{
  rrc_eNB_ue_context_t *ue_context;
  protocol_ctxt_t      ctxt;

  ue_context = rrc_eNB_find_ue_context_from_gnb_rnti(RC.rrc[module_id], m->gnb_rnti);
  if (ue_context == NULL) {
    LOG_E(RRC, "receiving ENDC SgNB Release Required for unknown UE (with gNB's rnti %d)\n", m->gnb_rnti);
    return;
  }

  /* TODO: what to do? release the UE? if yes, how? Or re-establish bearers in LTE?
   * Or something else?
   * The following removes the UE, maybe it's not correct at all.
   */
  ue_context->ue_context.ue_release_timer_thres_rrc = 100;
  ue_context->ue_context.ue_release_timer_rrc = 1;

8062
  ue_context->ue_context.StatusRrc = RRC_NR_NSA_DELETED;
Cedric Roux's avatar
Cedric Roux committed
8063 8064 8065 8066 8067 8068 8069 8070

  PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
                                module_id,  /* TODO: should be 'instance' */
                                ENB_FLAG_YES,
                                ue_context->ue_context.rnti,
                                0, 0);

  rrc_eNB_generate_RRCConnectionRelease(&ctxt, ue_context);
8071 8072
}

8073
//-----------------------------------------------------------------------------
laurent's avatar
laurent committed
8074
void *rrc_enb_process_itti_msg(void *notUsed) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8075 8076 8077 8078 8079
  MessageDef                         *msg_p;
  const char                         *msg_name_p;
  instance_t                          instance;
  int                                 result;
  protocol_ctxt_t                     ctxt;
8080
  memset(&ctxt, 0, sizeof(ctxt));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8081
  // Wait for a message
8082 8083
  itti_poll_msg(TASK_RRC_ENB, &msg_p);
  while (msg_p) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8084
  msg_name_p = ITTI_MSG_NAME(msg_p);
8085
  instance = ITTI_MSG_DESTINATION_INSTANCE(msg_p);
8086

8087 8088
  /* RRC_SUBFRAME_PROCESS is sent every subframe, do not log it */
  if (ITTI_MSG_ID(msg_p) != RRC_SUBFRAME_PROCESS)
8089
      LOG_D(RRC, "Received message %s\n", msg_name_p);
8090

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8091
  switch (ITTI_MSG_ID(msg_p)) {
8092
    case TERMINATE_MESSAGE:
8093
      LOG_W(RRC, " *** Exiting RRC thread\n");
8094 8095 8096 8097
      itti_exit_task();
      break;

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

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8101
    /* Messages from MAC */
8102
    case RRC_MAC_CCCH_DATA_IND:
8103 8104 8105
        PROTOCOL_CTXT_SET_BY_INSTANCE(
            &ctxt, RRC_MAC_CCCH_DATA_IND(msg_p).enb_index, ENB_FLAG_YES, RRC_MAC_CCCH_DATA_IND(msg_p).rnti, msg_p->ittiMsgHeader.lte_time.frame, msg_p->ittiMsgHeader.lte_time.slot);
        LOG_I(RRC, "Decoding CCCH : inst %ld, CC_id %d, ctxt %p, sib_info_p->Rx_buffer.payload_size %d\n", 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
8106

8107
      if (RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size >= CCCH_SDU_SIZE) {
8108
          LOG_I(RRC, "CCCH message has size %d > %d\n", RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size, CCCH_SDU_SIZE);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8109
        break;
8110
      }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8111

8112
        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);
8113
      break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8114 8115

    /* Messages from PDCP */
8116
    case RRC_DCCH_DATA_IND:
8117 8118 8119
        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);
        LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT " Received on DCCH %d %s\n", 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, RRC_DCCH_DATA_IND(msg_p).sdu_size);
8120 8121
      // 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
8122

8123
      if (result != EXIT_SUCCESS) {
8124
          LOG_I(RRC, "Failed to free memory (%d)!\n", result);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8125
        break;
8126
      }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
8127

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8128
      break;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
8129

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8130
    /* Messages from S1AP */
8131 8132 8133
    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
8134

8135 8136 8137
    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
8138

8139 8140 8141
    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
8142

8143
    case S1AP_PAGING_IND:
8144
      LOG_D(RRC, "[eNB %ld] Received Paging message from S1AP: %s\n", instance, msg_name_p);
8145
      rrc_eNB_process_PAGING_IND(msg_p, msg_name_p, instance);
8146
      break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8147 8148

    case S1AP_E_RAB_SETUP_REQ:
8149
      rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(msg_p, msg_name_p, instance);
8150
      LOG_D(RRC, "[eNB %ld] Received the message %s\n", instance, msg_name_p);
8151
      break;
8152 8153 8154 8155 8156 8157 8158 8159

    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
8160

8161 8162 8163
    case S1AP_UE_CONTEXT_RELEASE_REQ:
      rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_REQ(msg_p, msg_name_p, instance);
      break;
8164

8165 8166 8167
    case S1AP_UE_CONTEXT_RELEASE_COMMAND:
      rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND(msg_p, msg_name_p, instance);
      break;
8168

8169
    case S1AP_PATH_SWITCH_REQ_ACK:
8170
      LOG_I(RRC, "[eNB %ld] received path switch ack %s\n", instance, msg_name_p);
8171 8172
      rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK(msg_p, msg_name_p, instance);
      break;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
8173

8174 8175 8176 8177 8178 8179 8180 8181
    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;

8182
    case X2AP_HANDOVER_REQ:
8183
      LOG_I(RRC, "[eNB %ld] target eNB Receives X2 HO Req %s\n", instance, msg_name_p);
8184 8185
      rrc_eNB_process_handoverPreparationInformation(instance, &X2AP_HANDOVER_REQ(msg_p));
      break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8186

8187 8188
    case X2AP_HANDOVER_REQ_ACK: {
      struct rrc_eNB_ue_context_s        *ue_context_p = NULL;
8189 8190 8191
      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;
8192
      ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], X2AP_HANDOVER_REQ_ACK(msg_p).rnti);
8193

8194 8195
      if (ue_context_p == NULL) {
        /* is it possible? */
8196
          LOG_E(RRC, "could not find UE (rnti %x) while processing X2AP_HANDOVER_REQ_ACK\n", X2AP_HANDOVER_REQ_ACK(msg_p).rnti);
8197
        exit(1);
8198
      }
8199

8200
      LOG_I(RRC, "[eNB %ld] source eNB receives the X2 HO ACK %s\n", instance, msg_name_p);
8201
      DevAssert(ue_context_p != NULL);
8202

8203 8204
        if (ue_context_p->ue_context.handover_info->state != HO_REQUEST)
          abort();
8205 8206 8207

      hash_rc = hashtable_get(RC.gtpv1u_data_g->ue_mapping, ue_context_p->ue_context.rnti, (void **)&gtpv1u_ue_data_p);

luaihui's avatar
luaihui committed
8208 8209 8210 8211 8212
      /* 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;
8213 8214 8215 8216 8217
        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;
luaihui's avatar
luaihui committed
8218
        ue_context_p->ue_context.nb_x2u_e_rabs = nb_e_rabs_tobesetup;
8219

8220
          for (int i = 0; i < nb_e_rabs_tobesetup; i++) {
8221 8222
          ip_offset               = 0;
          eps_bearer_id = x2ap_handover_req_ack->e_rabs_tobesetup[i].e_rab_id;
luaihui's avatar
luaihui committed
8223 8224
          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;
8225 8226
          gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_teNB = x2ap_handover_req_ack->e_rabs_tobesetup[i].gtp_teid;

8227
            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)) {
8228 8229 8230 8231
            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;
luaihui's avatar
luaihui committed
8232
          }
Cedric Roux's avatar
Cedric Roux committed
8233

8234 8235
            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);
8236
          }
luaihui's avatar
luaihui committed
8237 8238
        }
      }
8239

8240 8241 8242 8243
      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;
    }
8244

8245
    case X2AP_UE_CONTEXT_RELEASE: {
8246
      struct rrc_eNB_ue_context_s        *ue_context_p = NULL;
8247
      ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], X2AP_UE_CONTEXT_RELEASE(msg_p).rnti);
8248
      LOG_I(RRC, "[eNB %ld] source eNB receives the X2 UE CONTEXT RELEASE %s\n", instance, msg_name_p);
8249 8250
      DevAssert(ue_context_p != NULL);

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

8254 8255 8256 8257
      ue_context_p->ue_context.handover_info->state = HO_RELEASE;
      break;
    }

8258
    case X2AP_HANDOVER_CANCEL: {
Cedric Roux's avatar
Cedric Roux committed
8259 8260
      struct rrc_eNB_ue_context_s        *ue_context_p = NULL;
      char *cause;
8261

Cedric Roux's avatar
Cedric Roux committed
8262
      switch (X2AP_HANDOVER_CANCEL(msg_p).cause) {
8263 8264 8265 8266 8267 8268 8269 8270 8271 8272 8273
        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);
Cedric Roux's avatar
Cedric Roux committed
8274
      }
8275

Cedric Roux's avatar
Cedric Roux committed
8276
      ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], X2AP_HANDOVER_CANCEL(msg_p).rnti);
8277

8278 8279
        if (ue_context_p != NULL && ue_context_p->ue_context.handover_info != NULL) {
          LOG_I(RRC, "[eNB %ld] eNB receives X2 HANDOVER CANCEL for rnti %x, cause %s [%s]\n", instance, X2AP_HANDOVER_CANCEL(msg_p).rnti, cause, msg_name_p);
8280

Cedric Roux's avatar
Cedric Roux committed
8281 8282 8283
        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 */
8284
          ue_context_p->ue_context.StatusRrc = RRC_RECONFIGURED;
Cedric Roux's avatar
Cedric Roux committed
8285 8286 8287 8288 8289 8290 8291 8292 8293
          /* 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;
8294

Cedric Roux's avatar
Cedric Roux committed
8295 8296 8297 8298
        if (ue_context_p == NULL)
          failure_cause = "no UE found";
        else
          failure_cause = "UE not in handover";
8299

8300
          LOG_W(RRC, "[eNB %ld] cannot process (%s) X2 HANDOVER CANCEL for rnti %x, cause %s, ignoring\n", instance, failure_cause, X2AP_HANDOVER_CANCEL(msg_p).rnti, cause);
Cedric Roux's avatar
Cedric Roux committed
8301
      }
8302

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8303
      break;
Cedric Roux's avatar
Cedric Roux committed
8304
    }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
8305

8306 8307 8308 8309
    case X2AP_ENDC_SETUP_REQ:
      rrc_eNB_process_ENDC_x2_setup_request(instance, &X2AP_ENDC_SETUP_REQ(msg_p));
      break;

8310
    case X2AP_ENDC_SGNB_ADDITION_REQ_ACK: {
8311 8312
      rrc_eNB_process_AdditionResponseInformation(ENB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg_p));
      break;
8313 8314
    }

Cedric Roux's avatar
Cedric Roux committed
8315 8316 8317 8318 8319 8320 8321 8322 8323 8324
    case X2AP_ENDC_DC_PREP_TIMEOUT: {
      rrc_eNB_process_ENDC_DC_prep_timeout(ENB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_DC_PREP_TIMEOUT(msg_p));
      break;
    }

    case X2AP_ENDC_SGNB_RELEASE_REQUIRED: {
      rrc_eNB_process_ENDC_sgNB_release_required(ENB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_SGNB_RELEASE_REQUIRED(msg_p));
      break;
    }

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8325
    /* Messages from eNB app */
8326
    case RRC_CONFIGURATION_REQ:
8327
      LOG_I(RRC, "[eNB %ld] Received %s : %p\n", instance, msg_name_p, &RRC_CONFIGURATION_REQ(msg_p));
8328
      openair_rrc_eNB_configuration(ENB_INSTANCE_TO_MODULE_ID(instance), &RRC_CONFIGURATION_REQ(msg_p));
8329
      break;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
8330

8331
    /* Messages from F1AP task */
Raymond Knopp's avatar
Raymond Knopp committed
8332
    case F1AP_SETUP_REQ:
8333 8334
        AssertFatal(NODE_IS_CU(RC.rrc[instance]->node_type), "should not receive F1AP_SETUP_REQUEST, need call by CU!\n");
        LOG_I(RRC, "[eNB %ld] Received %s : %p\n", instance, msg_name_p, &F1AP_SETUP_REQ(msg_p));
8335
      handle_f1_setup_req(&F1AP_SETUP_REQ(msg_p));
8336
      break;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
8337

8338 8339
    case RRC_SUBFRAME_PROCESS:
      rrc_subframe_process(&RRC_SUBFRAME_PROCESS(msg_p).ctxt, RRC_SUBFRAME_PROCESS(msg_p).CC_id);
8340
      break;
8341

8342
    case M2AP_SETUP_RESP:
8343
        rrc_eNB_process_M2AP_SETUP_RESP(&ctxt, 0 /*CC_id*/, ENB_INSTANCE_TO_MODULE_ID(instance), &M2AP_SETUP_RESP(msg_p));
8344 8345 8346
      break;

    case M2AP_MBMS_SCHEDULING_INFORMATION:
8347
        rrc_eNB_process_M2AP_MBMS_SCHEDULING_INFORMATION(&ctxt, 0 /*CC_id*/, ENB_INSTANCE_TO_MODULE_ID(instance), &M2AP_MBMS_SCHEDULING_INFORMATION(msg_p));
8348
      break;
8349 8350

    case M2AP_MBMS_SESSION_START_REQ:
8351
        rrc_eNB_process_M2AP_MBMS_SESSION_START_REQ(&ctxt, 0 /*CC_id*/, ENB_INSTANCE_TO_MODULE_ID(instance), &M2AP_MBMS_SESSION_START_REQ(msg_p));
8352
      break;
8353 8354

    case M2AP_MBMS_SESSION_STOP_REQ:
8355
        rrc_eNB_process_M2AP_MBMS_SESSION_STOP_REQ(&ctxt, &M2AP_MBMS_SESSION_STOP_REQ(msg_p));
8356
      break;
8357 8358

    case M2AP_RESET:
8359
        rrc_eNB_process_M2AP_RESET(&ctxt, &M2AP_RESET(msg_p));
8360
      break;
8361 8362

    case M2AP_ENB_CONFIGURATION_UPDATE_ACK:
8363
        rrc_eNB_process_M2AP_ENB_CONFIGURATION_UPDATE_ACK(&ctxt, &M2AP_ENB_CONFIGURATION_UPDATE_ACK(msg_p));
8364
      break;
8365 8366

    case M2AP_ERROR_INDICATION:
8367
        rrc_eNB_process_M2AP_ERROR_INDICATION(&ctxt, &M2AP_ERROR_INDICATION(msg_p));
8368
      break;
8369 8370

    case M2AP_MBMS_SERVICE_COUNTING_REQ:
8371
        rrc_eNB_process_M2AP_MBMS_SERVICE_COUNTING_REQ(&ctxt, &M2AP_MBMS_SERVICE_COUNTING_REQ(msg_p));
8372
      break;
8373 8374

    case M2AP_MCE_CONFIGURATION_UPDATE:
8375
        rrc_eNB_process_M2AP_MCE_CONFIGURATION_UPDATE(&ctxt, &M2AP_MCE_CONFIGURATION_UPDATE(msg_p));
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
8376
      break;
8377

8378
    case RLC_SDU_INDICATION:
8379
        process_rlc_sdu_indication(instance, RLC_SDU_INDICATION(msg_p).rnti, RLC_SDU_INDICATION(msg_p).is_successful, RLC_SDU_INDICATION(msg_p).srb_id, RLC_SDU_INDICATION(msg_p).message_id);
8380
      break;
8381

8382
    default:
8383
      LOG_E(RRC, "[eNB %ld] Received unexpected message %s\n", instance, msg_name_p);
8384
      break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8385
  }
8386

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8387 8388 8389
  result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p);

  if (result != EXIT_SUCCESS) {
8390
      LOG_I(RRC, "Failed to free memory (%d)!\n", result);
8391
    }
8392
    itti_poll_msg(TASK_RRC_ENB, &msg_p);
8393
  }
8394
  return NULL;
Sergey Aranovskiy's avatar
Sergey Aranovskiy committed
8395
}
winckel's avatar
winckel committed
8396

8397 8398 8399 8400 8401 8402 8403 8404 8405 8406 8407 8408 8409 8410 8411 8412 8413 8414 8415 8416 8417 8418 8419 8420 8421
/*------------------------------------------------------------------------------*/
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;
    }

    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;
      }
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8422
  }
8423 8424 8425 8426 8427 8428 8429 8430 8431
}

//-----------------------------------------------------------------------------
void
rrc_top_cleanup_eNB(
  void
)
//-----------------------------------------------------------------------------
{
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8432
  for (int i=0; i<RC.nb_inst; i++) free (RC.rrc[i]);
8433 8434 8435 8436

  free(RC.rrc);
}

8437 8438

//-----------------------------------------------------------------------------
8439 8440 8441
//TTN - for D2D
uint8_t
rrc_eNB_process_SidelinkUEInformation(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8442 8443 8444
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t         *ue_context_pP,
  LTE_SidelinkUEInformation_r12_t *sidelinkUEInformation
8445 8446 8447
)
//-----------------------------------------------------------------------------
{
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8448 8449 8450 8451 8452 8453 8454 8455 8456 8457 8458 8459 8460 8461 8462 8463 8464 8465 8466 8467 8468 8469
  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]);
8470
          asn1cSeqAdd(&destinationInfoList->list, sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->destinationInfoList_r12.list.array[i]);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8471 8472 8473 8474
        }

        //generate RRC Reconfiguration
        rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, destinationInfoList, 0);
8475 8476
        free(destinationInfoList);
        destinationInfoList = NULL;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8477 8478 8479 8480 8481 8482 8483 8484 8485 8486 8487 8488
        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]);
8489
            asn1cSeqAdd(&destinationInfoList->list,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8490 8491 8492 8493 8494
                             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);
8495 8496
          free(destinationInfoList);
          destinationInfoList = NULL;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8497 8498 8499 8500 8501 8502 8503 8504 8505 8506 8507 8508 8509 8510 8511
          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]);
8512
            asn1cSeqAdd(&destinationInfoList->list,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8513 8514 8515 8516 8517
                             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);
8518 8519
          free(destinationInfoList);
          destinationInfoList = NULL;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8520 8521 8522 8523 8524 8525 8526 8527 8528 8529 8530 8531 8532 8533 8534
          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]);
8535
            asn1cSeqAdd(&destinationInfoList->list,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8536 8537 8538 8539 8540
                             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);
8541 8542
          free(destinationInfoList);
          destinationInfoList = NULL;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8543 8544 8545 8546 8547 8548 8549 8550 8551 8552 8553 8554 8555 8556 8557 8558 8559 8560 8561 8562 8563 8564 8565
          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;
        }
8566
      }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8567 8568 8569 8570
    }
  }

  return 0;
8571 8572 8573 8574 8575
}

//-----------------------------------------------------------------------------
int
rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8576 8577
  const protocol_ctxt_t *const ctxt_pP,
  rrc_eNB_ue_context_t *const ue_context_pP,
8578
  LTE_SL_DestinationInfoList_r12_t  *destinationInfoList,
8579 8580 8581 8582 8583
  int n_discoveryMessages
)
//-----------------------------------------------------------------------------
{
  uint8_t                             buffer[RRC_BUF_SIZE];
8584
  uint16_t                            size = 0;
8585
  memset(buffer, 0, sizeof(buffer));
8586 8587 8588 8589

  // 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
8590 8591 8592 8593 8594 8595 8596 8597
    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,
8598
                                           sizeof(buffer),
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8599 8600 8601 8602 8603 8604
                                           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
8605
                                           NULL, NULL,  NULL, NULL, NULL, NULL, NULL,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8606 8607
                                           (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)NULL,
                                           (LTE_SL_CommConfig_r12_t *)&sl_CommConfig,
8608 8609
                                           (LTE_SL_DiscConfig_r12_t *)NULL,
                                           (LTE_SCellToAddMod_r10_t *)NULL
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8610 8611
                                          );
    //
8612
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8613

8614 8615
  //populate dedicated resources for SL discovery (sl-DiscConfig)
  if (n_discoveryMessages > 0) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8616 8617 8618 8619 8620
    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,
8621
                                           sizeof(buffer),
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8622 8623 8624 8625 8626 8627
                                           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
8628
                                           NULL, NULL,  NULL, NULL, NULL, NULL, NULL,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8629 8630
                                           (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)NULL,
                                           (LTE_SL_CommConfig_r12_t *)NULL,
8631 8632
                                           (LTE_SL_DiscConfig_r12_t *)&sl_DiscConfig,
                                           (LTE_SCellToAddMod_r10_t *)NULL
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8633
                                          );
8634 8635
  }

8636
  LOG_I(RRC,"[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration_Sidelink (bytes %d, UE id %x)\n",
8637 8638 8639 8640 8641 8642 8643 8644 8645 8646 8647 8648 8649
        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
8650 8651
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
8652 8653
  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
8654
  LTE_SL_CommResourcePool_r12_t    *sc_CommTxConfig;
8655
  memset(sl_CommConfig,0,sizeof(LTE_SL_CommConfig_r12_t));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8656 8657 8658 8659 8660 8661
  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;
8662
  sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.buf[1] = 0x01; // ctxt_pP->rntiMaybeUEid;//rnti
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8663 8664 8665 8666 8667 8668 8669 8670 8671 8672 8673 8674 8675 8676 8677 8678 8679 8680 8681 8682 8683 8684 8685 8686 8687 8688 8689 8690 8691 8692 8693 8694 8695 8696 8697 8698 8699 8700 8701 8702 8703 8704 8705 8706 8707 8708 8709 8710 8711 8712 8713
  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;
8714 8715 8716
}


Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8717 8718 8719
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;
8720
  memset(&sl_DiscConfig,0,sizeof(LTE_SL_DiscConfig_r12_t));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8721 8722 8723 8724 8725 8726 8727
  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;
8728
}
8729

8730 8731
RRC_status_t
rrc_rx_tx(
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
8732
  protocol_ctxt_t *const ctxt_pP,
8733
  const int        CC_id
8734 8735 8736
)
//-----------------------------------------------------------------------------
{
8737
  MessageDef *message_p;
8738
  message_p = itti_alloc_new_message(TASK_RRC_ENB, 0, RRC_SUBFRAME_PROCESS);
8739 8740 8741
  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);
8742
  rrc_enb_process_itti_msg(NULL);
8743
  return RRC_OK;
8744
}