f1ap_cu_rrc_message_transfer.c 14.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
/*
 * 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
 */

/*! \file f1ap_cu_rrc_message_transfer.c
 * \brief f1ap rrc message transfer for CU
 * \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_decoder.h"
#include "f1ap_itti_messaging.h"
37
#include "f1ap_cu_rrc_message_transfer.h"
38 39 40
#include "common/ran_context.h"
#include "openair3/UTILS/conversions.h"

41 42 43 44 45
// undefine C_RNTI from
// openair1/PHY/LTE_TRANSPORT/transport_common.h which
// replaces in ie->value.choice.C_RNTI, causing
// a compile error
#undef C_RNTI 
46

47

48 49 50 51
// Bing Kai: create CU and DU context, and put all the information there.
uint64_t        du_ue_f1ap_id = 0;
uint32_t        f1ap_assoc_id = 0;
uint32_t        f1ap_stream = 0;
52 53 54 55


f1ap_cudu_ue_inst_t f1ap_cu_ue[MAX_eNB];

56 57 58 59
/*
    Initial UL RRC Message Transfer
*/

60 61
extern RAN_CONTEXT_t RC;

62 63
int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t             instance,
                                              uint32_t               assoc_id,
64 65
                                              uint32_t               stream,
                                              F1AP_F1AP_PDU_t       *pdu) {
66

Bing-Kai Hong's avatar
Bing-Kai Hong committed
67
  LOG_D(CU_F1AP, "CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER\n");
68 69 70
  // decode the F1 message
  // get the rrc message from the contauiner 
  // call func rrc_eNB_decode_ccch: <-- needs some update here
71 72 73 74 75 76 77 78
  MessageDef                            *message_p;
  F1AP_InitialULRRCMessageTransfer_t    *container;
  F1AP_InitialULRRCMessageTransferIEs_t *ie;
  
  rnti_t          rnti;
  uint8_t        *ccch_sdu;
  sdu_size_t      ccch_sdu_len;
  int             CC_id =0;
79
  
80

81 82 83
  DevAssert(pdu != NULL);
  
  if (stream != 0) {
84
    LOG_E(CU_F1AP, "[SCTP %d] Received F1 on stream != 0 (%d)\n",
85 86 87
               assoc_id, stream);
    return -1;
  }
88 89 90
  // TODO: use context 
  f1ap_stream    = stream;
  f1ap_assoc_id = assoc_id;
91 92 93 94 95 96 97

  container = &pdu->choice.initiatingMessage->value.choice.InitialULRRCMessageTransfer;

  /* GNB_DU_UE_F1AP_ID */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
                             F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
  du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
Bing-Kai Hong's avatar
Bing-Kai Hong committed
98
  LOG_D(CU_F1AP, "du_ue_f1ap_id %lu \n", du_ue_f1ap_id);
99

100 101 102
  /* NRCGI 
  * TODO: process NRCGI
  */
103 104 105
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
                             F1AP_ProtocolIE_ID_id_NRCGI, true);

106

107 108 109
  uint64_t nr_cellid;
  BIT_STRING_TO_NR_CELL_IDENTITY(&ie->value.choice.NRCGI.nRCellIdentity,nr_cellid);
					       
110 111 112
  /* RNTI */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
                             F1AP_ProtocolIE_ID_id_C_RNTI, true);
113
  BUFFER_TO_INT16(ie->value.choice.C_RNTI.buf, rnti);
114 115 116 117 118

  /* RRC Container */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
                             F1AP_ProtocolIE_ID_id_RRCContainer, true);

119
  // create an ITTI message and copy SDU
120 121
  message_p = itti_alloc_new_message (TASK_CU_F1, RRC_MAC_CCCH_DATA_IND);
  memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE);
122 123 124
  ccch_sdu_len = ie->value.choice.RRCContainer.size;
  memcpy(RRC_MAC_CCCH_DATA_IND (message_p).sdu, ie->value.choice.RRCContainer.buf,
         ccch_sdu_len);
Bing-Kai Hong's avatar
Bing-Kai Hong committed
125 126 127
  LOG_D(CU_F1AP, "RRCContainer(CCCH) :");
  for (int i=0;i<ie->value.choice.RRCContainer.size;i++) LOG_D(CU_F1AP, "%2x ",RRC_MAC_CCCH_DATA_IND (message_p).sdu[i]);
  LOG_D(CU_F1AP, "\n");
128 129 130 131 132 133 134 135 136 137 138
  // Find instance from nr_cellid
  int rrc_inst = -1;
  for (int i=0;i<RC.nb_inst;i++) {
          // first get RRC instance (note, no the ITTI instance)
    eNB_RRC_INST *rrc = RC.rrc[i];
    if (rrc->nr_cellid == nr_cellid) {
      rrc_inst = i; 
      break;
    }
  }
  AssertFatal(rrc_inst>=0,"couldn't find an RRC instance for nr_cell %ll\n",nr_cellid);
139

140 141 142 143 144 145 146 147
  int f1ap_uid = f1ap_add_ue(&f1ap_cu_ue[rrc_inst], rrc_inst, CC_id, 0, rnti);
  if (f1ap_uid  < 0 ) {
    LOG_E(CU_F1AP, "Failed to add UE \n");
    return -1;
  }
  f1ap_cu_ue[rrc_inst].du_ue_f1ap_id[f1ap_uid] = du_ue_f1ap_id;


148 149 150
  RRC_MAC_CCCH_DATA_IND (message_p).frame     = 0; 
  RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = 0;
  RRC_MAC_CCCH_DATA_IND (message_p).sdu_size  = ccch_sdu_len;
151
  RRC_MAC_CCCH_DATA_IND (message_p).enb_index = rrc_inst; // CU instance 
152 153 154 155 156
  RRC_MAC_CCCH_DATA_IND (message_p).rnti      = rnti;
  RRC_MAC_CCCH_DATA_IND (message_p).CC_id      = CC_id; 
  itti_send_msg_to_task (TASK_RRC_ENB, instance, message_p);


157
  return 0;
158 159 160 161 162 163 164 165
}


/*
    DL RRC Message Transfer.
*/

//void CU_send_DL_RRC_MESSAGE_TRANSFER(F1AP_DLRRCMessageTransfer_t *DLRRCMessageTransfer) {
166 167 168 169 170
int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t                instance,
                                    f1ap_dl_rrc_message_t    *f1ap_dl_rrc)
                                    {

  F1AP_F1AP_PDU_t                 pdu; 
171 172 173 174 175 176 177
  F1AP_DLRRCMessageTransfer_t    *out;
  F1AP_DLRRCMessageTransferIEs_t *ie;

  uint8_t  *buffer;
  uint32_t  len;

  /* Create */
178
  /* 0. Message Type */ 
179 180 181 182 183 184 185 186 187 188
  memset(&pdu, 0, sizeof(pdu));
  pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
  pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t));
  pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_DLRRCMessageTransfer;
  pdu.choice.initiatingMessage->criticality   = F1AP_Criticality_ignore;
  pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_DLRRCMessageTransfer;
  out = &pdu.choice.initiatingMessage->value.choice.DLRRCMessageTransfer;
  
  /* mandatory */
  /* c1. GNB_CU_UE_F1AP_ID */
189

190 191 192 193
  ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
  ie->id                             = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
  ie->criticality                    = F1AP_Criticality_reject;
  ie->value.present                  = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_CU_UE_F1AP_ID;
194
  ie->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(&f1ap_cu_ue[instance],f1ap_dl_rrc->rnti);  
195
  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
196 197 198
  LOG_I(CU_F1AP, "Setting GNB_CU_UE_F1AP_ID %d associated with UE RNTI %x (instance %d)\n", 
                  ie->value.choice.GNB_CU_UE_F1AP_ID, f1ap_dl_rrc->rnti, instance);

199 200 201 202 203 204 205

  /* mandatory */
  /* c2. GNB_DU_UE_F1AP_ID */
  ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
  ie->id                             = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
  ie->criticality                    = F1AP_Criticality_reject;
  ie->value.present                  = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID;
206
  ie->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(&f1ap_cu_ue[instance],f1ap_dl_rrc->rnti); //f1ap_dl_rrc->gNB_DU_ue_id; // TODO: f1ap_dl_rrc->gNB_DU_ue_id  
207
  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
208
  LOG_I(CU_F1AP, "GNB_DU_UE_F1AP_ID %d associated with UE RNTI %x \n", ie->value.choice.GNB_DU_UE_F1AP_ID, f1ap_dl_rrc->rnti);
209 210 211

  /* optional */
  /* c3. oldgNB_DU_UE_F1AP_ID */
212
 /* if (f1ap_dl_rrc->old_gNB_DU_ue_id != 0xFFFFFFFF) {
213
    ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
214 215 216 217
    ie->id                                = F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID;
    ie->criticality                       = F1AP_Criticality_reject;
    ie->value.present                     = F1AP_DLRRCMessageTransferIEs__value_PR_NOTHING;
    ie->value.choice.oldgNB_DU_UE_F1AP_ID = f1ap_dl_rrc->old_gNB_DU_ue_id;
218
    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
219
  }*/ 
220 221 222 223 224 225 226

  /* mandatory */
  /* c4. SRBID */
  ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
  ie->id                            = F1AP_ProtocolIE_ID_id_SRBID;
  ie->criticality                   = F1AP_Criticality_reject;
  ie->value.present                 = F1AP_DLRRCMessageTransferIEs__value_PR_SRBID;
227
  ie->value.choice.SRBID            = f1ap_dl_rrc->srb_id;
228 229 230 231
  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);

  /* optional */
  /* c5. ExecuteDuplication */
232
  if (f1ap_dl_rrc->execute_duplication) {
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
    ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
    ie->id                            = F1AP_ProtocolIE_ID_id_ExecuteDuplication;
    ie->criticality                   = F1AP_Criticality_ignore;
    ie->value.present                 = F1AP_DLRRCMessageTransferIEs__value_PR_ExecuteDuplication;
    ie->value.choice.ExecuteDuplication = F1AP_ExecuteDuplication_true;
    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
  }

  // issue in here
  /* mandatory */
  /* c6. RRCContainer */
  ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
  ie->id                            = F1AP_ProtocolIE_ID_id_RRCContainer;
  ie->criticality                   = F1AP_Criticality_reject;
  ie->value.present                 = F1AP_DLRRCMessageTransferIEs__value_PR_RRCContainer;
248
  OCTET_STRING_fromBuf(&ie->value.choice.RRCContainer, f1ap_dl_rrc->rrc_container, f1ap_dl_rrc->rrc_container_length);
249 250 251 252
  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);

  /* optional */
  /* c7. RAT_FrequencyPriorityInformation */
253
  /* TODO */ 
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
  if (0) {
    ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
    ie->id                            = F1AP_ProtocolIE_ID_id_RAT_FrequencyPriorityInformation;
    ie->criticality                   = F1AP_Criticality_reject;
    ie->value.present                 = F1AP_DLRRCMessageTransferIEs__value_PR_RAT_FrequencyPriorityInformation;

    ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_subscriberProfileIDforRFP;
    ie->value.choice.RAT_FrequencyPriorityInformation.choice.subscriberProfileIDforRFP = 123L;

    //ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_rAT_FrequencySelectionPriority;
    //ie->value.choice.RAT_FrequencyPriorityInformation.choice.rAT_FrequencySelectionPriority = 123L;
    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
  }

  /* encode */
  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
Bing-Kai Hong's avatar
Bing-Kai Hong committed
270
    LOG_E(CU_F1AP, "Failed to encode F1 setup request\n");
271
    return -1;
272 273
  }

274
  cu_f1ap_itti_send_sctp_data_req(instance, f1ap_assoc_id /* BK: fix me*/ , buffer, len, 0 /* BK: fix me*/);
275

276
  return 0;
277 278 279 280 281 282
}

/*
    UL RRC Message Transfer
*/

283 284 285 286
int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t       instance,
                                      uint32_t         assoc_id,
                                      uint32_t         stream,
                                      F1AP_F1AP_PDU_t *pdu) {
287

Bing-Kai Hong's avatar
Bing-Kai Hong committed
288
  LOG_D(CU_F1AP, "CU_handle_UL_RRC_MESSAGE_TRANSFER \n");
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
  
  MessageDef                     *message_p;
  F1AP_ULRRCMessageTransfer_t    *container;
  F1AP_ULRRCMessageTransferIEs_t *ie;

  uint8_t  *buffer;
  uint32_t  len;
  
  uint64_t        cu_ue_f1ap_id;
  uint64_t        du_ue_f1ap_id;
  uint64_t        srb_id;
  int             executeDuplication;
  sdu_size_t      ccch_sdu_len;
  uint64_t        subscriberProfileIDforRFP;
  uint64_t        rAT_FrequencySelectionPriority;

  DevAssert(pdu != NULL);
  
  if (stream != 0) {
    LOG_E(F1AP, "[SCTP %d] Received F1 on stream != 0 (%d)\n",
               assoc_id, stream);
    return -1;
  }

  container = &pdu->choice.initiatingMessage->value.choice.ULRRCMessageTransfer;


  /* GNB_CU_UE_F1AP_ID */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container,
                             F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
  cu_ue_f1ap_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
320
  LOG_D(CU_F1AP, "cu_ue_f1ap_id %lu associated with RNTI %x \n", cu_ue_f1ap_id, f1ap_get_rnti_by_cu_id(&f1ap_cu_ue[instance],cu_ue_f1ap_id));
321 322 323 324 325 326


  /* GNB_DU_UE_F1AP_ID */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container,
                             F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
  du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
327
  LOG_D(CU_F1AP, "du_ue_f1ap_id %lu associated with RNTI %x \n", du_ue_f1ap_id, f1ap_get_rnti_by_cu_id(&f1ap_cu_ue[instance],du_ue_f1ap_id));
328 329 330 331 332 333 334


  /* mandatory */
  /* SRBID */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container,
                             F1AP_ProtocolIE_ID_id_SRBID, true);
  srb_id = ie->value.choice.SRBID;
335
  if (srb_id < 1 ) 
336
    LOG_E(CU_F1AP, "Unexpected UL RRC MESSAGE for srb_id %lu \n", srb_id);
337 338
  else  
    LOG_D(CU_F1AP, "UL RRC MESSAGE for srb_id %lu in DCCH \n", srb_id);
339 340 341 342 343 344 345


  // issue in here
  /* mandatory */
  /* RRC Container */
  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container,
                             F1AP_ProtocolIE_ID_id_RRCContainer, true);
346
  // print message in debug mode 
347

348
  // create an ITTI message and copy SDU
349
  /*
350
  
351
  message_p = itti_alloc_new_message (TASK_CU_F1, RRC_DCCH_DATA_IND);
352 353

  RRC_DCCH_DATA_IND (message_p).sdu_p = malloc(ie->value.choice.RRCContainer.size);
354 355 356 357 358 359 360 361 362 363 364

  RRC_DCCH_DATA_IND (message_p).sdu_size = ie->value.choice.RRCContainer.size;
  memcpy(RRC_DCCH_DATA_IND (message_p).sdu_p, ie->value.choice.RRCContainer.buf,
         ie->value.choice.RRCContainer.size);

  RRC_DCCH_DATA_IND (message_p).dcch_index = srb_id;
  RRC_DCCH_DATA_IND (message_p).rnti = f1ap_get_rnti_by_cu_id(&f1ap_cu_ue[instance],cu_ue_f1ap_id);
  RRC_DCCH_DATA_IND (message_p).module_id = instance;
  RRC_DCCH_DATA_IND (message_p).eNB_index = instance; // not needed for CU

  itti_send_msg_to_task(TASK_RRC_ENB, instance, message_p);
365 366 367 368 369 370 371 372 373 374 375 376 377
  */
  protocol_ctxt_t ctxt;
  ctxt.module_id = instance;
  ctxt.rnti = f1ap_get_rnti_by_cu_id(&f1ap_cu_ue[instance],cu_ue_f1ap_id);
  ctxt.enb_flag = 1;
  mem_block_t *mb = get_free_mem_block(ie->value.choice.RRCContainer.size,__func__);
  memcpy((void*)mb->data,(void*)ie->value.choice.RRCContainer.buf,ie->value.choice.RRCContainer.size);
  pdcp_data_ind (&ctxt,
		 1,
		 0,
		 srb_id,
		 ie->value.choice.RRCContainer.size,
		 mb);
378
  return 0;
379
}