From 34adf865820f09900a5efed693ada1ccf6f0f1ad Mon Sep 17 00:00:00 2001
From: Sakthivel Velumani <velumani@eurecom.fr>
Date: Wed, 31 Aug 2022 19:31:50 -0400
Subject: [PATCH] Removed RRC thread from CUUP

---
 executables/nr-softmodem.c                |  39 ++--
 openair2/COMMON/e1ap_messages_types.h     |   1 +
 openair2/E1AP/CMakeLists.txt              |   2 +-
 openair2/E1AP/e1ap.c                      |  20 +-
 openair2/E1AP/e1ap.h                      |   3 +
 openair2/E1AP/e1ap_api.c                  | 254 ++++++++++++++++++++++
 openair2/E1AP/e1ap_api.h                  |  39 ++++
 openair2/GNB_APP/gnb_app.c                |  19 +-
 openair2/GNB_APP/gnb_config.c             |   5 +-
 openair2/GNB_APP/gnb_config.h             |   1 +
 openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c |  15 +-
 openair2/RRC/NR/rrc_gNB.c                 | 243 +--------------------
 12 files changed, 353 insertions(+), 288 deletions(-)
 create mode 100644 openair2/E1AP/e1ap_api.c
 create mode 100644 openair2/E1AP/e1ap_api.h

diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c
index 57737247941..270ec810572 100644
--- a/executables/nr-softmodem.c
+++ b/executables/nr-softmodem.c
@@ -314,20 +314,23 @@ int create_gNB_tasks(void) {
 
   RC.nrrrc = (gNB_RRC_INST **)malloc(RC.nb_nr_inst*sizeof(gNB_RRC_INST *));
   LOG_I(PHY, "%s() RC.nb_nr_inst:%d RC.nrrrc:%p\n", __FUNCTION__, RC.nb_nr_inst, RC.nrrrc);
-  for (int gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) {
-    RC.nrrrc[gnb_id] = (gNB_RRC_INST*)calloc(1,sizeof(gNB_RRC_INST));
-    LOG_I(PHY, "%s() Creating RRC instance RC.nrrrc[%d]:%p (%d of %d)\n", __FUNCTION__, gnb_id, RC.nrrrc[gnb_id], gnb_id+1, gnb_id_end);
-    configure_nr_rrc(gnb_id);
+  ngran_node_t node_type = get_node_type();
+  if (node_type != ngran_gNB_CUUP) {
+    for (int gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) {
+      RC.nrrrc[gnb_id] = (gNB_RRC_INST*)calloc(1,sizeof(gNB_RRC_INST));
+      LOG_I(PHY, "%s() Creating RRC instance RC.nrrrc[%d]:%p (%d of %d)\n", __FUNCTION__, gnb_id, RC.nrrrc[gnb_id], gnb_id+1, gnb_id_end);
+      configure_nr_rrc(gnb_id);
+    }
   }
 
   if (RC.nb_nr_inst > 0 &&
       !get_softmodem_params()->nsa &&
-      !(RC.nrrrc[0]->node_type == ngran_gNB_DU))  {
+      !(node_type == ngran_gNB_DU))  {
     // we start pdcp in both cuup (for drb) and cucp (for srb)
     init_pdcp();
   }
 
-  if (is_x2ap_enabled() ) { //&& !NODE_IS_DU(RC.rrc[0]->node_type)
+  if (is_x2ap_enabled() ) { //&& !NODE_IS_DU(node_type)
 	  LOG_I(X2AP, "X2AP enabled \n");
 	  __attribute__((unused)) uint32_t x2_register_gnb_pending = gNB_app_register_x2 (gnb_id_start, gnb_id_end);
   }
@@ -335,8 +338,8 @@ int create_gNB_tasks(void) {
   /* For the CU case the gNB registration with the AMF might have to take place after the F1 setup, as the PLMN info
      * can originate from the DU. Add check on whether x2ap is enabled to account for ENDC NSA scenario.*/
   if ((get_softmodem_params()->sa || is_x2ap_enabled()) &&
-      !NODE_IS_DU(RC.nrrrc[0]->node_type) &&
-      RC.nrrrc[gnb_id_start]->node_type != ngran_gNB_CUUP) {
+      !NODE_IS_DU(node_type) &&
+      node_type != ngran_gNB_CUUP) {
     /* Try to register each gNB */
     //registered_gnb = 0;
     __attribute__((unused)) uint32_t register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);
@@ -364,8 +367,8 @@ int create_gNB_tasks(void) {
   }
 
   if (get_softmodem_params()->sa &&
-      !NODE_IS_DU(RC.nrrrc[0]->node_type) &&
-      RC.nrrrc[gnb_id_start]->node_type != ngran_gNB_CUUP ) {
+      !NODE_IS_DU(node_type) &&
+      node_type != ngran_gNB_CUUP ) {
 
     char*             gnb_ipv4_address_for_NGU      = NULL;
     uint32_t          gnb_port_for_NGU              = 0;
@@ -401,19 +404,21 @@ int create_gNB_tasks(void) {
 
     LOG_I(NR_RRC,"Creating NR RRC gNB Task\n");
 
-    if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) {
-      LOG_E(NR_RRC, "Create task for NR RRC gNB failed\n");
-      return -1;
+    if (node_type != ngran_gNB_CUUP) {
+      if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) {
+        LOG_E(NR_RRC, "Create task for NR RRC gNB failed\n");
+        return -1;
+      }
     }
 
     // If CU
-    if ((RC.nrrrc[gnb_id_start]->node_type == ngran_gNB_CU) ||
-        (RC.nrrrc[gnb_id_start]->node_type == ngran_gNB)) {
+    if ((node_type == ngran_gNB_CU) ||
+        (node_type == ngran_gNB)) {
       RC.nrrrc[gnb_id_start]->gtpInstN3 = RCconfig_nr_gtpu();
     }
 
     //Use check on x2ap to consider the NSA scenario 
-    if((is_x2ap_enabled() || get_softmodem_params()->sa) && (RC.nrrrc[0]->node_type != ngran_gNB_CUCP) ) {
+    if((is_x2ap_enabled() || get_softmodem_params()->sa) && (node_type != ngran_gNB_CUCP) ) {
       if (itti_create_task (TASK_GTPV1_U, &gtpv1uTask, NULL) < 0) {
         LOG_E(GTPU, "Create task for GTPV1U failed\n");
         return -1;
@@ -643,7 +648,7 @@ void init_pdcp(void) {
     LINK_ENB_PDCP_TO_GTPV1U_BIT;
   
   if (!get_softmodem_params()->nsa) {
-    if (!NODE_IS_DU(RC.nrrrc[0]->node_type)) {
+    if (!NODE_IS_DU(get_node_type())) {
       pdcp_layer_init();
       nr_pdcp_module_init(pdcp_initmask, 0);
     }
diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h
index 7698157a73c..19009ee427b 100644
--- a/openair2/COMMON/e1ap_messages_types.h
+++ b/openair2/COMMON/e1ap_messages_types.h
@@ -67,6 +67,7 @@ typedef struct e1ap_setup_req_s {
   long                  cn_support;
   int                   port_cuup;
   int                   port_cucp;
+  int                   remoteDUPort;
   in_addr_t             IPv4AddressN3;
   int                   portN3;
 } e1ap_setup_req_t;
diff --git a/openair2/E1AP/CMakeLists.txt b/openair2/E1AP/CMakeLists.txt
index 362b2bf4767..3726f0bbd64 100644
--- a/openair2/E1AP/CMakeLists.txt
+++ b/openair2/E1AP/CMakeLists.txt
@@ -1,6 +1,6 @@
 add_subdirectory(MESSAGES)
 
-add_library(E1AP e1ap.c e1ap_common.c)
+add_library(E1AP e1ap.c e1ap_common.c e1ap_api.c)
 target_link_libraries(E1AP
                         PUBLIC ASN1_E1AP_LIB
                         PRIVATE UTIL)
diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c
index 2f5c52b11ec..c5048161ca4 100644
--- a/openair2/E1AP/e1ap.c
+++ b/openair2/E1AP/e1ap.c
@@ -23,6 +23,7 @@
 
 #include "e1ap.h"
 #include "e1ap_common.h"
+#include "e1ap_api.h"
 #include "gnb_config.h"
 #include "openair2/SDAP/nr_sdap/nr_sdap_entity.h"
 
@@ -773,6 +774,7 @@ int e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance,
     }
   }
   e1ap_encode_send(UPtype, instance, &pdu, 0, __func__);
+  free(resp);
   return 0;
 }
 
@@ -802,9 +804,7 @@ int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance,
   E1AP_BearerContextSetupRequest_t *in = &pdu->choice.initiatingMessage->value.choice.BearerContextSetupRequest;
   E1AP_BearerContextSetupRequestIEs_t *ie;
 
-  MessageDef *msg = itti_alloc_new_message(TASK_CUUP_E1, 0, E1AP_BEARER_CONTEXT_SETUP_REQ);
-
-  e1ap_bearer_setup_req_t *bearerCxt = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg);
+  e1ap_bearer_setup_req_t *bearerCxt = calloc(1, sizeof(e1ap_bearer_setup_req_t));
   LOG_I(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count);
 
   for (int i=0; i < in->protocolIEs.list.count; i++) {
@@ -975,9 +975,8 @@ int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance,
     }
   }
 
-  itti_send_msg_to_task(TASK_RRC_GNB, instance, msg);
+  CUUP_process_e1_bearer_context_setup_req(bearerCxt, instance);
   return 0;
-
 }
 
 int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance,
@@ -1210,9 +1209,7 @@ int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
   E1AP_BearerContextModificationRequest_t *in = &pdu->choice.initiatingMessage->value.choice.BearerContextModificationRequest;
   E1AP_BearerContextModificationRequestIEs_t *ie;
 
-  MessageDef *msg = itti_alloc_new_message(TASK_CUUP_E1, 0, E1AP_BEARER_CONTEXT_MODIFICATION_REQ);
-
-  e1ap_bearer_setup_req_t *bearerCxt = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg);
+  e1ap_bearer_setup_req_t *bearerCxt = calloc(1, sizeof(e1ap_bearer_setup_req_t));
   LOG_I(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count);
 
   for (int i=0; i < in->protocolIEs.list.count; i++) {
@@ -1297,7 +1294,7 @@ int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
     }
   }
 
-  itti_send_msg_to_task(TASK_RRC_GNB, instance, msg);
+  CUUP_process_bearer_context_mod_req(bearerCxt, instance);
   return 0;
 }
 
@@ -1631,11 +1628,6 @@ void *E1AP_CUUP_task(void *arg) {
         cuxp_task_handle_sctp_data_ind(myInstance, &msg->ittiMsg.sctp_data_ind);
         break;
 
-      case E1AP_BEARER_CONTEXT_SETUP_RESP:
-        LOG_I(E1AP, "CUUP Task Received E1AP_BEARER_CONTEXT_SETUP_RESP %ld\n", myInstance);
-        e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(myInstance, &E1AP_BEARER_CONTEXT_SETUP_RESP(msg));
-        break;
-
       default:
         LOG_E(E1AP, "Unknown message received in TASK_CUUP_E1\n");
         break;
diff --git a/openair2/E1AP/e1ap.h b/openair2/E1AP/e1ap.h
index 5467f98b8fd..00d08babf74 100644
--- a/openair2/E1AP/e1ap.h
+++ b/openair2/E1AP/e1ap.h
@@ -56,6 +56,9 @@ int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance,
 int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
                                                         E1AP_E1AP_PDU_t *pdu);
 
+int e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance,
+                                                e1ap_bearer_setup_resp_t *resp);
+
 void *E1AP_CUUP_task(void *arg);
 
 void *E1AP_CUCP_task(void *arg);
diff --git a/openair2/E1AP/e1ap_api.c b/openair2/E1AP/e1ap_api.c
new file mode 100644
index 00000000000..a4cf3c56dd1
--- /dev/null
+++ b/openair2/E1AP/e1ap_api.c
@@ -0,0 +1,254 @@
+/*
+ * 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
+ *
+ * Author and copyright: Laurent Thomas, open-cells.com
+ *
+ * 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
+ */
+
+#include "e1ap_api.h"
+#include "UTIL/OSA/osa_defs.h"
+#include "nr_pdcp/nr_pdcp_entity.h"
+#include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h"
+#include "openair3/ocp-gtpu/gtp_itf.h"
+
+static void fill_DRB_configList(NR_DRB_ToAddModList_t *DRB_configList, pdu_session_to_setup_t *pdu) {
+
+  for (int i=0; i < pdu->numDRB2Setup; i++) {
+    DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + i;
+    asn1cSequenceAdd(DRB_configList->list, NR_DRB_ToAddMod_t, ie);
+    ie->drb_Identity = drb->id;
+    ie->cnAssociation = CALLOC(1, sizeof(*ie->cnAssociation));
+    ie->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
+
+    // sdap_Config
+    NR_SDAP_Config_t *sdap_config = CALLOC(1, sizeof(*sdap_config));
+    memset(sdap_config, 0, sizeof(*sdap_config));
+    ie->cnAssociation->choice.sdap_Config = sdap_config;
+    sdap_config->pdu_Session = pdu->sessionId;
+    sdap_config->sdap_HeaderDL = drb->sDAP_Header_DL;
+    sdap_config->sdap_HeaderUL = drb->sDAP_Header_UL;
+    sdap_config->defaultDRB = drb->defaultDRB;
+
+    sdap_config->mappedQoS_FlowsToAdd = calloc(1, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd));
+    for (int j=0; j < drb->numQosFlow2Setup; j++) {
+      NR_QFI_t *qfi = calloc(1, sizeof(NR_QFI_t));
+      *qfi = drb->qosFlows[j].fiveQI;
+      ASN_SEQUENCE_ADD(&sdap_config->mappedQoS_FlowsToAdd->list, qfi);
+    }
+    sdap_config->mappedQoS_FlowsToRelease = NULL;
+
+    // pdcp_Config
+    ie->reestablishPDCP = NULL;
+    ie->recoverPDCP = NULL;
+    NR_PDCP_Config_t *pdcp_config = calloc(1, sizeof(*pdcp_config));
+    memset(pdcp_config, 0, sizeof(*pdcp_config));
+    ie->pdcp_Config = pdcp_config;
+    pdcp_config->drb = calloc(1,sizeof(*pdcp_config->drb));
+    pdcp_config->drb->discardTimer = calloc(1, sizeof(*pdcp_config->drb->discardTimer));
+    *pdcp_config->drb->discardTimer = drb->discardTimer;
+    pdcp_config->drb->pdcp_SN_SizeUL = calloc(1, sizeof(*pdcp_config->drb->pdcp_SN_SizeUL));
+    *pdcp_config->drb->pdcp_SN_SizeUL = drb->pDCP_SN_Size_UL;
+    pdcp_config->drb->pdcp_SN_SizeDL = calloc(1, sizeof(*pdcp_config->drb->pdcp_SN_SizeDL));
+    *pdcp_config->drb->pdcp_SN_SizeDL = drb->pDCP_SN_Size_DL;
+    pdcp_config->drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
+    pdcp_config->drb->headerCompression.choice.notUsed = 0;
+
+    pdcp_config->drb->integrityProtection = NULL;
+    pdcp_config->drb->statusReportRequired = NULL;
+    pdcp_config->drb->outOfOrderDelivery = NULL;
+    pdcp_config->moreThanOneRLC = NULL;
+
+    pdcp_config->t_Reordering = calloc(1, sizeof(*pdcp_config->t_Reordering));
+    *pdcp_config->t_Reordering = drb->reorderingTimer;
+    pdcp_config->ext1 = NULL;
+
+    if (pdu->integrityProtectionIndication == 0 || // Required
+        pdu->integrityProtectionIndication == 1) { // Preferred
+      pdcp_config->drb->integrityProtection = calloc(1, sizeof(*pdcp_config->drb->integrityProtection));
+      *pdcp_config->drb->integrityProtection = NR_PDCP_Config__drb__integrityProtection_enabled;
+    }
+
+    if (pdu->confidentialityProtectionIndication == 0 || // Required
+        pdu->confidentialityProtectionIndication == 1) { // Preferred
+      pdcp_config->ext1 = calloc(1, sizeof(*pdcp_config->ext1));
+      pdcp_config->ext1->cipheringDisabled = calloc(1, sizeof(*pdcp_config->ext1->cipheringDisabled));
+      *pdcp_config->ext1->cipheringDisabled = NR_PDCP_Config__ext1__cipheringDisabled_true;
+    }
+  }
+}
+
+static int drb_config_N3gtpu_create(e1ap_bearer_setup_req_t *req,
+                                    gtpv1u_gnb_create_tunnel_resp_t *create_tunnel_resp,
+                                    instance_t instance) {
+
+  gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0};
+
+  NR_DRB_ToAddModList_t DRB_configList = {0};
+  for (int i=0; i < req->numPDUSessions; i++) {
+    pdu_session_to_setup_t *pdu = &req->pduSession[i];
+    create_tunnel_req.pdusession_id[i] = pdu->sessionId;
+    create_tunnel_req.incoming_rb_id[i] = pdu->DRBnGRanList[0].id; // taking only the first DRB. TODO:change this
+    memcpy(&create_tunnel_req.dst_addr[i].buffer,
+           &pdu->tlAddress,
+           sizeof(uint8_t)*4);
+    create_tunnel_req.dst_addr[i].length = 32; // 8bits * 4bytes
+    create_tunnel_req.outgoing_teid[i] = pdu->teId;
+    fill_DRB_configList(&DRB_configList, pdu);
+  }
+  create_tunnel_req.num_tunnels = req->numPDUSessions;
+  create_tunnel_req.ue_id = (req->gNB_cu_cp_ue_id & 0xFFFF);
+
+  // Create N3 tunnel
+  int 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 id %ld\n",
+          create_tunnel_req.ue_id);
+    return ret;
+  }
+
+  // Configure DRBs
+  uint8_t *kUPenc = NULL;
+  uint8_t *kUPint = NULL;
+
+  nr_derive_key_up_enc(req->cipheringAlgorithm,
+                       (uint8_t *)req->encryptionKey,
+                       &kUPenc);
+
+  nr_derive_key_up_int(req->integrityProtectionAlgorithm,
+                       (uint8_t *)req->integrityProtectionKey,
+                       &kUPint);
+
+  nr_pdcp_e1_add_drbs(true, // set this to notify PDCP that his not UE
+                      create_tunnel_req.ue_id,
+                      &DRB_configList,
+                      (req->integrityProtectionAlgorithm << 4) | req->cipheringAlgorithm,
+                      kUPenc,
+                      kUPint);
+  return ret;
+}
+
+void gNB_CU_create_up_ul_tunnel(e1ap_bearer_setup_resp_t *resp,
+                                e1ap_bearer_setup_req_t *req,
+                                instance_t gtpInst,
+                                ue_id_t ue_id,
+                                int remote_port,
+                                in_addr_t my_addr) {
+
+  resp->numPDUSessions = req->numPDUSessions;
+  transport_layer_addr_t dummy_address = {0};
+  dummy_address.length = 32; // IPv4
+  for (int i=0; i < req->numPDUSessions; i++) {
+    resp->pduSession[i].numDRBSetup = req->pduSession[i].numDRB2Setup;
+    for (int j=0; j < req->pduSession[i].numDRB2Setup; j++) {
+      DRB_nGRAN_to_setup_t *drb2Setup = req->pduSession[i].DRBnGRanList + j;
+      DRB_nGRAN_setup_t *drbSetup = resp->pduSession[i].DRBnGRanList + j;
+
+      drbSetup->numUpParam = 1;
+      drbSetup->UpParamList[0].tlAddress = my_addr;
+      drbSetup->UpParamList[0].teId = newGtpuCreateTunnel(gtpInst,
+                                                          (ue_id & 0xFFFF),
+                                                          drb2Setup->id,
+                                                          drb2Setup->id,
+                                                          0xFFFF, // We will set the right value from DU answer
+                                                          -1, // no qfi
+                                                          dummy_address, // We will set the right value from DU answer
+                                                          remote_port,
+                                                          cu_f1u_data_req,
+                                                          NULL);
+      drbSetup->id = drb2Setup->id;
+
+      drbSetup->numQosFlowSetup = drb2Setup->numQosFlow2Setup;
+      for (int k=0; k < drbSetup->numQosFlowSetup; k++) {
+        drbSetup->qosFlows[k].id = drb2Setup->qosFlows[k].id;
+      }
+    }
+  }
+}
+
+void CUUP_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *req, instance_t instance) {
+
+  gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp_N3={0};
+
+  // GTP tunnel for UL
+  instance_t gtpInst = getCxtE1(UPtype, instance)->gtpInstN3;
+  drb_config_N3gtpu_create(req, &create_tunnel_resp_N3, gtpInst);
+
+  e1ap_bearer_setup_resp_t *resp = calloc(1, sizeof(e1ap_bearer_setup_resp_t));
+
+  int remote_port = getCxtE1(UPtype, instance)->setupReq.remoteDUPort;
+  in_addr_t my_addr;
+  inet_pton(AF_INET,
+            getCxtE1(UPtype, instance)->setupReq.CUUP_e1_ip_address.ipv4_address,
+            &my_addr);
+
+  gtpInst = getCxtE1(UPtype, instance)->gtpInstF1U;
+  gNB_CU_create_up_ul_tunnel(resp, req, gtpInst, req->gNB_cu_cp_ue_id, remote_port, my_addr);
+
+  resp->gNB_cu_cp_ue_id = req->gNB_cu_cp_ue_id;
+  resp->numPDUSessions = req->numPDUSessions;
+  for (int i=0; i < req->numPDUSessions; i++) {
+    pdu_session_setup_t    *pduSetup  = resp->pduSession + i;
+    pdu_session_to_setup_t *pdu2Setup = req->pduSession + i;
+
+    pduSetup->id = pdu2Setup->sessionId;
+    memcpy(&pduSetup->tlAddress,
+           &getCxtE1(UPtype, instance)->setupReq.IPv4AddressN3,
+           sizeof(in_addr_t));
+    pduSetup->teId = create_tunnel_resp_N3.gnb_NGu_teid[i];
+    pduSetup->numDRBSetup = pdu2Setup->numDRB2Setup;
+
+    // At this point we don't have a way to know the DRBs that failed to setup
+    // We assume all DRBs to setup have are setup successfully so we always send successful outcome in response
+    // TODO: Modify nr_pdcp_add_drbs() to return DRB list that failed to setup to support E1AP
+    pduSetup->numDRBFailed = 0;
+  }
+
+  e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(instance, resp);
+  free(req);
+}
+
+void update_UL_UP_tunnel_info(e1ap_bearer_setup_req_t *req, instance_t instance, ue_id_t ue_id) {
+  for (int i=0; i < req->numPDUSessionsMod; i++) {
+    for (int j=0; j < req->pduSessionMod[i].numDRB2Modify; j++) {
+      DRB_nGRAN_to_setup_t *drb_p = req->pduSessionMod[i].DRBnGRanModList + j;
+
+      transport_layer_addr_t newRemoteAddr;
+      newRemoteAddr.length = 32; // IPv4
+      memcpy(newRemoteAddr.buffer,
+             &drb_p->DlUpParamList[0].tlAddress,
+             sizeof(in_addr_t));
+
+      GtpuUpdateTunnelOutgoingPair(instance,
+                                   (ue_id & 0xFFFF),
+                                   (ebi_t)drb_p->id,
+                                   drb_p->DlUpParamList[0].teId,
+                                   newRemoteAddr);
+    }
+  }
+}
+
+void CUUP_process_bearer_context_mod_req(e1ap_bearer_setup_req_t *req, instance_t instance) {
+  instance_t gtpInst = getCxtE1(UPtype, instance)->gtpInstF1U;
+  update_UL_UP_tunnel_info(req, gtpInst, req->gNB_cu_cp_ue_id);
+  free(req);
+  // TODO: send bearer cxt mod response
+}
+
diff --git a/openair2/E1AP/e1ap_api.h b/openair2/E1AP/e1ap_api.h
new file mode 100644
index 00000000000..3597eb740ee
--- /dev/null
+++ b/openair2/E1AP/e1ap_api.h
@@ -0,0 +1,39 @@
+/*
+ * 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
+ *
+ * Author and copyright: Laurent Thomas, open-cells.com
+ *
+ * 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
+ */
+
+#include "e1ap.h"
+#include "e1ap_common.h"
+#include "NR_DRB-ToAddModList.h"
+
+void gNB_CU_create_up_ul_tunnel(e1ap_bearer_setup_resp_t *resp,
+                                e1ap_bearer_setup_req_t *req,
+                                instance_t gtpInst,
+                                ue_id_t ue_id,
+                                int remote_port,
+                                in_addr_t my_addr);
+
+void update_UL_UP_tunnel_info(e1ap_bearer_setup_req_t *req, instance_t instance, ue_id_t ue_id);
+
+void CUUP_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *req, instance_t instance);
+
+void CUUP_process_bearer_context_mod_req(e1ap_bearer_setup_req_t *req, instance_t instance);
diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c
index 706ce91be06..0de4c020b03 100644
--- a/openair2/GNB_APP/gnb_app.c
+++ b/openair2/GNB_APP/gnb_app.c
@@ -147,12 +147,13 @@ void *gNB_app_task(void *args_p)
 
   int cell_to_activate = 0;
   itti_mark_task_ready (TASK_GNB_APP);
+  ngran_node_t node_type = get_node_type();
 
   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_type == ngran_gNB_CUCP ||
+        node_type == ngran_gNB_CU ||
+        node_type == ngran_eNB_CU ||
+        node_type == ngran_ng_eNB_CU) {
     
       if (itti_create_task(TASK_CU_F1, F1AP_CU_task, NULL) < 0) {
         LOG_E(F1AP, "Create task for F1AP CU failed\n");
@@ -160,7 +161,7 @@ void *gNB_app_task(void *args_p)
       }
     }
     
-    if (RC.nrrrc[0]->node_type == ngran_gNB_CUCP) {
+    if (node_type == ngran_gNB_CUCP) {
       
       if (itti_create_task(TASK_CUCP_E1, E1AP_CUCP_task, NULL) < 0) {
         LOG_E(E1AP, "Create task for E1AP CP failed\n");
@@ -174,7 +175,7 @@ void *gNB_app_task(void *args_p)
       
     }
 
-    if (RC.nrrrc[0]->node_type == ngran_gNB_CUUP) {
+    if (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");
@@ -187,7 +188,7 @@ void *gNB_app_task(void *args_p)
       itti_send_msg_to_task(TASK_CUUP_E1, GNB_MODULE_ID_TO_INSTANCE(0), msg_p);
     }
 
-    if (NODE_IS_DU(RC.nrrrc[0]->node_type)) {
+    if (NODE_IS_DU(node_type)) {
       
       if (itti_create_task(TASK_DU_F1, F1AP_DU_task, NULL) < 0) {
         LOG_E(F1AP, "Create task for F1AP DU failed\n");
@@ -263,7 +264,7 @@ void *gNB_app_task(void *args_p)
       break;
 
     case F1AP_SETUP_RESP:
-      AssertFatal(NODE_IS_DU(RC.nrrrc[0]->node_type), "Should not have received F1AP_SETUP_RESP in CU/gNB\n");
+      AssertFatal(NODE_IS_DU(node_type), "Should not have received F1AP_SETUP_RESP in CU/gNB\n");
 
       LOG_I(GNB_APP, "Received %s: associated ngran_gNB_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p),
       F1AP_SETUP_RESP(msg_p).gNB_CU_name,F1AP_SETUP_RESP(msg_p).num_cells_to_activate);
@@ -273,7 +274,7 @@ void *gNB_app_task(void *args_p)
 
       break;
     case F1AP_GNB_CU_CONFIGURATION_UPDATE:
-      AssertFatal(NODE_IS_DU(RC.nrrrc[0]->node_type), "Should not have received F1AP_GNB_CU_CONFIGURATION_UPDATE in CU/gNB\n");
+      AssertFatal(NODE_IS_DU(node_type), "Should not have received F1AP_GNB_CU_CONFIGURATION_UPDATE in CU/gNB\n");
 
       LOG_I(GNB_APP, "Received %s: associated ngran_gNB_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p),
       F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).gNB_CU_name,F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).num_cells_to_activate);
diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c
index f08ab4474f4..3971ac5a335 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -87,7 +87,7 @@
 extern uint16_t sf_ahead;
 int macrlc_has_f1 = 0;
 
-static ngran_node_t get_node_type(void);
+ngran_node_t get_node_type(void);
 
 extern int config_check_band_frequencies(int ind, int16_t band, uint64_t downlink_frequency,
                                          int32_t uplink_frequency_offset, uint32_t  frame_type);
@@ -1848,6 +1848,7 @@ int RCconfig_NR_CU_E1(MessageDef *msg_p, uint32_t i) {
     strcpy(e1Setup->CUUP_e1_ip_address.ipv4_address, *(GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_IPV4_ADDRESS_CUUP].strptr));
     e1Setup->CUUP_e1_ip_address.ipv4 = 1;
     e1Setup->port_cuup = *GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_PORT_CUUP].uptr;
+    e1Setup->remoteDUPort = e1Setup->port_cuup; // set same as local port for now TODO: get from F1 config
     char N3Addr[64];
     int N3Port;
     if (!get_NGU_S1U_addr(N3Addr, &N3Port)) {;
@@ -2289,7 +2290,7 @@ int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_up
   return(ret);
 }
 
-static ngran_node_t get_node_type(void)
+ngran_node_t get_node_type(void)
 {
   paramdef_t        MacRLC_Params[] = MACRLCPARAMS_DESC;
   paramlist_def_t   MacRLC_ParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0};
diff --git a/openair2/GNB_APP/gnb_config.h b/openair2/GNB_APP/gnb_config.h
index ea5772491f5..e1d0311d5d8 100644
--- a/openair2/GNB_APP/gnb_config.h
+++ b/openair2/GNB_APP/gnb_config.h
@@ -109,6 +109,7 @@ 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);
 int RCconfig_NR_CU_E1(MessageDef *msg_p, uint32_t i);
+ngran_node_t get_node_type(void);
 
 #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 e509a9b5914..d0cc882f39d 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
@@ -38,6 +38,7 @@
 #include <openair3/ocp-gtpu/gtp_itf.h>
 #include "openair2/SDAP/nr_sdap/nr_sdap.h"
 #include "nr_pdcp_e1_api.h"
+#include "gnb_config.h"
 
 #define TODO do { \
     printf("%s:%d:%s: todo\n", __FILE__, __LINE__, __FUNCTION__); \
@@ -58,6 +59,8 @@ static uint64_t pdcp_optmask;
 uint8_t first_dcch = 0;
 uint8_t proto_agent_flag = 0;
 
+static ngran_node_t node_type;
+
 /****************************************************************************/
 /* rlc_data_req queue - begin                                               */
 /****************************************************************************/
@@ -528,6 +531,10 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP)
   return 0;
 }
 
+static void set_node_type() {
+  node_type = get_node_type();
+}
+
 void pdcp_layer_init(void)
 {
   /* hack: be sure to initialize only once */
@@ -543,7 +550,9 @@ void pdcp_layer_init(void)
 
   nr_pdcp_ue_manager = new_nr_pdcp_ue_manager(1);
 
-  if ((RC.nrrrc == NULL) || (!NODE_IS_CU(RC.nrrrc[0]->node_type))) {
+  set_node_type();
+
+  if ((RC.nrrrc == NULL) || (!NODE_IS_CU(node_type))) {
     init_nr_rlc_data_req_queue();
   }
 
@@ -687,7 +696,7 @@ rb_found:
   ctxt.brOption = 0;
 
   ctxt.rnti = ue->ue_id;
-  if (RC.nrrrc != NULL && NODE_IS_CU(RC.nrrrc[0]->node_type)) {
+  if (RC.nrrrc != NULL && NODE_IS_CU(node_type)) {
     MessageDef  *message_p = itti_alloc_new_message_sized(TASK_PDCP_ENB, 0,
 							  GTPV1U_TUNNEL_DATA_REQ,
 							  sizeof(gtpv1u_tunnel_data_req_t)
@@ -788,7 +797,7 @@ srb_found:
   LOG_D(PDCP, "%s(): (srb %d) calling rlc_data_req size %d\n", __func__, srb_id, size);
   //for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)memblock->data[i]);
   //printf("\n");
-  if ((RC.nrrrc == NULL) || (!NODE_IS_CU(RC.nrrrc[0]->node_type))) {
+  if ((RC.nrrrc == NULL) || (!NODE_IS_CU(node_type))) {
     ctxt.module_id = 0;
     ctxt.enb_flag = 1;
     ctxt.instance = 0;
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index 8dedc8448eb..4b0ee2257b4 100755
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -104,6 +104,7 @@
 #include "openair2/F1AP/f1ap_common.h"
 #include "openair2/E1AP/e1ap_common.h"
 #include "openair2/SDAP/nr_sdap/nr_sdap_entity.h"
+#include "openair2/E1AP/e1ap_api.h"
 
 #include "BIT_STRING.h"
 #include "assertions.h"
@@ -208,9 +209,6 @@ static void rrc_gNB_mac_rrc_init(gNB_RRC_INST *rrc)
       rrc->mac_rrc.nr_e1_bearer_cxt_msg_transfer = bearer_context_setup_e1ap;
       rrc->mac_rrc.nr_e1_ue_cxt_mod_msg_transfer = ue_cxt_mod_send_e1ap;
       break;
-    case ngran_gNB_CUUP:
-      // CUUP should not have a RRC instance but we let it for now
-      break;
     case ngran_gNB_CU:
       mac_rrc_dl_f1ap_init(&rrc->mac_rrc);
       rrc->mac_rrc.nr_e1_bearer_cxt_msg_transfer = bearer_context_setup_direct;
@@ -3609,32 +3607,6 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, const ch
 
 }
 
-static void update_UL_UP_tunnel_info(e1ap_bearer_setup_req_t *req, instance_t instance, ue_id_t ue_id) {
-  for (int i=0; i < req->numPDUSessionsMod; i++) {
-    for (int j=0; j < req->pduSessionMod[i].numDRB2Modify; j++) {
-      DRB_nGRAN_to_setup_t *drb_p = req->pduSessionMod[i].DRBnGRanModList + j;
-
-      transport_layer_addr_t newRemoteAddr;
-      newRemoteAddr.length = 32; // IPv4
-      memcpy(newRemoteAddr.buffer,
-             &drb_p->DlUpParamList[0].tlAddress,
-             sizeof(in_addr_t));
-
-      GtpuUpdateTunnelOutgoingPair(instance,
-                                   (ue_id & 0xFFFF),
-                                   (ebi_t)drb_p->id,
-                                   drb_p->DlUpParamList[0].teId,
-                                   newRemoteAddr);
-    }
-  }
-}
-
-void rrc_CUUP_process_bearer_context_mod_req(e1ap_bearer_setup_req_t *req, instance_t instance) {
-  instance_t gtpInst = getCxtE1(UPtype, instance)->gtpInstF1U;
-  update_UL_UP_tunnel_info(req, gtpInst, req->gNB_cu_cp_ue_id);
-  // TODO: send bearer cxt mod response
-}
-
 void ue_cxt_mod_send_e1ap(MessageDef *msg, instance_t instance) {
   int module_id = 0;
   itti_send_msg_to_task(TASK_CUCP_E1, module_id, msg);
@@ -4017,209 +3989,6 @@ int rrc_gNB_process_e1_setup_req(e1ap_setup_req_t *req, instance_t instance) {
   return 0;
 }
 
-void fill_DRB_configList_e1(NR_DRB_ToAddModList_t *DRB_configList, pdu_session_to_setup_t *pdu) {
-
-  for (int i=0; i < pdu->numDRB2Setup; i++) {
-    DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + i;
-    asn1cSequenceAdd(DRB_configList->list, NR_DRB_ToAddMod_t, ie);
-    ie->drb_Identity = drb->id;
-    ie->cnAssociation = CALLOC(1, sizeof(*ie->cnAssociation));
-    ie->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
-
-    // sdap_Config
-    NR_SDAP_Config_t *sdap_config = CALLOC(1, sizeof(*sdap_config));
-    memset(sdap_config, 0, sizeof(*sdap_config));
-    ie->cnAssociation->choice.sdap_Config = sdap_config;
-    sdap_config->pdu_Session = pdu->sessionId;
-    sdap_config->sdap_HeaderDL = drb->sDAP_Header_DL;
-    sdap_config->sdap_HeaderUL = drb->sDAP_Header_UL;
-    sdap_config->defaultDRB = drb->defaultDRB;
-
-    sdap_config->mappedQoS_FlowsToAdd = calloc(1, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd));
-    // LTSFIXME
-    for (int j=0; j < drb->numQosFlow2Setup; j++) {
-      NR_QFI_t *qfi = calloc(1, sizeof(NR_QFI_t));
-      *qfi = drb->qosFlows[j].fiveQI;
-      ASN_SEQUENCE_ADD(&sdap_config->mappedQoS_FlowsToAdd->list, qfi);
-    }
-    sdap_config->mappedQoS_FlowsToRelease = NULL;
-
-    // pdcp_Config
-    ie->reestablishPDCP = NULL;
-    ie->recoverPDCP = NULL;
-    NR_PDCP_Config_t *pdcp_config = calloc(1, sizeof(*pdcp_config));
-    memset(pdcp_config, 0, sizeof(*pdcp_config));
-    ie->pdcp_Config = pdcp_config;
-    pdcp_config->drb = calloc(1,sizeof(*pdcp_config->drb));
-    pdcp_config->drb->discardTimer = calloc(1, sizeof(*pdcp_config->drb->discardTimer));
-    *pdcp_config->drb->discardTimer = drb->discardTimer;
-    pdcp_config->drb->pdcp_SN_SizeUL = calloc(1, sizeof(*pdcp_config->drb->pdcp_SN_SizeUL));
-    *pdcp_config->drb->pdcp_SN_SizeUL = drb->pDCP_SN_Size_UL;
-    pdcp_config->drb->pdcp_SN_SizeDL = calloc(1, sizeof(*pdcp_config->drb->pdcp_SN_SizeDL));
-    *pdcp_config->drb->pdcp_SN_SizeDL = drb->pDCP_SN_Size_DL;
-    pdcp_config->drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
-    pdcp_config->drb->headerCompression.choice.notUsed = 0;
-
-    pdcp_config->drb->integrityProtection = NULL;
-    pdcp_config->drb->statusReportRequired = NULL;
-    pdcp_config->drb->outOfOrderDelivery = NULL;
-    pdcp_config->moreThanOneRLC = NULL;
-
-    pdcp_config->t_Reordering = calloc(1, sizeof(*pdcp_config->t_Reordering));
-    *pdcp_config->t_Reordering = drb->reorderingTimer;
-    pdcp_config->ext1 = NULL;
-
-    if (pdu->integrityProtectionIndication == 0 || // Required
-        pdu->integrityProtectionIndication == 1) { // Preferred
-      pdcp_config->drb->integrityProtection = calloc(1, sizeof(*pdcp_config->drb->integrityProtection));
-      *pdcp_config->drb->integrityProtection = NR_PDCP_Config__drb__integrityProtection_enabled;
-    }
-
-    if (pdu->confidentialityProtectionIndication == 0 || // Required
-        pdu->confidentialityProtectionIndication == 1) { // Preferred
-      pdcp_config->ext1 = calloc(1, sizeof(*pdcp_config->ext1));
-      pdcp_config->ext1->cipheringDisabled = calloc(1, sizeof(*pdcp_config->ext1->cipheringDisabled));
-      *pdcp_config->ext1->cipheringDisabled = NR_PDCP_Config__ext1__cipheringDisabled_true;
-    }
-  }
-}
-
-int drb_config_N3gtpu_create_e1(e1ap_bearer_setup_req_t *req,
-                                gtpv1u_gnb_create_tunnel_resp_t *create_tunnel_resp,
-                                instance_t instance) {
-
-  gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0};
-
-  NR_DRB_ToAddModList_t DRB_configList = {0};
-  for (int i=0; i < req->numPDUSessions; i++) {
-    pdu_session_to_setup_t *pdu = &req->pduSession[i];
-    create_tunnel_req.pdusession_id[i] = pdu->sessionId;
-    create_tunnel_req.incoming_rb_id[i] = pdu->DRBnGRanList[0].id; // taking only the first DRB. TODO:change this
-    memcpy(&create_tunnel_req.dst_addr[i].buffer,
-           &pdu->tlAddress,
-           sizeof(uint8_t)*4);
-    create_tunnel_req.dst_addr[i].length = 32; // 8bits * 4bytes
-    create_tunnel_req.outgoing_teid[i] = pdu->teId;
-    fill_DRB_configList_e1(&DRB_configList, pdu);
-  }
-  create_tunnel_req.num_tunnels = req->numPDUSessions;
-  create_tunnel_req.ue_id = (req->gNB_cu_cp_ue_id & 0xFFFF);
-
-  // Create N3 tunnel
-  int 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 id %ld\n",
-          create_tunnel_req.ue_id);
-    return ret;
-  }
-
-  // Configure DRBs
-  uint8_t *kUPenc = NULL;
-  uint8_t *kUPint = NULL;
-
-  nr_derive_key_up_enc(req->cipheringAlgorithm,
-                       (uint8_t *)req->encryptionKey,
-                       &kUPenc);
-
-  nr_derive_key_up_int(req->integrityProtectionAlgorithm,
-                       (uint8_t *)req->integrityProtectionKey,
-                       &kUPint);
-
-  nr_pdcp_e1_add_drbs(true, // set this to notify PDCP that his not UE
-                      create_tunnel_req.ue_id,
-                      &DRB_configList,
-                      (req->integrityProtectionAlgorithm << 4) | req->cipheringAlgorithm,
-                      kUPenc,
-                      kUPint);
-  return ret;
-}
-
-void gNB_CU_create_up_ul_tunnel(e1ap_bearer_setup_resp_t *resp,
-                                e1ap_bearer_setup_req_t *req,
-                                instance_t gtpInst,
-                                ue_id_t ue_id,
-                                int remote_port,
-                                in_addr_t my_addr) {
-
-  resp->numPDUSessions = req->numPDUSessions;
-  transport_layer_addr_t dummy_address = {0};
-  dummy_address.length = 32; // IPv4
-  for (int i=0; i < req->numPDUSessions; i++) {
-    resp->pduSession[i].numDRBSetup = req->pduSession[i].numDRB2Setup;
-    for (int j=0; j < req->pduSession[i].numDRB2Setup; j++) {
-      DRB_nGRAN_to_setup_t *drb2Setup = req->pduSession[i].DRBnGRanList + j;
-      DRB_nGRAN_setup_t *drbSetup = resp->pduSession[i].DRBnGRanList + j;
-
-      drbSetup->numUpParam = 1;
-      drbSetup->UpParamList[0].tlAddress = my_addr;
-      drbSetup->UpParamList[0].teId = newGtpuCreateTunnel(gtpInst,
-                                                          (ue_id & 0xFFFF),
-                                                          drb2Setup->id,
-                                                          drb2Setup->id,
-                                                          0xFFFF, // We will set the right value from DU answer
-                                                          -1, // no qfi
-                                                          dummy_address, // We will set the right value from DU answer
-                                                          remote_port,
-                                                          cu_f1u_data_req,
-                                                          NULL);
-      drbSetup->id = drb2Setup->id;
-
-      drbSetup->numQosFlowSetup = drb2Setup->numQosFlow2Setup;
-      for (int k=0; k < drbSetup->numQosFlowSetup; k++) {
-        drbSetup->qosFlows[k].id = drb2Setup->qosFlows[k].id;
-      }
-    }
-  }
-}
-
-void rrc_gNB_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *req, instance_t instance) {
-
-  protocol_ctxt_t ctxt={0};
-  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, req->gNB_cu_cp_ue_id, 0, 0, 0);
-  gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp_N3={0};
-
-  // GTP tunnel for UL
-  instance_t gtpInst = getCxtE1(UPtype, instance)->gtpInstN3;
-  drb_config_N3gtpu_create_e1(req, &create_tunnel_resp_N3, gtpInst);
-
-  MessageDef *message_p;
-  message_p = itti_alloc_new_message (TASK_RRC_GNB, instance, E1AP_BEARER_CONTEXT_SETUP_RESP);
-  e1ap_bearer_setup_resp_t *resp = &E1AP_BEARER_CONTEXT_SETUP_RESP(message_p);
-
-  int remote_port = RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd;
-  in_addr_t my_addr;
-  inet_pton(AF_INET,
-            getCxtE1(UPtype, instance)->setupReq.CUUP_e1_ip_address.ipv4_address,
-            &my_addr);
-
-  gtpInst = getCxtE1(UPtype, instance)->gtpInstF1U;
-  gNB_CU_create_up_ul_tunnel(resp, req, gtpInst, req->gNB_cu_cp_ue_id, remote_port, my_addr);
-
-  resp->gNB_cu_cp_ue_id = req->gNB_cu_cp_ue_id;
-  resp->numPDUSessions = req->numPDUSessions;
-  for (int i=0; i < req->numPDUSessions; i++) {
-    pdu_session_setup_t    *pduSetup  = resp->pduSession + i;
-    pdu_session_to_setup_t *pdu2Setup = req->pduSession + i;
-
-    pduSetup->id = pdu2Setup->sessionId;
-    memcpy(&pduSetup->tlAddress,
-           &getCxtE1(UPtype, instance)->setupReq.IPv4AddressN3,
-           sizeof(in_addr_t));
-    pduSetup->teId = create_tunnel_resp_N3.gnb_NGu_teid[i];
-    pduSetup->numDRBSetup = pdu2Setup->numDRB2Setup;
-
-    // At this point we don't have a way to know the DRBs that failed to setup
-    // We assume all DRBs to setup have are setup successfully so we always send successful outcome in response
-    // TODO: Modify nr_pdcp_add_drbs() to return DRB list that failed to setup to support E1AP
-    pduSetup->numDRBFailed = 0;
-  }
-
-  itti_send_msg_to_task(TASK_CUUP_E1, instance, message_p);
-}
-
 void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p,
                                                  e1ap_bearer_setup_resp_t *e1ap_resp) {
 
@@ -4502,21 +4271,11 @@ void *rrc_gnb_task(void *args_p) {
         rrc_gNB_process_e1_setup_req(&E1AP_SETUP_REQ(msg_p), instance);
         break;
 
-      case E1AP_BEARER_CONTEXT_SETUP_REQ:
-        LOG_I(NR_RRC, "Received E1AP_BEARER_CONTEXT_SETUP_REQ for instance %d\n", (int)instance);
-        rrc_gNB_process_e1_bearer_context_setup_req(&E1AP_BEARER_CONTEXT_SETUP_REQ(msg_p), instance);
-        break;
-
       case E1AP_BEARER_CONTEXT_SETUP_RESP:
         LOG_I(NR_RRC, "Received E1AP_BEARER_CONTEXT_SETUP_RESP for instance %d\n", (int)instance);
         rrc_gNB_process_e1_bearer_context_setup_resp(&E1AP_BEARER_CONTEXT_SETUP_RESP(msg_p), instance);
         break;
 
-      case E1AP_BEARER_CONTEXT_MODIFICATION_REQ:
-        LOG_I(NR_RRC, "Received E1AP_BEARER_CONTEXT_MODIFICATION_REQ for instance %d\n", (int)instance);
-        rrc_CUUP_process_bearer_context_mod_req(&E1AP_BEARER_CONTEXT_SETUP_REQ(msg_p), instance);
-        break;
-
       default:
         LOG_E(NR_RRC, "[gNB %ld] Received unexpected message %s\n", instance, msg_name_p);
         break;
-- 
GitLab