From d092788aa3f8229eb5c938a41534dfb318955135 Mon Sep 17 00:00:00 2001
From: laurent <laurent Thomas>
Date: Wed, 6 Jul 2022 14:18:39 +0200
Subject: [PATCH] fix regression with F1, some basic cleaning in NGAP

---
 openair2/GNB_APP/gnb_app.c                |  11 +-
 openair2/GNB_APP/gnb_config.c             |  24 +-
 openair2/GNB_APP/gnb_config.h             |   2 +-
 openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c |   1 -
 openair2/RRC/NR/rrc_gNB.c                 |  44 ----
 openair2/RRC/NR/rrc_gNB_NGAP.c            | 293 +++++++++++-----------
 6 files changed, 162 insertions(+), 213 deletions(-)

diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c
index d504e912919..1d0c210158d 100644
--- a/openair2/GNB_APP/gnb_app.c
+++ b/openair2/GNB_APP/gnb_app.c
@@ -68,7 +68,7 @@ static void configure_nr_rrc(uint32_t gnb_id)
   msg_p = itti_alloc_new_message (TASK_GNB_APP, 0, NRRRC_CONFIGURATION_REQ);
 
   if (RC.nrrrc[gnb_id]) {
-    set_node_type();
+    RC.nrrrc[gnb_id]->node_type=set_node_type();
     RCconfig_NRRRC(msg_p,gnb_id, RC.nrrrc[gnb_id]);
     
     LOG_I(GNB_APP, "RRC starting with node type %d\n", RC.nrrrc[gnb_id]->node_type);
@@ -196,8 +196,11 @@ void *gNB_app_task(void *args_p)
   }
   
   if (RC.nb_nr_inst > 0) {
+    if (RC.nrrrc[0]->node_type == ngran_gNB_CUCP ||
+        RC.nrrrc[0]->node_type == ngran_gNB_CU ||
+        RC.nrrrc[0]->node_type == ngran_eNB_CU ||
+        RC.nrrrc[0]->node_type == ngran_ng_eNB_CU) {
     
-    if (NODE_IS_CU(RC.nrrrc[0]->node_type)) {
       if (itti_create_task(TASK_CU_F1, F1AP_CU_task, NULL) < 0) {
         LOG_E(F1AP, "Create task for F1AP CU failed\n");
         AssertFatal(1==0,"exiting");
@@ -216,7 +219,9 @@ void *gNB_app_task(void *args_p)
       
       itti_send_msg_to_task(TASK_CUCP_E1, GNB_MODULE_ID_TO_INSTANCE(0), msg_p);
       
-    } else if (RC.nrrrc[0]->node_type == ngran_gNB_CUUP) {
+    }
+
+    if (RC.nrrrc[0]->node_type == ngran_gNB_CUUP) {
       if (itti_create_task(TASK_CUUP_E1, E1AP_CUUP_task, NULL) < 0) {
         LOG_E(E1AP, "Create task for E1AP UP failed\n");
         AssertFatal(1==0, "exiting");
diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c
index 5bf81a7fc3c..d779ff3827c 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -1149,7 +1149,8 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
 
     printf("NRRRC %d: Southbound Transport %s\n",i,*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr));
 
-    if (strcmp(*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "f1") == 0) {
+    rrc->node_type = set_node_type();
+    if (NODE_IS_CU(rrc->node_type)) {
       paramdef_t SCTPParams[]  = GNBSCTPPARAMS_DESC;
       char aprefix[MAX_OPTNAME_SIZE*2 + 8];
       sprintf(aprefix,"%s.[%u].%s",GNB_CONFIG_STRING_GNB_LIST,i,GNB_CONFIG_STRING_SCTP_CONFIG);
@@ -1170,7 +1171,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
       rrc->sctp_out_streams                      = (uint16_t)*(SCTPParams[GNB_SCTP_OUTSTREAMS_IDX].uptr);
     }
 
-    rrc->node_type = node_type;
+   
 
     rrc->nr_cellid        = (uint64_t)*(GNBParamList.paramarray[i][GNB_NRCELLID_IDX].u64ptr);
 
@@ -2330,15 +2331,14 @@ static ngran_node_t get_node_type(void)
     }
   }
 
-  if ((strcmp(*(GNBParamList.paramarray[0][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "f1") == 0) &&
-      (strcmp(*(GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_CU_TYPE_IDX].strptr), "cp") == 0))
-    return ngran_gNB_CUCP;
-  else if ((strcmp(*(GNBParamList.paramarray[0][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "f1") == 0) &&
-           (strcmp(*(GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_CU_TYPE_IDX].strptr), "up") == 0))
-    return ngran_gNB_CUUP;
-  else if (strcmp(*(GNBParamList.paramarray[0][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "f1") == 0)
-    return ngran_gNB_CU;
-  else if (macrlc_has_f1 == 0)
+  if (strcmp(*(GNBParamList.paramarray[0][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "f1") == 0) {
+    if ( GNBE1ParamList.paramarray == NULL || GNBE1ParamList.numelt == 0 )
+      return ngran_gNB_CU;
+    if (strcmp(*(GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_CU_TYPE_IDX].strptr), "cp") == 0)
+      return ngran_gNB_CUCP;
+    if (strcmp(*(GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_CU_TYPE_IDX].strptr), "up") == 0)
+      return ngran_gNB_CUUP;
+  } else if (macrlc_has_f1 == 0)
     return ngran_gNB;
   else
     return ngran_gNB_DU;
@@ -2373,7 +2373,7 @@ void nr_read_config_and_init(void) {
     RCconfig_NRRRC(msg_p,gnb_id, RC.nrrrc[gnb_id]);
   }
 
-  if (NODE_IS_CU(RC.nrrrc[0]->node_type)) {
+  if (NODE_IS_CU(RC.nrrrc[0]->node_type) && RC.nrrrc[0]->node_type != ngran_gNB_CUCP) {
     pdcp_layer_init();
 //    nr_DRB_preconfiguration(0x1234);
     rrc_init_nr_global_param();
diff --git a/openair2/GNB_APP/gnb_config.h b/openair2/GNB_APP/gnb_config.h
index ec6e6cf4b7f..a80ac4cfa93 100644
--- a/openair2/GNB_APP/gnb_config.h
+++ b/openair2/GNB_APP/gnb_config.h
@@ -108,7 +108,7 @@ int RCconfig_NR_DU_F1(MessageDef *msg_p, uint32_t i);
 int gNB_app_handle_f1ap_setup_resp(f1ap_setup_resp_t *resp);
 int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_update_t *gnb_cu_cfg_update);
 void nr_read_config_and_init(void);
-void set_node_type(void);
+ngran_node_t  set_node_type(void);
 int RCconfig_NR_CU_E1(MessageDef *msg_p, uint32_t i);
 
 #endif /* GNB_CONFIG_H_ */
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
index ece0b0274d2..042352e8eac 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
@@ -54,7 +54,6 @@ static int      nr_pdcp_current_time_last_subframe;
 hash_table_t  *pdcp_coll_p;
 static uint64_t pdcp_optmask;
 
-ngran_node_t node_type = ngran_gNB;
 uint8_t first_dcch = 0;
 uint8_t proto_agent_flag = 0;
 
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index bee2c39935d..e69ed804b6b 100755
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -369,54 +369,10 @@ rrc_gNB_generate_RRCSetup(
               ue_p->Srb0.Tx_buffer.payload_size,
               "[MSG] RRC Setup\n");
 
-<<<<<<< HEAD
   // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE
   ue_context_pP->ue_context.ue_release_timer = 1;
   // remove UE after 10 frames after RRCConnectionRelease is triggered
   ue_context_pP->ue_context.ue_release_timer_thres = 1000;
-=======
-  switch (rrc->node_type) {
-    case ngran_gNB_CU:
-      // create an ITTI message
-      /* TODO: F1 IDs ar missing in RRC */
-      nr_rrc_pdcp_config_asn1_req(ctxt_pP,
-				  ue_context_pP->ue_context.SRB_configList,
-				  NULL,
-				  NULL,
-				  0,
-				  NULL,
-				  NULL,
-				  NULL,
-				  NULL,
-				  NULL,
-				  NULL,
-				  NULL);
-      message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_DL_RRC_MESSAGE);
-      F1AP_DL_RRC_MESSAGE (message_p).rrc_container        =  (uint8_t *)ue_p->Srb0.Tx_buffer.Payload;
-      F1AP_DL_RRC_MESSAGE (message_p).rrc_container_length = ue_p->Srb0.Tx_buffer.payload_size;
-      F1AP_DL_RRC_MESSAGE (message_p).gNB_CU_ue_id         = 0;
-      F1AP_DL_RRC_MESSAGE (message_p).gNB_DU_ue_id         = 0;
-      F1AP_DL_RRC_MESSAGE (message_p).old_gNB_DU_ue_id     = 0xFFFFFFFF; // unknown
-      F1AP_DL_RRC_MESSAGE (message_p).rnti                 = ue_p->rnti;
-      F1AP_DL_RRC_MESSAGE (message_p).srb_id               = CCCH;
-      F1AP_DL_RRC_MESSAGE (message_p).execute_duplication  = 1;
-      F1AP_DL_RRC_MESSAGE (message_p).RAT_frequency_priority_information.en_dc = 0;
-      itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p);
-      LOG_D(NR_RRC, "Send F1AP_DL_RRC_MESSAGE with ITTI\n");
-
-    break;
-
-  case ngran_gNB_DU:
-  case ngran_gNB_CUCP:
-  case ngran_gNB_CUUP:
-      // nothing to do for DU
-      AssertFatal(1==0,"nothing to do for DU\n");
-      break;
-
-    case ngran_gNB:
-    {
-      // rrc_mac_config_req_gNB
->>>>>>> build, run in F1 mode until UE connect but pdu session still fails
 
   /* TODO: this should go through the E1 interface */
   apply_pdcp_config(ue_context_pP,ctxt_pP);
diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c
index 329da1e272f..a92f43b080f 100644
--- a/openair2/RRC/NR/rrc_gNB_NGAP.c
+++ b/openair2/RRC/NR/rrc_gNB_NGAP.c
@@ -962,208 +962,197 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(
   uint32_t                        gNB_ue_ngap_id;
   rrc_gNB_ue_context_t            *ue_context_p = NULL;
   protocol_ctxt_t                 ctxt={0};
-  gtpv1u_gnb_create_tunnel_req_t  create_tunnel_req={0};
-  gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0};
   uint8_t                         pdu_sessions_done;
   uint8_t                         inde_list[NR_NB_RB_MAX - 3]= {0};
   int                             ret = 0;
 
-  ue_initial_id  = NGAP_PDUSESSION_SETUP_REQ(msg_p).ue_initial_id;
-  gNB_ue_ngap_id = NGAP_PDUSESSION_SETUP_REQ(msg_p).gNB_ue_ngap_id;
+  ngap_pdusession_setup_req_t* msg=&NGAP_PDUSESSION_SETUP_REQ(msg_p);
+  ue_initial_id  = msg->ue_initial_id;
+  gNB_ue_ngap_id = msg->gNB_ue_ngap_id;
   ue_context_p   = rrc_gNB_get_ue_context_from_ngap_ids(instance, ue_initial_id, gNB_ue_ngap_id);
   PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0);
   rrc = RC.nrrrc[ctxt.module_id];
   LOG_I(NR_RRC, "[gNB %ld] Received %s: ue_initial_id %d, gNB_ue_ngap_id %u \n",
-    instance, msg_name, ue_initial_id, gNB_ue_ngap_id);
+        instance, msg_name, ue_initial_id, gNB_ue_ngap_id);
 
-  if (RC.nrrrc[ctxt.module_id]->node_type == ngran_gNB_CUCP) { // E1 split CU-CP node
+  if (ue_context_p == NULL) {
+    MessageDef *msg_fail_p = NULL;
+    LOG_W(NR_RRC, "[gNB %ld] In NGAP_PDUSESSION_SETUP_REQ: unknown UE from NGAP ids (%d, %u)\n", instance, ue_initial_id, gNB_ue_ngap_id);
+    msg_fail_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_PDUSESSION_SETUP_REQUEST_FAIL);
+    NGAP_PDUSESSION_SETUP_REQ(msg_fail_p).gNB_ue_ngap_id = gNB_ue_ngap_id;
+    // TODO add failure cause when defined!
+    itti_send_msg_to_task (TASK_NGAP, instance, msg_fail_p);
+    return ;
+  }
+  
+  if (rrc->node_type == ngran_gNB_CUCP) { // E1 split CU-CP node
     /* Configurations are referred from rrc_gNB_generate_dedicatedRRCReconfiguration() and
        rrc_gNB_process_RRCReconfigurationComplete()
-
+       
        At CU-CP we configure the E1 bearer context setup parameters (PDU sessions, DRBs and 
        QoS flows) same as in these functions. At CU-UP we create PDU Sessions and allocate DRBs.
     */
     MessageDef *msg_p = NULL;
     msg_p = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_BEARER_CONTEXT_SETUP_REQ);
     e1ap_bearer_setup_req_t *bearer_req = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg_p);
-
+    
     bearer_req->gNB_cu_cp_ue_id = gNB_ue_ngap_id;
     bearer_req->cipheringAlgorithm = ue_context_p->ue_context.ciphering_algorithm;
     memcpy(bearer_req->encryptionKey, ue_context_p->ue_context.kgnb, 128);
-    bearer_req->ueDlAggMaxBitRate = NGAP_PDUSESSION_SETUP_REQ(msg_p).ueAggMaxBitRateDownlink;
-
-    bearer_req->numPDUSessions = NGAP_PDUSESSION_SETUP_REQ(msg_p).nb_pdusessions_tosetup;
+    bearer_req->ueDlAggMaxBitRate = msg->ueAggMaxBitRateDownlink;
+    
+    bearer_req->numPDUSessions = msg->nb_pdusessions_tosetup;
     for (int i=0; i < bearer_req->numPDUSessions; i++) {
       pdu_session_to_setup_t *pdu = bearer_req->pduSession + i;
-      pdu->sessionId   = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].pdusession_id;
-      pdu->sessionType = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].upf_addr.pdu_session_type;
-      pdu->sst         = NGAP_PDUSESSION_SETUP_REQ(msg_p).allowed_nssai[i].sST;
+      pdu->sessionId   = msg->pdusession_setup_params[i].pdusession_id;
+      pdu->sessionType = msg->pdusession_setup_params[i].upf_addr.pdu_session_type;
+      pdu->sst         = msg->allowed_nssai[i].sST;
       pdu->integrityProtectionIndication       = 1; // Preferred. TODO: Remove hardcoding
       pdu->confidentialityProtectionIndication = 1; // Preferred. TODO: Remove hardcoding
-      pdu->teId                                = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].gtp_teid;
+      pdu->teId                                = msg->pdusession_setup_params[i].gtp_teid;
       memcpy(&pdu->tlAddress,
-             NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].upf_addr.buffer,
+             msg->pdusession_setup_params[i].upf_addr.buffer,
              sizeof(uint8_t)*20);
-
+      
       pdu->numDRB2Setup = 1; // One DRB per PDU Session. TODO: Remove hardcoding
       for (int j=0; j < pdu->numDRB2Setup; j++) {
         DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + j;
         drb->id = i + j;
         drb->defaultDRB = E1AP_DefaultDRB_true;
-
+        
         drb->sDAP_Header_UL = !(rrc->configuration.enable_sdap);
         drb->sDAP_Header_DL = !(rrc->configuration.enable_sdap);
-
+        
         drb->pDCP_SN_Size_UL = E1AP_PDCP_SN_Size_s_18;
         drb->pDCP_SN_Size_DL = E1AP_PDCP_SN_Size_s_18;
-
+        
         drb->rLC_Mode = E1AP_RLC_Mode_rlc_am;
-
+        
         drb->numCellGroups = 1; // assume one cell group associated with a DRB
         for (int k=0; k < drb->numCellGroups; k++) {
           cell_group_t *cellGroup = drb->cellGroupList + k;
           cellGroup->id = 0; // MCG
         }
-
-        drb->numQosFlow2Setup = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].nb_qos;
+        
+        drb->numQosFlow2Setup = msg->pdusession_setup_params[i].nb_qos;
         for (int k=0; k < drb->numQosFlow2Setup; k++) {
           qos_flow_to_setup_t *qos = drb->qosFlows + k;
-
-          qos->id          = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].qos[k].qfi;
-          qos->fiveQI      = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].qos[k].fiveQI;
-          qos->fiveQI_type = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].qos[k].fiveQI_type;
-
-          qos->qoSPriorityLevel = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].qos[k].allocation_retention_priority.priority_level;
-          qos->pre_emptionCapability = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].qos[k].allocation_retention_priority.pre_emp_capability;
-          qos->pre_emptionVulnerability = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].qos[k].allocation_retention_priority.pre_emp_vulnerability;
+          
+          qos->id          = msg->pdusession_setup_params[i].qos[k].qfi;
+          qos->fiveQI      = msg->pdusession_setup_params[i].qos[k].fiveQI;
+          qos->fiveQI_type = msg->pdusession_setup_params[i].qos[k].fiveQI_type;
+          
+          qos->qoSPriorityLevel = msg->pdusession_setup_params[i].qos[k].allocation_retention_priority.priority_level;
+          qos->pre_emptionCapability = msg->pdusession_setup_params[i].qos[k].allocation_retention_priority.pre_emp_capability;
+          qos->pre_emptionVulnerability = msg->pdusession_setup_params[i].qos[k].allocation_retention_priority.pre_emp_vulnerability;
         }
       }
     }
     itti_send_msg_to_task (TASK_CUCP_E1, ctxt.module_id, msg_p);
+    return;
+  }
 
-  } else { // Monolithic
-    if (ue_context_p == NULL) {
-      MessageDef *msg_fail_p = NULL;
-      LOG_W(NR_RRC, "[gNB %ld] In NGAP_PDUSESSION_SETUP_REQ: unknown UE from NGAP ids (%d, %u)\n", instance, ue_initial_id, gNB_ue_ngap_id);
-      msg_fail_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_PDUSESSION_SETUP_REQUEST_FAIL);
-      NGAP_PDUSESSION_SETUP_REQ(msg_fail_p).gNB_ue_ngap_id = gNB_ue_ngap_id;
-      // TODO add failure cause when defined!
-      itti_send_msg_to_task (TASK_NGAP, instance, msg_fail_p);
-      return ;
-    } else {
-      memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t));
-      uint8_t nb_pdusessions_tosetup = NGAP_PDUSESSION_SETUP_REQ(msg_p).nb_pdusessions_tosetup;
-      pdu_sessions_done = 0;
-
-      for (int i = 0; i < NR_NB_RB_MAX - 3; i++) {
-        if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE)
-          continue;
-        ue_context_p->ue_context.pduSession[i].status      = PDU_SESSION_STATUS_NEW;
-        ue_context_p->ue_context.pduSession[i].param       = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done];
-        create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].pdusession_id;
-        create_tunnel_req.incoming_rb_id[pdu_sessions_done]= i+1;
-        create_tunnel_req.outgoing_teid[pdu_sessions_done]  = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].gtp_teid;
-        create_tunnel_req.outgoing_qfi[pdu_sessions_done]  = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].qos[0].qfi;
-        memcpy(create_tunnel_req.dst_addr[pdu_sessions_done].buffer,
-                NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.buffer,
-                sizeof(uint8_t)*20);
-        create_tunnel_req.dst_addr[pdu_sessions_done].length = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.length;
-        LOG_I(NR_RRC,"NGAP PDUSESSION SETUP REQ: local index %d teid %u, pdusession id %d \n",
-              i,
-              create_tunnel_req.outgoing_teid[pdu_sessions_done],
-              create_tunnel_req.pdusession_id[pdu_sessions_done]);
-        inde_list[pdu_sessions_done] = i;
-        pdu_sessions_done++;
-
-        if(pdu_sessions_done >= nb_pdusessions_tosetup) {
-          break;
-        }
-      }
-
-      ue_context_p->ue_context.nb_of_pdusessions = NGAP_PDUSESSION_SETUP_REQ(msg_p).nb_pdusessions_tosetup;
-      ue_context_p->ue_context.gNB_ue_ngap_id    = NGAP_PDUSESSION_SETUP_REQ(msg_p).gNB_ue_ngap_id;
-      ue_context_p->ue_context.amf_ue_ngap_id    = NGAP_PDUSESSION_SETUP_REQ(msg_p).amf_ue_ngap_id;
-      create_tunnel_req.rnti                     = ue_context_p->ue_context.rnti;
-      create_tunnel_req.num_tunnels              = pdu_sessions_done;
-
-      ret = gtpv1u_create_ngu_tunnel(
-              instance,
-              &create_tunnel_req,
-              &create_tunnel_resp);
-      if (ret != 0) {
-        LOG_E(NR_RRC,"rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE %x\n",ue_context_p->ue_context.rnti);
-        ue_context_p->ue_context.ue_release_timer_ng = 1;
-        ue_context_p->ue_context.ue_release_timer_thres_ng = 100;
-        ue_context_p->ue_context.ue_release_timer = 0;
-        ue_context_p->ue_context.ue_reestablishment_timer = 0;
-        ue_context_p->ue_context.ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ
-        // rrc_gNB_free_UE(ctxt.module_id,ue_context_p);
-        ue_context_p->ue_context.ul_failure_timer = 0;
-        return ;
-      }
-      nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
-        &ctxt,
-        &create_tunnel_resp,
-        &inde_list[0]);
-      ue_context_p->ue_context.setup_pdu_sessions += nb_pdusessions_tosetup;
-
-      // TEST 
-      // ue_context_p->ue_context.pdusession[0].status = PDU_SESSION_STATUS_DONE;
-      // rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(&ctxt, ue_context_p, 0);
-      rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, NULL);
-      return;
-    }
-    nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
-      &ctxt,
-      &create_tunnel_resp,
-      &inde_list[0]);
-    ue_context_p->ue_context.setup_pdu_sessions += NGAP_PDUSESSION_SETUP_REQ(msg_p).nb_pdusessions_tosetup;
-
-    // TEST 
-    // ue_context_p->ue_context.pdusession[0].status = PDU_SESSION_STATUS_DONE;
-    // rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(&ctxt, ue_context_p, 0);
-    if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)){
-      rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, NULL);
-    }
-    else{
-      /*Generate a UE context modification request message towards the DU to instruct the DU
-       *for SRB2 and DRB configuration and get the updates on master cell group config from the DU*/
-      MessageDef *message_p;
-      message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ);
-      f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_MODIFICATION_REQ (message_p);
-      req->rnti             = ue_context_p->ue_context.rnti;
-      req->mcc              = RC.nrrrc[ctxt.module_id]->configuration.mcc[0];
-      req->mnc              = RC.nrrrc[ctxt.module_id]->configuration.mnc[0];
-      req->mnc_digit_length = RC.nrrrc[ctxt.module_id]->configuration.mnc_digit_length[0];
-      req->nr_cellid        = RC.nrrrc[ctxt.module_id]->nr_cellid;
-
-      /*Instruction towards the DU for SRB2 configuration*/
-      req->srbs_to_be_setup = malloc(1*sizeof(f1ap_srb_to_be_setup_t));
-      req->srbs_to_be_setup_length = 1;
-      f1ap_srb_to_be_setup_t *SRBs=req->srbs_to_be_setup;
-      SRBs[0].srb_id = 2;
-      SRBs[0].lcid = 2;
-
-      /*Instruction towards the DU for DRB configuration and tunnel creation*/
-      gtpv1u_gnb_create_tunnel_req_t  create_tunnel_req;
-      memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t));
-      req->drbs_to_be_setup = malloc(1*sizeof(f1ap_drb_to_be_setup_t));
-      req->drbs_to_be_setup_length = 1;
-      f1ap_drb_to_be_setup_t *DRBs=req->drbs_to_be_setup;
-      LOG_D(RRC, "Length of DRB list:%d \n", req->drbs_to_be_setup_length);
-      DRBs[0].drb_id = 1;
-      DRBs[0].rlc_mode = RLC_MODE_AM;
-      DRBs[0].up_ul_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr);
-      DRBs[0].up_ul_tnl[0].port=RC.nrrrc[ctxt.module_id]->eth_params_s.my_portd;
-      DRBs[0].up_ul_tnl_length = 1;
-      DRBs[0].up_dl_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.remote_addr);
-      DRBs[0].up_dl_tnl[0].port=RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd;
-      DRBs[0].up_dl_tnl_length = 1;
-
-      itti_send_msg_to_task (TASK_CU_F1, ctxt.module_id, message_p);
+  // No E1-AP
+  gtpv1u_gnb_create_tunnel_req_t  create_tunnel_req={0};
+  gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0};
+  uint8_t nb_pdusessions_tosetup = msg->nb_pdusessions_tosetup;
+  pdu_sessions_done = 0;
+    
+  for (int i = 0; i < NR_NB_RB_MAX - 3; i++) {
+    if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE)
+      continue;
+    ue_context_p->ue_context.pduSession[i].status      = PDU_SESSION_STATUS_NEW;
+    ue_context_p->ue_context.pduSession[i].param       = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done];
+    create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].pdusession_id;
+    create_tunnel_req.incoming_rb_id[pdu_sessions_done]= i+1;
+    create_tunnel_req.outgoing_teid[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].gtp_teid;
+    create_tunnel_req.outgoing_qfi[pdu_sessions_done]  = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].qos[0].qfi;
+    memcpy(create_tunnel_req.dst_addr[pdu_sessions_done].buffer,
+           NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.buffer,
+           sizeof(uint8_t)*20);
+    create_tunnel_req.dst_addr[pdu_sessions_done].length = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.length;
+    LOG_I(NR_RRC,"NGAP PDUSESSION SETUP REQ: local index %d teid %u, pdusession id %d \n",
+          i,
+          create_tunnel_req.outgoing_teid[pdu_sessions_done],
+          create_tunnel_req.pdusession_id[pdu_sessions_done]);
+    inde_list[pdu_sessions_done] = i;
+    pdu_sessions_done++;
+      
+    if(pdu_sessions_done >= nb_pdusessions_tosetup) {
+      break;
     }
-    return;
   }
+    
+  ue_context_p->ue_context.nb_of_pdusessions = msg->nb_pdusessions_tosetup;
+  ue_context_p->ue_context.gNB_ue_ngap_id    = msg->gNB_ue_ngap_id;
+  ue_context_p->ue_context.amf_ue_ngap_id    = msg->amf_ue_ngap_id;
+  create_tunnel_req.rnti                     = ue_context_p->ue_context.rnti;
+  create_tunnel_req.num_tunnels              = pdu_sessions_done;
+    
+  ret = gtpv1u_create_ngu_tunnel(
+                                 instance,
+                                 &create_tunnel_req,
+                                 &create_tunnel_resp);
+  if (ret != 0) {
+    LOG_E(NR_RRC,"rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE %x\n",
+          ue_context_p->ue_context.rnti);
+    ue_context_p->ue_context.ue_release_timer_ng = 1;
+    ue_context_p->ue_context.ue_release_timer_thres_ng = 100;
+    ue_context_p->ue_context.ue_release_timer = 0;
+    ue_context_p->ue_context.ue_reestablishment_timer = 0;
+    // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ
+    ue_context_p->ue_context.ul_failure_timer = 20000; 
+    // rrc_gNB_free_UE(ctxt.module_id,ue_context_p);
+    ue_context_p->ue_context.ul_failure_timer = 0;
+    //Fix me: should send error to 5GC
+    return ;
+  }
+  
+  nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(&ctxt,
+                                               &create_tunnel_resp,
+                                               &inde_list[0]);
+  ue_context_p->ue_context.setup_pdu_sessions += nb_pdusessions_tosetup;
+
+  if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)){
+    rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, NULL);
+  } else {
+    /*Generate a UE context modification request message towards the DU to instruct the DU
+     *for SRB2 and DRB configuration and get the updates on master cell group config from the DU*/
+    MessageDef *message_p;
+    message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ);
+    f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_MODIFICATION_REQ (message_p);
+    req->rnti             = ue_context_p->ue_context.rnti;
+    req->mcc              = RC.nrrrc[ctxt.module_id]->configuration.mcc[0];
+    req->mnc              = RC.nrrrc[ctxt.module_id]->configuration.mnc[0];
+    req->mnc_digit_length = RC.nrrrc[ctxt.module_id]->configuration.mnc_digit_length[0];
+    req->nr_cellid        = RC.nrrrc[ctxt.module_id]->nr_cellid;
+
+    /*Instruction towards the DU for SRB2 configuration*/
+    req->srbs_to_be_setup = malloc(1*sizeof(f1ap_srb_to_be_setup_t));
+    req->srbs_to_be_setup_length = 1;
+    f1ap_srb_to_be_setup_t *SRBs=req->srbs_to_be_setup;
+    SRBs[0].srb_id = 2;
+    SRBs[0].lcid = 2;
+
+    /*Instruction towards the DU for DRB configuration and tunnel creation*/
+    gtpv1u_gnb_create_tunnel_req_t  create_tunnel_req;
+    memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t));
+    req->drbs_to_be_setup = malloc(1*sizeof(f1ap_drb_to_be_setup_t));
+    req->drbs_to_be_setup_length = 1;
+    f1ap_drb_to_be_setup_t *DRBs=req->drbs_to_be_setup;
+    LOG_D(RRC, "Length of DRB list:%d \n", req->drbs_to_be_setup_length);
+    DRBs[0].drb_id = 1;
+    DRBs[0].rlc_mode = RLC_MODE_AM;
+    DRBs[0].up_ul_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr);
+    DRBs[0].up_ul_tnl[0].port=RC.nrrrc[ctxt.module_id]->eth_params_s.my_portd;
+    DRBs[0].up_ul_tnl_length = 1;
+    DRBs[0].up_dl_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.remote_addr);
+    DRBs[0].up_dl_tnl[0].port=RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd;
+    DRBs[0].up_dl_tnl_length = 1;
+
+    itti_send_msg_to_task (TASK_CU_F1, ctxt.module_id, message_p);
+  }
+  return;
 }
 
 //------------------------------------------------------------------------------
-- 
GitLab