f1ap_cu_ue_context_management.c 95.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * 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
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
 * 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
 */

22 23
/*! \file f1ap_cu_ue_context_management.c
 * \brief F1AP UE Context Management, CU side
24 25 26 27 28 29 30 31 32 33
 * \author EURECOM/NTUST
 * \date 2018
 * \version 0.1
 * \company Eurecom
 * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
 * \note
 * \warning
 */

#include "f1ap_common.h"
34 35 36
#include "f1ap_encoder.h"
#include "f1ap_itti_messaging.h"
#include "f1ap_cu_ue_context_management.h"
Raymond Knopp's avatar
Raymond Knopp committed
37
#include <string.h>
38

39
#include "rrc_extern.h"
40
#include "openair2/RRC/NR/rrc_gNB_NGAP.h"
Laurent Thomas's avatar
Laurent Thomas committed
41
#include <openair3/ocp-gtpu/gtp_itf.h>
42
#include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
43

44
static void setQos(F1AP_NonDynamic5QIDescriptor_t *toFill) {
Laurent THOMAS's avatar
Laurent THOMAS committed
45
  asn1cCalloc(toFill, tmp);
46 47
  /* fiveQI */
  tmp->fiveQI = 1L;
48

49 50 51
  /* OPTIONAL */
  /* qoSPriorityLevel */
  if (0) {
Laurent THOMAS's avatar
Laurent THOMAS committed
52
    asn1cCallocOne(toFill->qoSPriorityLevel, 1L);
53
  }
54

55 56 57
  /* OPTIONAL */
  /* averagingWindow */
  if (0) {
Laurent THOMAS's avatar
Laurent THOMAS committed
58
    asn1cCallocOne(toFill->averagingWindow, 1L);
59
  }
60

61 62 63
  /* OPTIONAL */
  /* maxDataBurstVolume */
  if (0) {
Laurent THOMAS's avatar
Laurent THOMAS committed
64
    asn1cCallocOne(toFill->maxDataBurstVolume, 1L);
65 66 67
  }
}

68
int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
69
                                     f1ap_ue_context_setup_t *f1ap_ue_context_setup_req) {
70
  F1AP_F1AP_PDU_t  pdu= {0};
71 72 73
  /* Create */
  /* 0. Message Type */
  pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
Laurent THOMAS's avatar
Laurent THOMAS committed
74
  asn1cCalloc(pdu.choice.initiatingMessage, tmp);
75 76 77 78
  tmp->procedureCode = F1AP_ProcedureCode_id_UEContextSetup;
  tmp->criticality   = F1AP_Criticality_reject;
  tmp->value.present = F1AP_InitiatingMessage__value_PR_UEContextSetupRequest;
  F1AP_UEContextSetupRequest_t    *out = &pdu.choice.initiatingMessage->value.choice.UEContextSetupRequest;
79 80
  /* mandatory */
  /* c1. GNB_CU_UE_F1AP_ID */
81 82 83 84
  asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie1);
  ie1->id                             = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
  ie1->criticality                    = F1AP_Criticality_reject;
  ie1->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_GNB_CU_UE_F1AP_ID;
85
  ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_ue_context_setup_req->gNB_CU_ue_id;
86 87 88

  /* optional */
  /* c2. GNB_DU_UE_F1AP_ID */
89
  if (f1ap_ue_context_setup_req->gNB_DU_ue_id) {
90 91 92 93
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie2);
    ie2->id                             = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
    ie2->criticality                    = F1AP_Criticality_ignore;
    ie2->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_GNB_DU_UE_F1AP_ID;
94
    ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_ue_context_setup_req->gNB_DU_ue_id;
95 96 97 98
  }

  /* mandatory */
  /* c3. SpCell_ID */
99 100 101 102
  asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie3);
  ie3->id                             = F1AP_ProtocolIE_ID_id_SpCell_ID;
  ie3->criticality                    = F1AP_Criticality_reject;
  ie3->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_NRCGI;
103
  /* - nRCGI */
104
  addnRCGI(ie3->value.choice.NRCGI, f1ap_ue_context_setup_req);
105 106
  /* mandatory */
  /* c4. ServCellIndex */
107 108 109 110
  asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie4);
  ie4->id                             = F1AP_ProtocolIE_ID_id_ServCellIndex;
  ie4->criticality                    = F1AP_Criticality_reject;
  ie4->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_ServCellIndex;
Laurent THOMAS's avatar
Laurent THOMAS committed
111
  ie4->value.choice.ServCellIndex = 0;
Laurent Thomas's avatar
Laurent Thomas committed
112

113 114 115
  /* optional */
  /* c5. CellULConfigured */
  if (0) {
116 117 118 119 120
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie5);
    ie5->id                             = F1AP_ProtocolIE_ID_id_SpCellULConfigured;
    ie5->criticality                    = F1AP_Criticality_ignore;
    ie5->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_CellULConfigured;
    ie5->value.choice.CellULConfigured = F1AP_CellULConfigured_ul;
121 122 123 124
  }

  /* mandatory */
  /* c6. CUtoDURRCInformation */
125 126 127 128
  asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie6);
  ie6->id                             = F1AP_ProtocolIE_ID_id_CUtoDURRCInformation;
  ie6->criticality                    = F1AP_Criticality_reject;
  ie6->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_CUtoDURRCInformation;
129 130 131 132 133

  if (f1ap_ue_context_setup_req->cu_to_du_rrc_information!=NULL) {
    /* optional */
    /* 6.1 cG_ConfigInfo */
    if(f1ap_ue_context_setup_req->cu_to_du_rrc_information->cG_ConfigInfo!=NULL){
134
      asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.cG_ConfigInfo, cG_ConfigInfo);
matzakos's avatar
matzakos committed
135 136
      OCTET_STRING_fromBuf(cG_ConfigInfo, (const char *)f1ap_ue_context_setup_req->cu_to_du_rrc_information->cG_ConfigInfo,
        f1ap_ue_context_setup_req->cu_to_du_rrc_information->cG_ConfigInfo_length);
137
    }
138 139
    /* optional */
    /* 6.2 uE_CapabilityRAT_ContainerList */
140
    if(f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList!=NULL){
141
      asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList, uE_CapabilityRAT_ContainerList );
142
      OCTET_STRING_fromBuf(uE_CapabilityRAT_ContainerList, (const char *)f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList,
matzakos's avatar
matzakos committed
143
        f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length);
144
    }
145 146
    /* optional */
    /* 6.3 measConfig */
147
    if(f1ap_ue_context_setup_req->cu_to_du_rrc_information->measConfig!=NULL){
148
      asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.measConfig,  measConfig);
matzakos's avatar
matzakos committed
149 150
      OCTET_STRING_fromBuf(measConfig, (const char*)f1ap_ue_context_setup_req->cu_to_du_rrc_information->measConfig,
        f1ap_ue_context_setup_req->cu_to_du_rrc_information->measConfig_length);
151
    }
152
  }
153
  
154 155 156

  /* mandatory */
  /* c7. Candidate_SpCell_List */
Laurent THOMAS's avatar
Laurent THOMAS committed
157 158 159 160
  asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie7);
  ie7->id                             = F1AP_ProtocolIE_ID_id_Candidate_SpCell_List;  //90
  ie7->criticality                    = F1AP_Criticality_ignore;
  ie7->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_Candidate_SpCell_List;
Laurent Thomas's avatar
Laurent Thomas committed
161

Laurent THOMAS's avatar
Laurent THOMAS committed
162 163 164 165 166 167 168 169 170 171 172 173
  for (int i=0;   i<1;  i++) {
    asn1cSequenceAdd(ie7->value.choice.Candidate_SpCell_List.list,F1AP_Candidate_SpCell_ItemIEs_t, candidate_spCell_item_ies);
    candidate_spCell_item_ies->id            = F1AP_ProtocolIE_ID_id_Candidate_SpCell_Item; // 91
    candidate_spCell_item_ies->criticality   = F1AP_Criticality_reject;
    candidate_spCell_item_ies->value.present = F1AP_Candidate_SpCell_ItemIEs__value_PR_Candidate_SpCell_Item;
    /* 7.1 Candidate_SpCell_Item */
    F1AP_Candidate_SpCell_Item_t *candidate_spCell_item=
      &candidate_spCell_item_ies->value.choice.Candidate_SpCell_Item;
    /* - candidate_SpCell_ID */
    //FixMe: first cell ???
    addnRCGI(candidate_spCell_item->candidate_SpCell_ID,f1ap_ue_context_setup_req);
    /* TODO add correct mcc/mnc */
174
  }
175

176 177 178
  /* optional */
  /* c8. DRXCycle */
  if (0) {
179 180 181 182
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie8);
    ie8->id                             = F1AP_ProtocolIE_ID_id_DRXCycle;
    ie8->criticality                    = F1AP_Criticality_ignore;
    ie8->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_DRXCycle;
183
    /* 8.1 longDRXCycleLength */
184
    ie8->value.choice.DRXCycle.longDRXCycleLength = F1AP_LongDRXCycleLength_ms10; // enum
185

186 187
    /* optional */
    /* 8.2 shortDRXCycleLength */
188
    if (0) {
189
      asn1cCallocOne(ie6->value.choice.DRXCycle.shortDRXCycleLength,
Laurent THOMAS's avatar
Laurent THOMAS committed
190
                     F1AP_ShortDRXCycleLength_ms2); // enum
191
    }
192

193 194
    /* optional */
    /* 8.3 shortDRXCycleTimer */
195
    if (0) {
196
      asn1cCallocOne(ie8->value.choice.DRXCycle.shortDRXCycleTimer,
Laurent THOMAS's avatar
Laurent THOMAS committed
197
                     123L);
198 199 200 201 202 203
    }
  }

  /* optional */
  /* c9. ResourceCoordinationTransferContainer */
  if (0) {
204 205 206 207 208 209 210 211
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie9);
    ie9->id                             = F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer;
    ie9->criticality                    = F1AP_Criticality_ignore;
    ie9->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_ResourceCoordinationTransferContainer;
    ie9->value.choice.ResourceCoordinationTransferContainer.buf = malloc(4);
    ie9->value.choice.ResourceCoordinationTransferContainer.size = 4;
    strncpy((char *)ie9->value.choice.ResourceCoordinationTransferContainer.buf, "123", 4);
    OCTET_STRING_fromBuf(&ie9->value.choice.ResourceCoordinationTransferContainer, "asdsa1d32sa1d31asd31as",
212 213
                         strlen("asdsa1d32sa1d31asd31as"));
  }
Laurent Thomas's avatar
Laurent Thomas committed
214 215

  /* mandatory */
216
  /* c10. SCell_ToBeSetup_List */
Laurent OpenCells's avatar
Laurent OpenCells committed
217 218 219 220
  asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie10);
  ie10->id                             = F1AP_ProtocolIE_ID_id_SCell_ToBeSetup_List;
  ie10->criticality                    = F1AP_Criticality_ignore;
  ie10->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_SCell_ToBeSetup_List;
Laurent Thomas's avatar
Laurent Thomas committed
221

Laurent THOMAS's avatar
Laurent THOMAS committed
222
  for (int i=0; i<1; i++) {
Laurent OpenCells's avatar
Laurent OpenCells committed
223 224 225 226 227 228 229 230 231 232 233 234
    //
    asn1cSequenceAdd(ie10->value.choice.SCell_ToBeSetup_List.list, F1AP_SCell_ToBeSetup_ItemIEs_t, scell_toBeSetup_item_ies);
    scell_toBeSetup_item_ies->id            = F1AP_ProtocolIE_ID_id_SCell_ToBeSetup_Item; //53
    scell_toBeSetup_item_ies->criticality   = F1AP_Criticality_ignore;
    scell_toBeSetup_item_ies->value.present = F1AP_SCell_ToBeSetup_ItemIEs__value_PR_SCell_ToBeSetup_Item;
    /* 10.1 SCell_ToBeSetup_Item */
    F1AP_SCell_ToBeSetup_Item_t *scell_toBeSetup_item=&scell_toBeSetup_item_ies->value.choice.SCell_ToBeSetup_Item;
    /* 10.1.1 sCell_ID */
    addnRCGI(scell_toBeSetup_item->sCell_ID, f1ap_ue_context_setup_req);
    /* TODO correct MCC/MNC */
    /* 10.1.2 sCellIndex */
    scell_toBeSetup_item->sCellIndex = 3;  // issue here
235

Laurent OpenCells's avatar
Laurent OpenCells committed
236 237 238 239
    /* OPTIONAL */
    /* 10.1.3 sCellULConfigured*/
    if (0) {
      asn1cCallocOne(scell_toBeSetup_item->sCellULConfigured,
Laurent THOMAS's avatar
Laurent THOMAS committed
240
                     F1AP_CellULConfigured_ul_and_sul); // enum
241 242
    }
  }
243 244

  /* mandatory */
245
  /* c11. SRBs_ToBeSetup_List */
246
  if(f1ap_ue_context_setup_req->srbs_to_be_setup_length > 0){
matzakos's avatar
matzakos committed
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie11);
    ie11->id                             = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_List;
    ie11->criticality                    = F1AP_Criticality_reject;  // ?
    ie11->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_SRBs_ToBeSetup_List;

    for (int i=0; i<f1ap_ue_context_setup_req->srbs_to_be_setup_length; i++) {
      asn1cSequenceAdd(ie11->value.choice.SRBs_ToBeSetup_List.list, F1AP_SRBs_ToBeSetup_ItemIEs_t, srbs_toBeSetup_item_ies);
      srbs_toBeSetup_item_ies->id            = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_Item; // 73
      srbs_toBeSetup_item_ies->criticality   = F1AP_Criticality_ignore;
      srbs_toBeSetup_item_ies->value.present = F1AP_SRBs_ToBeSetup_ItemIEs__value_PR_SRBs_ToBeSetup_Item;
      /* 11.1 SRBs_ToBeSetup_Item */
      F1AP_SRBs_ToBeSetup_Item_t *srbs_toBeSetup_item=&srbs_toBeSetup_item_ies->value.choice.SRBs_ToBeSetup_Item;
      /* 11.1.1 sRBID */
      srbs_toBeSetup_item->sRBID = f1ap_ue_context_setup_req->srbs_to_be_setup[i].srb_id;
      /* OPTIONAL */
      /* 11.1.2 duplicationIndication */
      asn1cCallocOne(srbs_toBeSetup_item->duplicationIndication,
Laurent THOMAS's avatar
Laurent THOMAS committed
264
                   F1AP_DuplicationIndication_true); // enum
matzakos's avatar
matzakos committed
265
    }
266
  }
267 268 269

  /* mandatory */
  /* c12. DRBs_ToBeSetup_List */
270
  if(f1ap_ue_context_setup_req->drbs_to_be_setup_length){
matzakos's avatar
matzakos committed
271 272 273 274 275
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie12);
    ie12->id                             = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_List;
    ie12->criticality                    = F1AP_Criticality_reject;
    ie12->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_DRBs_ToBeSetup_List;
    LOG_I(F1AP, "Length of drbs_to_be_setup: %d \n", f1ap_ue_context_setup_req->drbs_to_be_setup_length);
276

matzakos's avatar
matzakos committed
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
    for (int i = 0; i < f1ap_ue_context_setup_req->drbs_to_be_setup_length; i++) {
      //
      asn1cSequenceAdd(ie12->value.choice.DRBs_ToBeSetup_List.list, F1AP_DRBs_ToBeSetup_ItemIEs_t, drbs_toBeSetup_item_ies);
      drbs_toBeSetup_item_ies->id            = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_Item;
      drbs_toBeSetup_item_ies->criticality   = F1AP_Criticality_reject;
      drbs_toBeSetup_item_ies->value.present = F1AP_DRBs_ToBeSetup_ItemIEs__value_PR_DRBs_ToBeSetup_Item;
      /* 12.1 DRBs_ToBeSetup_Item */
      F1AP_DRBs_ToBeSetup_Item_t *drbs_toBeSetup_item=&drbs_toBeSetup_item_ies->value.choice.DRBs_ToBeSetup_Item;
      /* 12.1.1 dRBID */
      drbs_toBeSetup_item->dRBID = f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id; // 9
      /* 12.1.2 qoSInformation */
      int some_decide_qos = 0; // BK: Need Check

      if (some_decide_qos) {
        drbs_toBeSetup_item->qoSInformation.present = F1AP_QoSInformation_PR_eUTRANQoS;
        /*  12.1.2.1 eUTRANQoS */
        asn1cCalloc(drbs_toBeSetup_item->qoSInformation.choice.eUTRANQoS, eUTRANQoS);
        /*  12.1.2.1.1 qCI */
        eUTRANQoS->qCI = 254L;
        /*  12.1.2.1.2 allocationAndRetentionPriority */
297
        {
matzakos's avatar
matzakos committed
298 299 300 301 302 303
          /*  12.1.2.1.2.1 priorityLevel */
          eUTRANQoS->allocationAndRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum
          /*  12.1.2.1.2.2 pre_emptionCapability */
          eUTRANQoS->allocationAndRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_may_trigger_pre_emption; // enum
          /*  12.1.2.1.2.2 pre_emptionVulnerability */
          eUTRANQoS->allocationAndRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum
304
        }
305

306
        /* OPTIONAL */
matzakos's avatar
matzakos committed
307
        /*  12.1.2.1.3 gbrQosInformation */
308
        if (0) {
matzakos's avatar
matzakos committed
309 310 311 312 313
          eUTRANQoS->gbrQosInformation = (F1AP_GBR_QosInformation_t *)calloc(1, sizeof(F1AP_GBR_QosInformation_t));
          asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_MaximumBitrateDL, 1L);
          asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_MaximumBitrateUL, 1L);
          asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_GuaranteedBitrateDL, 1L);
          asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_GuaranteedBitrateUL, 1L);
314
        }
matzakos's avatar
matzakos committed
315 316 317 318 319 320 321 322 323 324
      } else {
        /* 12.1.2 DRB_Information */
        drbs_toBeSetup_item->qoSInformation.present = F1AP_QoSInformation_PR_choice_extension;
        F1AP_QoSInformation_ExtIEs_t *ie = (F1AP_QoSInformation_ExtIEs_t *)calloc(1, sizeof(*ie));
        ie->id                             = F1AP_ProtocolIE_ID_id_DRB_Information;
        ie->criticality                    = F1AP_Criticality_reject;
        ie->value.present                  = F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information;
        F1AP_DRB_Information_t   *DRB_Information = &ie->value.choice.DRB_Information;
        drbs_toBeSetup_item->qoSInformation.choice.choice_extension = (struct F1AP_ProtocolIE_SingleContainer *)ie;
        /* 12.1.2.1 dRB_QoS */
325
        {
326 327
          /* qoS_Characteristics */
          {
328
            int some_decide_qoS_characteristics = 0; // BK: Need Check
329

330
            if (some_decide_qoS_characteristics) {
matzakos's avatar
matzakos committed
331 332
              DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI;
              setQos(DRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI);
333
            } else {
matzakos's avatar
matzakos committed
334 335
              DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_dynamic_5QI;
              asn1cCalloc(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI, tmp);
336
              /* qoSPriorityLevel */
337
              tmp->qoSPriorityLevel = 1L;
338
              /* packetDelayBudget */
339
              tmp->packetDelayBudget = 1L;
340
              /* packetErrorRate */
341 342 343
              tmp->packetErrorRate.pER_Scalar = 1L;
              tmp->packetErrorRate.pER_Exponent = 6L;

344 345 346
              /* OPTIONAL */
              /* delayCritical */
              if (0) {
matzakos's avatar
matzakos committed
347
                asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->delayCritical, 1L);
348 349 350 351 352
              }

              /* OPTIONAL */
              /* averagingWindow */
              if (0) {
matzakos's avatar
matzakos committed
353
                asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->averagingWindow, 1L);
354 355 356 357 358
              }

              /* OPTIONAL */
              /* maxDataBurstVolume */
              if (0) {
matzakos's avatar
matzakos committed
359
                asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume, 1L);
360 361 362 363 364
              }
            } // if some_decide_qoS_characteristics
          } // qoS_Characteristics
          /* nGRANallocationRetentionPriority */
          {
matzakos's avatar
matzakos committed
365 366 367
            DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum
            DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum
            DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum
368 369 370 371 372
          } // nGRANallocationRetentionPriority

          /* OPTIONAL */
          /* gBR_QoS_Flow_Information */
          if (0) {
matzakos's avatar
matzakos committed
373
            asn1cCalloc(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information, tmp);
374 375 376 377
            asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L);
            asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L);
            asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L);
            asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, 1L);
378 379 380 381

            /* OPTIONAL */
            /* maxPacketLossRateDownlink */
            if (0) {
matzakos's avatar
matzakos committed
382
              asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L);
383 384 385 386 387
            }

            /* OPTIONAL */
            /* maxPacketLossRateUplink */
            if (0) {
matzakos's avatar
matzakos committed
388
              asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L);
389 390 391 392 393 394
            }
          }

          /* OPTIONAL */
          /* reflective_QoS_Attribute */
          if (0) {
matzakos's avatar
matzakos committed
395
            asn1cCallocOne(DRB_Information->dRB_QoS.reflective_QoS_Attribute, 1L);
396
          }
matzakos's avatar
matzakos committed
397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 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 497 498 499 500 501 502 503 504 505 506 507 508
        } // dRB_QoS
        /* 12.1.2.2 sNSSAI */
        {
          /* sST */
          OCTET_STRING_fromBuf(&DRB_Information->sNSSAI.sST, "1", 1);

          /* OPTIONAL */
          /* sD */
          if (0) {
            asn1cCalloc(DRB_Information->sNSSAI.sD, tmp);
            OCTET_STRING_fromBuf(tmp, "asdsa1d32sa1d31asd31as",
                               strlen("asdsa1d32sa1d31asd31as"));
          }
        }

        /* OPTIONAL */
        /* 12.1.2.3 notificationControl */
        if (0) {
          asn1cCallocOne(DRB_Information->notificationControl,
            F1AP_NotificationControl_active); // enum
        }

        /* 12.1.2.4 flows_Mapped_To_DRB_List */  // BK: need verifiy

        for (int k = 0; k < 1; k ++) {
          asn1cSequenceAdd(DRB_Information->flows_Mapped_To_DRB_List.list,
            F1AP_Flows_Mapped_To_DRB_Item_t, flows_mapped_to_drb_item);
          /* qoSFlowIndicator */
          flows_mapped_to_drb_item->qoSFlowIdentifier = 1L;
          /* qoSFlowLevelQoSParameters */
          {
            /* qoS_Characteristics */
            {
              int some_decide_qoS_characteristics = 0; // BK: Need Check
              F1AP_QoS_Characteristics_t *QosParams=&flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.qoS_Characteristics;

              if (some_decide_qoS_characteristics) {
                QosParams->present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI;
                setQos(QosParams->choice.non_Dynamic_5QI);
              } else {
                QosParams->present = F1AP_QoS_Characteristics_PR_dynamic_5QI;
                asn1cCalloc(QosParams->choice.dynamic_5QI, tmp);
                /* qoSPriorityLevel */
                tmp->qoSPriorityLevel = 1L;
                /* packetDelayBudget */
                tmp->packetDelayBudget = 1L;
                /* packetErrorRate */
                tmp->packetErrorRate.pER_Scalar = 1L;
                tmp->packetErrorRate.pER_Exponent = 6L;

                /* OPTIONAL */
                /* delayCritical */
                if (0) {
                  asn1cCalloc(QosParams->choice.dynamic_5QI->delayCritical, tmp);
                  *tmp = 1L;
                }

                /* OPTIONAL */
                /* averagingWindow */
                if (0) {
                  asn1cCalloc(QosParams->choice.dynamic_5QI->averagingWindow, tmp);
                  *tmp = 1L;
                }

                /* OPTIONAL */
                /* maxDataBurstVolume */
                if (0) {
                  asn1cCalloc(QosParams->choice.dynamic_5QI->maxDataBurstVolume, tmp);
                  *tmp= 1L;
                }
              } // if some_decide_qoS_characteristics
            } // qoS_Characteristics
            /* nGRANallocationRetentionPriority */
            {
              flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum
              flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum
              flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum
            } // nGRANallocationRetentionPriority

            /* OPTIONAL */
            /* gBR_QoS_Flow_Information */
            if (0) {
              asn1cCalloc(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information, tmp);
              asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L);
              asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L);
              asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L);
              asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, 1L);

              /* OPTIONAL */
              /* maxPacketLossRateDownlink */
              if (0) {
                asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L);
              }

              /* OPTIONAL */
              /* maxPacketLossRateUplink */
              if (0) {
                asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L);
              }
            }

            /* OPTIONAL */
            /* reflective_QoS_Attribute */
            if (0) {
              asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.reflective_QoS_Attribute, 1L);
            }
          } // qoSFlowLevelQoSParameters
        }
      } // if some_decide_qos

      /* 12.1.3 uLUPTNLInformation_ToBeSetup_List */
      for (int j = 0; j < f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) {
509
        /*Use a dummy teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU*/
510
        /* Use a dummy address and teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU */
511
        transport_layer_addr_t addr = { .length= 32, .buffer= { 0 } };
512
        f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst,
513
                                                                                               f1ap_ue_context_setup_req->gNB_CU_ue_id,
514 515 516 517
                                                                                               f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id,
                                                                                               f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id,
                                                                                               0xFFFF, // We will set the right value from DU answer
                                                                                               -1, // no qfi
518
                                                                                               addr,   // We will set the right value from DU answer
519 520 521
                                                                                               f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].port,
                                                                                               cu_f1u_data_req,
                                                                                               NULL);
matzakos's avatar
matzakos committed
522 523 524 525 526 527 528 529
        /*  12.3.1 ULTunnels_ToBeSetup_Item */
        asn1cSequenceAdd(drbs_toBeSetup_item->uLUPTNLInformation_ToBeSetup_List.list,
          F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item);
        uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel;
        asn1cCalloc( uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel,
          gTPTunnel);
        /* 12.3.1.1.1 transportLayerAddress */
        TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].tl_address,
Laurent Thomas's avatar
Laurent Thomas committed
530
          &gTPTunnel->transportLayerAddress);
matzakos's avatar
matzakos committed
531 532 533 534
        /* 12.3.1.1.2 gTP_TEID */
        INT32_TO_OCTET_STRING(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid,
          &gTPTunnel->gTP_TEID);
      }
535

matzakos's avatar
matzakos committed
536 537 538 539 540 541
      /* 12.1.4 rLCMode */
      /* TODO use rlc_mode from f1ap_drb_to_be_setup */
      switch (f1ap_ue_context_setup_req->drbs_to_be_setup[i].rlc_mode) {
        case RLC_MODE_AM:
          drbs_toBeSetup_item->rLCMode = F1AP_RLCMode_rlc_am;
          break;
542

matzakos's avatar
matzakos committed
543 544 545
        default:
          drbs_toBeSetup_item->rLCMode = F1AP_RLCMode_rlc_um_bidirectional;
      }
546

matzakos's avatar
matzakos committed
547 548 549 550 551 552
      /* OPTIONAL */
      /* 12.1.5 ULConfiguration */
      if (0) {
        asn1cCalloc(drbs_toBeSetup_item->uLConfiguration, tmp);
        tmp->uLUEConfiguration = F1AP_ULUEConfiguration_no_data;
      }
553

matzakos's avatar
matzakos committed
554 555 556 557 558 559
      /* OPTIONAL */
      /* 12.1.6 duplicationActivation */
      if (0) {
        asn1cCalloc(drbs_toBeSetup_item->duplicationActivation, tmp);
        *tmp = F1AP_DuplicationActivation_active;  // enum
      }
560 561
    }
  }
562

563
  /* OPTIONAL */
564 565
  /* InactivityMonitoringRequest */
  if (0) {
566 567 568 569 570
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie12);
    ie12->id                             = F1AP_ProtocolIE_ID_id_InactivityMonitoringRequest;
    ie12->criticality                    = F1AP_Criticality_reject;
    ie12->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_InactivityMonitoringRequest;
    ie12->value.choice.InactivityMonitoringRequest = F1AP_InactivityMonitoringRequest_true; // 0
571 572 573 574 575
  }

  /* OPTIONAL */
  /* RAT_FrequencyPriorityInformation */
  if (0) {
576 577 578 579 580
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie13);
    ie13->id                             = F1AP_ProtocolIE_ID_id_RAT_FrequencyPriorityInformation;
    ie13->criticality                    = F1AP_Criticality_reject;
    ie13->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_RAT_FrequencyPriorityInformation;
    int endc = 1; // RK: Get this from somewhere ...
581

Xue Song's avatar
Xue Song committed
582
    if (endc) {
583 584
      ie13->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_eNDC;
      ie13->value.choice.RAT_FrequencyPriorityInformation.choice.eNDC = 11L;
585
    } else {
586 587
      ie13->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_nGRAN;
      ie13->value.choice.RAT_FrequencyPriorityInformation.choice.nGRAN = 11L;
588 589 590 591 592
    }
  }

  /* OPTIONAL */
  /* RRCContainer */
593 594 595 596 597 598 599
  if(f1ap_ue_context_setup_req->rrc_container_length > 0) {
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie14);
    ie14->id                             = F1AP_ProtocolIE_ID_id_RRCContainer;
    ie14->criticality                    = F1AP_Criticality_reject;
    ie14->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_RRCContainer;
    OCTET_STRING_fromBuf(&ie14->value.choice.RRCContainer, (const char *)f1ap_ue_context_setup_req->rrc_container,
                         f1ap_ue_context_setup_req->rrc_container_length);
600
  }
601 602 603 604

  /* OPTIONAL */
  /* MaskedIMEISV */
  if (0) {
605 606 607 608 609
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie15);
    ie15->id                             = F1AP_ProtocolIE_ID_id_MaskedIMEISV;
    ie15->criticality                    = F1AP_Criticality_reject;
    ie15->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_MaskedIMEISV;
    MaskedIMEISV_TO_BIT_STRING(12340000l, &ie15->value.choice.MaskedIMEISV); // size (64)
610 611 612
  }

  /* encode */
Laurent THOMAS's avatar
Laurent THOMAS committed
613 614 615
  uint8_t  *buffer=NULL;
  uint32_t  len=0;

616
  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
Xue Song's avatar
Xue Song committed
617
    LOG_E(F1AP, "Failed to encode F1 UE CONTEXT SETUP REQUEST\n");
618
    return -1;
619 620
  }

Xue Song's avatar
Xue Song committed
621 622 623 624 625 626 627 628 629
  // xer_fprint(stdout, &asn_DEF_F1AP_F1AP_PDU, (void *)pdu);
  // asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
  // res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu);
  // buffer = res.buffer;
  // len = res.result.encoded;
  // if (res.result.encoded <= 0) {
  //   LOG_E(F1AP, "ASN1 message encoding failed (%s, %lu)!\n", res.result.failed_type->name, res.result.encoded);
  //   return -1;
  // }
Xue Song's avatar
Xue Song committed
630
  LOG_D(F1AP,"F1AP UEContextSetupRequest Encoded %u bits\n", len);
631
  f1ap_itti_send_sctp_data_req(true, instance, buffer, len, 0 /* BK: fix me*/);
632
  return 0;
633 634
}

635 636 637 638
int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t       instance,
                                        uint32_t         assoc_id,
                                        uint32_t         stream,
                                        F1AP_F1AP_PDU_t *pdu) {
639
  MessageDef                       *msg_p;
Xue Song's avatar
Xue Song committed
640 641 642
  F1AP_UEContextSetupResponse_t    *container;
  F1AP_UEContextSetupResponseIEs_t *ie;
  DevAssert(pdu);
643
  msg_p = itti_alloc_new_message(TASK_DU_F1, 0,  F1AP_UE_CONTEXT_SETUP_RESP);
644
  f1ap_ue_context_setup_t *f1ap_ue_context_setup_resp = &F1AP_UE_CONTEXT_SETUP_RESP(msg_p);
Xue Song's avatar
Xue Song committed
645
  container = &pdu->choice.successfulOutcome->value.choice.UEContextSetupResponse;
646
  int i;
Xue Song's avatar
Xue Song committed
647 648
  /* GNB_CU_UE_F1AP_ID */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupResponseIEs_t, ie, container,
649
                             F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
Laurent Thomas's avatar
Laurent Thomas committed
650
  f1ap_ue_context_setup_resp->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
651
  LOG_D(F1AP, "f1ap_ue_context_setup_resp->gNB_CU_ue_id is: %d \n", f1ap_ue_context_setup_resp->gNB_CU_ue_id);
Xue Song's avatar
Xue Song committed
652 653 654
  /* GNB_DU_UE_F1AP_ID */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupResponseIEs_t, ie, container,
                             F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
655
  f1ap_ue_context_setup_resp->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
656
  LOG_D(F1AP, "f1ap_ue_context_setup_resp->gNB_DU_ue_id is: %d \n", f1ap_ue_context_setup_resp->gNB_DU_ue_id);
Laurent Thomas's avatar
Laurent Thomas committed
657
  // DUtoCURRCInformation
Xue Song's avatar
Xue Song committed
658 659
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupResponseIEs_t, ie, container,
                             F1AP_ProtocolIE_ID_id_DUtoCURRCInformation, true);
Laurent Thomas's avatar
Laurent Thomas committed
660 661

  if (ie == NULL) {
662 663 664
    LOG_E(F1AP,"%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
    return -1;
  }
665

matzakos's avatar
matzakos committed
666 667 668 669
  f1ap_ue_context_setup_resp->du_to_cu_rrc_information = (du_to_cu_rrc_information_t *)calloc(1,sizeof(du_to_cu_rrc_information_t));
  f1ap_ue_context_setup_resp->du_to_cu_rrc_information->cellGroupConfig = (uint8_t *)calloc(1,ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size);
  memcpy(f1ap_ue_context_setup_resp->du_to_cu_rrc_information->cellGroupConfig, ie->value.choice.DUtoCURRCInformation.cellGroupConfig.buf, ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size);
  f1ap_ue_context_setup_resp->du_to_cu_rrc_information->cellGroupConfig_length = ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size;
Laurent Thomas's avatar
Laurent Thomas committed
670
  // DRBs_Setup_List
Xue Song's avatar
Xue Song committed
671
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupResponseIEs_t, ie, container,
672
                             F1AP_ProtocolIE_ID_id_DRBs_Setup_List, false);
Laurent Thomas's avatar
Laurent Thomas committed
673 674

  if(ie!=NULL) {
675 676
    f1ap_ue_context_setup_resp->drbs_to_be_setup_length = ie->value.choice.DRBs_Setup_List.list.count;
    f1ap_ue_context_setup_resp->drbs_to_be_setup = calloc(f1ap_ue_context_setup_resp->drbs_to_be_setup_length,
677
        sizeof(f1ap_drb_to_be_setup_t));
678
    AssertFatal(f1ap_ue_context_setup_resp->drbs_to_be_setup,
Laurent Thomas's avatar
Laurent Thomas committed
679 680
                "could not allocate memory for f1ap_ue_context_setup_resp->drbs_setup\n");

681 682
    for (i = 0; i < f1ap_ue_context_setup_resp->drbs_to_be_setup_length; ++i) {
      f1ap_drb_to_be_setup_t *drb_p = &f1ap_ue_context_setup_resp->drbs_to_be_setup[i];
683 684 685
      F1AP_DRBs_Setup_Item_t *drbs_setup_item_p;
      drbs_setup_item_p = &((F1AP_DRBs_Setup_ItemIEs_t *)ie->value.choice.DRBs_Setup_List.list.array[i])->value.choice.DRBs_Setup_Item;
      drb_p->drb_id = drbs_setup_item_p->dRBID;
686
      // TODO in the following, assume only one UP UL TNL is present.
Laurent Thomas's avatar
Laurent Thomas committed
687
      // this matches/assumes OAI CU/DU implementation, can be up to 2!
688 689
      drb_p->up_dl_tnl_length = 1;
      AssertFatal(drbs_setup_item_p->dLUPTNLInformation_ToBeSetup_List.list.count > 0,
Laurent Thomas's avatar
Laurent Thomas committed
690
                  "no DL UP TNL Information in DRBs to be Setup list\n");
691 692 693
      F1AP_DLUPTNLInformation_ToBeSetup_Item_t *dl_up_tnl_info_p = (F1AP_DLUPTNLInformation_ToBeSetup_Item_t *)drbs_setup_item_p->dLUPTNLInformation_ToBeSetup_List.list.array[0];
      F1AP_GTPTunnel_t *dl_up_tnl0 = dl_up_tnl_info_p->dLUPTNLInformation.choice.gTPTunnel;
      BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address);
694
      OCTET_STRING_TO_UINT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid);
695
      GtpuUpdateTunnelOutgoingAddressAndTeid(getCxt(CUtype, instance)->gtpInst,
696
                                             f1ap_ue_context_setup_resp->gNB_DU_ue_id,
697 698 699
                                             (ebi_t)drbs_setup_item_p->dRBID,
                                             drb_p->up_dl_tnl[0].tl_address,
                                             drb_p->up_dl_tnl[0].teid);
700 701
    }
  }
Laurent Thomas's avatar
Laurent Thomas committed
702 703

  // SRBs_FailedToBeSetup_List
Xue Song's avatar
Xue Song committed
704
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupResponseIEs_t, ie, container,
705
                             F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetup_List, false);
Laurent Thomas's avatar
Laurent Thomas committed
706 707

  if(ie!=NULL) {
708 709 710 711
    f1ap_ue_context_setup_resp->srbs_failed_to_be_setup_length = ie->value.choice.SRBs_FailedToBeSetup_List.list.count;
    f1ap_ue_context_setup_resp->srbs_failed_to_be_setup = calloc(f1ap_ue_context_setup_resp->srbs_failed_to_be_setup_length,
        sizeof(f1ap_rb_failed_to_be_setup_t));
    AssertFatal(f1ap_ue_context_setup_resp->srbs_failed_to_be_setup,
Laurent Thomas's avatar
Laurent Thomas committed
712 713
                "could not allocate memory for f1ap_ue_context_setup_resp->srbs_failed_to_be_setup\n");

714 715 716 717 718
    for (i = 0; i < f1ap_ue_context_setup_resp->srbs_failed_to_be_setup_length; ++i) {
      f1ap_rb_failed_to_be_setup_t *srb_p = &f1ap_ue_context_setup_resp->srbs_failed_to_be_setup[i];
      srb_p->rb_id = ((F1AP_SRBs_FailedToBeSetup_Item_t *)ie->value.choice.SRBs_FailedToBeSetup_List.list.array[i])->sRBID;
    }
  }
Laurent Thomas's avatar
Laurent Thomas committed
719 720

  // DRBs_FailedToBeSetup_List
Xue Song's avatar
Xue Song committed
721
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupResponseIEs_t, ie, container,
722
                             F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetup_List, false);
Laurent Thomas's avatar
Laurent Thomas committed
723 724

  if(ie!=NULL) {
725 726 727 728
    f1ap_ue_context_setup_resp->drbs_failed_to_be_setup_length = ie->value.choice.DRBs_FailedToBeSetup_List.list.count;
    f1ap_ue_context_setup_resp->drbs_failed_to_be_setup = calloc(f1ap_ue_context_setup_resp->drbs_failed_to_be_setup_length,
        sizeof(f1ap_rb_failed_to_be_setup_t));
    AssertFatal(f1ap_ue_context_setup_resp->drbs_failed_to_be_setup,
Laurent Thomas's avatar
Laurent Thomas committed
729 730
                "could not allocate memory for f1ap_ue_context_setup_resp->drbs_failed_to_be_setup\n");

731 732 733 734 735 736
    for (i = 0; i < f1ap_ue_context_setup_resp->drbs_failed_to_be_setup_length; ++i) {
      f1ap_rb_failed_to_be_setup_t *drb_p = &f1ap_ue_context_setup_resp->drbs_failed_to_be_setup[i];
      drb_p->rb_id = ((F1AP_DRBs_FailedToBeSetup_Item_t *)ie->value.choice.DRBs_FailedToBeSetup_List.list.array[i])->dRBID;
    }
  }

Laurent Thomas's avatar
Laurent Thomas committed
737
  // SCell_FailedtoSetup_List
Xue Song's avatar
Xue Song committed
738
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupResponseIEs_t, ie, container,
739
                             F1AP_ProtocolIE_ID_id_SCell_FailedtoSetup_List, false);
Laurent Thomas's avatar
Laurent Thomas committed
740 741

  if(ie!=NULL) {
742 743 744
    LOG_E (F1AP, "Not supporting handling of SCell_FailedtoSetup_List \n");
  }

Laurent Thomas's avatar
Laurent Thomas committed
745
  // SRBs_Setup_List
746
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupResponseIEs_t, ie, container,
Laurent Thomas's avatar
Laurent Thomas committed
747 748 749
                             F1AP_ProtocolIE_ID_id_SRBs_Setup_List, false);

  if(ie!=NULL) {
750 751
    f1ap_ue_context_setup_resp->srbs_to_be_setup_length = ie->value.choice.SRBs_Setup_List.list.count;
    f1ap_ue_context_setup_resp->srbs_to_be_setup = calloc(f1ap_ue_context_setup_resp->srbs_to_be_setup_length,
752
        sizeof(f1ap_srb_to_be_setup_t));
753
    AssertFatal(f1ap_ue_context_setup_resp->srbs_to_be_setup,
Laurent Thomas's avatar
Laurent Thomas committed
754 755
                "could not allocate memory for f1ap_ue_context_setup_resp->drbs_setup\n");

756 757
    for (i = 0; i < f1ap_ue_context_setup_resp->srbs_to_be_setup_length; ++i) {
      f1ap_srb_to_be_setup_t *srb_p = &f1ap_ue_context_setup_resp->srbs_to_be_setup[i];
758 759 760 761 762 763 764 765
      F1AP_SRBs_Setup_Item_t *srbs_setup_item_p;
      srbs_setup_item_p = &((F1AP_SRBs_Setup_ItemIEs_t *)ie->value.choice.SRBs_Setup_List.list.array[i])->value.choice.SRBs_Setup_Item;
      srb_p->srb_id = srbs_setup_item_p->sRBID;
      srb_p->lcid = srbs_setup_item_p->lCID;
    }
  }

  itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p);
Xue Song's avatar
Xue Song committed
766
  return 0;
767 768
}

769 770 771 772
int CU_handle_UE_CONTEXT_SETUP_FAILURE(instance_t       instance,
                                       uint32_t         assoc_id,
                                       uint32_t         stream,
                                       F1AP_F1AP_PDU_t *pdu) {
773 774 775
  AssertFatal(1==0,"Not implemented yet\n");
}

776 777 778 779
int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
{
  MessageDef *msg = itti_alloc_new_message(TASK_CU_F1, 0,  F1AP_UE_CONTEXT_RELEASE_REQ);
  f1ap_ue_context_release_req_t *req = &F1AP_UE_CONTEXT_RELEASE_REQ(msg);
780 781 782 783 784 785 786
  F1AP_UEContextReleaseRequest_t    *container;
  F1AP_UEContextReleaseRequestIEs_t *ie;
  DevAssert(pdu);
  container = &pdu->choice.initiatingMessage->value.choice.UEContextReleaseRequest;
  /* GNB_CU_UE_F1AP_ID */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container,
                             F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
787
  req->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
788

789 790 791
  /* GNB_DU_UE_F1AP_ID */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container,
                             F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
792
  req->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
793

794 795 796 797 798 799 800
  /* Cause */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container,
                             F1AP_ProtocolIE_ID_id_Cause, true);

  switch(ie->value.choice.Cause.present)
  {
    case F1AP_Cause_PR_radioNetwork:
801 802
      req->cause = F1AP_CAUSE_RADIO_NETWORK;
      req->cause_value = ie->value.choice.Cause.choice.radioNetwork;
803 804
      break;
    case F1AP_Cause_PR_transport:
805 806
      req->cause = F1AP_CAUSE_TRANSPORT;
      req->cause_value = ie->value.choice.Cause.choice.transport;
807 808
      break;
    case F1AP_Cause_PR_protocol:
809 810
      req->cause = F1AP_CAUSE_PROTOCOL;
      req->cause_value = ie->value.choice.Cause.choice.protocol;
811 812
      break;
    case F1AP_Cause_PR_misc:
813 814
      req->cause = F1AP_CAUSE_MISC;
      req->cause_value = ie->value.choice.Cause.choice.misc;
815 816 817
      break;
    case F1AP_Cause_PR_NOTHING:
    default:
818
      req->cause = F1AP_CAUSE_NOTHING;
819 820
      break;
  }
821

822 823 824 825 826 827 828
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container, F1AP_ProtocolIE_ID_id_targetCellsToCancel, false);
  if (ie != NULL) {
    LOG_W(F1AP, "ignoring list of target cells to cancel in UE Context Release Request: implementation missing\n");
  }

  itti_send_msg_to_task(TASK_RRC_GNB, instance, msg);

829
  return 0;
830 831 832
}


833
int CU_send_UE_CONTEXT_RELEASE_COMMAND(instance_t instance,
834
                                       f1ap_ue_context_release_cmd_t *cmd) {
835
  F1AP_F1AP_PDU_t                   pdu= {0};
836
  F1AP_UEContextReleaseCommand_t    *out;
837 838
  uint8_t  *buffer=NULL;
  uint32_t  len=0;
839 840 841
  /* Create */
  /* 0. Message Type */
  pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
Laurent THOMAS's avatar
Laurent THOMAS committed
842
  asn1cCalloc(pdu.choice.initiatingMessage, tmp);
843 844 845 846
  tmp->procedureCode = F1AP_ProcedureCode_id_UEContextRelease;
  tmp->criticality   = F1AP_Criticality_reject;
  tmp->value.present = F1AP_InitiatingMessage__value_PR_UEContextReleaseCommand;
  out = &tmp->value.choice.UEContextReleaseCommand;
847 848
  /* mandatory */
  /* c1. GNB_CU_UE_F1AP_ID */
849 850 851 852
  asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseCommandIEs_t, ie1);
  ie1->id                             = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
  ie1->criticality                    = F1AP_Criticality_reject;
  ie1->value.present                  = F1AP_UEContextReleaseCommandIEs__value_PR_GNB_CU_UE_F1AP_ID;
853
  ie1->value.choice.GNB_CU_UE_F1AP_ID = cmd->gNB_CU_ue_id;
854 855
  /* mandatory */
  /* c2. GNB_DU_UE_F1AP_ID */
856 857 858 859
  asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseCommandIEs_t, ie2);
  ie2->id                             = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
  ie2->criticality                    = F1AP_Criticality_reject;
  ie2->value.present                  = F1AP_UEContextReleaseCommandIEs__value_PR_GNB_DU_UE_F1AP_ID;
860
  ie2->value.choice.GNB_DU_UE_F1AP_ID = cmd->gNB_DU_ue_id;
861 862
  /* mandatory */
  /* c3. Cause */
863 864 865 866
  asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseCommandIEs_t, ie3);
  ie3->id                             = F1AP_ProtocolIE_ID_id_Cause;
  ie3->criticality                    = F1AP_Criticality_ignore;
  ie3->value.present                  = F1AP_UEContextReleaseCommandIEs__value_PR_Cause;
867

868 869
  switch (cmd->cause) {
    case F1AP_CAUSE_RADIO_NETWORK:
870 871
      ie3->value.choice.Cause.present = F1AP_Cause_PR_radioNetwork;
      ie3->value.choice.Cause.choice.radioNetwork = cmd->cause_value;
872
      break;
873

874
    case F1AP_CAUSE_TRANSPORT:
875 876
      ie3->value.choice.Cause.present = F1AP_Cause_PR_transport;
      ie3->value.choice.Cause.choice.transport = cmd->cause_value;
877
      break;
878

879
    case F1AP_CAUSE_PROTOCOL:
880 881
      ie3->value.choice.Cause.present = F1AP_Cause_PR_protocol;
      ie3->value.choice.Cause.choice.protocol = cmd->cause_value;
882
      break;
883

884
    case F1AP_CAUSE_MISC:
885 886
      ie3->value.choice.Cause.present = F1AP_Cause_PR_misc;
      ie3->value.choice.Cause.choice.misc = cmd->cause_value;
887
      break;
888

889
    case F1AP_CAUSE_NOTHING:
890
    default:
891
      ie3->value.choice.Cause.present = F1AP_Cause_PR_NOTHING;
892 893 894 895 896
      break;
  }

  /* optional */
  /* c4. RRCContainer */
897 898 899 900 901 902
  if(cmd->rrc_container!=NULL){
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseCommandIEs_t, ie4);
    ie4->id                             = F1AP_ProtocolIE_ID_id_RRCContainer;
    ie4->criticality                    = F1AP_Criticality_ignore;
    ie4->value.present                  = F1AP_UEContextReleaseCommandIEs__value_PR_RRCContainer;
    OCTET_STRING_fromBuf(&ie4->value.choice.RRCContainer, (const char *)cmd->rrc_container,
903
                       cmd->rrc_container_length);
904 905 906 907 908 909 910

    // conditionally have SRBID if RRC Container
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseCommandIEs_t, ie5);
    ie5->id = F1AP_ProtocolIE_ID_id_SRBID;
    ie5->criticality = F1AP_Criticality_ignore;
    ie5->value.present = F1AP_UEContextReleaseCommandIEs__value_PR_SRBID;
    ie5->value.choice.SRBID = cmd->srb_id;
911
  }
912 913 914

  /* encode */
  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
915
    LOG_E(F1AP, "Failed to encode F1 context release command\n");
916 917 918
    return -1;
  }

919
  f1ap_itti_send_sctp_data_req(true, instance, buffer, len, 0);
920
  return 0;
921
}
922
int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t       instance,
923 924 925
    uint32_t         assoc_id,
    uint32_t         stream,
    F1AP_F1AP_PDU_t *pdu) {
926 927 928
  F1AP_UEContextReleaseComplete_t    *container;
  F1AP_UEContextReleaseCompleteIEs_t *ie;
  DevAssert(pdu);
929 930
  MessageDef *msg_p = itti_alloc_new_message(TASK_DU_F1, 0,  F1AP_UE_CONTEXT_RELEASE_COMPLETE);
  f1ap_ue_context_release_complete_t *complete = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_p);
931 932 933 934
  container = &pdu->choice.successfulOutcome->value.choice.UEContextReleaseComplete;
  /* GNB_CU_UE_F1AP_ID */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCompleteIEs_t, ie, container,
                             F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
935
  complete->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
936 937 938
  /* GNB_DU_UE_F1AP_ID */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCompleteIEs_t, ie, container,
                             F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
939 940
  complete->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;

941 942 943 944
  /* Optional*/
  /* CriticalityDiagnostics */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCompleteIEs_t, ie, container,
                             F1AP_ProtocolIE_ID_id_CriticalityDiagnostics, false);
945

946 947 948 949 950 951 952 953
  if (ie) {
    // ie->value.choice.CriticalityDiagnostics.procedureCode
    // ie->value.choice.CriticalityDiagnostics.triggeringMessage
    // ie->value.choice.CriticalityDiagnostics.procedureCriticality
    // ie->value.choice.CriticalityDiagnostics.transactionID
    // F1AP_CriticalityDiagnostics_IE_List
  }

954
  itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p);
955

956
  return 0;
957
}
958

959 960
int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req)
{
961
  F1AP_F1AP_PDU_t                        pdu= {0};
962
  F1AP_UEContextModificationRequest_t    *out;
963 964
  uint8_t  *buffer=NULL;
  uint32_t  len=0;
965
  // for test
966
  cellIDs_t hardCoded= { .mcc=208, .mnc=93, .mnc_digit_length=2};
967 968 969
  /* Create */
  /* 0. Message Type */
  pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
Laurent THOMAS's avatar
Laurent THOMAS committed
970
  asn1cCalloc(pdu.choice.initiatingMessage, tmp);
971 972 973 974
  tmp->procedureCode = F1AP_ProcedureCode_id_UEContextModification;
  tmp->criticality   = F1AP_Criticality_reject;
  tmp->value.present = F1AP_InitiatingMessage__value_PR_UEContextModificationRequest;
  out = &tmp->value.choice.UEContextModificationRequest;
975 976
  /* mandatory */
  /* c1. GNB_CU_UE_F1AP_ID */
977 978 979 980
  asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie1);
  ie1->id                             = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
  ie1->criticality                    = F1AP_Criticality_reject;
  ie1->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_GNB_CU_UE_F1AP_ID;
981
  ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_ue_context_modification_req->gNB_CU_ue_id;
982 983
  /* mandatory */
  /* c2. GNB_DU_UE_F1AP_ID */
984 985 986 987
  asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie2);
  ie2->id                             = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
  ie2->criticality                    = F1AP_Criticality_reject;
  ie2->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_GNB_DU_UE_F1AP_ID;
988
  ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_ue_context_modification_req->gNB_DU_ue_id;
989 990 991

  /* optional */
  /* c3. NRCGI */
992
  if (0) {
993 994 995 996
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie3);
    ie3->id                             = F1AP_ProtocolIE_ID_id_SpCell_ID;
    ie3->criticality                    = F1AP_Criticality_ignore;
    ie3->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_NRCGI;
997
    /* - nRCGI */
998
    addnRCGI(ie3->value.choice.NRCGI, &hardCoded);
999 1000
  }

1001
  /* optional */
1002
  /* c4. ServCellIndex */
1003 1004 1005 1006 1007 1008 1009
  if(0){
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie4);
    ie4->id                             = F1AP_ProtocolIE_ID_id_ServCellIndex;
    ie4->criticality                    = F1AP_Criticality_reject;
    ie4->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_ServCellIndex;
    ie4->value.choice.ServCellIndex     = 5L;
  }
1010 1011 1012 1013

  /* optional */
  /* c5. DRXCycle */
  if (0) {
1014 1015 1016 1017 1018 1019
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie5);
    ie5->id                             = F1AP_ProtocolIE_ID_id_DRXCycle;
    ie5->criticality                    = F1AP_Criticality_ignore;
    ie5->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_DRXCycle;
    ie5->value.choice.DRXCycle.longDRXCycleLength = F1AP_LongDRXCycleLength_ms10; // enum

1020
    if (0) {
Laurent Thomas's avatar
Laurent Thomas committed
1021 1022
      asn1cCallocOne(ie5->value.choice.DRXCycle.shortDRXCycleLength,
                     F1AP_ShortDRXCycleLength_ms2); // enum
1023
    }
1024

1025
    if (0) {
Laurent THOMAS's avatar
Laurent THOMAS committed
1026
      asn1cCallocOne(ie5->value.choice.DRXCycle.shortDRXCycleTimer, 123L);
1027 1028 1029 1030
    }
  }

  /* optional */
1031
  /* c6. CUtoDURRCInformation */
1032
  if (f1ap_ue_context_modification_req->cu_to_du_rrc_information!=NULL) {
1033 1034 1035 1036
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie6);
    ie6->id                             = F1AP_ProtocolIE_ID_id_CUtoDURRCInformation;
    ie6->criticality                    = F1AP_Criticality_reject;
    ie6->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_CUtoDURRCInformation;
1037 1038
    /* 6.1 cG_ConfigInfo */
    if(f1ap_ue_context_modification_req->cu_to_du_rrc_information->cG_ConfigInfo!=NULL){
1039 1040 1041
      asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.cG_ConfigInfo, cG_ConfigInfo);
      OCTET_STRING_fromBuf(cG_ConfigInfo, (const char *)f1ap_ue_context_modification_req->cu_to_du_rrc_information->cG_ConfigInfo,
        f1ap_ue_context_modification_req->cu_to_du_rrc_information->cG_ConfigInfo_length);
1042
    }
1043
    /* optional */
1044 1045
    /* 6.2 uE_CapabilityRAT_ContainerList */
    if(f1ap_ue_context_modification_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList!=NULL){
1046
      asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList, uE_CapabilityRAT_ContainerList );
1047 1048 1049
      OCTET_STRING_fromBuf(uE_CapabilityRAT_ContainerList, (const char *)f1ap_ue_context_modification_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList,
          f1ap_ue_context_modification_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length) ;
    }
1050
    /* optional */
1051 1052
    /* 6.3 measConfig */
    if(f1ap_ue_context_modification_req->cu_to_du_rrc_information->measConfig!=NULL){
1053 1054 1055
      asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.measConfig,  measConfig);
      OCTET_STRING_fromBuf(measConfig, (const char *)f1ap_ue_context_modification_req->cu_to_du_rrc_information->measConfig,
          f1ap_ue_context_modification_req->cu_to_du_rrc_information->measConfig_length);
1056
    }
1057 1058 1059
  }

  /* optional */
1060
  /* c7. TransmissionActionIndicator */
1061
  if (0) {
1062 1063 1064 1065 1066
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie7);
    ie7->id                                     = F1AP_ProtocolIE_ID_id_TransmissionActionIndicator;
    ie7->criticality                            = F1AP_Criticality_ignore;
    ie7->value.present                          = F1AP_UEContextModificationRequestIEs__value_PR_TransmissionActionIndicator;
    ie7->value.choice.TransmissionActionIndicator = F1AP_TransmissionActionIndicator_stop;
1067 1068 1069
  }

  /* optional */
1070
  /* c8. ResourceCoordinationTransferContainer */
1071
  if (0) {
1072 1073 1074 1075 1076
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie8);
    ie8->id                             = F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer;
    ie8->criticality                    = F1AP_Criticality_ignore;
    ie8->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_ResourceCoordinationTransferContainer;
    OCTET_STRING_fromBuf(&ie8->value.choice.ResourceCoordinationTransferContainer, "asdsa1d32sa1d31asd31as",
1077 1078 1079 1080 1081
                         strlen("asdsa1d32sa1d31asd31as"));
  }

  /* optional */
  /* c7. RRCRconfigurationCompleteIndicator */
matzakos's avatar
matzakos committed
1082
  if (f1ap_ue_context_modification_req->ReconfigComplOutcome == RRCreconf_success) {
1083 1084 1085 1086 1087
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie71);
    ie71->id                             = F1AP_ProtocolIE_ID_id_RRCReconfigurationCompleteIndicator;
    ie71->criticality                    = F1AP_Criticality_ignore;
    ie71->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_RRCReconfigurationCompleteIndicator;
    ie71->value.choice.RRCReconfigurationCompleteIndicator = F1AP_RRCReconfigurationCompleteIndicator_true;
1088 1089 1090 1091
  }

  /* optional */
  /* c8. RRCContainer */
matzakos's avatar
matzakos committed
1092
  if (f1ap_ue_context_modification_req->rrc_container != NULL) {
1093 1094 1095 1096
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie81);
    ie81->id                             = F1AP_ProtocolIE_ID_id_RRCContainer;
    ie81->criticality                    = F1AP_Criticality_ignore;
    ie81->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_RRCContainer;
matzakos's avatar
matzakos committed
1097
    OCTET_STRING_fromBuf(&ie81->value.choice.RRCContainer, (const char*)f1ap_ue_context_modification_req->rrc_container,
matzakos's avatar
matzakos committed
1098
        f1ap_ue_context_modification_req->rrc_container_length);
1099 1100
  }

1101
  /* optional */
1102
  /* c9. SCell_ToBeSetupMod_List */
1103
  if(0){
1104 1105 1106 1107
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie9);
    ie9->id                             = F1AP_ProtocolIE_ID_id_SCell_ToBeSetupMod_List;
    ie9->criticality                    = F1AP_Criticality_ignore;
    ie9->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_SCell_ToBeSetupMod_List;
1108

1109 1110 1111
    for (int i=0; i<1; i++) {
      //
      asn1cSequenceAdd(ie9->value.choice.SCell_ToBeSetupMod_List.list,
1112
                     F1AP_SCell_ToBeSetupMod_ItemIEs_t, scell_toBeSetupMod_item_ies);
1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123
      scell_toBeSetupMod_item_ies->id            = F1AP_ProtocolIE_ID_id_SCell_ToBeSetupMod_Item;
      scell_toBeSetupMod_item_ies->criticality   = F1AP_Criticality_ignore;
      scell_toBeSetupMod_item_ies->value.present = F1AP_SCell_ToBeSetupMod_ItemIEs__value_PR_SCell_ToBeSetupMod_Item;
      /* 8.1 SCell_ToBeSetup_Item */
      F1AP_SCell_ToBeSetupMod_Item_t *scell_toBeSetupMod_item=
          &scell_toBeSetupMod_item_ies->value.choice.SCell_ToBeSetupMod_Item;
      //   /* - sCell_ID */
      addnRCGI(scell_toBeSetupMod_item->sCell_ID, &hardCoded);
      /* sCellIndex */
      scell_toBeSetupMod_item->sCellIndex = 6;  // issue here
      }
1124
  }
1125

1126
  /* optional */
1127
  /* c10. SCell_ToBeRemoved_List */
1128
  if(0){
1129 1130 1131 1132 1133 1134 1135 1136
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie10);
    ie10->id                             = F1AP_ProtocolIE_ID_id_SCell_ToBeRemoved_List;
    ie10->criticality                    = F1AP_Criticality_ignore;
    ie10->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_SCell_ToBeRemoved_List;

    for (int i=0;  i<1; i++) {
      //
      asn1cSequenceAdd(ie10->value.choice.SCell_ToBeRemoved_List.list,
1137
                     F1AP_SCell_ToBeRemoved_ItemIEs_t, scell_toBeRemoved_item_ies);
1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148
      scell_toBeRemoved_item_ies = (F1AP_SCell_ToBeRemoved_ItemIEs_t *)calloc(1, sizeof(F1AP_SCell_ToBeRemoved_ItemIEs_t));
      //memset((void *)&scell_toBeRemoved_item_ies, 0, sizeof(F1AP_SCell_ToBeRemoved_ItemIEs_t));
      scell_toBeRemoved_item_ies->id            = F1AP_ProtocolIE_ID_id_SCell_ToBeRemoved_Item;
      scell_toBeRemoved_item_ies->criticality   = F1AP_Criticality_ignore;
      scell_toBeRemoved_item_ies->value.present = F1AP_SCell_ToBeRemoved_ItemIEs__value_PR_SCell_ToBeRemoved_Item;
      /* 10.1 SCell_ToBeRemoved_Item */
      F1AP_SCell_ToBeRemoved_Item_t *scell_toBeRemoved_item=
        &scell_toBeRemoved_item_ies->value.choice.SCell_ToBeRemoved_Item;
      /* - sCell_ID */
      addnRCGI(scell_toBeRemoved_item->sCell_ID, &hardCoded);
    }
1149
  }
1150 1151 1152

  /* mandatory */
  /* c11. SRBs_ToBeSetupMod_List */
1153
  if(f1ap_ue_context_modification_req->srbs_to_be_setup_length > 0){
1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie11);
    ie11->id                             = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_List;
    ie11->criticality                    = F1AP_Criticality_reject;
    ie11->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_SRBs_ToBeSetupMod_List;

    for (int i=0; i<f1ap_ue_context_modification_req->srbs_to_be_setup_length; i++) {
      //
      asn1cSequenceAdd(ie11->value.choice.SRBs_ToBeSetupMod_List, F1AP_SRBs_ToBeSetupMod_ItemIEs_t, srbs_toBeSetupMod_item_ies);
      srbs_toBeSetupMod_item_ies->id            = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_Item; // 73
      srbs_toBeSetupMod_item_ies->criticality   = F1AP_Criticality_reject;
      srbs_toBeSetupMod_item_ies->value.present = F1AP_SRBs_ToBeSetupMod_ItemIEs__value_PR_SRBs_ToBeSetupMod_Item;
      /* 11.1 SRBs_ToBeSetup_Item */
      F1AP_SRBs_ToBeSetupMod_Item_t *srbs_toBeSetupMod_item=&srbs_toBeSetupMod_item_ies->value.choice.SRBs_ToBeSetupMod_Item;
      /* 11.1.1 sRBID */
      srbs_toBeSetupMod_item->sRBID = f1ap_ue_context_modification_req->srbs_to_be_setup[i].srb_id;
      /* OPTIONAL */
      /* 11.1.2 duplicationIndication */
      asn1cCallocOne(srbs_toBeSetupMod_item->duplicationIndication,
1172
                   F1AP_DuplicationIndication_true); // enum
1173
    }
1174 1175 1176 1177
  }

  /* mandatory */
  /* c12. DRBs_ToBeSetupMod_List */
1178
  if(f1ap_ue_context_modification_req->drbs_to_be_setup_length){
1179 1180 1181 1182
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie12);
    ie12->id                             = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_List;
    ie12->criticality                    = F1AP_Criticality_reject;
    ie12->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeSetupMod_List;
1183

1184 1185
    for (int i = 0; i < f1ap_ue_context_modification_req->drbs_to_be_setup_length; i++) {
      asn1cSequenceAdd(ie12->value.choice.DRBs_ToBeSetupMod_List.list,
1186
                     F1AP_DRBs_ToBeSetupMod_ItemIEs_t, drbs_toBeSetupMod_item_ies);
1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206
      drbs_toBeSetupMod_item_ies->id            = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_Item;
      drbs_toBeSetupMod_item_ies->criticality   = F1AP_Criticality_reject;
      drbs_toBeSetupMod_item_ies->value.present = F1AP_DRBs_ToBeSetupMod_ItemIEs__value_PR_DRBs_ToBeSetupMod_Item;
      /* 12.1 DRBs_ToBeSetupMod_Item */
      F1AP_DRBs_ToBeSetupMod_Item_t *drbs_toBeSetupMod_item=
          &drbs_toBeSetupMod_item_ies->value.choice.DRBs_ToBeSetupMod_Item;
      /* dRBID */
      drbs_toBeSetupMod_item->dRBID = f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id;
      /* qoSInformation */

      if(f1ap_ue_context_modification_req->QoS_information_type == EUTRAN_QoS){
        drbs_toBeSetupMod_item->qoSInformation.present = F1AP_QoSInformation_PR_eUTRANQoS;
        drbs_toBeSetupMod_item->qoSInformation.choice.eUTRANQoS = (F1AP_EUTRANQoS_t *)calloc(1, sizeof(F1AP_EUTRANQoS_t));
        drbs_toBeSetupMod_item->qoSInformation.choice.eUTRANQoS->qCI = 253L;
        /* uLUPTNLInformation_ToBeSetup_List */
        int maxnoofULTunnels = 1; // 2;

        for (int j=0;  j<maxnoofULTunnels;  j++) {
          /*  ULTunnels_ToBeSetup_Item */
          asn1cSequenceAdd( drbs_toBeSetupMod_item->uLUPTNLInformation_ToBeSetup_List.list,
1207
                        F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item);
1208 1209
          uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel;
          asn1cCalloc(uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel,
1210
                      gTPTunnel);
1211 1212 1213 1214
          /* transportLayerAddress */
          TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress);
          /* gTP_TEID */
          OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "4567",
1215 1216 1217
            strlen("4567"));
        }

1218 1219 1220
        /* rLCMode */
        drbs_toBeSetupMod_item->rLCMode = F1AP_RLCMode_rlc_um_bidirectional; // enum

1221
        /* OPTIONAL */
1222
        /* ULConfiguration */
1223
        if (0) {
1224
          drbs_toBeSetupMod_item->uLConfiguration = (F1AP_ULConfiguration_t *)calloc(1, sizeof(F1AP_ULConfiguration_t));
1225
        }
1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241
      } //QoS information

      else{
        /* 12.1.2 DRB_Information */
        drbs_toBeSetupMod_item->qoSInformation.present = F1AP_QoSInformation_PR_choice_extension;
        F1AP_QoSInformation_ExtIEs_t *ie = (F1AP_QoSInformation_ExtIEs_t *)calloc(1, sizeof(*ie));
        ie->id                             = F1AP_ProtocolIE_ID_id_DRB_Information;
        ie->criticality                    = F1AP_Criticality_reject;
        ie->value.present                  = F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information;
        F1AP_DRB_Information_t   *DRB_Information = &ie->value.choice.DRB_Information;
        drbs_toBeSetupMod_item->qoSInformation.choice.choice_extension = (struct F1AP_ProtocolIE_SingleContainer *)ie;
        /* 12.1.2.1 dRB_QoS */
        {
          /* qoS_Characteristics */
          {
            int some_decide_qoS_characteristics = 0; // BK: Need Check
1242

1243 1244 1245 1246
            if (some_decide_qoS_characteristics) {
              DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI;
              setQos(DRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI);
            } else {
matzakos's avatar
matzakos committed
1247 1248 1249 1250 1251 1252 1253 1254 1255
                DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_dynamic_5QI;
                asn1cCalloc(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI, tmp);
                /* qoSPriorityLevel */
                tmp->qoSPriorityLevel = 1L;
                /* packetDelayBudget */
                tmp->packetDelayBudget = 1L;
                /* packetErrorRate */
                tmp->packetErrorRate.pER_Scalar = 1L;
                tmp->packetErrorRate.pER_Exponent = 6L;
1256

matzakos's avatar
matzakos committed
1257 1258 1259 1260 1261
                /* OPTIONAL */
                /* delayCritical */
                if (0) {
                  asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->delayCritical, 1L);
                }
1262

matzakos's avatar
matzakos committed
1263 1264 1265 1266 1267
                /* OPTIONAL */
                /* averagingWindow */
                if (0) {
                  asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->averagingWindow, 1L);
                }
1268

matzakos's avatar
matzakos committed
1269 1270 1271 1272 1273 1274
                /* OPTIONAL */
                /* maxDataBurstVolume */
                if (0) {
                  asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume, 1L);
                }
              } // if some_decide_qoS_characteristics
1275

matzakos's avatar
matzakos committed
1276 1277 1278 1279 1280 1281 1282
            } // qoS_Characteristics
            /* nGRANallocationRetentionPriority */
            {
              DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum
              DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum
              DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum
            } // nGRANallocationRetentionPriority
1283

1284 1285 1286 1287 1288 1289 1290 1291
          /* OPTIONAL */
          /* gBR_QoS_Flow_Information */
          if (0) {
            asn1cCalloc(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information, tmp);
            asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L);
            asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L);
            asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L);
            asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, 1L);
1292 1293

            /* OPTIONAL */
1294
            /* maxPacketLossRateDownlink */
1295
            if (0) {
1296
              asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L);
1297 1298 1299
            }

            /* OPTIONAL */
1300
            /* maxPacketLossRateUplink */
1301
            if (0) {
1302
              asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L);
1303
            }
1304
          }
1305

1306 1307 1308 1309 1310 1311 1312
          /* OPTIONAL */
          /* reflective_QoS_Attribute */
          if (0) {
            asn1cCallocOne(DRB_Information->dRB_QoS.reflective_QoS_Attribute, 1L);
          }
        } // dRB_QoS
        /* 12.1.2.2 sNSSAI */
1313
        {
1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325
          /* sST */

          OCTET_STRING_fromBuf(&DRB_Information->sNSSAI.sST, "1", 1);

          /* OPTIONAL */
          /* sD */
          if (0) {
            asn1cCalloc(DRB_Information->sNSSAI.sD, tmp);
            OCTET_STRING_fromBuf(tmp, "asdsa1d32sa1d31asd31as",
            strlen("asdsa1d32sa1d31asd31as"));
          }
        }
1326 1327

        /* OPTIONAL */
1328
        /* 12.1.2.3 notificationControl */
1329
        if (0) {
1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390
          asn1cCallocOne(DRB_Information->notificationControl,
              F1AP_NotificationControl_active); // enum
        }

        /* 12.1.2.4 flows_Mapped_To_DRB_List */  // BK: need verifiy

        for (int k = 0; k < 1; k ++) {
          asn1cSequenceAdd(DRB_Information->flows_Mapped_To_DRB_List.list,
                         F1AP_Flows_Mapped_To_DRB_Item_t, flows_mapped_to_drb_item);
          /* qoSFlowIndicator */
          flows_mapped_to_drb_item->qoSFlowIdentifier = 1L;
          /* qoSFlowLevelQoSParameters */
          {
            /* qoS_Characteristics */
            {
              int some_decide_qoS_characteristics = 0; // BK: Need Check
              F1AP_QoS_Characteristics_t *QosParams=&flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.qoS_Characteristics;

              if (some_decide_qoS_characteristics) {
                QosParams->present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI;
                setQos(QosParams->choice.non_Dynamic_5QI);
              } else {
                QosParams->present = F1AP_QoS_Characteristics_PR_dynamic_5QI;
                asn1cCalloc(QosParams->choice.dynamic_5QI, tmp);
                /* qoSPriorityLevel */
                tmp->qoSPriorityLevel = 1L;
                /* packetDelayBudget */
                tmp->packetDelayBudget = 1L;
                /* packetErrorRate */
                tmp->packetErrorRate.pER_Scalar = 1L;
                tmp->packetErrorRate.pER_Exponent = 6L;

                /* OPTIONAL */
                /* delayCritical */
                if (0) {
                  asn1cCalloc(QosParams->choice.dynamic_5QI->delayCritical, tmp);
                  *tmp = 1L;
                }

                /* OPTIONAL */
                /* averagingWindow */
                if (0) {
                  asn1cCalloc(QosParams->choice.dynamic_5QI->averagingWindow, tmp);
                  *tmp = 1L;
                }

                /* OPTIONAL */
                /* maxDataBurstVolume */
                if (0) {
                  asn1cCalloc(QosParams->choice.dynamic_5QI->maxDataBurstVolume, tmp);
                  *tmp= 1L;
                }
              } // if some_decide_qoS_characteristics

            } // qoS_Characteristics
            /* nGRANallocationRetentionPriority */
            {
              flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum
              flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum
              flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum
            } // nGRANallocationRetentionPriority
1391 1392

            /* OPTIONAL */
1393
            /* gBR_QoS_Flow_Information */
1394
            if (0) {
1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411
              asn1cCalloc(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information, tmp);
              asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L);
              asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L);
              asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L);
              asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, 1L);

              /* OPTIONAL */
              /* maxPacketLossRateDownlink */
              if (0) {
                asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L);
              }

              /* OPTIONAL */
              /* maxPacketLossRateUplink */
              if (0) {
                asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L);
              }
1412 1413 1414
            }

            /* OPTIONAL */
1415
            /* reflective_QoS_Attribute */
1416
            if (0) {
1417
              asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.reflective_QoS_Attribute, 1L);
1418
            }
1419 1420
          } // qoSFlowLevelQoSParameters
        }
1421

1422
      } //QoS information
1423

1424 1425
      /* 12.1.3 uLUPTNLInformation_ToBeSetup_List */
      for (int j = 0; j < f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) {
1426
        /* Use a dummy address and teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context modification response from the DU */
1427
        asn1cSequenceAdd(drbs_toBeSetupMod_item->uLUPTNLInformation_ToBeSetup_List.list,
1428
                       F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item);
1429 1430
        uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel;
        asn1cCalloc( uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel,
1431
                   gTPTunnel);
1432 1433
        /* 12.3.1.1.1 transportLayerAddress */
        TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl[j].tl_address,
1434
                          &gTPTunnel->transportLayerAddress);
1435 1436
        /* 12.3.1.1.2 gTP_TEID */
        INT32_TO_OCTET_STRING(f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl[j].teid,
1437
                &gTPTunnel->gTP_TEID);
1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448
      }
      /* 12.1.4 rLCMode */
      /* TODO use rlc_mode from f1ap_drb_to_be_setup */
      switch (f1ap_ue_context_modification_req->drbs_to_be_setup[i].rlc_mode) {
        case RLC_MODE_AM:
          drbs_toBeSetupMod_item->rLCMode = F1AP_RLCMode_rlc_am;
          break;

        default:
          drbs_toBeSetupMod_item->rLCMode = F1AP_RLCMode_rlc_um_bidirectional;
      }
1449

1450 1451 1452 1453 1454 1455
      /* OPTIONAL */
      /* 12.1.5 ULConfiguration */
      if (0) {
        asn1cCalloc(drbs_toBeSetupMod_item->uLConfiguration, tmp);
        tmp->uLUEConfiguration = F1AP_ULUEConfiguration_no_data;
      }
1456

1457 1458 1459 1460 1461 1462
      /* OPTIONAL */
      /* 12.1.6 duplicationActivation */
      if (0) {
        asn1cCalloc(drbs_toBeSetupMod_item->duplicationActivation, tmp);
        *tmp = F1AP_DuplicationActivation_active;  // enum
      }
1463 1464 1465
    }
  }

1466 1467
  /* optional */
  if(0){
1468 1469 1470 1471 1472
    /* c13. DRBs_ToBeModified_List */
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie13);
    ie13->id                             = F1AP_ProtocolIE_ID_id_DRBs_ToBeModified_List;
    ie13->criticality                    = F1AP_Criticality_reject;
    ie13->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeModified_List;
1473

1474 1475 1476
    for (int i=0;   i<1; i++) {
      //
      asn1cSequenceAdd( ie13->value.choice.DRBs_ToBeModified_List.list,
1477
                      F1AP_DRBs_ToBeModified_ItemIEs_t, drbs_toBeModified_item_ies);
1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496
      drbs_toBeModified_item_ies->id            = F1AP_ProtocolIE_ID_id_DRBs_ToBeModified_Item;
      drbs_toBeModified_item_ies->criticality   = F1AP_Criticality_reject;
      drbs_toBeModified_item_ies->value.present = F1AP_DRBs_ToBeModified_ItemIEs__value_PR_DRBs_ToBeModified_Item;
      /* 13.1 SRBs_ToBeModified_Item */
      F1AP_DRBs_ToBeModified_Item_t *drbs_toBeModified_item=
          &drbs_toBeModified_item_ies->value.choice.DRBs_ToBeModified_Item;
      /* dRBID */
      drbs_toBeModified_item->dRBID = 30L;
      /* qoSInformation */
      asn1cCalloc(drbs_toBeModified_item->qoSInformation, tmp);
      tmp->present = F1AP_QoSInformation_PR_eUTRANQoS;
      tmp->choice.eUTRANQoS = (F1AP_EUTRANQoS_t *)calloc(1, sizeof(F1AP_EUTRANQoS_t));
      tmp->choice.eUTRANQoS->qCI = 254L;
      /* ULTunnels_ToBeModified_List */
      int maxnoofULTunnels = 1; // 2;

      for (int j=0; j<maxnoofULTunnels; j++) {
        /*  ULTunnels_ToBeModified_Item */
        asn1cSequenceAdd(drbs_toBeModified_item->uLUPTNLInformation_ToBeSetup_List.list,
1497
                       F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item);
1498 1499
        uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel;
        asn1cCalloc(uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel,
Laurent THOMAS's avatar
Laurent THOMAS committed
1500
                  gTPTunnel);
1501 1502
        TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress);
        OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1204",
1503
                           strlen("1204"));
1504
      }
1505

1506 1507 1508 1509 1510
      /* OPTIONAL */
      /* ULConfiguration */
      if (0) {
        drbs_toBeModified_item->uLConfiguration = (F1AP_ULConfiguration_t *)calloc(1, sizeof(F1AP_ULConfiguration_t));
      }
1511 1512 1513
    }
  }

1514 1515
  /* optional */
  if(0){
1516 1517 1518 1519 1520
    /* c14. SRBs_ToBeReleased_List */
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie14);
    ie14->id                             = F1AP_ProtocolIE_ID_id_SRBs_ToBeReleased_List;
    ie14->criticality                    = F1AP_Criticality_reject;
    ie14->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_SRBs_ToBeReleased_List;
1521

1522 1523 1524
    for (int i=0;  i<1; i++) {
      //
      asn1cSequenceAdd(ie14->value.choice.SRBs_ToBeReleased_List.list,
1525
                     F1AP_SRBs_ToBeReleased_ItemIEs_t, srbs_toBeReleased_item_ies);
1526 1527 1528 1529 1530 1531 1532 1533 1534
      srbs_toBeReleased_item_ies->id            = F1AP_ProtocolIE_ID_id_SRBs_ToBeReleased_Item;
      srbs_toBeReleased_item_ies->criticality   = F1AP_Criticality_ignore;
      srbs_toBeReleased_item_ies->value.present = F1AP_SRBs_ToBeReleased_ItemIEs__value_PR_SRBs_ToBeReleased_Item;
      /* 9.1 SRBs_ToBeReleased_Item */
      F1AP_SRBs_ToBeReleased_Item_t *srbs_toBeReleased_item=
          &srbs_toBeReleased_item_ies->value.choice.SRBs_ToBeReleased_Item;
      /* - sRBID */
      srbs_toBeReleased_item->sRBID = 2L;
    }
1535
  }
1536

1537 1538
  /* optional */
  if(0){
1539 1540 1541 1542 1543
    /* c15. DRBs_ToBeReleased_List */
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie15);
    ie15->id                             = F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_List;
    ie15->criticality                    = F1AP_Criticality_reject;
    ie15->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeReleased_List;
1544

1545 1546 1547
    for (int i=0; i<1;  i++) {
      //
      asn1cSequenceAdd(ie15->value.choice.DRBs_ToBeReleased_List.list,
1548
                     F1AP_DRBs_ToBeReleased_ItemIEs_t, drbs_toBeReleased_item_ies);
1549 1550 1551 1552 1553 1554 1555 1556 1557
      drbs_toBeReleased_item_ies->id            = F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_Item;
      drbs_toBeReleased_item_ies->criticality   = F1AP_Criticality_reject;
      drbs_toBeReleased_item_ies->value.present = F1AP_DRBs_ToBeReleased_ItemIEs__value_PR_DRBs_ToBeReleased_Item;
      /* 14.1 SRBs_ToBeReleased_Item */
      F1AP_DRBs_ToBeReleased_Item_t *drbs_toBeReleased_item=
          &drbs_toBeReleased_item_ies->value.choice.DRBs_ToBeReleased_Item;
      /* dRBID */
      drbs_toBeReleased_item->dRBID = 30L;
    }
1558
  }
1559 1560 1561

  /* encode */
  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
Xue Song's avatar
Xue Song committed
1562
    LOG_E(F1AP, "Failed to encode F1 UE CONTEXT_MODIFICATION REQUEST\n");
1563
    return -1;
1564
  }
1565
  f1ap_itti_send_sctp_data_req(true, instance, buffer, len, 0 /* BK: fix me*/);
1566
  return 0;
1567 1568
}

1569
int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t       instance,
1570 1571 1572
    uint32_t         assoc_id,
    uint32_t         stream,
    F1AP_F1AP_PDU_t *pdu) {
1573 1574 1575 1576 1577 1578

  MessageDef                       *msg_p;
  F1AP_UEContextModificationResponse_t    *container;
  F1AP_UEContextModificationResponseIEs_t *ie;
  DevAssert(pdu);
  msg_p = itti_alloc_new_message(TASK_DU_F1, 0,  F1AP_UE_CONTEXT_MODIFICATION_RESP);
1579
  f1ap_ue_context_modif_resp_t *f1ap_ue_context_modification_resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg_p);
1580 1581 1582 1583 1584
  container = &pdu->choice.successfulOutcome->value.choice.UEContextModificationResponse;
  int i;

    /* GNB_CU_UE_F1AP_ID */
    F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
1585
                               F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
1586 1587
    f1ap_ue_context_modification_resp->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;

1588
    LOG_D(F1AP, "f1ap_ue_context_modif_resp->gNB_CU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_CU_ue_id);
1589 1590 1591 1592 1593 1594

    /* GNB_DU_UE_F1AP_ID */
    F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
                               F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
    f1ap_ue_context_modification_resp->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;

1595
    LOG_D(F1AP, "f1ap_ue_context_modification_resp->gNB_DU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_DU_ue_id);
1596 1597 1598

    // DUtoCURRCInformation
    F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
1599 1600
                               F1AP_ProtocolIE_ID_id_DUtoCURRCInformation, false);
    if(ie!=NULL){
matzakos's avatar
matzakos committed
1601 1602
      f1ap_ue_context_modification_resp->du_to_cu_rrc_information = (du_to_cu_rrc_information_t *)calloc(1, sizeof(du_to_cu_rrc_information_t));
      f1ap_ue_context_modification_resp->du_to_cu_rrc_information->cellGroupConfig = (uint8_t *)calloc(1,ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size);
1603

matzakos's avatar
matzakos committed
1604 1605
      memcpy(f1ap_ue_context_modification_resp->du_to_cu_rrc_information->cellGroupConfig, ie->value.choice.DUtoCURRCInformation.cellGroupConfig.buf, ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size);
      f1ap_ue_context_modification_resp->du_to_cu_rrc_information->cellGroupConfig_length = ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size;
1606
    }
1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629

    // DRBs_SetupMod_List
    F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
                               F1AP_ProtocolIE_ID_id_DRBs_SetupMod_List, false);
    if(ie!=NULL){
      f1ap_ue_context_modification_resp->drbs_to_be_setup_length = ie->value.choice.DRBs_SetupMod_List.list.count;
      f1ap_ue_context_modification_resp->drbs_to_be_setup = calloc(f1ap_ue_context_modification_resp->drbs_to_be_setup_length,
          sizeof(f1ap_drb_to_be_setup_t));
      AssertFatal(f1ap_ue_context_modification_resp->drbs_to_be_setup,
                "could not allocate memory for f1ap_ue_context_setup_resp->drbs_setup\n");
      for (i = 0; i < f1ap_ue_context_modification_resp->drbs_to_be_setup_length; ++i) {
        f1ap_drb_to_be_setup_t *drb_p = &f1ap_ue_context_modification_resp->drbs_to_be_setup[i];
        F1AP_DRBs_SetupMod_Item_t *drbs_setupmod_item_p;
        drbs_setupmod_item_p = &((F1AP_DRBs_SetupMod_ItemIEs_t *)ie->value.choice.DRBs_SetupMod_List.list.array[i])->value.choice.DRBs_SetupMod_Item;
        drb_p->drb_id = drbs_setupmod_item_p->dRBID;
        // TODO in the following, assume only one UP UL TNL is present.
         // this matches/assumes OAI CU/DU implementation, can be up to 2!
        drb_p->up_dl_tnl_length = 1;
        AssertFatal(drbs_setupmod_item_p->dLUPTNLInformation_ToBeSetup_List.list.count > 0,
            "no DL UP TNL Information in DRBs to be Setup list\n");
        F1AP_DLUPTNLInformation_ToBeSetup_Item_t *dl_up_tnl_info_p = (F1AP_DLUPTNLInformation_ToBeSetup_Item_t *)drbs_setupmod_item_p->dLUPTNLInformation_ToBeSetup_List.list.array[0];
        F1AP_GTPTunnel_t *dl_up_tnl0 = dl_up_tnl_info_p->dLUPTNLInformation.choice.gTPTunnel;
        BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address);
1630
        OCTET_STRING_TO_UINT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid);
1631
        GtpuUpdateTunnelOutgoingAddressAndTeid(getCxt(CUtype, instance)->gtpInst,
1632
                     f1ap_ue_context_modification_resp->gNB_CU_ue_id,
1633
                     (ebi_t)drbs_setupmod_item_p->dRBID,
1634
                     drb_p->up_dl_tnl[0].tl_address,
1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694
                     drb_p->up_dl_tnl[0].teid);
      }
    }
    // SRBs_FailedToBeSetupMod_List
    F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
                               F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetupMod_List, false);
    if(ie!=NULL){
      f1ap_ue_context_modification_resp->srbs_failed_to_be_setup_length = ie->value.choice.SRBs_FailedToBeSetupMod_List.list.count;
      f1ap_ue_context_modification_resp->srbs_failed_to_be_setup = calloc(f1ap_ue_context_modification_resp->srbs_failed_to_be_setup_length,
          sizeof(f1ap_rb_failed_to_be_setup_t));
      AssertFatal(f1ap_ue_context_modification_resp->srbs_failed_to_be_setup,
          "could not allocate memory for f1ap_ue_context_setup_resp->srbs_failed_to_be_setup\n");
      for (i = 0; i < f1ap_ue_context_modification_resp->srbs_failed_to_be_setup_length; ++i) {
        f1ap_rb_failed_to_be_setup_t *srb_p = &f1ap_ue_context_modification_resp->srbs_failed_to_be_setup[i];
        srb_p->rb_id = ((F1AP_SRBs_FailedToBeSetupMod_Item_t *)ie->value.choice.SRBs_FailedToBeSetupMod_List.list.array[i])->sRBID;
      }

    }
    // DRBs_FailedToBeSetupMod_List
    F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
                               F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetupMod_List, false);
    if(ie!=NULL){
      f1ap_ue_context_modification_resp->drbs_failed_to_be_setup_length = ie->value.choice.DRBs_FailedToBeSetupMod_List.list.count;
      f1ap_ue_context_modification_resp->drbs_failed_to_be_setup = calloc(f1ap_ue_context_modification_resp->drbs_failed_to_be_setup_length,
          sizeof(f1ap_rb_failed_to_be_setup_t));
      AssertFatal(f1ap_ue_context_modification_resp->drbs_failed_to_be_setup,
          "could not allocate memory for f1ap_ue_context_setup_resp->drbs_failed_to_be_setup\n");
      for (i = 0; i < f1ap_ue_context_modification_resp->drbs_failed_to_be_setup_length; ++i) {
        f1ap_rb_failed_to_be_setup_t *drb_p = &f1ap_ue_context_modification_resp->drbs_failed_to_be_setup[i];
        drb_p->rb_id = ((F1AP_DRBs_FailedToBeSetupMod_Item_t *)ie->value.choice.DRBs_FailedToBeSetupMod_List.list.array[i])->dRBID;
      }
    }

    // SCell_FailedtoSetupMod_List
    F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
                               F1AP_ProtocolIE_ID_id_SCell_FailedtoSetupMod_List, false);
    if(ie!=NULL){
      LOG_E (F1AP, "Not supporting handling of SCell_FailedtoSetupMod_List \n");
    }

    // SRBs_Setup_List
    F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
        F1AP_ProtocolIE_ID_id_SRBs_SetupMod_List, false);
    if(ie!=NULL){
      f1ap_ue_context_modification_resp->srbs_to_be_setup_length = ie->value.choice.SRBs_SetupMod_List.list.count;
      f1ap_ue_context_modification_resp->srbs_to_be_setup = calloc(f1ap_ue_context_modification_resp->srbs_to_be_setup_length,
          sizeof(f1ap_srb_to_be_setup_t));
      AssertFatal(f1ap_ue_context_modification_resp->srbs_to_be_setup,
          "could not allocate memory for f1ap_ue_context_setup_resp->drbs_setup\n");
      for (i = 0; i < f1ap_ue_context_modification_resp->srbs_to_be_setup_length; ++i) {
        f1ap_srb_to_be_setup_t *srb_p = &f1ap_ue_context_modification_resp->srbs_to_be_setup[i];
        F1AP_SRBs_SetupMod_Item_t *srbs_setup_item_p;
        srbs_setup_item_p = &((F1AP_SRBs_SetupMod_ItemIEs_t *)ie->value.choice.SRBs_SetupMod_List.list.array[i])->value.choice.SRBs_SetupMod_Item;
        srb_p->srb_id = srbs_setup_item_p->sRBID;
        srb_p->lcid = srbs_setup_item_p->lCID;
      }
    }

    itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p);
    return 0;
1695 1696
}

1697
int CU_handle_UE_CONTEXT_MODIFICATION_FAILURE(instance_t       instance,
1698 1699 1700
    uint32_t         assoc_id,
    uint32_t         stream,
    F1AP_F1AP_PDU_t *pdu) {
1701 1702 1703
  AssertFatal(1==0,"Not implemented yet\n");
}

1704 1705
int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
{
1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833
  DevAssert(pdu != NULL);

  MessageDef *msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_REQUIRED);
  f1ap_ue_context_modif_required_t *required = &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg_p);

  F1AP_UEContextModificationRequired_t *container = &pdu->choice.initiatingMessage->value.choice.UEContextModificationRequired;
  F1AP_UEContextModificationRequiredIEs_t *ie = NULL;

  /* required: GNB_CU_UE_F1AP_ID */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
  required->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;

  /* required: GNB_DU_UE_F1AP_ID */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
  required->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;

  /* optional: Resource Coordination Transfer Container */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t,
                             ie,
                             container,
                             F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer,
                             false);
  AssertFatal(ie == NULL, "handling of Resource Coordination Transfer Container not implemented\n");

  /* optional: DU to CU RRC Information */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t,
                             ie,
                             container,
                             F1AP_ProtocolIE_ID_id_DUtoCURRCInformation,
                             false);
  if (ie != NULL) {
    F1AP_DUtoCURRCInformation_t *du2cu = &ie->value.choice.DUtoCURRCInformation;
    required->du_to_cu_rrc_information = malloc(sizeof(*required->du_to_cu_rrc_information));
    AssertFatal(required->du_to_cu_rrc_information != NULL, "memory allocation failed\n");

    required->du_to_cu_rrc_information->cellGroupConfig = malloc(du2cu->cellGroupConfig.size);
    AssertFatal(required->du_to_cu_rrc_information->cellGroupConfig != NULL, "memory allocation failed\n");
    memcpy(required->du_to_cu_rrc_information->cellGroupConfig, du2cu->cellGroupConfig.buf, du2cu->cellGroupConfig.size);
    required->du_to_cu_rrc_information->cellGroupConfig_length = du2cu->cellGroupConfig.size;

    AssertFatal(du2cu->measGapConfig == NULL, "handling of measGapConfig not implemented\n");
    AssertFatal(du2cu->requestedP_MaxFR1 == NULL, "handling of requestedP_MaxFR1 not implemented\n");
  }

  /* optional: DRB Required to Be Modified List */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t,
                             ie,
                             container,
                             F1AP_ProtocolIE_ID_id_DRBs_Required_ToBeModified_List,
                             false);
  AssertFatal(ie == NULL, "handling of DRBs Required to be modified list not implemented\n");

  /* optional: SRB Required to be Released List */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t,
                             ie,
                             container,
                             F1AP_ProtocolIE_ID_id_SRBs_Required_ToBeReleased_List,
                             false);
  AssertFatal(ie == NULL, "handling of SRBs Required to be released list not implemented\n");

  /* optional: DRB Required to be Released List */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t,
                             ie,
                             container,
                             F1AP_ProtocolIE_ID_id_DRBs_Required_ToBeReleased_List,
                             false);
  AssertFatal(ie == NULL, "handling of DRBs Required to be released list not implemented\n");

  /* mandatory: Cause */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t, ie, container, F1AP_ProtocolIE_ID_id_Cause, true);
  switch (ie->value.choice.Cause.present) {
    case F1AP_Cause_PR_radioNetwork:
      required->cause = F1AP_CAUSE_RADIO_NETWORK;
      required->cause_value = ie->value.choice.Cause.choice.radioNetwork;
      break;
    case F1AP_Cause_PR_transport:
      required->cause = F1AP_CAUSE_TRANSPORT;
      required->cause_value = ie->value.choice.Cause.choice.transport;
      break;
    case F1AP_Cause_PR_protocol:
      required->cause = F1AP_CAUSE_PROTOCOL;
      required->cause_value = ie->value.choice.Cause.choice.protocol;
      break;
    case F1AP_Cause_PR_misc:
      required->cause = F1AP_CAUSE_MISC;
      required->cause_value = ie->value.choice.Cause.choice.misc;
      break;
    default:
      LOG_W(F1AP, "Unknown cause for UE Context Modification required message\n");
      /* fall through */
    case F1AP_Cause_PR_NOTHING:
      required->cause = F1AP_CAUSE_NOTHING;
      break;
  }

  /* optional: BH RLC Channel Required to be Released List */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t,
                             ie,
                             container,
                             F1AP_ProtocolIE_ID_id_BHChannels_Required_ToBeReleased_List,
                             false);
  AssertFatal(ie == NULL, "handling of BH RLC Channel Required to be Released list not implemented\n");

  /* optional: SL DRB Required to Be Modified List */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t,
                             ie,
                             container,
                             F1AP_ProtocolIE_ID_id_SLDRBs_Required_ToBeModified_List,
                             false);
  AssertFatal(ie == NULL, "handling of SL DRB Required to be modified list not implemented\n");

  /* optional: SL DRB Required to be Released List */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t,
                             ie,
                             container,
                             F1AP_ProtocolIE_ID_id_SLDRBs_Required_ToBeReleased_List,
                             false);
  AssertFatal(ie == NULL, "handling of SL DRBs Required to be released list not implemented\n");

  /* optional: Candidate Cells To Be Cancelled List */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t,
                             ie,
                             container,
                             F1AP_ProtocolIE_ID_id_Candidate_SpCell_List,
                             false);
  AssertFatal(ie == NULL, "handling of candidate cells to be cancelled list not implemented\n");

  itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p);
1834
  return 0;
1835 1836
}

1837 1838
int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, f1ap_ue_context_modif_confirm_t *confirm)
{
1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895
  F1AP_F1AP_PDU_t pdu = {0};
  pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome;
  asn1cCalloc(pdu.choice.successfulOutcome, tmp);
  tmp->procedureCode = F1AP_ProcedureCode_id_UEContextModificationRequired;
  tmp->criticality = F1AP_Criticality_reject;
  tmp->value.present = F1AP_SuccessfulOutcome__value_PR_UEContextModificationConfirm;
  F1AP_UEContextModificationConfirm_t *out = &tmp->value.choice.UEContextModificationConfirm;

  /* mandatory: GNB_CU_UE_F1AP_ID */
  asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationConfirmIEs_t, ie1);
  ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
  ie1->criticality = F1AP_Criticality_reject;
  ie1->value.present = F1AP_UEContextModificationConfirmIEs__value_PR_GNB_CU_UE_F1AP_ID;
  ie1->value.choice.GNB_CU_UE_F1AP_ID = confirm->gNB_CU_ue_id;

  /* mandatory: GNB_DU_UE_F1AP_ID */
  asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationConfirmIEs_t, ie2);
  ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
  ie2->criticality = F1AP_Criticality_reject;
  ie2->value.present = F1AP_UEContextModificationConfirmIEs__value_PR_GNB_DU_UE_F1AP_ID;
  ie2->value.choice.GNB_DU_UE_F1AP_ID = confirm->gNB_DU_ue_id;

  /* optional: Resource Coordination Transfer Container */
  /* not implemented*/

  /* optional: DRB Modified List */
  /* not implemented*/

  /* optional: RRC Container */
  if (confirm->rrc_container != NULL) {
    asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationConfirmIEs_t, ie);
    ie->id = F1AP_ProtocolIE_ID_id_RRCContainer;
    ie->criticality = F1AP_Criticality_ignore;
    ie->value.present = F1AP_UEContextModificationConfirmIEs__value_PR_RRCContainer;
    OCTET_STRING_fromBuf(&ie->value.choice.RRCContainer, (const char *)confirm->rrc_container, confirm->rrc_container_length);
  }

  /* optional: CriticalityDiagnostics */
  /* not implemented*/

  /* optional: Execute Duplication */
  /* not implemented*/

  /* optional: Resource Coordination Transfer Information */
  /* not implemented*/

  /* optional: SL DRB Modified List */
  /* not implemented*/

  /* encode */
  uint8_t *buffer = NULL;
  uint32_t len = 0;
  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
    LOG_E(F1AP, "Failed to encode F1 UE Context Modification Confirm\n");
    return -1;
  }
  f1ap_itti_send_sctp_data_req(true, instance, buffer, len, 0);
1896 1897 1898 1899 1900
  return 0;
}

int CU_send_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, f1ap_ue_context_modif_refuse_t *refuse)
{
1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962
  F1AP_F1AP_PDU_t pdu = {0};
  pdu.present = F1AP_F1AP_PDU_PR_unsuccessfulOutcome;
  asn1cCalloc(pdu.choice.unsuccessfulOutcome, tmp);
  tmp->procedureCode = F1AP_ProcedureCode_id_UEContextModificationRequired;
  tmp->criticality = F1AP_Criticality_reject;
  tmp->value.present = F1AP_UnsuccessfulOutcome__value_PR_UEContextModificationRefuse;
  F1AP_UEContextModificationRefuse_t *out = &tmp->value.choice.UEContextModificationRefuse;

  /* mandatory: GNB_CU_UE_F1AP_ID */
  asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRefuseIEs_t, ie1);
  ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
  ie1->criticality = F1AP_Criticality_reject;
  ie1->value.present = F1AP_UEContextModificationRefuseIEs__value_PR_GNB_CU_UE_F1AP_ID;
  ie1->value.choice.GNB_CU_UE_F1AP_ID = refuse->gNB_CU_ue_id;

  /* mandatory: GNB_DU_UE_F1AP_ID */
  asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRefuseIEs_t, ie2);
  ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
  ie2->criticality = F1AP_Criticality_reject;
  ie2->value.present = F1AP_UEContextModificationRefuseIEs__value_PR_GNB_DU_UE_F1AP_ID;
  ie2->value.choice.GNB_DU_UE_F1AP_ID = refuse->gNB_DU_ue_id;

  /* optional: Cause */
  asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRefuseIEs_t, ie3);
  ie3->id = F1AP_ProtocolIE_ID_id_Cause;
  ie3->criticality = F1AP_Criticality_reject;
  ie3->value.present = F1AP_UEContextModificationRefuseIEs__value_PR_Cause;
  F1AP_Cause_t *cause = &ie3->value.choice.Cause;
  switch (refuse->cause) {
    case F1AP_CAUSE_RADIO_NETWORK:
      cause->present = F1AP_Cause_PR_radioNetwork;
      cause->choice.radioNetwork = refuse->cause_value;
      break;
    case F1AP_CAUSE_TRANSPORT:
      cause->present = F1AP_Cause_PR_transport;
      cause->choice.transport = refuse->cause_value;
      break;
    case F1AP_CAUSE_PROTOCOL:
      cause->present = F1AP_Cause_PR_protocol;
      cause->choice.protocol = refuse->cause_value;
      break;
    case F1AP_CAUSE_MISC:
      cause->present = F1AP_Cause_PR_misc;
      cause->choice.misc = refuse->cause_value;
      break;
    case F1AP_CAUSE_NOTHING:
    default:
      cause->present = F1AP_Cause_PR_NOTHING;
      break;
  } // switch

  /* optional: CriticalityDiagnostics */
  /* not implemented*/

  /* encode */
  uint8_t *buffer = NULL;
  uint32_t len = 0;
  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
    LOG_E(F1AP, "Failed to encode F1 UE Context Modification Refuse\n");
    return -1;
  }
  f1ap_itti_send_sctp_data_req(true, instance, buffer, len, 0);
1963
  return 0;
1964
}