From 6a7a01043bf1e6e0ee9ac40b4d85ced7cdf6dcf4 Mon Sep 17 00:00:00 2001
From: laurent <laurent Thomas>
Date: Tue, 27 Dec 2022 15:59:28 +0100
Subject: [PATCH] first functional commit standalone cu-up

---
 CMakeLists.txt                            |  21 +++-
 executables/cuup.c                        | 140 ++++++++++++++++++++++
 openair2/COMMON/e1ap_messages_types.h     |  15 ---
 openair2/E1AP/e1ap.c                      |  94 ++++++++-------
 openair2/E1AP/e1ap_common.c               |   4 +-
 openair2/E1AP/e1ap_common.h               |  13 ++
 openair2/E1AP/e1ap_setup.c                |  93 ++++++++++++++
 openair2/GNB_APP/gnb_app.c                |  36 +++---
 openair2/GNB_APP/gnb_config.c             | 121 -------------------
 openair2/GNB_APP/gnb_config.h             |   2 +-
 openair2/LAYER2/MAC/mac_proto.h           |   2 -
 openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c |   3 +-
 openair3/ocp-gtpu/gtp_itf.cpp             |  18 ++-
 openair3/ocp-gtpu/gtp_itf.h               |   4 +-
 openair3/ocp-gtpu/gtpu_setup.c            |  91 ++++++++++++++
 15 files changed, 435 insertions(+), 222 deletions(-)
 create mode 100644 executables/cuup.c
 create mode 100644 openair2/E1AP/e1ap_setup.c
 create mode 100644 openair3/ocp-gtpu/gtpu_setup.c

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 69c8eeaa242..88e672d44b4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -847,7 +847,6 @@ include_directories("${OPENAIR2_DIR}/UTIL/OTG")
 include_directories("${OPENAIR2_DIR}/UTIL/CLI")
 include_directories("${OPENAIR2_DIR}/UTIL/OPT")
 include_directories("${OPENAIR2_DIR}/UTIL/OMV")
-include_directories("${OPENAIR2_DIR}/RRC/LTE/MESSAGES")
 include_directories("${OPENAIR_DIR}")
 
 ###########
@@ -1660,6 +1659,8 @@ set (ENB_APP_SRC
 
 set (GNB_APP_SRC
   ${OPENAIR2_DIR}/GNB_APP/gnb_app.c
+  ${OPENAIR2_DIR}/E1AP/e1ap_setup.c
+  ${OPENAIR3_DIR}/ocp-gtpu/gtpu_setup.c
   ${OPENAIR2_DIR}/GNB_APP/gnb_config.c
   )
 
@@ -2469,8 +2470,24 @@ endif ()
 
 # force the generation of ASN.1 so that we don't need to wait during the build
 target_link_libraries(nr-softmodem PRIVATE
-                      asn1_lte_rrc asn1_nr_rrc asn1_s1ap asn1_ngap asn1_m2ap asn1_m3ap asn1_x2ap asn1_f1ap asn1_lpp)
+  asn1_lte_rrc asn1_nr_rrc asn1_s1ap asn1_ngap asn1_m2ap asn1_m3ap asn1_x2ap asn1_f1ap asn1_lpp)
+
+add_executable(cu-up
+  executables/cuup.c
+  executables/softmodem-common.c
+  ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
+  ${OPENAIR2_DIR}/RRC/NAS/nas_config.c
+  ${NR_RRC_DIR}/rrc_gNB_UE_context.c
+  ${OPENAIR2_DIR}/E1AP/e1ap_setup.c
+  ${OPENAIR3_DIR}/ocp-gtpu/gtpu_setup.c
+  ${NR_PDCP_SRC}
+  ${NR_SDAP_SRC}
+  ${T_SOURCE}
+  ${SHLIB_LOADER_SOURCES}
+  )
 
+target_link_libraries(cu-up -Wl,--start-group CONFIG_LIB ITTI SCTP_CLIENT SECU_OSA GTPV1U E1AP E1_PDCP_IF asn1_lte_rrc asn1_nr_rrc asn1_f1ap ${OPENSSL_LIBRARIES}  -Wl,--end-group crypt z sctp dl)
+                      
 # nr-uesoftmodem is  UE implementation
 #######################################
 
diff --git a/executables/cuup.c b/executables/cuup.c
new file mode 100644
index 00000000000..c34384489e2
--- /dev/null
+++ b/executables/cuup.c
@@ -0,0 +1,140 @@
+#include "common/utils/simple_executable.h"
+#include "executables/softmodem-common.h"
+#include "common/utils/ocp_itti/intertask_interface.h"
+#include "openair3/ocp-gtpu/gtp_itf.h"
+#include "openair2/E1AP/e1ap.h"
+#include "common/ran_context.h"
+#include "nfapi/oai_integration/vendor_ext.h"
+#include "openair2/F1AP/f1ap_common.h"
+#include "openair2/GNB_APP/gnb_config.h"
+
+unsigned char NB_eNB_INST = 1;
+RAN_CONTEXT_t RC;
+THREAD_STRUCT thread_struct;
+uint64_t downlink_frequency[MAX_NUM_CCs][4];
+int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
+int asn1_xer_print;
+int oai_exit = 0;
+instance_t CUuniqInstance = 0;
+RRC_release_list_t rrc_release_info;
+
+void exit_function(const char *file, const char *function, const int line, const char *s)
+{
+}
+
+nfapi_mode_t nfapi_mod = -1;
+
+void nfapi_setmode(nfapi_mode_t nfapi_mode)
+{
+  nfapi_mod = nfapi_mode;
+}
+
+nfapi_mode_t nfapi_getmode(void)
+{
+  return nfapi_mod;
+}
+
+ngran_node_t get_node_type()
+{
+  return ngran_gNB_CUUP;
+}
+
+rlc_op_status_t rlc_data_req(const protocol_ctxt_t *const,
+                             const srb_flag_t,
+                             const MBMS_flag_t,
+                             const rb_id_t,
+                             const mui_t,
+                             const confirm_t,
+                             const sdu_size_t,
+                             mem_block_t *const,
+                             const uint32_t *const,
+                             const uint32_t *const)
+{
+  abort();
+  return 0;
+}
+
+int nr_rlc_get_available_tx_space(const rnti_t rntiP, const logical_chan_id_t channel_idP)
+{
+  abort();
+  return 0;
+}
+
+void nr_rlc_bearer_init(NR_RLC_BearerConfig_t *RLC_BearerConfig, NR_RLC_BearerConfig__servedRadioBearer_PR rb_type)
+{
+  abort();
+}
+
+void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, NR_CellGroupConfig_t *cell_groupConfig_from_DU)
+{
+  abort();
+}
+
+void nr_rlc_bearer_init_ul_spec(struct NR_LogicalChannelConfig *mac_LogicalChannelConfig)
+{
+  abort();
+}
+
+rlc_op_status_t nr_rrc_rlc_config_asn1_req(const protocol_ctxt_t *const ctxt_pP,
+                                           const NR_SRB_ToAddModList_t *const srb2add_listP,
+                                           const NR_DRB_ToAddModList_t *const drb2add_listP,
+                                           const NR_DRB_ToReleaseList_t *const drb2release_listP,
+                                           const LTE_PMCH_InfoList_r9_t *const pmch_InfoList_r9_pP,
+                                           struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list)
+{
+  abort();
+  return 0;
+}
+
+int nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ctxt_pP, const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP)
+{
+  abort();
+  return 0;
+}
+
+void nr_drb_config(struct NR_RLC_Config *rlc_Config, NR_RLC_Config_PR rlc_config_pr)
+{
+  abort();
+}
+
+void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p, e1ap_bearer_setup_resp_t *e1ap_resp)
+{
+  abort();
+}
+
+f1ap_cudu_inst_t *getCxt(F1_t isCU, instance_t instanceP)
+{
+  abort();
+  return NULL;
+}
+
+void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP)
+{
+  abort();
+}
+
+int main(int argc, char **argv)
+{
+  /// static configuration for NR at the moment
+  if (load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY) == NULL) {
+    exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
+  }
+  logInit();
+  set_softmodem_sighandler();
+  itti_init(TASK_MAX, tasks_info);
+  int rc;
+  rc = itti_create_task(TASK_SCTP, sctp_eNB_task, NULL);
+  AssertFatal(rc >= 0, "Create task for SCTP failed\n");
+  rc = itti_create_task(TASK_GTPV1_U, gtpv1uTask, NULL);
+  AssertFatal(rc >= 0, "Create task for GTPV1U failed\n");
+  rc = itti_create_task(TASK_CUUP_E1, E1AP_CUUP_task, NULL);
+  AssertFatal(rc >= 0, "Create task for CUUP E1 failed\n");
+  pdcp_layer_init();
+  MessageDef *msg = RCconfig_NR_CU_E1();
+  if (msg)
+    itti_send_msg_to_task(TASK_CUUP_E1, 0, msg);
+  else
+    AssertFatal(false, "Send inti to task for E1AP UP failed\n");
+  sleep(3600 * 24 * 1000);
+  return 0;
+}
diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h
index f4d8e88a34e..01087744196 100644
--- a/openair2/COMMON/e1ap_messages_types.h
+++ b/openair2/COMMON/e1ap_messages_types.h
@@ -36,8 +36,6 @@
 #define E1AP_MAX_NUM_DRBS 4
 #define E1AP_MAX_NUM_DRBS 4
 #define E1AP_MAX_NUM_UP_PARAM 4
-#define E1AP_GTP_INST_N3 10
-#define E1AP_GTP_INST_F1U 11
 
 #define E1AP_SETUP_REQ(mSGpTR)                            (mSGpTR)->ittiMsg.e1ap_setup_req
 #define E1AP_SETUP_RESP(mSGpTR)                           (mSGpTR)->ittiMsg.e1ap_setup_resp
@@ -217,17 +215,4 @@ typedef struct e1ap_bearer_setup_resp_s {
   pdu_session_setup_t pduSession[E1AP_MAX_NUM_PDU_SESSIONS];
 } e1ap_bearer_setup_resp_t;
 
-typedef struct e1ap_upcp_inst_s {
-  uint32_t                assoc_id;
-  instance_t              gtpInstN3;
-  instance_t              gtpInstF1U;
-  e1ap_setup_req_t        setupReq;
-  e1ap_bearer_setup_req_t bearerSetupReq;
-  e1ap_bearer_setup_resp_t bearerSetupResp;
-} e1ap_upcp_inst_t;
-
-typedef enum {
-  CPtype = 0,
-  UPtype
-} E1_t;
 #endif /* E1AP_MESSAGES_TYPES_H */
diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c
index b1d804908da..089f3e6e53c 100644
--- a/openair2/E1AP/e1ap.c
+++ b/openair2/E1AP/e1ap.c
@@ -548,11 +548,9 @@ int e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance,
   OCTET_STRING_fromBuf(&ieC2->value.choice.SecurityInformation.uPSecuritykey.encryptionKey,
                        bearerCxt->encryptionKey, strlen(bearerCxt->encryptionKey));
 
-  ieC2->value.choice.SecurityInformation.securityAlgorithm.integrityProtectionAlgorithm = (E1AP_IntegrityProtectionAlgorithm_t *) calloc(1, sizeof(E1AP_IntegrityProtectionAlgorithm_t));
-  *ieC2->value.choice.SecurityInformation.securityAlgorithm.integrityProtectionAlgorithm = bearerCxt->integrityProtectionAlgorithm;
-  ieC2->value.choice.SecurityInformation.uPSecuritykey.integrityProtectionKey = (E1AP_IntegrityProtectionKey_t *) calloc(1, sizeof(E1AP_IntegrityProtectionKey_t));
-  OCTET_STRING_fromBuf(ieC2->value.choice.SecurityInformation.uPSecuritykey.integrityProtectionKey,
-                       bearerCxt->integrityProtectionKey, strlen(bearerCxt->integrityProtectionKey));
+  asn1cCallocOne(ieC2->value.choice.SecurityInformation.securityAlgorithm.integrityProtectionAlgorithm, bearerCxt->integrityProtectionAlgorithm);
+  asn1cCalloc(ieC2->value.choice.SecurityInformation.uPSecuritykey.integrityProtectionKey, protKey);
+  OCTET_STRING_fromBuf(protKey, bearerCxt->integrityProtectionKey, strlen(bearerCxt->integrityProtectionKey));
   /* mandatory */
   /* c3. UE DL Aggregate Maximum Bit Rate */
   asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupRequestIEs_t, ieC3);
@@ -1442,34 +1440,31 @@ static instance_t cuup_task_create_gtpu_instance_to_du(eth_params_t *IPaddrs) {
 
 void cuup_task_send_sctp_association_req(instance_t instance, e1ap_setup_req_t *e1ap_setup_req) {
   DevAssert(e1ap_setup_req != NULL);
-  MessageDef                 *message_p                   = NULL;
-  sctp_new_association_req_t *sctp_new_association_req_p  = NULL;
-  message_p = itti_alloc_new_message(TASK_CUUP_E1, 0, SCTP_NEW_ASSOCIATION_REQ);
-  sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req;
-  sctp_new_association_req_p->ulp_cnx_id = instance;
-  sctp_new_association_req_p->port = E1AP_PORT_NUMBER;
-  sctp_new_association_req_p->ppid = E1AP_SCTP_PPID;
-  sctp_new_association_req_p->in_streams  = e1ap_setup_req->sctp_in_streams;
-  sctp_new_association_req_p->out_streams = e1ap_setup_req->sctp_out_streams;
+  getCxtE1(UPtype, instance)->sockState = SCTP_STATE_CLOSED;
+  MessageDef *message_p = itti_alloc_new_message(TASK_CUUP_E1, 0, SCTP_NEW_ASSOCIATION_REQ);
+  sctp_new_association_req_t *sctp_new_req = &message_p->ittiMsg.sctp_new_association_req;
+  sctp_new_req->ulp_cnx_id = instance;
+  sctp_new_req->port = E1AP_PORT_NUMBER;
+  sctp_new_req->ppid = E1AP_SCTP_PPID;
+  sctp_new_req->in_streams = e1ap_setup_req->sctp_in_streams;
+  sctp_new_req->out_streams = e1ap_setup_req->sctp_out_streams;
   // remote
-  memcpy(&sctp_new_association_req_p->remote_address,
-         &e1ap_setup_req->CUCP_e1_ip_address,
-         sizeof(e1ap_setup_req->CUCP_e1_ip_address));
+  memcpy(&sctp_new_req->remote_address, &e1ap_setup_req->CUCP_e1_ip_address, sizeof(e1ap_setup_req->CUCP_e1_ip_address));
   // local
-  memcpy(&sctp_new_association_req_p->local_address,
-         &e1ap_setup_req->CUUP_e1_ip_address,
-         sizeof(e1ap_setup_req->CUUP_e1_ip_address));
+  memcpy(&sctp_new_req->local_address, &e1ap_setup_req->CUUP_e1_ip_address, sizeof(e1ap_setup_req->CUUP_e1_ip_address));
   itti_send_msg_to_task(TASK_SCTP, instance, message_p);
 }
 
 void cuup_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) {
   DevAssert(sctp_new_association_resp != NULL);
-
+  getCxtE1(UPtype, instance)->sockState = sctp_new_association_resp->sctp_state;
   if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
     LOG_W(E1AP, "Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n",
           sctp_new_association_resp->sctp_state,
           instance,
           sctp_new_association_resp->ulp_cnx_id);
+    long timer_id; // if we want to cancel timer
+    timer_setup(1, 0, TASK_CUUP_E1, 0, TIMER_ONE_SHOT, NULL, &timer_id);
     return;
   }
 
@@ -1482,13 +1477,17 @@ void cuup_task_handle_sctp_association_resp(instance_t instance, sctp_new_associ
   eth_params_t IPaddr;
   IPaddr.my_addr = e1ap_cuup_setup_req->CUUP_e1_ip_address.ipv4_address;
   IPaddr.my_portd = e1ap_cuup_setup_req->port_cuup;
-  getCxtE1(UPtype, instance)->gtpInstF1U = cuup_task_create_gtpu_instance_to_du(&IPaddr);
-  AssertFatal(getCxtE1(UPtype, instance)->gtpInstF1U>0,"Failed to create CUUP F1-U UDP listener");
+  if (getCxtE1(UPtype, instance)->gtpInstF1U < 0)
+    getCxtE1(UPtype, instance)->gtpInstF1U = cuup_task_create_gtpu_instance_to_du(&IPaddr);
+  if (getCxtE1(UPtype, instance)->gtpInstF1U < 0)
+    LOG_E(E1AP, "Failed to create CUUP F1-U UDP listener");
   extern instance_t CUuniqInstance;
   CUuniqInstance = getCxtE1(UPtype, instance)->gtpInstF1U;
 
-  getCxtE1(UPtype, instance)->gtpInstN3 = RCconfig_nr_gtpu();
-  AssertFatal(getCxtE1(UPtype, instance)->gtpInstN3>0,"Failed to create CUUP N3 UDP listener");
+  if (getCxtE1(UPtype, instance)->gtpInstN3 < 0)
+    getCxtE1(UPtype, instance)->gtpInstN3 = RCconfig_nr_gtpu();
+  if (getCxtE1(UPtype, instance)->gtpInstN3 < 0)
+    LOG_E(E1AP, "Failed to create CUUP N3 UDP listener");
   N3GTPUInst = &getCxtE1(UPtype, instance)->gtpInstN3;
 
   e1apCUUP_send_SETUP_REQUEST(instance);
@@ -1513,27 +1512,38 @@ void cucp_task_send_sctp_init_req(instance_t instance, char *my_addr) {
   itti_send_msg_to_task(TASK_SCTP, instance, message_p);
 }
 
-void cucp_task_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind) {
+void cucp_task_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_ind)
+{
   createE1inst(CPtype, instance, NULL);
+  getCxtE1(CPtype, instance)->sockState = SCTP_STATE_ESTABLISHED;
   e1ap_setup_req_t *setup_req = &getCxtE1(CPtype, instance)->setupReq;
-  setup_req->assoc_id         = sctp_new_association_ind->assoc_id;
-  setup_req->sctp_in_streams  = sctp_new_association_ind->in_streams;
-  setup_req->sctp_out_streams = sctp_new_association_ind->out_streams;
+  setup_req->assoc_id = sctp_new_ind->assoc_id;
+  setup_req->sctp_in_streams = sctp_new_ind->in_streams;
+  setup_req->sctp_out_streams = sctp_new_ind->out_streams;
   setup_req->default_sctp_stream_id = 0;
 }
 
 void cucp_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) {
   DevAssert(sctp_new_association_resp != NULL);
-
+  getCxtE1(CPtype, instance)->sockState = sctp_new_association_resp->sctp_state;
   if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
     LOG_W(E1AP, "Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n",
           sctp_new_association_resp->sctp_state,
           instance,
           sctp_new_association_resp->ulp_cnx_id);
+    long timer_id; // if we want to cancel timer
+    timer_setup(1, 0, TASK_CUCP_E1, 0, TIMER_ONE_SHOT, NULL, &timer_id);
     return;
   }
 }
 
+void e1apHandleTimer(instance_t myInstance)
+{
+  LOG_W(E1AP, "Try to reconnect to CP\n");
+  if (getCxtE1(UPtype, myInstance)->sockState != SCTP_STATE_ESTABLISHED)
+    cuup_task_send_sctp_association_req(myInstance, &getCxtE1(UPtype, myInstance)->setupReq);
+}
+
 void *E1AP_CUCP_task(void *arg) {
   LOG_I(E1AP, "Starting E1AP at CU CP\n");
   MessageDef *msg = NULL;
@@ -1543,23 +1553,21 @@ void *E1AP_CUCP_task(void *arg) {
   while (1) {
     itti_receive_msg(TASK_CUCP_E1, &msg);
     instance_t myInstance=ITTI_MSG_DESTINATION_INSTANCE(msg);
+    const int msgType = ITTI_MSG_ID(msg);
+    LOG_I(E1AP, "CUCP received %s for instance %ld\n", messages_info[msgType].name, myInstance);
 
     switch (ITTI_MSG_ID(msg)) {
       case SCTP_NEW_ASSOCIATION_IND:
-        LOG_I(E1AP, "CUCP Task Received SCTP_NEW_ASSOCIATION_IND for instance %ld\n", myInstance);
         cucp_task_handle_sctp_association_ind(ITTI_MSG_ORIGIN_INSTANCE(msg),
                                               &msg->ittiMsg.sctp_new_association_ind);
         break;
 
       case SCTP_NEW_ASSOCIATION_RESP:
-        LOG_I(E1AP, "CUCP Task Received SCTP_NEW_ASSOCIATION_RESP for instance %ld\n", myInstance);
         cucp_task_handle_sctp_association_resp(ITTI_MSG_ORIGIN_INSTANCE(msg),
                                                &msg->ittiMsg.sctp_new_association_resp);
         break;
 
       case E1AP_SETUP_REQ:
-        LOG_I(E1AP, "CUCP Task Received E1AP_SETUP_REQ for instance %ld. Initializing SCTP listener\n",
-              myInstance);
         e1ap_setup_req_t *req = &E1AP_SETUP_REQ(msg);
         char *ipaddr;
         if (req->CUCP_e1_ip_address.ipv4 == 0) {
@@ -1572,22 +1580,18 @@ void *E1AP_CUCP_task(void *arg) {
         break;
 
       case SCTP_DATA_IND:
-        LOG_I(E1AP, "CUCP Task Received SCTP_DATA_IND\n");
         cuxp_task_handle_sctp_data_ind(myInstance, &msg->ittiMsg.sctp_data_ind);
         break;
 
       case E1AP_SETUP_RESP:
-        LOG_I(E1AP, "CUCP Task Received E1AP_SETUP_RESP\n");
         e1apCUCP_send_SETUP_RESPONSE(myInstance, &E1AP_SETUP_RESP(msg));
         break;
 
       case E1AP_BEARER_CONTEXT_SETUP_REQ:
-        LOG_I(E1AP, "CUCP Task Received E1AP_BEARER_CONTEXT_SETUP_REQ\n");
         e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(myInstance, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg));
         break;
 
       case E1AP_BEARER_CONTEXT_MODIFICATION_REQ:
-        LOG_I(E1AP, "CUCP Task Received E1AP_BEARER_CONTEXT_MODIFICATION_REQ\n");
         e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(myInstance, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg));
         break;
 
@@ -1612,11 +1616,11 @@ void *E1AP_CUUP_task(void *arg) {
   while (1) {
     MessageDef *msg = NULL;
     itti_receive_msg(TASK_CUUP_E1, &msg);
-    instance_t myInstance=ITTI_MSG_DESTINATION_INSTANCE(msg);
-
-    switch (ITTI_MSG_ID(msg)) {
+    const instance_t myInstance = ITTI_MSG_DESTINATION_INSTANCE(msg);
+    const int msgType = ITTI_MSG_ID(msg);
+    LOG_I(E1AP, "CUUP received %s for instance %ld\n", messages_info[msgType].name, myInstance);
+    switch (msgType) {
       case E1AP_SETUP_REQ:
-        LOG_I(E1AP, "CUUP Task Received E1AP_SETUP_REQ for instance %ld\n", myInstance);
         e1ap_setup_req_t *msgSetup = &E1AP_SETUP_REQ(msg);
         createE1inst(UPtype, myInstance, msgSetup);
 
@@ -1624,15 +1628,17 @@ void *E1AP_CUUP_task(void *arg) {
         break;
 
       case SCTP_NEW_ASSOCIATION_RESP:
-        LOG_I(E1AP, "CUUP Task Received SCTP_NEW_ASSOCIATION_RESP for instance %ld\n", myInstance);
         cuup_task_handle_sctp_association_resp(myInstance, &msg->ittiMsg.sctp_new_association_resp);
         break;
 
       case SCTP_DATA_IND:
-        LOG_I(E1AP, "CUUP Task Received SCTP_DATA_IND for instance %ld\n", myInstance);
         cuxp_task_handle_sctp_data_ind(myInstance, &msg->ittiMsg.sctp_data_ind);
         break;
 
+      case TIMER_HAS_EXPIRED:
+        e1apHandleTimer(myInstance);
+        break;
+
       default:
         LOG_E(E1AP, "Unknown message received in TASK_CUUP_E1\n");
         break;
diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c
index 1985859cbbd..12ab9af5e22 100644
--- a/openair2/E1AP/e1ap_common.c
+++ b/openair2/E1AP/e1ap_common.c
@@ -58,8 +58,8 @@ void createE1inst(E1_t type, instance_t instance, e1ap_setup_req_t *req) {
     AssertFatal(e1ap_up_inst[instance] == NULL, "Double call to E1 UP instance %d\n", (int)instance);
     e1ap_up_inst[instance] = (e1ap_upcp_inst_t *) calloc(1, sizeof(e1ap_upcp_inst_t));
     memcpy(&e1ap_up_inst[instance]->setupReq, req, sizeof(e1ap_setup_req_t));
-    e1ap_up_inst[instance]->gtpInstN3 = E1AP_GTP_INST_N3;
-    e1ap_up_inst[instance]->gtpInstF1U = E1AP_GTP_INST_F1U;
+    e1ap_up_inst[instance]->gtpInstN3 = -1;
+    e1ap_up_inst[instance]->gtpInstF1U = -1;
   } else {
     AssertFatal(false, "Unknown CU type\n");
   }
diff --git a/openair2/E1AP/e1ap_common.h b/openair2/E1AP/e1ap_common.h
index a5f9b1e508e..1fe60c82510 100644
--- a/openair2/E1AP/e1ap_common.h
+++ b/openair2/E1AP/e1ap_common.h
@@ -25,6 +25,19 @@
 #define E1AP_COMMON_H_
 #include "openair2/COMMON/e1ap_messages_types.h"
 #include "e1ap_asnc.h"
+#include "openair2/COMMON/sctp_messages_types.h"
+
+typedef struct e1ap_upcp_inst_s {
+  enum sctp_state_e sockState;
+  uint32_t assoc_id;
+  instance_t gtpInstN3;
+  instance_t gtpInstF1U;
+  e1ap_setup_req_t setupReq;
+  e1ap_bearer_setup_req_t bearerSetupReq;
+  e1ap_bearer_setup_resp_t bearerSetupResp;
+} e1ap_upcp_inst_t;
+
+typedef enum { CPtype = 0, UPtype } E1_t;
 
 extern int asn1_xer_print;
 
diff --git a/openair2/E1AP/e1ap_setup.c b/openair2/E1AP/e1ap_setup.c
new file mode 100644
index 00000000000..5845315ca7b
--- /dev/null
+++ b/openair2/E1AP/e1ap_setup.c
@@ -0,0 +1,93 @@
+/*
+ * 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
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <arpa/inet.h>
+#include "common/utils/LOG/log.h"
+#include "common/utils/nr/nr_common.h"
+#include "common/utils/LOG/log_extern.h"
+#include "assertions.h"
+#include "common/utils/ocp_itti/intertask_interface.h"
+#include "openair2/GNB_APP/gnb_paramdef.h"
+#include "openair3/ocp-gtpu/gtp_itf.h"
+
+MessageDef *RCconfig_NR_CU_E1(void)
+{
+  MessageDef *msgConfig = itti_alloc_new_message(TASK_GNB_APP, 0, E1AP_SETUP_REQ);
+  if (!msgConfig)
+    return NULL;
+
+  paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
+  paramdef_t GNBParams[] = GNBPARAMS_DESC;
+  paramdef_t GNBE1Params[] = GNBE1PARAMS_DESC;
+  paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST, NULL, 0};
+  paramlist_def_t GNBE1ParamList = {GNB_CONFIG_STRING_E1_PARAMETERS, NULL, 0};
+  config_get(GNBSParams, sizeof(GNBSParams) / sizeof(paramdef_t), NULL);
+  char aprefix[MAX_OPTNAME_SIZE * 2 + 8];
+  sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0);
+  int num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt;
+  AssertFatal(num_gnbs == 1, "Support only one gNB per process\n");
+
+  if (num_gnbs > 0) {
+    config_getlist(&GNBParamList, GNBParams, sizeof(GNBParams) / sizeof(paramdef_t), NULL);
+    AssertFatal(GNBParamList.paramarray[0][GNB_GNB_ID_IDX].uptr != NULL, "gNB id %u is not defined in configuration file\n", 0);
+    config_getlist(&GNBE1ParamList, GNBE1Params, sizeof(GNBE1Params) / sizeof(paramdef_t), aprefix);
+    e1ap_setup_req_t *e1Setup = &E1AP_SETUP_REQ(msgConfig);
+    msgConfig->ittiMsgHeader.destinationInstance = 0;
+    e1Setup->gNB_cu_up_id = *(GNBParamList.paramarray[0][GNB_GNB_ID_IDX].uptr);
+
+    paramdef_t PLMNParams[] = GNBPLMNPARAMS_DESC;
+    paramlist_def_t PLMNParamList = {GNB_CONFIG_STRING_PLMN_LIST, NULL, 0};
+    /* map parameter checking array instances to parameter definition array instances */
+    checkedparam_t config_check_PLMNParams[] = PLMNPARAMS_CHECK;
+
+    for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I)
+      PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]);
+
+    config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams) / sizeof(paramdef_t), aprefix);
+    int numPLMNs = PLMNParamList.numelt;
+    e1Setup->supported_plmns = numPLMNs;
+
+    for (int I = 0; I < numPLMNs; I++) {
+      e1Setup->plmns[I].mcc = *PLMNParamList.paramarray[I][GNB_MOBILE_COUNTRY_CODE_IDX].uptr;
+      e1Setup->plmns[I].mnc = *PLMNParamList.paramarray[I][GNB_MOBILE_NETWORK_CODE_IDX].uptr;
+      e1Setup->plmns[I].mnc = *PLMNParamList.paramarray[I][GNB_MNC_DIGIT_LENGTH].u8ptr;
+    }
+
+    strcpy(e1Setup->CUCP_e1_ip_address.ipv4_address, *(GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_IPV4_ADDRESS_CUCP].strptr));
+    e1Setup->CUCP_e1_ip_address.ipv4 = 1;
+    e1Setup->port_cucp = *GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_PORT_CUCP].uptr;
+    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)) {
+      ;
+      inet_pton(AF_INET, N3Addr, &e1Setup->IPv4AddressN3);
+      e1Setup->portN3 = N3Port;
+    }
+    e1Setup->cn_support = *GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_CN_SUPPORT].uptr;
+  }
+  return msgConfig;
+}
diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c
index 0976e314b89..dbe0b238baf 100644
--- a/openair2/GNB_APP/gnb_app.c
+++ b/openair2/GNB_APP/gnb_app.c
@@ -162,34 +162,26 @@ void *gNB_app_task(void *args_p)
     }
 
     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");
-        AssertFatal(1==0, "exiting");
-      }
-        // To initialize SCTP listener
-      msg_p = itti_alloc_new_message(TASK_GNB_APP, 0, E1AP_SETUP_REQ);
-      RCconfig_NR_CU_E1(msg_p, 0);
-
-      itti_send_msg_to_task(TASK_CUCP_E1, GNB_MODULE_ID_TO_INSTANCE(0), msg_p);
-
+      if (itti_create_task(TASK_CUCP_E1, E1AP_CUCP_task, NULL) < 0)
+        AssertFatal(false, "Create task for E1AP CP failed\n");
+      MessageDef *msg = RCconfig_NR_CU_E1();
+      if (msg)
+        itti_send_msg_to_task(TASK_CUCP_E1, 0, msg);
+      else
+        AssertFatal(false, "Send inti to task for E1AP CP failed\n");
     }
 
     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");
-      }
-      // configure E1AP here
-      LOG_I(GNB_APP, "ngran_gNB_CU: Allocating ITTI message for E1AP_SETUP_REQ\n");
-      msg_p = itti_alloc_new_message(TASK_GNB_APP, 0, E1AP_SETUP_REQ);
-      RCconfig_NR_CU_E1(msg_p, 0);
-
-      itti_send_msg_to_task(TASK_CUUP_E1, GNB_MODULE_ID_TO_INSTANCE(0), msg_p);
+      if (itti_create_task(TASK_CUUP_E1, E1AP_CUUP_task, NULL) < 0)
+        AssertFatal(false, "Create task for E1AP UP failed\n");
+      MessageDef *msg = RCconfig_NR_CU_E1();
+      if (msg)
+        itti_send_msg_to_task(TASK_CUUP_E1, 0, msg);
+      else
+        AssertFatal(false, "Send inti to task for E1AP UP failed\n");
     }
 
     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");
         AssertFatal(1==0,"exiting");
diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c
index 22892043a56..4363c15392e 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -89,8 +89,6 @@
 extern uint16_t sf_ahead;
 int macrlc_has_f1 = 0;
 
-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);
 
@@ -1265,64 +1263,6 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
   config_security(rrc);
 }//End RCconfig_NRRRC function
 
-static int get_NGU_S1U_addr(char *addr, int *port) {
-  int               num_gnbs                      = 0;
-  char*             gnb_ipv4_address_for_NGU      = NULL;
-  uint32_t          gnb_port_for_NGU              = 0;
-  char*             gnb_ipv4_address_for_S1U      = NULL;
-  uint32_t          gnb_port_for_S1U              = 0;
-  char gtpupath[MAX_OPTNAME_SIZE*2 + 8];
-
-  paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
-  paramdef_t NETParams[]  =  GNBNETPARAMS_DESC;
-  LOG_I(GTPU,"Configuring GTPu\n");
-
-/* get number of active eNodeBs */
-  config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL); 
-  num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt;
-  AssertFatal (num_gnbs >0,
-           "Failed to parse config file no active gNodeBs in %s \n", GNB_CONFIG_STRING_ACTIVE_GNBS);
-
-  sprintf(gtpupath,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,0,GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
-  config_get(NETParams,sizeof(NETParams)/sizeof(paramdef_t),gtpupath); 
-  char *cidr=NULL, *address = NULL;
-  if (NETParams[1].strptr != NULL) {
-    LOG_I(GTPU, "SA mode \n");
-    address = strtok_r(gnb_ipv4_address_for_NGU, "/", &cidr);
-    *port=gnb_port_for_NGU;
-  } else { 
-    LOG_I(GTPU, "NSA mode \n");
-    address = strtok_r(gnb_ipv4_address_for_S1U, "/", &cidr);
-    *port=gnb_port_for_S1U;
-  }
-  if (address == NULL) return 1;
-  else {
-    strcpy(addr, address);
-    return 0;
-  }
-}
-
-instance_t RCconfig_nr_gtpu(void) {
-  char address[64];
-  int port;
-  int ret = get_NGU_S1U_addr(address, &port);
-  instance_t ret_inst = 0;
-  if (!ret) {
-    eth_params_t IPaddr;
-    IPaddr.my_addr = address;
-    IPaddr.my_portd = port;
-    openAddr_t tmp= {0};
-    strcpy(tmp.originHost, IPaddr.my_addr);
-    sprintf(tmp.originService, "%d",  IPaddr.my_portd);
-    strcpy(tmp.destinationService, tmp.originService);
-    LOG_I(GTPU,"Configuring GTPu address : %s, port : %s\n", tmp.originHost, tmp.originService);
-    ret_inst = gtpv1Init(tmp);
-  } else
-    LOG_E(GTPU,"invalid address for NGU or S1U\n");
-
-  return ret_inst;
-}
-
 int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) {
 
   int               j,k = 0;
@@ -1817,67 +1757,6 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) {
   return 0;
 }
 
-int RCconfig_NR_CU_E1(MessageDef *msg_p, uint32_t i) {
-  paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
-  paramdef_t GNBParams[]  = GNBPARAMS_DESC;
-  paramdef_t GNBE1Params[] = GNBE1PARAMS_DESC;
-  paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0};
-  paramlist_def_t GNBE1ParamList = {GNB_CONFIG_STRING_E1_PARAMETERS, NULL, 0};
-  config_get(GNBSParams, sizeof(GNBSParams)/sizeof(paramdef_t), NULL);
-  char aprefix[MAX_OPTNAME_SIZE*2 + 8];
-  sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0);
-  int num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt;
-  AssertFatal (i < num_gnbs,
-               "Failed to parse config file no %uth element in %s \n",i, GNB_CONFIG_STRING_ACTIVE_GNBS);
-
-  if (num_gnbs > 0) {
-    config_getlist(&GNBParamList, GNBParams, sizeof(GNBParams)/sizeof(paramdef_t), NULL);
-    AssertFatal(GNBParamList.paramarray[i][GNB_GNB_ID_IDX].uptr != NULL,
-                "gNB id %u is not defined in configuration file\n",i);
-    config_getlist(&GNBE1ParamList, GNBE1Params, sizeof(GNBE1Params)/sizeof(paramdef_t), aprefix);
-    e1ap_setup_req_t *e1Setup = &E1AP_SETUP_REQ(msg_p);
-    msg_p->ittiMsgHeader.destinationInstance = 0;
-    e1Setup->gNB_cu_up_id = *(GNBParamList.paramarray[0][GNB_GNB_ID_IDX].uptr);
-
-    paramdef_t PLMNParams[] = GNBPLMNPARAMS_DESC;
-    paramlist_def_t PLMNParamList = {GNB_CONFIG_STRING_PLMN_LIST, NULL, 0};
-    /* map parameter checking array instances to parameter definition array instances */
-    checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK;
-
-    for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I)
-      PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]);
-
-    config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix);
-    int numPLMNs = PLMNParamList.numelt;
-    e1Setup->supported_plmns = numPLMNs;
-
-    for (int I = 0; I < numPLMNs; I++) {
-      e1Setup->plmns[I].mcc = *PLMNParamList.paramarray[I][GNB_MOBILE_COUNTRY_CODE_IDX].uptr;
-      e1Setup->plmns[I].mnc = *PLMNParamList.paramarray[I][GNB_MOBILE_NETWORK_CODE_IDX].uptr;
-      e1Setup->plmns[I].mnc = *PLMNParamList.paramarray[I][GNB_MNC_DIGIT_LENGTH].u8ptr;
-    }
-
-    strcpy(e1Setup->CUCP_e1_ip_address.ipv4_address, *(GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_IPV4_ADDRESS_CUCP].strptr));
-    e1Setup->CUCP_e1_ip_address.ipv4 = 1;
-    e1Setup->port_cucp = *GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_PORT_CUCP].uptr;
-    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)) {;
-      inet_pton(AF_INET,
-                N3Addr,
-                &e1Setup->IPv4AddressN3);
-      e1Setup->portN3 = N3Port;
-    }
-    e1Setup->cn_support = *GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_CN_SUPPORT].uptr;
-  }
-
-  return 0;
-}
-
 int RCconfig_NR_DU_F1(MessageDef *msg_p, uint32_t i) {
   int k;
   paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
diff --git a/openair2/GNB_APP/gnb_config.h b/openair2/GNB_APP/gnb_config.h
index 98d5b4581ee..f8dbeb5d6ca 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);
-int RCconfig_NR_CU_E1(MessageDef *msg_p, uint32_t i);
+MessageDef *RCconfig_NR_CU_E1();
 ngran_node_t get_node_type(void);
 
 #endif /* GNB_CONFIG_H_ */
diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h
index 6e9d36e2426..2055a176819 100644
--- a/openair2/LAYER2/MAC/mac_proto.h
+++ b/openair2/LAYER2/MAC/mac_proto.h
@@ -675,8 +675,6 @@ int remove_ue_list(UE_list_t *listP, int UE_id);
 void dump_ue_list(UE_list_t *listP);
 void init_ue_list(UE_list_t *listP);
 int UE_num_active_CC(UE_info_t *listP, int ue_idP);
-int UE_PCCID(module_id_t mod_idP, int ue_idP);
-rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP);
 
 uint8_t find_rb_table_index(uint8_t average_rbs);
 
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
index a26233328dc..ad4a0fec448 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
@@ -675,7 +675,7 @@ rb_found:
   ctxt.brOption = 0;
 
   ctxt.rntiMaybeUEid = ue->rntiMaybeUEid;
-  if (RC.nrrrc != NULL && NODE_IS_CU(node_type)) {
+  if (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)
@@ -696,7 +696,6 @@ rb_found:
     extern instance_t CUuniqInstance;
     itti_send_msg_to_task(TASK_GTPV1_U, CUuniqInstance, message_p);
   } else {
-    
     memblock = get_free_mem_block(size, __FUNCTION__);
     memcpy(memblock->data, buf, size);
     LOG_D(PDCP, "%s(): (drb %d) calling rlc_data_req size %d\n", __func__, rb_id, size);
diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp
index 84307ee39a5..9deec938aef 100644
--- a/openair3/ocp-gtpu/gtp_itf.cpp
+++ b/openair3/ocp-gtpu/gtp_itf.cpp
@@ -1249,22 +1249,21 @@ void *gtpv1uTask(void *args)  {
     */
     MessageDef *message_p = NULL;
     itti_receive_msg(TASK_GTPV1_U, &message_p);
-
     if (message_p != NULL ) {
       openAddr_t addr= {0};
-
-      switch (ITTI_MSG_ID(message_p)) {
-        // DATA TO BE SENT TO UDP
+      const instance_t myInstance = ITTI_MSG_DESTINATION_INSTANCE(message_p);
+      const int msgType = ITTI_MSG_ID(message_p);
+      LOG_D(GTPU, "GTP-U received %s for instance %ld\n", messages_info[msgType].name, myInstance);
+      switch (msgType) {
+          // DATA TO BE SENT TO UDP
 
         case GTPV1U_TUNNEL_DATA_REQ: {
-          gtpv1uSend(compatInst(ITTI_MSG_DESTINATION_INSTANCE(message_p)),
-                      &GTPV1U_TUNNEL_DATA_REQ(message_p), false, false);
+          gtpv1uSend(compatInst(myInstance), &GTPV1U_TUNNEL_DATA_REQ(message_p), false, false);
         }
         break;
 
         case GTPV1U_DU_BUFFER_REPORT_REQ:{
-          gtpv1uSendDlDeliveryStatus(compatInst(ITTI_MSG_DESTINATION_INSTANCE(message_p)),
-              &GTPV1U_DU_BUFFER_REPORT_REQ(message_p));
+          gtpv1uSendDlDeliveryStatus(compatInst(myInstance), &GTPV1U_DU_BUFFER_REPORT_REQ(message_p));
         }
         break;
 
@@ -1276,8 +1275,7 @@ void *gtpv1uTask(void *args)  {
           break;
 
         case GTPV1U_ENB_END_MARKER_REQ:
-          gtpv1uEndTunnel(compatInst(ITTI_MSG_DESTINATION_INSTANCE(message_p)),
-                          &GTPV1U_TUNNEL_DATA_REQ(message_p));
+          gtpv1uEndTunnel(compatInst(myInstance), &GTPV1U_TUNNEL_DATA_REQ(message_p));
           itti_free(TASK_GTPV1_U, GTPV1U_TUNNEL_DATA_REQ(message_p).buffer);
           break;
 
diff --git a/openair3/ocp-gtpu/gtp_itf.h b/openair3/ocp-gtpu/gtp_itf.h
index aa22a1990f6..5d61d9adc0b 100644
--- a/openair3/ocp-gtpu/gtp_itf.h
+++ b/openair3/ocp-gtpu/gtp_itf.h
@@ -149,7 +149,9 @@ extern "C" {
 
     //RB_ENTRY(gtpv1u_ue_data_s) gtpv1u_ue_node;
   } gtpv1u_ue_data_t;
-  
+
+  int get_NGU_S1U_addr(char *addr, int *port);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/openair3/ocp-gtpu/gtpu_setup.c b/openair3/ocp-gtpu/gtpu_setup.c
new file mode 100644
index 00000000000..74367120185
--- /dev/null
+++ b/openair3/ocp-gtpu/gtpu_setup.c
@@ -0,0 +1,91 @@
+/*
+ * 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
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <arpa/inet.h>
+#include "common/utils/LOG/log.h"
+#include "common/utils/nr/nr_common.h"
+#include "common/utils/LOG/log_extern.h"
+#include "assertions.h"
+#include "common/utils/ocp_itti/intertask_interface.h"
+#include "openair2/GNB_APP/gnb_paramdef.h"
+#include "openair3/ocp-gtpu/gtp_itf.h"
+
+int get_NGU_S1U_addr(char *addr, int *port)
+{
+  int num_gnbs = 0;
+  char *gnb_ipv4_address_for_NGU = NULL;
+  uint32_t gnb_port_for_NGU = 0;
+  char *gnb_ipv4_address_for_S1U = NULL;
+  uint32_t gnb_port_for_S1U = 0;
+  char gtpupath[MAX_OPTNAME_SIZE * 2 + 8];
+
+  paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
+  paramdef_t NETParams[] = GNBNETPARAMS_DESC;
+  LOG_I(GTPU, "Configuring GTPu\n");
+
+  /* get number of active eNodeBs */
+  config_get(GNBSParams, sizeof(GNBSParams) / sizeof(paramdef_t), NULL);
+  num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt;
+  AssertFatal(num_gnbs > 0, "Failed to parse config file no active gNodeBs in %s \n", GNB_CONFIG_STRING_ACTIVE_GNBS);
+
+  sprintf(gtpupath, "%s.[%i].%s", GNB_CONFIG_STRING_GNB_LIST, 0, GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
+  config_get(NETParams, sizeof(NETParams) / sizeof(paramdef_t), gtpupath);
+  char *cidr = NULL, *address = NULL;
+  if (NETParams[1].strptr != NULL) {
+    LOG_I(GTPU, "SA mode \n");
+    address = strtok_r(gnb_ipv4_address_for_NGU, "/", &cidr);
+    *port = gnb_port_for_NGU;
+  } else {
+    LOG_I(GTPU, "NSA mode \n");
+    address = strtok_r(gnb_ipv4_address_for_S1U, "/", &cidr);
+    *port = gnb_port_for_S1U;
+  }
+  if (address == NULL)
+    return 1;
+  else {
+    strcpy(addr, address);
+    return 0;
+  }
+}
+
+instance_t RCconfig_nr_gtpu(void)
+{
+  char address[64];
+  int port;
+  int ret = get_NGU_S1U_addr(address, &port);
+  instance_t ret_inst = 0;
+  if (!ret) {
+    eth_params_t IPaddr;
+    IPaddr.my_addr = address;
+    IPaddr.my_portd = port;
+    openAddr_t tmp = {0};
+    strcpy(tmp.originHost, IPaddr.my_addr);
+    sprintf(tmp.originService, "%d", IPaddr.my_portd);
+    strcpy(tmp.destinationService, tmp.originService);
+    LOG_I(GTPU, "Configuring GTPu address : %s, port : %s\n", tmp.originHost, tmp.originService);
+    ret_inst = gtpv1Init(tmp);
+  } else
+    LOG_E(GTPU, "invalid address for NGU or S1U\n");
+
+  return ret_inst;
+}
-- 
GitLab