diff --git a/CMakeLists.txt b/CMakeLists.txt
index 68c3e08efcde6e81fce7b2560dc39d47615934b4..a496acc71a902b4df3e5b4677584a6b3ac4c472a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1707,7 +1707,7 @@ add_library(e1_if
   ${NR_RRC_DIR}/cucp_cuup_e1ap.c
   )
 
-target_link_libraries(e1_if PRIVATE asn1_nr_rrc asn1_lte_rrc asn1_f1ap)
+target_link_libraries(e1_if PRIVATE asn1_nr_rrc asn1_lte_rrc asn1_f1ap e1ap)
 
 add_library(e1_pdcp_if
   ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_e1_api.c
@@ -2449,7 +2449,7 @@ target_link_libraries(nr-softmodem PRIVATE
   UTIL HASHTABLE SCTP_CLIENT SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU GTPV1U SECU_CN SECU_OSA
   ITTI ${RAL_LIB} ${NAS_UE_LIB} lte_rrc nr_rrc
   ngap s1ap L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB SIMU
-  x2ap f1ap m2ap m3ap
+  x2ap f1ap m2ap m3ap e1ap
   -Wl,--end-group z dl)
 
 target_link_libraries(nr-softmodem PRIVATE ${LIBXML2_LIBRARIES})
diff --git a/common/ngran_types.h b/common/ngran_types.h
index 476d64b7c853aeb93a2d5edf47feb14d9a61d3e9..c77f2b14f0e19fa29fdf9d70c1835367a0828d4a 100644
--- a/common/ngran_types.h
+++ b/common/ngran_types.h
@@ -47,6 +47,8 @@ typedef enum {
   ngran_gNB_CUUP  = 10
 } ngran_node_t;
 
+typedef enum { CPtype = 0, UPtype } E1_t;
+
 #define NODE_IS_MONOLITHIC(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB    || (nOdE_TyPe) == ngran_ng_eNB    || (nOdE_TyPe) == ngran_gNB)
 #define NODE_IS_CU(nOdE_TyPe)         ((nOdE_TyPe) == ngran_eNB_CU || (nOdE_TyPe) == ngran_ng_eNB_CU || (nOdE_TyPe) == ngran_gNB_CU || (nOdE_TyPe) == ngran_gNB_CUCP || (nOdE_TyPe) == ngran_gNB_CUUP)
 #define NODE_IS_DU(nOdE_TyPe)         ((nOdE_TyPe) == ngran_eNB_DU || (nOdE_TyPe) == ngran_gNB_DU)
diff --git a/executables/cuup.c b/executables/cuup.c
index 85af9396c006efc1515b0d03f9ba072c473897d3..7ffc45aa350fb2b89949af7a9635f69452fc980f 100644
--- a/executables/cuup.c
+++ b/executables/cuup.c
@@ -112,10 +112,7 @@ void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_contex
 {
   abort();
 }
-NR_SRB_ToAddModList_t **generateSRB2_confList(gNB_RRC_UE_t *ue, NR_SRB_ToAddModList_t *SRB_configList, uint8_t xid)
-{
-  abort();
-}
+
 int main(int argc, char **argv)
 {
   /// static configuration for NR at the moment
@@ -133,7 +130,7 @@ int main(int argc, char **argv)
   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();
+  MessageDef *msg = RCconfig_NR_CU_E1(true);
   if (msg)
     itti_send_msg_to_task(TASK_CUUP_E1, 0, msg);
   else
diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c
index 033df5b8b7dc76c24930094a88dcb3e9d7ee5426..332dd8286cc38b9cee9e5c2af6e684907ad14c4b 100644
--- a/executables/nr-softmodem.c
+++ b/executables/nr-softmodem.c
@@ -81,6 +81,7 @@ unsigned short config_frames[4] = {2,9,11,13};
 #include <openair3/ocp-gtpu/gtp_itf.h>
 #include "nfapi/oai_integration/vendor_ext.h"
 #include "gnb_config.h"
+#include "openair2/E1AP/e1ap_common.h"
 
 pthread_cond_t nfapi_sync_cond;
 pthread_mutex_t nfapi_sync_mutex;
@@ -342,14 +343,8 @@ int create_gNB_tasks(void) {
     //registered_gnb = 0;
     __attribute__((unused)) uint32_t register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);
   }
-  
 
   if (gnb_nb > 0) {
-    /* Last task to create, others task must be ready before its start */
-    /*if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) {
-      LOG_E(GNB_APP, "Create task for gNB APP failed\n");
-      return -1;
-    }*/
     if(itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0) {
       LOG_E(SCTP, "Create task for SCTP failed\n");
       return -1;
@@ -399,17 +394,22 @@ int create_gNB_tasks(void) {
       return -1;
     }
 
-    LOG_I(NR_RRC,"Creating NR RRC gNB Task\n");
-
+    LOG_I(NR_RRC, "Creating NR RRC gNB Task, that will also create TASKS\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 CU
-    if ((node_type == ngran_gNB_CU) ||
-        (node_type == ngran_gNB)) {
-      RC.nrrrc[gnb_id_start]->gtpInstN3 = RCconfig_nr_gtpu();
+    if (node_type == ngran_gNB_CU || node_type == ngran_gNB) {
+      MessageDef *msg = RCconfig_NR_CU_E1(false);
+      instance_t inst = 0;
+      createE1inst(UPtype, inst, &E1AP_SETUP_REQ(msg));
+      cuup_init_n3(inst);
+      itti_free(TASK_UNKNOWN, msg);
+      getCxtE1(inst)->same_process = true;
+      ;
+      RC.nrrrc[gnb_id_start]->e1_inst = inst; // stupid instance !!!*/
     }
 
     //Use check on x2ap to consider the NSA scenario 
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
index 2aeb7e3c7c0ceb8fac41bb5e8f4690da43fea732..069969ad11f94da2fc9039da0359cab0948bfb67 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
@@ -2036,7 +2036,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
       //--------------------- Channel Compensation ---------------
       //----------------------------------------------------------
       start_meas(&gNB->ulsch_channel_compensation_stats);
-      LOG_D(PHY,"Doing channel compensations log2_maxh %d, avgs %d (%d,%d)\n",gNB->pusch_vars[ulsch_id]->log2_maxh,avgs,avg[0],avg[1]);
+      LOG_D(PHY, "Doing channel compensations log2_maxh %d, avgs %d (%d)\n", gNB->pusch_vars[ulsch_id]->log2_maxh, avgs, avg[0]);
       nr_ulsch_channel_compensation(gNB->pusch_vars[ulsch_id]->rxdataF_ext,
                                     gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext,
                                     gNB->pusch_vars[ulsch_id]->ul_ch_mag0,
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index 01e4cbefd9e0c0ba2da5fc52fcf4c069c7704047..d13204984e70af97bb0bc653e988b52740233dde 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -1360,7 +1360,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
 
   stop_meas(&ue->generic_stat);
   if (cpumeas(CPUMEAS_GETSTATE))
-    LOG_D(PHY,"after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*1000.0));
+    LOG_D(PHY, "after LDPC until end of Rx %5.2f \n", ue->generic_stat.p_time / (cpuf * 1000.0));
 
 #ifdef EMOS
   phy_procedures_emos_UE_RX(ue,slot,gNB_id);
diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c
index a587b8f996e07f4ecc722b0b46476ca52382560a..49c421348c213df346df468ec780207ac3283f30 100644
--- a/openair2/E1AP/e1ap.c
+++ b/openair2/E1AP/e1ap.c
@@ -34,10 +34,7 @@
 #include "e1ap_default_values.h"
 
 #define E1AP_NUM_MSG_HANDLERS 14
-typedef int (*e1ap_message_processing_t)(
-  instance_t            instance,
-  const E1AP_E1AP_PDU_t       *message_p
-);
+typedef int (*e1ap_message_processing_t)(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *message_p);
 e1ap_message_processing_t e1ap_message_processing[E1AP_NUM_MSG_HANDLERS][3] = {
 
   { 0, 0, 0 }, /* Reset */
@@ -76,35 +73,30 @@ int e1ap_handle_message(instance_t instance, uint32_t assoc_id,
     LOG_E(E1AP, "Failed to decode PDU\n");
     return -1;
   }
-
+  const E1AP_ProcedureCode_t procedureCode = pdu.choice.initiatingMessage->procedureCode;
   /* Checking procedure Code and direction of message */
-  if ((pdu.choice.initiatingMessage->procedureCode >= E1AP_NUM_MSG_HANDLERS)
-      || (pdu.present >  E1AP_E1AP_PDU_PR_unsuccessfulOutcome)
-      || (pdu.present <= E1AP_E1AP_PDU_PR_NOTHING)) {
-    LOG_E(E1AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n",
-          assoc_id, pdu.choice.initiatingMessage->procedureCode, pdu.present);
+  if ((procedureCode >= E1AP_NUM_MSG_HANDLERS) || (pdu.present > E1AP_E1AP_PDU_PR_unsuccessfulOutcome) || (pdu.present <= E1AP_E1AP_PDU_PR_NOTHING)) {
+    LOG_E(E1AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n", assoc_id, procedureCode, pdu.present);
     ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_E1AP_E1AP_PDU, &pdu);
     return -1;
   }
 
-  if (e1ap_message_processing[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1] == NULL) {
+  if (e1ap_message_processing[procedureCode][pdu.present - 1] == NULL) {
     // No handler present. This can mean not implemented or no procedure for eNB (wrong direction).
-    LOG_E(E1AP, "[SCTP %d] No handler for procedureCode %ld in %s\n",
-          assoc_id, pdu.choice.initiatingMessage->procedureCode,
-          e1ap_direction2String(pdu.present - 1));
+    LOG_E(E1AP, "[SCTP %d] No handler for procedureCode %ld in %s\n", assoc_id, procedureCode, e1ap_direction2String(pdu.present - 1));
     ret=-1;
   } else {
     /* Calling the right handler */
     LOG_I(E1AP, "Calling handler with instance %ld\n",instance);
-    ret = (*e1ap_message_processing[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1])
-          (instance, &pdu);
+    ret = (*e1ap_message_processing[procedureCode][pdu.present - 1])(getCxtE1(instance), &pdu);
   }
 
   ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_E1AP_E1AP_PDU, &pdu);
   return ret;
 }
 
-void cuxp_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) {
+void e1_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind)
+{
   int result;
   DevAssert(sctp_data_ind != NULL);
   e1ap_handle_message(instance, sctp_data_ind->assoc_id,
@@ -120,10 +112,11 @@ void e1ap_itti_send_sctp_close_association(bool isCu, instance_t instance) {
   itti_send_msg_to_task(TASK_SCTP, instance, message);
 }
 
-int e1ap_send_RESET(bool isCu, instance_t instance, E1AP_Reset_t *Reset) {
+int e1ap_send_RESET(bool isCu, e1ap_setup_req_t *setupReq, E1AP_Reset_t *Reset)
+{
   AssertFatal(false,"Not implemented yet\n");
   E1AP_E1AP_PDU_t pdu= {0};
-  return e1ap_encode_send(isCu, instance, &pdu,0, __func__);
+  return e1ap_encode_send(isCu, setupReq, &pdu, 0, __func__);
 }
 
 int e1ap_send_RESET_ACKNOWLEDGE(instance_t instance, E1AP_Reset_t *Reset) {
@@ -168,9 +161,8 @@ int e1ap_send_ERROR_INDICATION(instance_t instance, E1AP_ErrorIndication_t *Erro
     E1 Setup: can be sent on both ways, to be refined
 */
 
-void fill_SETUP_REQUEST(instance_t instance,
-                        E1AP_E1AP_PDU_t *pdu) {
-  e1ap_setup_req_t *setup = &getCxtE1(UPtype, instance)->setupReq;
+static void fill_SETUP_REQUEST(e1ap_setup_req_t *setup, E1AP_E1AP_PDU_t *pdu)
+{
   /* Create */
   /* 0. pdu Type */
   pdu->present = E1AP_E1AP_PDU_PR_initiatingMessage;
@@ -219,9 +211,8 @@ void fill_SETUP_REQUEST(instance_t instance,
   }
 }
 
-void fill_SETUP_RESPONSE(instance_t instance,
-                           const e1ap_setup_resp_t *e1ap_setup_resp,
-                           E1AP_E1AP_PDU_t *pdu) {
+static void fill_SETUP_RESPONSE(const e1ap_setup_resp_t *e1ap_setup_resp, E1AP_E1AP_PDU_t *pdu)
+{
   /* Create */
   /* 0. pdu Type */
   pdu->present = E1AP_E1AP_PDU_PR_successfulOutcome;
@@ -239,17 +230,17 @@ void fill_SETUP_RESPONSE(instance_t instance,
   ieC1->value.choice.TransactionID = e1ap_setup_resp->transac_id;
 }
 
-void e1apCUCP_send_SETUP_RESPONSE(instance_t instance,
-                                  const e1ap_setup_resp_t *e1ap_setup_resp) {
+void e1ap_send_SETUP_RESPONSE(instance_t inst, const e1ap_setup_resp_t *e1ap_setup_resp)
+{
+  AssertFatal(getCxtE1(inst), "");
+  e1ap_setup_req_t *setupReq = &getCxtE1(inst)->setupReq;
   E1AP_E1AP_PDU_t pdu = {0};
-  fill_SETUP_RESPONSE(instance, e1ap_setup_resp, &pdu);
-  e1ap_encode_send(CPtype, instance, &pdu, 0, __func__);
-
+  fill_SETUP_RESPONSE(e1ap_setup_resp, &pdu);
+  e1ap_encode_send(getCxtE1(inst)->type, setupReq, &pdu, 0, __func__);
 }
 
-void fill_SETUP_FAILURE(instance_t instance,
-                        long transac_id,
-                        E1AP_E1AP_PDU_t *pdu) {
+static void fill_SETUP_FAILURE(long transac_id, E1AP_E1AP_PDU_t *pdu)
+{
   /* Create */
   /* 0. pdu Type */
   pdu->present = E1AP_E1AP_PDU_PR_unsuccessfulOutcome;
@@ -275,11 +266,11 @@ void fill_SETUP_FAILURE(instance_t instance,
   ieC2->value.choice.Cause.choice.radioNetwork = E1AP_CauseRadioNetwork_unspecified;
 }
 
-void e1apCUCP_send_SETUP_FAILURE(instance_t instance,
-                                long transac_id) {
+void e1apCUCP_send_SETUP_FAILURE(e1ap_setup_req_t *setupReq, long transac_id)
+{
   E1AP_E1AP_PDU_t pdu = {0};
-  fill_SETUP_FAILURE(instance, transac_id, &pdu);
-  e1ap_encode_send(CPtype, instance, &pdu, 0, __func__);
+  fill_SETUP_FAILURE(transac_id, &pdu);
+  e1ap_encode_send(CPtype, setupReq, &pdu, 0, __func__);
 }
 
 void extract_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu,
@@ -325,22 +316,18 @@ void extract_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu,
   }
 }
 
-int e1apCUCP_handle_SETUP_REQUEST(instance_t instance,
-                                  const E1AP_E1AP_PDU_t *pdu) {
-
+int e1apCUCP_handle_SETUP_REQUEST(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu)
+{
   DevAssert(pdu != NULL);
-
-  e1ap_setup_req_t *req = &getCxtE1(CPtype, instance)->setupReq;
-
-  extract_SETUP_REQUEST(pdu, req);
+  extract_SETUP_REQUEST(pdu, &inst->setupReq);
   /* Create ITTI message and send to queue */
-  MessageDef *msg_p = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_SETUP_REQ);
-  memcpy(&E1AP_SETUP_REQ(msg_p), req, sizeof(e1ap_setup_req_t));
+  MessageDef *msg_p = itti_alloc_new_message(TASK_CUCP_E1, 0 /*unused by callee*/, E1AP_SETUP_REQ);
+  memcpy(&E1AP_SETUP_REQ(msg_p), &inst->setupReq, sizeof(e1ap_setup_req_t));
 
-  if (req->supported_plmns > 0) {
-    itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p);
+  if (inst->setupReq.supported_plmns > 0) {
+    itti_send_msg_to_task(TASK_RRC_GNB, 0 /*unused by callee*/, msg_p);
   } else {
-    e1apCUCP_send_SETUP_FAILURE(instance, req->transac_id);
+    e1apCUCP_send_SETUP_FAILURE(&inst->setupReq, inst->setupReq.transac_id);
     itti_free(TASK_CUCP_E1, msg_p);
     return -1;
   }
@@ -348,8 +335,8 @@ int e1apCUCP_handle_SETUP_REQUEST(instance_t instance,
   return 0;
 }
 
-int e1apCUUP_handle_SETUP_RESPONSE(instance_t instance,
-                                   const E1AP_E1AP_PDU_t *pdu) {
+int e1apCUUP_handle_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu)
+{
   LOG_D(E1AP, "%s\n", __func__);
   DevAssert(pdu->present == E1AP_E1AP_PDU_PR_successfulOutcome);
   DevAssert(pdu->choice.successfulOutcome->procedureCode  == E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup);
@@ -360,7 +347,7 @@ int e1apCUUP_handle_SETUP_RESPONSE(instance_t instance,
 
   /* transac_id */
   long transaction_id;
-  long old_transaction_id = getCxtE1(UPtype, instance)->setupReq.transac_id;
+  long old_transaction_id = inst->setupReq.transac_id;
   F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupResponseIEs_t, ie, in,
                              E1AP_ProtocolIE_ID_id_TransactionID, true);
   transaction_id = ie->value.choice.TransactionID;
@@ -376,8 +363,8 @@ int e1apCUUP_handle_SETUP_RESPONSE(instance_t instance,
   return 0;
 }
 
-int e1apCUUP_handle_SETUP_FAILURE(instance_t instance,
-                                  const E1AP_E1AP_PDU_t *pdu) {
+int e1apCUUP_handle_SETUP_FAILURE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu)
+{
   E1AP_GNB_CU_UP_E1SetupFailureIEs_t *ie;
   DevAssert(pdu != NULL);
   E1AP_GNB_CU_UP_E1SetupFailure_t *in = &pdu->choice.unsuccessfulOutcome->value.choice.GNB_CU_UP_E1SetupFailure;
@@ -391,7 +378,8 @@ int e1apCUUP_handle_SETUP_FAILURE(instance_t instance,
   return 0;
 }
 
-void fill_CONFIGURATION_UPDATE(E1AP_E1AP_PDU_t *pdu) {
+static void fill_CONFIGURATION_UPDATE(E1AP_E1AP_PDU_t *pdu)
+{
   /* Create */
   /* 0. pdu Type */
   pdu->present = E1AP_E1AP_PDU_PR_initiatingMessage;
@@ -437,30 +425,32 @@ void fill_CONFIGURATION_UPDATE(E1AP_E1AP_PDU_t *pdu) {
     TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &TNLAtoRemove->tNLAssociationTransportLayerAddress.choice.endpoint_IP_Address); // TODO: correct me
   }
 }
-                               
+
 /*
   E1 configuration update: can be sent in both ways, to be refined
 */
 
-void e1apCUUP_send_CONFIGURATION_UPDATE(instance_t instance) {
+void e1apCUUP_send_CONFIGURATION_UPDATE(e1ap_setup_req_t *setupReq)
+{
   E1AP_E1AP_PDU_t pdu = {0};
   fill_CONFIGURATION_UPDATE(&pdu);
-  e1ap_encode_send(UPtype, instance, &pdu, 0, __func__);
+  e1ap_encode_send(UPtype, setupReq, &pdu, 0, __func__);
 }
 
-int e1apCUCP_send_gNB_DU_CONFIGURATION_FAILURE(instance_t instance) {
+int e1apCUCP_send_gNB_DU_CONFIGURATION_FAILURE(e1ap_setup_req_t *setupReq)
+{
   AssertFatal(false,"Not implemented yet\n");
   return -1;
 }
 
-int e1apCUCP_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance) {
+int e1apCUCP_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(e1ap_setup_req_t *setupReq)
+{
   AssertFatal(false,"Not implemented yet\n");
   return -1;
 }
 
-int e1apCUCP_handle_CONFIGURATION_UPDATE(instance_t instance,
-    E1AP_E1AP_PDU_t *pdu) {
-
+int e1apCUCP_handle_CONFIGURATION_UPDATE(e1ap_setup_req_t *setupReq, E1AP_E1AP_PDU_t *pdu)
+{
   /*
   E1AP_GNB_CU_UP_E1SetupRequestIEs_t *ie;
   DevAssert(pdu != NULL);
@@ -471,18 +461,14 @@ int e1apCUCP_handle_CONFIGURATION_UPDATE(instance_t instance,
   return -1;
 }
 
-int e1apCUUP_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
-    uint32_t assoc_id,
-    uint32_t stream,
-    E1AP_E1AP_PDU_t *pdu) {
+int e1apCUUP_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(e1ap_setup_req_t *setupReq, uint32_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu)
+{
   AssertFatal(false,"Not implemented yet\n");
   return -1;
 }
 
-int e1apCUUP_handle_gNB_DU_CONFIGURATION_FAILURE(instance_t instance,
-    uint32_t assoc_id,
-    uint32_t stream,
-    E1AP_E1AP_PDU_t *pdu) {
+int e1apCUUP_handle_gNB_DU_CONFIGURATION_FAILURE(e1ap_setup_req_t *setupReq, uint32_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu)
+{
   AssertFatal(false,"Not implemented yet\n");
   return -1;
 }
@@ -521,17 +507,8 @@ int e1ap_handle_RELEASE_ACKNOWLEDGE(instance_t instance,
   BEARER CONTEXT SETUP REQUEST
 */
 
-int fill_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance,
-                                       e1ap_bearer_setup_req_t *const bearerCxt,
-                                       E1AP_E1AP_PDU_t *pdu) {
-  /* Create */
-  /* 0. pdu Type */
-  e1ap_setup_req_t *setup = &getCxtE1(CPtype, instance)->setupReq;
-  if (!setup) {
-    LOG_E(E1AP, "got send_BEARER_CONTEXT_SETUP_REQUEST on not established instance (%ld)\n", instance);
-    return -1;
-  }
-
+static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_setup_req_t *setup, e1ap_bearer_setup_req_t *const bearerCxt, E1AP_E1AP_PDU_t *pdu)
+{
   pdu->present = E1AP_E1AP_PDU_PR_initiatingMessage;
   asn1cCalloc(pdu->choice.initiatingMessage, msg);
   msg->procedureCode = E1AP_ProcedureCode_id_bearerContextSetup;
@@ -656,20 +633,22 @@ int fill_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance,
   return 0;
 }
 
-void e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance,
-                                                e1ap_bearer_setup_req_t *const bearerCxt) {
-  if (!getCxtE1(CPtype,instance)) {
+void e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance, e1ap_bearer_setup_req_t *const bearerCxt)
+{
+  if (!getCxtE1(instance)) {
     LOG_E(E1AP, "Received a UE bearer to establish while no CU-UP is connected, response on NGAP to send failure is not developped\n");
     // Fixme: add response on NGAP to send failure
     return;
   }
+
   E1AP_E1AP_PDU_t pdu = {0};
-  fill_BEARER_CONTEXT_SETUP_REQUEST(instance, bearerCxt, &pdu);
-  e1ap_encode_send(CPtype, instance, &pdu, 0, __func__);
+  e1ap_setup_req_t *setupReq = &getCxtE1(instance)->setupReq;
+  fill_BEARER_CONTEXT_SETUP_REQUEST(setupReq, bearerCxt, &pdu);
+  e1ap_encode_send(CPtype, setupReq, &pdu, 0, __func__);
 }
 
-void fill_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_bearer_setup_resp_t *const resp,
-                                        E1AP_E1AP_PDU_t *pdu) {
+static void fill_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_bearer_setup_resp_t *const resp, E1AP_E1AP_PDU_t *pdu)
+{
   /* Create */
   /* 0. pdu Type */
   pdu->present = E1AP_E1AP_PDU_PR_successfulOutcome;
@@ -795,11 +774,11 @@ void fill_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_bearer_setup_resp_t *const resp,
   }
 }
 
-void e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance,
-                                                 e1ap_bearer_setup_resp_t *const resp) {
+void e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, e1ap_bearer_setup_resp_t *const resp)
+{
   E1AP_E1AP_PDU_t pdu = {0};
   fill_BEARER_CONTEXT_SETUP_RESPONSE(resp, &pdu);
-  e1ap_encode_send(UPtype, instance, &pdu, 0, __func__);
+  e1ap_encode_send(UPtype, &inst->setupReq, &pdu, 0, __func__);
 }
 
 int e1apCUUP_send_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance) {
@@ -967,14 +946,8 @@ void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu,
 
 }
 
-int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance,
-                                                 const E1AP_E1AP_PDU_t *pdu) {
-  e1ap_upcp_inst_t *e1_inst = getCxtE1(UPtype, instance);
-  if (!e1_inst) {
-    LOG_E(E1AP, "got BEARER_CONTEXT_SETUP_REQUEST on not established instance (%ld)\n", instance);
-    return -1;
-  }
-  
+int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu)
+{
   DevAssert(pdu != NULL);
   DevAssert(pdu->present == E1AP_E1AP_PDU_PR_initiatingMessage);
   DevAssert(pdu->choice.initiatingMessage->procedureCode == E1AP_ProcedureCode_id_bearerContextSetup);
@@ -983,7 +956,7 @@ int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance,
 
   e1ap_bearer_setup_req_t bearerCxt = {0};
   extract_BEARER_CONTEXT_SETUP_REQUEST(pdu, &bearerCxt);
-  CUUP_process_e1_bearer_context_setup_req(&bearerCxt, instance);
+  process_e1_bearer_context_setup_req(e1_inst->instance, &bearerCxt);
   return 0;
 }
 
@@ -1073,8 +1046,8 @@ void extract_BEARER_CONTEXT_SETUP_RESPONSE(const E1AP_E1AP_PDU_t *pdu,
   }
 }
 
-int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance,
-                                                  const E1AP_E1AP_PDU_t *pdu) {
+int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu)
+{
   DevAssert(pdu->present == E1AP_E1AP_PDU_PR_successfulOutcome);
   DevAssert(pdu->choice.successfulOutcome->procedureCode == E1AP_ProcedureCode_id_bearerContextSetup);
   DevAssert(pdu->choice.successfulOutcome->criticality == E1AP_Criticality_reject);
@@ -1083,13 +1056,15 @@ int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance,
   MessageDef *msg = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_BEARER_CONTEXT_SETUP_RESP);
   e1ap_bearer_setup_resp_t *bearerCxt = &E1AP_BEARER_CONTEXT_SETUP_RESP(msg);
   extract_BEARER_CONTEXT_SETUP_RESPONSE(pdu, bearerCxt);
+  // Fixme: instance is the NGAP instance, no good way to set it here
+  instance_t instance = 0;
   itti_send_msg_to_task(TASK_RRC_GNB, instance, msg);
 
   return 0;
 }
 
-int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance,
-                                                 const E1AP_E1AP_PDU_t *pdu) {
+int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu)
+{
   AssertFatal(false,"Not implemented yet\n");
   return -1;
 }
@@ -1098,17 +1073,8 @@ int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance,
   BEARER CONTEXT MODIFICATION REQUEST
 */
 
-int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
-                                             e1ap_bearer_setup_req_t *const bearerCxt,
-                                             E1AP_E1AP_PDU_t *pdu) {
-  /* Create */
-  /* 0. pdu Type */
-  e1ap_setup_req_t *setup = &getCxtE1(CPtype, instance)->setupReq;
-  if (!setup) {
-    LOG_E(E1AP, "got send_BEARER_CONTEXT_MODIFICATION_REQUEST on not established instance (%ld)\n", instance);
-    return -1;
-  }
-
+static int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_setup_req_t *setupReq, e1ap_bearer_setup_req_t *const bearerCxt, E1AP_E1AP_PDU_t *pdu)
+{
   pdu->present = E1AP_E1AP_PDU_PR_initiatingMessage;
   asn1cCalloc(pdu->choice.initiatingMessage, msg);
   msg->procedureCode = E1AP_ProcedureCode_id_bearerContextModification;
@@ -1169,11 +1135,13 @@ int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
   return 0;
 }
 
-void e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
-                                                       e1ap_bearer_setup_req_t *const bearerCxt) {
+static void e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t inst, e1ap_bearer_setup_req_t *const bearerCxt)
+{
+  AssertFatal(getCxtE1(inst), "");
+  e1ap_setup_req_t *setupReq = &getCxtE1(inst)->setupReq;
   E1AP_E1AP_PDU_t pdu = {0};
-  fill_BEARER_CONTEXT_MODIFICATION_REQUEST(instance, bearerCxt, &pdu);
-  e1ap_encode_send(CPtype, instance, &pdu, 0, __func__);
+  fill_BEARER_CONTEXT_MODIFICATION_REQUEST(setupReq, bearerCxt, &pdu);
+  e1ap_encode_send(CPtype, setupReq, &pdu, 0, __func__);
 }
 
 int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) {
@@ -1264,14 +1232,8 @@ void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *pdu,
   }
 }
 
-int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
-                                                        const E1AP_E1AP_PDU_t *pdu) {
-  e1ap_upcp_inst_t *e1_inst = getCxtE1(UPtype, instance);
-  if (!e1_inst) {
-    LOG_E(E1AP, "got BEARER_CONTEXT_MODIFICATION_REQUEST on not established instance (%ld)\n", instance);
-    return -1;
-  }
-  
+int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu)
+{
   DevAssert(pdu != NULL);
   DevAssert(pdu->present == E1AP_E1AP_PDU_PR_initiatingMessage);
   DevAssert(pdu->choice.initiatingMessage->procedureCode == E1AP_ProcedureCode_id_bearerContextModification);
@@ -1280,7 +1242,7 @@ int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
 
   e1ap_bearer_setup_req_t bearerCxt = {0};
   extract_BEARER_CONTEXT_MODIFICATION_REQUEST(pdu, &bearerCxt);
-  CUUP_process_bearer_context_mod_req(&bearerCxt, instance);
+  CUUP_process_bearer_context_mod_req(e1_inst->instance, &bearerCxt);
   return 0;
 }
 
@@ -1329,16 +1291,8 @@ int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_CONFIRM(instance_t instance,
   BEARER CONTEXT RELEASE
 */
 
-int fill_BEARER_CONTEXT_RELEASE_COMMAND(instance_t instance,
-                                        e1ap_bearer_release_cmd_t *const cmd,
-                                        E1AP_E1AP_PDU_t *pdu) {
-
-  e1ap_setup_req_t *setup = &getCxtE1(CPtype, instance)->setupReq;
-  if (!setup) {
-    LOG_E(E1AP, "got send_BEARER_CONTEXT_RELEASE_COMMAND on not established instance (%ld)\n", instance);
-    return -1;
-  }
-
+static int fill_BEARER_CONTEXT_RELEASE_COMMAND(e1ap_setup_req_t *setupReq, e1ap_bearer_release_cmd_t *const cmd, E1AP_E1AP_PDU_t *pdu)
+{
   pdu->present = E1AP_E1AP_PDU_PR_initiatingMessage;
   asn1cCalloc(pdu->choice.initiatingMessage, msg);
   msg->procedureCode = E1AP_ProcedureCode_id_bearerContextRelease;
@@ -1363,23 +1317,15 @@ int fill_BEARER_CONTEXT_RELEASE_COMMAND(instance_t instance,
   return 0;
 }
 
-int e1apCUCP_send_BEARER_CONTEXT_RELEASE_COMMAND(instance_t instance,
-                                                 e1ap_bearer_release_cmd_t *const cmd) {
+int e1apCUCP_send_BEARER_CONTEXT_RELEASE_COMMAND(e1ap_setup_req_t *setupReq, e1ap_bearer_release_cmd_t *const cmd)
+{
   E1AP_E1AP_PDU_t pdu = {0};
-  fill_BEARER_CONTEXT_RELEASE_COMMAND(instance, cmd, &pdu);
-  return e1ap_encode_send(CPtype, instance, &pdu, 0, __func__);
+  fill_BEARER_CONTEXT_RELEASE_COMMAND(setupReq, cmd, &pdu);
+  return e1ap_encode_send(CPtype, setupReq, &pdu, 0, __func__);
 }
 
-int fill_BEARER_CONTEXT_RELEASE_COMPLETE(instance_t instance,
-                                         e1ap_bearer_release_cmd_t *const cmd,
-                                         E1AP_E1AP_PDU_t *pdu) {
-
-  e1ap_setup_req_t *setup = &getCxtE1(CPtype, instance)->setupReq;
-  if (!setup) {
-    LOG_E(E1AP, "got send_BEARER_CONTEXT_RELEASE_COMPLETE on not established instance (%ld)\n", instance);
-    return -1;
-  }
-
+int fill_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_setup_req_t *setupReq, e1ap_bearer_release_cmd_t *const cmd, E1AP_E1AP_PDU_t *pdu)
+{
   pdu->present = E1AP_E1AP_PDU_PR_successfulOutcome;
   asn1cCalloc(pdu->choice.successfulOutcome, msg);
   msg->procedureCode = E1AP_ProcedureCode_id_bearerContextRelease;
@@ -1404,10 +1350,11 @@ int fill_BEARER_CONTEXT_RELEASE_COMPLETE(instance_t instance,
   return 0;
 }
 
-int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(instance_t instance, e1ap_bearer_release_cmd_t *const cmd) {
+int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_upcp_inst_t *inst, e1ap_bearer_release_cmd_t *const cmd)
+{
   E1AP_E1AP_PDU_t pdu = {0};
-  fill_BEARER_CONTEXT_RELEASE_COMPLETE(instance, cmd, &pdu);
-  return e1ap_encode_send(CPtype, instance, &pdu, 0, __func__);
+  fill_BEARER_CONTEXT_RELEASE_COMPLETE(&inst->setupReq, cmd, &pdu);
+  return e1ap_encode_send(CPtype, &inst->setupReq, &pdu, 0, __func__);
 }
 
 int e1apCUUP_send_BEARER_CONTEXT_RELEASE_REQUEST(instance_t instance) {
@@ -1454,14 +1401,8 @@ void extract_BEARER_CONTEXT_RELEASE_COMMAND(const E1AP_E1AP_PDU_t *pdu,
   }
 }
 
-int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(instance_t instance,
-                                                   const E1AP_E1AP_PDU_t *pdu) {
-  e1ap_upcp_inst_t *e1_inst = getCxtE1(UPtype, instance);
-  if (!e1_inst) {
-    LOG_E(E1AP, "got BEARER_CONTEXT_RELEASE_COMMAND on not established instance (%ld)\n", instance);
-    return -1;
-  }
-  
+int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu)
+{
   DevAssert(pdu != NULL);
   DevAssert(pdu->present == E1AP_E1AP_PDU_PR_initiatingMessage);
   DevAssert(pdu->choice.initiatingMessage->procedureCode == E1AP_ProcedureCode_id_bearerContextRelease);
@@ -1470,7 +1411,7 @@ int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(instance_t instance,
 
   e1ap_bearer_release_cmd_t bearerCxt = {0};
   extract_BEARER_CONTEXT_RELEASE_COMMAND(pdu, &bearerCxt);
-  CUUP_process_bearer_release_command(&bearerCxt, instance);
+  CUUP_process_bearer_release_command(e1_inst->instance, &bearerCxt);
   return 0;
 }
 
@@ -1504,14 +1445,8 @@ void extract_BEARER_CONTEXT_RELEASE_COMPLETE(const E1AP_E1AP_PDU_t *pdu,
   }
 }
 
-int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE(instance_t instance,
-                                                    const E1AP_E1AP_PDU_t *pdu) {
-  e1ap_upcp_inst_t *e1_inst = getCxtE1(UPtype, instance);
-  if (!e1_inst) {
-    LOG_E(E1AP, "got BEARER_CONTEXT_RELEASE_COMPLETE on not established instance (%ld)\n", instance);
-    return -1;
-  }
-  
+int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu)
+{
   DevAssert(pdu != NULL);
   DevAssert(pdu->present == E1AP_E1AP_PDU_PR_successfulOutcome);
   DevAssert(pdu->choice.successfulOutcome->procedureCode == E1AP_ProcedureCode_id_bearerContextRelease);
@@ -1585,10 +1520,11 @@ static instance_t cuup_task_create_gtpu_instance_to_du(eth_params_t *IPaddrs) {
   return gtpv1Init(tmp);
 }
 
-void cuup_task_send_sctp_association_req(instance_t instance, e1ap_setup_req_t *e1ap_setup_req) {
+void e1_task_send_sctp_association_req(long task_id, instance_t instance, e1ap_setup_req_t *e1ap_setup_req)
+{
   DevAssert(e1ap_setup_req != NULL);
-  getCxtE1(UPtype, instance)->sockState = SCTP_STATE_CLOSED;
-  MessageDef *message_p = itti_alloc_new_message(TASK_CUUP_E1, 0, SCTP_NEW_ASSOCIATION_REQ);
+  getCxtE1(instance)->sockState = SCTP_STATE_CLOSED;
+  MessageDef *message_p = itti_alloc_new_message(task_id, 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;
@@ -1602,15 +1538,17 @@ void cuup_task_send_sctp_association_req(instance_t instance, e1ap_setup_req_t *
   itti_send_msg_to_task(TASK_SCTP, instance, message_p);
 }
 
-void e1apCUUP_send_SETUP_REQUEST(instance_t instance) {
+static void e1apCUUP_send_SETUP_REQUEST(e1ap_setup_req_t *setup)
+{
   E1AP_E1AP_PDU_t pdu = {0};
-  fill_SETUP_REQUEST(instance, &pdu);
-  e1ap_encode_send(UPtype, instance, &pdu, 0, __func__);
+  fill_SETUP_REQUEST(setup, &pdu);
+  e1ap_encode_send(UPtype, setup, &pdu, 0, __func__);
 }
-  
-void cuup_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) {
+
+static void e1_task_handle_sctp_association_resp(E1_t type, 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;
+  getCxtE1(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,
@@ -1621,28 +1559,35 @@ void cuup_task_handle_sctp_association_resp(instance_t instance, sctp_new_associ
     return;
   }
 
-  e1ap_setup_req_t *e1ap_cuup_setup_req       = &getCxtE1(UPtype, instance)->setupReq;
-  e1ap_cuup_setup_req->assoc_id               = sctp_new_association_resp->assoc_id;
-  e1ap_cuup_setup_req->sctp_in_streams        = sctp_new_association_resp->in_streams;
-  e1ap_cuup_setup_req->sctp_out_streams       = sctp_new_association_resp->out_streams;
-  e1ap_cuup_setup_req->default_sctp_stream_id = 0;
-
-  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;
-  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;
-
-  if (getCxtE1(UPtype, instance)->gtpInstN3 < 0)
-    getCxtE1(UPtype, instance)->gtpInstN3 = RCconfig_nr_gtpu();
-  if (getCxtE1(UPtype, instance)->gtpInstN3 < 0)
+  if (type == UPtype) {
+    e1ap_setup_req_t *e1ap_cuup_setup_req = &getCxtE1(instance)->setupReq;
+    e1ap_cuup_setup_req->assoc_id = sctp_new_association_resp->assoc_id;
+    e1ap_cuup_setup_req->sctp_in_streams = sctp_new_association_resp->in_streams;
+    e1ap_cuup_setup_req->sctp_out_streams = sctp_new_association_resp->out_streams;
+    e1ap_cuup_setup_req->default_sctp_stream_id = 0;
+
+    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;
+    if (getCxtE1(instance)->gtpInstF1U < 0)
+      getCxtE1(instance)->gtpInstF1U = cuup_task_create_gtpu_instance_to_du(&IPaddr);
+    if (getCxtE1(instance)->gtpInstF1U < 0)
+      LOG_E(E1AP, "Failed to create CUUP F1-U UDP listener");
+    extern instance_t CUuniqInstance;
+    CUuniqInstance = getCxtE1(instance)->gtpInstF1U;
+    cuup_init_n3(instance);
+    e1apCUUP_send_SETUP_REQUEST(&getCxtE1(instance)->setupReq);
+  }
+}
+
+void cuup_init_n3(instance_t instance)
+{
+  if (getCxtE1(instance)->gtpInstN3 < 0)
+    getCxtE1(instance)->gtpInstN3 = RCconfig_nr_gtpu();
+  if (getCxtE1(instance)->gtpInstN3 < 0)
     LOG_E(E1AP, "Failed to create CUUP N3 UDP listener");
-  N3GTPUInst = &getCxtE1(UPtype, instance)->gtpInstN3;
-  e1apCUUP_send_SETUP_REQUEST(instance);
+  extern instance_t *N3GTPUInst;
+  N3GTPUInst = &getCxtE1(instance)->gtpInstN3;
 }
 
 void cucp_task_send_sctp_init_req(instance_t instance, char *my_addr) {
@@ -1664,36 +1609,26 @@ 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_ind)
+void e1_task_handle_sctp_association_ind(E1_t type, 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;
+  if (getCxtE1(instance))
+    LOG_W(E1AP, "CUCP incoming call, re-use older socket context, finish implementation required\n");
+  else
+    createE1inst(type, instance, NULL);
+  getCxtE1(instance)->sockState = SCTP_STATE_ESTABLISHED;
+  getCxtE1(instance)->incoming_sock = true;
+  e1ap_setup_req_t *setup_req = &getCxtE1(instance)->setupReq;
   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);
+  if (getCxtE1(myInstance)->sockState != SCTP_STATE_ESTABLISHED)
+    e1_task_send_sctp_association_req(TASK_CUUP_E1, myInstance, &getCxtE1(myInstance)->setupReq);
 }
 
 void *E1AP_CUCP_task(void *arg) {
@@ -1710,13 +1645,11 @@ void *E1AP_CUCP_task(void *arg) {
 
     switch (ITTI_MSG_ID(msg)) {
       case SCTP_NEW_ASSOCIATION_IND:
-        cucp_task_handle_sctp_association_ind(ITTI_MSG_ORIGIN_INSTANCE(msg),
-                                              &msg->ittiMsg.sctp_new_association_ind);
+        e1_task_handle_sctp_association_ind(CPtype, ITTI_MSG_ORIGIN_INSTANCE(msg), &msg->ittiMsg.sctp_new_association_ind);
         break;
 
       case SCTP_NEW_ASSOCIATION_RESP:
-        cucp_task_handle_sctp_association_resp(ITTI_MSG_ORIGIN_INSTANCE(msg),
-                                               &msg->ittiMsg.sctp_new_association_resp);
+        e1_task_handle_sctp_association_resp(CPtype, ITTI_MSG_ORIGIN_INSTANCE(msg), &msg->ittiMsg.sctp_new_association_resp);
         break;
 
       case E1AP_SETUP_REQ: {
@@ -1732,11 +1665,11 @@ void *E1AP_CUCP_task(void *arg) {
       } break;
 
       case SCTP_DATA_IND:
-        cuxp_task_handle_sctp_data_ind(myInstance, &msg->ittiMsg.sctp_data_ind);
+        e1_task_handle_sctp_data_ind(myInstance, &msg->ittiMsg.sctp_data_ind);
         break;
 
       case E1AP_SETUP_RESP:
-        e1apCUCP_send_SETUP_RESPONSE(myInstance, &E1AP_SETUP_RESP(msg));
+        e1ap_send_SETUP_RESPONSE(myInstance, &E1AP_SETUP_RESP(msg));
         break;
 
       case E1AP_BEARER_CONTEXT_SETUP_REQ:
@@ -1776,15 +1709,15 @@ void *E1AP_CUUP_task(void *arg) {
         e1ap_setup_req_t *msgSetup = &E1AP_SETUP_REQ(msg);
         createE1inst(UPtype, myInstance, msgSetup);
 
-        cuup_task_send_sctp_association_req(myInstance, msgSetup);
+        e1_task_send_sctp_association_req(TASK_CUUP_E1, myInstance, msgSetup);
       } break;
 
       case SCTP_NEW_ASSOCIATION_RESP:
-        cuup_task_handle_sctp_association_resp(myInstance, &msg->ittiMsg.sctp_new_association_resp);
+        e1_task_handle_sctp_association_resp(UPtype, myInstance, &msg->ittiMsg.sctp_new_association_resp);
         break;
 
       case SCTP_DATA_IND:
-        cuxp_task_handle_sctp_data_ind(myInstance, &msg->ittiMsg.sctp_data_ind);
+        e1_task_handle_sctp_data_ind(myInstance, &msg->ittiMsg.sctp_data_ind);
         break;
 
       case TIMER_HAS_EXPIRED:
diff --git a/openair2/E1AP/e1ap.h b/openair2/E1AP/e1ap.h
index 7e3abe8fb46c5f60621eba582da668d18d9bc08b..af1dcae3632ed13e9f44854914747376e3485a8f 100644
--- a/openair2/E1AP/e1ap.h
+++ b/openair2/E1AP/e1ap.h
@@ -26,42 +26,31 @@
 
 #include "openair2/COMMON/e1ap_messages_types.h"
 #include "e1ap_asnc.h"
+#include "openair2/E1AP/e1ap_common.h"
 
-#endif
-
+int e1apCUCP_handle_SETUP_REQUEST(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu);
 
-int e1apCUCP_handle_SETUP_REQUEST(instance_t instance,
-                                  const E1AP_E1AP_PDU_t *pdu);
+int e1apCUUP_handle_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu);
 
-int e1apCUUP_handle_SETUP_RESPONSE(instance_t instance,
-                                   const E1AP_E1AP_PDU_t *pdu);
+int e1apCUUP_handle_SETUP_FAILURE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu);
 
-int e1apCUUP_handle_SETUP_FAILURE(instance_t instance,
-                                  const E1AP_E1AP_PDU_t *pdu);
+int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu);
 
-int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance,
-                                                 const E1AP_E1AP_PDU_t *pdu);
+int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu);
 
-int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance,
-                                                  const E1AP_E1AP_PDU_t *pdu);
+int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu);
 
-int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance,
-                                                 const E1AP_E1AP_PDU_t *pdu);
+int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu);
 
-int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
-                                                        const E1AP_E1AP_PDU_t *pdu);
+void e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, e1ap_bearer_setup_resp_t *const resp);
 
-void e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance,
-                                                 e1ap_bearer_setup_resp_t *const resp);
+int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu);
 
-int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(instance_t instance,
-                                                   const E1AP_E1AP_PDU_t *pdu);
+int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu);
 
-int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE(instance_t instance,
-                                                    const E1AP_E1AP_PDU_t *pdu);
-
-int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(instance_t instance, e1ap_bearer_release_cmd_t *const cmd);
+int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_upcp_inst_t *inst, e1ap_bearer_release_cmd_t *const cmd);
 
 void *E1AP_CUUP_task(void *arg);
 
 void *E1AP_CUCP_task(void *arg);
+#endif
diff --git a/openair2/E1AP/e1ap_api.c b/openair2/E1AP/e1ap_api.c
index 37d8e289d326e6cbed92885020c73584cd87209c..a2362f133fc7e3dc6efffa7acb5fb54272fce858 100644
--- a/openair2/E1AP/e1ap_api.c
+++ b/openair2/E1AP/e1ap_api.c
@@ -44,41 +44,33 @@ static void fill_DRB_configList_e1(NR_DRB_ToAddModList_t *DRB_configList, pdu_se
     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;
+    asn1cCalloc(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));
+    asn1cCalloc(sdap_config->mappedQoS_FlowsToAdd, FlowsToAdd);
     for (int j=0; j < drb->numQosFlow2Setup; j++) {
-      NR_QFI_t *qfi = calloc(1, sizeof(NR_QFI_t));
+      asn1cSequenceAdd(FlowsToAdd->list, NR_QFI_t, qfi);
       *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;
+    asn1cCalloc(ie->pdcp_Config, pdcp_config);
+    asn1cCalloc(pdcp_config->drb, drbCfg);
+    asn1cCallocOne(drbCfg->discardTimer, drb->discardTimer);
+    asn1cCallocOne(drbCfg->pdcp_SN_SizeUL, drb->pDCP_SN_Size_UL);
+    asn1cCallocOne(drbCfg->pdcp_SN_SizeDL, drb->pDCP_SN_Size_DL);
+    drbCfg->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
+    drbCfg->headerCompression.choice.notUsed = 0;
+
+    drbCfg->integrityProtection = NULL;
+    drbCfg->statusReportRequired = NULL;
+    drbCfg->outOfOrderDelivery = NULL;
     pdcp_config->moreThanOneRLC = NULL;
 
     pdcp_config->t_Reordering = calloc(1, sizeof(*pdcp_config->t_Reordering));
@@ -87,15 +79,13 @@ static void fill_DRB_configList_e1(NR_DRB_ToAddModList_t *DRB_configList, pdu_se
 
     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;
+      asn1cCallocOne(drbCfg->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;
+      asn1cCalloc(pdcp_config->ext1, ext1);
+      asn1cCallocOne(ext1->cipheringDisabled, NR_PDCP_Config__ext1__cipheringDisabled_true);
     }
   }
 }
@@ -135,13 +125,9 @@ static int drb_config_N3gtpu_create(e1ap_bearer_setup_req_t * const req,
   uint8_t *kUPenc = NULL;
   uint8_t *kUPint = NULL;
 
-  nr_derive_key_up_enc(req->cipheringAlgorithm,
-                       (uint8_t *)req->encryptionKey,
-                       &kUPenc);
+  nr_derive_key(UP_ENC_ALG, req->cipheringAlgorithm, (uint8_t *)req->encryptionKey, &kUPenc);
 
-  nr_derive_key_up_int(req->integrityProtectionAlgorithm,
-                       (uint8_t *)req->integrityProtectionKey,
-                       &kUPint);
+  nr_derive_key(UP_INT_ALG, 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,
@@ -152,35 +138,32 @@ static int drb_config_N3gtpu_create(e1ap_bearer_setup_req_t * const req,
   return ret;
 }
 
-void CUUP_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *const req, instance_t instance) {
-
+void process_e1_bearer_context_setup_req(instance_t instance, e1ap_bearer_setup_req_t *const req)
+{
+  e1ap_upcp_inst_t *inst = getCxtE1(instance);
+  AssertFatal(inst, "");
   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);
+  drb_config_N3gtpu_create(req, &create_tunnel_resp_N3, inst->gtpInstN3);
 
-  e1ap_bearer_setup_resp_t resp = {0};
+  MessageDef *msg = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_BEARER_CONTEXT_SETUP_RESP);
+  e1ap_bearer_setup_resp_t *resp = &E1AP_BEARER_CONTEXT_SETUP_RESP(msg);
 
-  int remote_port = getCxtE1(UPtype, instance)->setupReq.remoteDUPort;
+  int remote_port = inst->setupReq.remoteDUPort;
   in_addr_t my_addr;
-  inet_pton(AF_INET,
-            getCxtE1(UPtype, instance)->setupReq.CUUP_e1_ip_address.ipv4_address,
-            &my_addr);
+  inet_pton(AF_INET, inst->setupReq.CUUP_e1_ip_address.ipv4_address, &my_addr);
 
-  gtpInst = getCxtE1(UPtype, instance)->gtpInstF1U;
-  fill_e1ap_bearer_setup_resp(&resp, req, gtpInst, req->gNB_cu_cp_ue_id, remote_port, my_addr);
+  fill_e1ap_bearer_setup_resp(resp, req, inst->gtpInstF1U, 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;
+  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_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));
+    memcpy(&pduSetup->tlAddress, &inst->setupReq.IPv4AddressN3, sizeof(in_addr_t));
     pduSetup->teId = create_tunnel_resp_N3.gnb_NGu_teid[i];
     pduSetup->numDRBSetup = pdu2Setup->numDRB2Setup;
 
@@ -190,21 +173,23 @@ void CUUP_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *const req
     pduSetup->numDRBFailed = 0;
   }
 
-  e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(instance, &resp);
+  e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(inst, resp);
 }
 
-void CUUP_process_bearer_context_mod_req(e1ap_bearer_setup_req_t *const req, instance_t instance) {
-  instance_t gtpInst = getCxtE1(UPtype, instance)->gtpInstF1U;
-  CU_update_UP_DL_tunnel(req, gtpInst, req->gNB_cu_cp_ue_id);
+void CUUP_process_bearer_context_mod_req(instance_t instance, e1ap_bearer_setup_req_t *const req)
+{
+  e1ap_upcp_inst_t *inst = getCxtE1(instance);
+  AssertFatal(inst, "");
+  // assume we receive modification of F1-U but it is wrong, we can also get modification of N3 when HO will occur
+  CU_update_UP_DL_tunnel(req, inst->gtpInstF1U, req->gNB_cu_cp_ue_id);
   // TODO: send bearer cxt mod response
 }
 
-void CUUP_process_bearer_release_command(e1ap_bearer_release_cmd_t *const cmd, instance_t instance) {
-  instance_t gtpInst = getCxtE1(UPtype, instance)->gtpInstN3;
-  newGtpuDeleteAllTunnels(gtpInst, cmd->gNB_cu_up_ue_id);
-  gtpInst = getCxtE1(UPtype, instance)->gtpInstF1U;
-  newGtpuDeleteAllTunnels(gtpInst, cmd->gNB_cu_up_ue_id);
-
-  e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(instance, cmd);
+void CUUP_process_bearer_release_command(instance_t instance, e1ap_bearer_release_cmd_t *const cmd)
+{
+  e1ap_upcp_inst_t *inst = getCxtE1(instance);
+  AssertFatal(inst, "");
+  newGtpuDeleteAllTunnels(inst->gtpInstN3, cmd->gNB_cu_up_ue_id);
+  newGtpuDeleteAllTunnels(inst->gtpInstF1U, cmd->gNB_cu_up_ue_id);
+  e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(inst, cmd);
 }
-
diff --git a/openair2/E1AP/e1ap_api.h b/openair2/E1AP/e1ap_api.h
index 64cfce44200ecc28869e389e9f438fd04e222833..1b9f219fcc347f7bc08a351c9f76c76d99038ea5 100644
--- a/openair2/E1AP/e1ap_api.h
+++ b/openair2/E1AP/e1ap_api.h
@@ -26,10 +26,10 @@
 
 #include "platform_types.h"
 #include "openair2/COMMON/e1ap_messages_types.h"
+#include "openair2/E1AP/e1ap_common.h"
+void cuup_init_n3(instance_t instance);
+void process_e1_bearer_context_setup_req(instance_t, e1ap_bearer_setup_req_t *const req);
+void CUUP_process_bearer_context_mod_req(instance_t, e1ap_bearer_setup_req_t *const req);
 
-void CUUP_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *const req, instance_t instance);
-
-void CUUP_process_bearer_context_mod_req(e1ap_bearer_setup_req_t *const req, instance_t instance);
-
-void CUUP_process_bearer_release_command(e1ap_bearer_release_cmd_t *const cmd, instance_t instance);
+void CUUP_process_bearer_release_command(instance_t, e1ap_bearer_release_cmd_t *const cmd);
 #endif
diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c
index 12ab9af5e2246b52248593688da735bca6ad6855..a826e5089497c0c46c44f266b161cea66e46a73a 100644
--- a/openair2/E1AP/e1ap_common.c
+++ b/openair2/E1AP/e1ap_common.c
@@ -29,40 +29,28 @@
 #include "common/openairinterface5g_limits.h"
 #include "common/utils/ocp_itti/intertask_interface.h"
 
-static e1ap_upcp_inst_t *e1ap_cp_inst[NUMBER_OF_gNB_MAX] = {0};
-static e1ap_upcp_inst_t *e1ap_up_inst[NUMBER_OF_gNB_MAX] = {0};
+static e1ap_upcp_inst_t *e1ap_inst[NUMBER_OF_gNB_MAX] = {0};
 
-e1ap_upcp_inst_t *getCxtE1(E1_t type, instance_t instance) {
-  AssertFatal( instance < sizeofArray(e1ap_cp_inst), "instance exceeds limit\n");
-  return type == UPtype ? e1ap_up_inst[instance] : e1ap_cp_inst[instance];
+e1ap_upcp_inst_t *getCxtE1(instance_t instance)
+{
+  AssertFatal(instance < sizeofArray(e1ap_inst), "instance exceeds limit\n");
+  return e1ap_inst[instance];
 }
 
 int e1ap_assoc_id(E1_t type, instance_t instance) {
-  if (type == CPtype) {
-    AssertFatal(e1ap_cp_inst[instance] != NULL, "Trying to access uninitiated instance of CUCP\n");
-    return e1ap_cp_inst[instance]->setupReq.assoc_id;
-  } else if (type == UPtype) {
-    AssertFatal(e1ap_up_inst[instance] != NULL, "Trying to access uninitiated instance of CUUP\n");
-    return e1ap_up_inst[instance]->setupReq.assoc_id;
-  } else {
-    AssertFatal(false, "Unknown CU type\n");
-  }
-  return -1;
+  AssertFatal(e1ap_inst[instance] != NULL, "Trying to access uninitiated instance of CUCP\n");
+  return e1ap_inst[instance]->setupReq.assoc_id;
 }
 
 void createE1inst(E1_t type, instance_t instance, e1ap_setup_req_t *req) {
-  if (type == CPtype) {
-    AssertFatal(e1ap_cp_inst[instance] == NULL, "Double call to E1 CP instance %d\n", (int)instance);
-    e1ap_cp_inst[instance] = (e1ap_upcp_inst_t *) calloc(1, sizeof(e1ap_upcp_inst_t));
-  } else if (type == UPtype) {
-    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 = -1;
-    e1ap_up_inst[instance]->gtpInstF1U = -1;
-  } else {
-    AssertFatal(false, "Unknown CU type\n");
-  }
+  AssertFatal(e1ap_inst[instance] == NULL, "Double call to E1 instance %d\n", (int)instance);
+  e1ap_inst[instance] = calloc(1, sizeof(e1ap_upcp_inst_t));
+  e1ap_inst[instance]->type = type;
+  e1ap_inst[instance]->instance = instance;
+  if (req)
+    memcpy(&e1ap_inst[instance]->setupReq, req, sizeof(*req));
+  e1ap_inst[instance]->gtpInstN3 = -1;
+  e1ap_inst[instance]->gtpInstF1U = -1;
 }
 
 E1AP_TransactionID_t transacID[E1AP_MAX_NUM_TRANSAC_IDS] = {0}; 
@@ -207,7 +195,8 @@ int e1ap_decode_pdu(E1AP_E1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t
   return -1;
 }
 
-int e1ap_encode_send(E1_t type, instance_t instance, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func) {
+int e1ap_encode_send(E1_t type, e1ap_setup_req_t *setupReq, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func)
+{
   DevAssert(pdu != NULL);
 
   if (asn1_xer_print) {
@@ -234,14 +223,13 @@ int e1ap_encode_send(E1_t type, instance_t instance, E1AP_E1AP_PDU_t *pdu, uint1
   } else {
     MessageDef *message = itti_alloc_new_message((type==CPtype)?TASK_CUCP_E1:TASK_CUUP_E1, 0, SCTP_DATA_REQ);
     sctp_data_req_t *s = &message->ittiMsg.sctp_data_req;
-    s->assoc_id      = e1ap_assoc_id(type, instance);
+    s->assoc_id = setupReq->assoc_id;
     s->buffer        = buffer;
     s->buffer_length = encoded;
     s->stream        = stream;
     LOG_I(E1AP, "%s: Sending ITTI message to SCTP Task\n", func);
-    itti_send_msg_to_task(TASK_SCTP, instance, message);
+    itti_send_msg_to_task(TASK_SCTP, 0 /*unused by callee*/, message);
   }
 
   return encoded;
 }
-
diff --git a/openair2/E1AP/e1ap_common.h b/openair2/E1AP/e1ap_common.h
index 1fe60c82510415b9f06b0bd10771cde2971b217e..80a2b925e106b64a479fafccf21b31ff5ee78e7a 100644
--- a/openair2/E1AP/e1ap_common.h
+++ b/openair2/E1AP/e1ap_common.h
@@ -26,8 +26,13 @@
 #include "openair2/COMMON/e1ap_messages_types.h"
 #include "e1ap_asnc.h"
 #include "openair2/COMMON/sctp_messages_types.h"
+#include "common/ngran_types.h"
 
 typedef struct e1ap_upcp_inst_s {
+  bool incoming_sock;
+  instance_t instance;
+  bool same_process;
+  E1_t type;
   enum sctp_state_e sockState;
   uint32_t assoc_id;
   instance_t gtpInstN3;
@@ -37,13 +42,11 @@ typedef struct e1ap_upcp_inst_s {
   e1ap_bearer_setup_resp_t bearerSetupResp;
 } e1ap_upcp_inst_t;
 
-typedef enum { CPtype = 0, UPtype } E1_t;
-
 extern int asn1_xer_print;
 
 int e1ap_decode_pdu(E1AP_E1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length);
 
-e1ap_upcp_inst_t *getCxtE1(E1_t type, instance_t instance);
+e1ap_upcp_inst_t *getCxtE1(instance_t instance);
 
 E1AP_TransactionID_t E1AP_get_next_transaction_identifier();
 
@@ -53,7 +56,7 @@ bool check_transac_id(E1AP_TransactionID_t id, int *freeIdx);
 
 int e1ap_assoc_id(E1_t type, instance_t instance);
 
-int e1ap_encode_send(E1_t type, instance_t instance, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func);
+int e1ap_encode_send(E1_t type, e1ap_setup_req_t *setupReq, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func);
 
 void e1ap_common_init();
 
diff --git a/openair2/E1AP/e1ap_setup.c b/openair2/E1AP/e1ap_setup.c
index 5845315ca7b387119d9a5b08df84e16f63bc5344..9eba53e48f9d9fe541975e5329d9e90ab1738f0b 100644
--- a/openair2/E1AP/e1ap_setup.c
+++ b/openair2/E1AP/e1ap_setup.c
@@ -30,7 +30,7 @@
 #include "openair2/GNB_APP/gnb_paramdef.h"
 #include "openair3/ocp-gtpu/gtp_itf.h"
 
-MessageDef *RCconfig_NR_CU_E1(void)
+MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process)
 {
   MessageDef *msgConfig = itti_alloc_new_message(TASK_GNB_APP, 0, E1AP_SETUP_REQ);
   if (!msgConfig)
@@ -73,21 +73,23 @@ MessageDef *RCconfig_NR_CU_E1(void)
       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
+    if (separate_CUUP_process) {
+      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
+      e1Setup->cn_support = *GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_CN_SUPPORT].uptr;
+    }
+
     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/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c
index 4cb3156e22c86147e6cf11d32d6e940c9229dd3c..c11316e19b6bec3583838d1969684c015f9cea77 100644
--- a/openair2/F1AP/f1ap_du_task.c
+++ b/openair2/F1AP/f1ap_du_task.c
@@ -110,15 +110,15 @@ void *F1AP_DU_task(void *arg) {
     LOG_I(F1AP, "DU Task Received %s for instance %ld\n",
           ITTI_MSG_NAME(msg),myInstance);
     switch (ITTI_MSG_ID(msg)) {
-      case F1AP_SETUP_REQ:
+      case F1AP_SETUP_REQ: {
         // this is not a true F1 message, but rather an ITTI message sent by enb_app
         // 1. save the itti msg so that you can use it to sen f1ap_setup_req, fill the f1ap_setup_req message,
         // 2. store the message in f1ap context, that is also stored in RC
         // 2. send a sctp_association req
-        f1ap_setup_req_t *msgSetup=&F1AP_SETUP_REQ(msg);
+        f1ap_setup_req_t *msgSetup = &F1AP_SETUP_REQ(msg);
         createF1inst(false, myInstance, msgSetup);
-        du_task_send_sctp_association_req(myInstance,msgSetup);
-        break;
+        du_task_send_sctp_association_req(myInstance, msgSetup);
+      } break;
 
       case F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE:
         DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(ITTI_MSG_ORIGIN_INSTANCE(msg),
@@ -144,14 +144,10 @@ void *F1AP_DU_task(void *arg) {
         break;
 
       case F1AP_INITIAL_UL_RRC_MESSAGE: // from rrc
+      {
         f1ap_initial_ul_rrc_message_t *msgRrc = &F1AP_INITIAL_UL_RRC_MESSAGE(msg);
-        DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(0,0,0,msgRrc->crnti,
-                                                msgRrc->rrc_container,
-                                                msgRrc->rrc_container_length,
-                                                msgRrc->du2cu_rrc_container,
-                                                msgRrc->du2cu_rrc_container_length
-                                               );
-        break;
+        DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(0, 0, 0, msgRrc->crnti, msgRrc->rrc_container, msgRrc->rrc_container_length, msgRrc->du2cu_rrc_container, msgRrc->du2cu_rrc_container_length);
+      } break;
 
       case F1AP_UL_RRC_MESSAGE: // to rrc
         if (RC.nrrrc && RC.nrrrc[0]->node_type == ngran_gNB_DU) {
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
index 3842d43421e9d8743801d49a74c144e5e8e6fdc6..8ff9b2adc7f5f887a11faab50b9fd8d974fc3ef3 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
@@ -1061,35 +1061,30 @@ void nr_DRB_preconfiguration(ue_id_t crntiMaybeUEid)
   drb_ToAddMod->reestablishPDCP = NULL;
   drb_ToAddMod->recoverPDCP = NULL;
   drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config));
-  drb_ToAddMod->pdcp_Config->drb = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb));
-  drb_ToAddMod->pdcp_Config->drb->discardTimer = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->discardTimer));
-  *drb_ToAddMod->pdcp_Config->drb->discardTimer=NR_PDCP_Config__drb__discardTimer_infinity;
-  drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL));
-  *drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
-  drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL));
-  *drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
-  drb_ToAddMod->pdcp_Config->drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
-  drb_ToAddMod->pdcp_Config->drb->headerCompression.choice.notUsed = 0;
-
-  drb_ToAddMod->pdcp_Config->drb->integrityProtection=NULL;
-  drb_ToAddMod->pdcp_Config->drb->statusReportRequired=NULL;
-  drb_ToAddMod->pdcp_Config->drb->outOfOrderDelivery=NULL;
+  asn1cCalloc(drb_ToAddMod->pdcp_Config->drb, drb);
+  asn1cCallocOne(drb->discardTimer, NR_PDCP_Config__drb__discardTimer_infinity);
+  asn1cCallocOne(drb->pdcp_SN_SizeUL, NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits);
+  asn1cCallocOne(drb->pdcp_SN_SizeDL, NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits);
+  drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
+  drb->headerCompression.choice.notUsed = 0;
+
+  drb->integrityProtection = NULL;
+  drb->statusReportRequired = NULL;
+  drb->outOfOrderDelivery = NULL;
   drb_ToAddMod->pdcp_Config->moreThanOneRLC = NULL;
 
-  drb_ToAddMod->pdcp_Config->t_Reordering = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->t_Reordering));
-  *drb_ToAddMod->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms0;
+  asn1cCallocOne(drb_ToAddMod->pdcp_Config->t_Reordering, NR_PDCP_Config__t_Reordering_ms0);
   drb_ToAddMod->pdcp_Config->ext1 = NULL;
 
   asn1cSeqAdd(&rbconfig->drb_ToAddModList->list,drb_ToAddMod);
 
   rbconfig->drb_ToReleaseList = NULL;
 
-  rbconfig->securityConfig = calloc(1,sizeof(*rbconfig->securityConfig));
-  rbconfig->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(*rbconfig->securityConfig->securityAlgorithmConfig));
-  rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0;
-  rbconfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm=NULL;
-  rbconfig->securityConfig->keyToUse = calloc(1,sizeof(*rbconfig->securityConfig->keyToUse));
-  *rbconfig->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master;
+  asn1cCalloc(rbconfig->securityConfig, secConf);
+  asn1cCalloc(secConf->securityAlgorithmConfig, secConfAlgo);
+  secConfAlgo->cipheringAlgorithm = NR_CipheringAlgorithm_nea0;
+  secConfAlgo->integrityProtAlgorithm = NULL;
+  asn1cCallocOne(secConf->keyToUse, NR_SecurityConfig__keyToUse_master);
 
   if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
     xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig);
diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c
index 29683684d5585faa2c9c95682c140efbf7fec112..c09b4954d4474dfe1e41d7aa639c0551bfbd9526 100644
--- a/openair2/RRC/NR/cucp_cuup_direct.c
+++ b/openair2/RRC/NR/cucp_cuup_direct.c
@@ -37,7 +37,7 @@
 #include "rrc_gNB_GTPV1U.h"
 #include "common/ran_context.h"
 #include "openair2/F1AP/f1ap_common.h"
-
+#include "openair2/E1AP/e1ap_common.h"
 extern RAN_CONTEXT_t RC;
 
 void fill_e1ap_bearer_setup_resp(e1ap_bearer_setup_resp_t *resp,
@@ -122,9 +122,7 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p,
   create_tunnel_req.num_tunnels = ue_context_p->ue_context.nb_of_pdusessions;
   create_tunnel_req.ue_id       = ue_context_p->ue_context.rnti;
 
-  int ret = gtpv1u_create_ngu_tunnel(instance,
-                                     &create_tunnel_req,
-                                     &create_tunnel_resp);
+  int ret = gtpv1u_create_ngu_tunnel(getCxtE1(instance)->gtpInstN3, &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 rnti %ld\n",
@@ -177,6 +175,21 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p,
   return ret;
 }
 
+static NR_SRB_ToAddModList_t **generateSRB2_confList(gNB_RRC_UE_t *ue, NR_SRB_ToAddModList_t *SRB_configList, uint8_t xid)
+{
+  NR_SRB_ToAddModList_t **SRB_configList2 = NULL;
+
+  SRB_configList2 = &ue->SRB_configList2[xid];
+  if (*SRB_configList2 == NULL) {
+    *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
+    NR_SRB_ToAddMod_t *SRB2_config = CALLOC(1, sizeof(*SRB2_config));
+    SRB2_config->srb_Identity = 2;
+    asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config);
+    asn1cSeqAdd(&SRB_configList->list, SRB2_config);
+  }
+
+  return SRB_configList2;
+}
 static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const req, instance_t instance) {
   rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)], req->rnti);
   protocol_ctxt_t ctxt = {0};
@@ -187,12 +200,7 @@ static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const
   gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
   NR_SRB_ToAddModList_t **SRB_configList2 = generateSRB2_confList(&ue_context_p->ue_context, ue_context_p->ue_context.SRB_configList, 1);
   // GTP tunnel for UL
-  int ret = drb_config_gtpu_create(&ctxt,
-                                   ue_context_p,
-                                   req,
-                                   ue_context_p->ue_context.DRB_configList,
-                                   *SRB_configList2,
-                                   rrc->gtpInstN3);
+  int ret = drb_config_gtpu_create(&ctxt, ue_context_p, req, ue_context_p->ue_context.DRB_configList, *SRB_configList2, rrc->e1_inst);
   if (ret < 0) AssertFatal(false, "Unable to configure DRB or to create GTP Tunnel\n");
 
   if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)) {
diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h
index f0b9b20039911d7e56c65d5d6c560cfa6a43d6e4..a38f59b8903db504706a2e668ba9373bf2d20b82 100644
--- a/openair2/RRC/NR/nr_rrc_defs.h
+++ b/openair2/RRC/NR/nr_rrc_defs.h
@@ -417,7 +417,7 @@ typedef struct rrc_gNB_ue_context_s {
   // another key for protocol layers but should not be used as a key for RB tree
   uid_t          local_uid;
 
-  /* UE id for initial connection to S1AP */
+  /* UE id for initial connection to NGAP */
   struct gNB_RRC_UE_s   ue_context;
 } rrc_gNB_ue_context_t;
 
@@ -506,7 +506,7 @@ typedef struct gNB_RRC_INST_s {
   gNB_RrcConfigurationReq configuration;
 
   // gNB N3 GTPU instance
-  instance_t gtpInstN3;
+  instance_t e1_inst;
 
   // other PLMN parameters
   /// Mobile country code
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index a3791ac676dcad3346d2e4a15c5a634cba2a0721..affc56c8527cbfb39266efff633cc8dde5a9f5f3 100644
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -247,8 +247,6 @@ static void openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_Rrc
   rrc->ngap_id2_ngap_ids    = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL);
   rrc->configuration = *configuration;
   rrc->carrier.servingcellconfigcommon = configuration->scc;
-  extern instance_t *N3GTPUInst;
-  N3GTPUInst = &rrc->gtpInstN3;
   rrc->carrier.servingcellconfig = configuration->scd;
   nr_rrc_config_ul_tda(configuration->scc,configuration->minRXTXTIME);
    /// System Information INIT
diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.c b/openair2/RRC/NR/rrc_gNB_radio_bearers.c
index 9c3b6aada0dc5ba5693d0c008ac80408969390fb..ff8149b83f47b1728db19de894bd9090e84d1588 100644
--- a/openair2/RRC/NR/rrc_gNB_radio_bearers.c
+++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.c
@@ -22,32 +22,6 @@
 #include "rrc_gNB_radio_bearers.h"
 #include "oai_asn1.h"
 
-NR_SRB_ToAddMod_t *generateSRB2() {
-  NR_SRB_ToAddMod_t *SRB2_config = NULL;
-
-  SRB2_config = CALLOC(1, sizeof(*SRB2_config));
-  SRB2_config->srb_Identity = 2;
-
-  return SRB2_config;
-}
-
-NR_SRB_ToAddModList_t **generateSRB2_confList(gNB_RRC_UE_t *ue, 
-                                              NR_SRB_ToAddModList_t *SRB_configList, 
-                                              uint8_t xid) {
-  NR_SRB_ToAddModList_t **SRB_configList2 = NULL;
-
-  SRB_configList2 = &ue->SRB_configList2[xid];
-  if (*SRB_configList2 == NULL) {
-    *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
-    memset(*SRB_configList2, 0, sizeof(**SRB_configList2));
-    NR_SRB_ToAddMod_t *SRB2_config = generateSRB2();
-    asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config);
-    asn1cSeqAdd(&SRB_configList->list, SRB2_config);
-  }
-
-  return SRB_configList2;
-}
-
 NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *ue,
                                uint8_t drb_id,
                                const pdu_session_param_t *pduSession,
diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.h b/openair2/RRC/NR/rrc_gNB_radio_bearers.h
index a686fed76711e23600214a1f2c22b28496ff4ccc..86ab093ced33be7d0bb612493add9ac2cfcdc38d 100644
--- a/openair2/RRC/NR/rrc_gNB_radio_bearers.h
+++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.h
@@ -35,10 +35,6 @@
 #define GBR_FLOW                (1)
 #define NONGBR_FLOW             (0)
 
-NR_SRB_ToAddMod_t *generateSRB2(void);
-NR_SRB_ToAddModList_t **generateSRB2_confList(gNB_RRC_UE_t *ue, 
-                                              NR_SRB_ToAddModList_t *SRB_configList, 
-                                              uint8_t xid);
 NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *rrc_ue,
                                uint8_t drb_id,
                                const pdu_session_param_t *pduSession,
diff --git a/openair2/SDAP/nr_sdap/nr_sdap_entity.c b/openair2/SDAP/nr_sdap/nr_sdap_entity.c
index e60b9bd638b8e91bbb10098cef64652daa9a45da..0361fdac6ff2b9c48886135308067c9e160577eb 100644
--- a/openair2/SDAP/nr_sdap/nr_sdap_entity.c
+++ b/openair2/SDAP/nr_sdap/nr_sdap_entity.c
@@ -219,6 +219,7 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity,
     req->ue_id         = ue_id;
     req->bearer_id     = pdusession_id;
     LOG_D(SDAP, "%s()  sending message to gtp size %d\n", __func__,  size-offset);
+    // very very dirty hack gloabl var N3GTPUInst
     itti_send_msg_to_task(TASK_GTPV1_U, *N3GTPUInst, message_p);
   } else { //nrUE
     /*
diff --git a/openair3/NGAP/ngap_gNB_handlers.c b/openair3/NGAP/ngap_gNB_handlers.c
index b6c8b9323b4af0e813693b64786f044c284042ff..47f4b8445d95b8a8436a51f66463fc2577637086 100644
--- a/openair3/NGAP/ngap_gNB_handlers.c
+++ b/openair3/NGAP/ngap_gNB_handlers.c
@@ -1046,14 +1046,14 @@ int ngap_gNB_handle_initial_context_request(uint32_t   assoc_id,
             break;
             
           default:
-            NGAP_ERROR("could not found protocolIEs id %ld\n", pdusessionTransfer_ies->id);
+            NGAP_ERROR("Not found protocolIEs id %ld\n", pdusessionTransfer_ies->id);
             return -1;
         }
       }
 
     } /* for i... */
   } else {/* ie != NULL */
-    NGAP_ERROR("could not found NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListCxtReq\n");
+    NGAP_ERROR("Not found NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListCxtReq\n");
   }
   
   /* id-AllowedNSSAI */
diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c
index 49a0674bdfcfebb6bf18db569618cec580d0a711..14128dd53e476fe26ee451d42e68ee3fa276f3bb 100644
--- a/openair3/SCTP/sctp_eNB_task.c
+++ b/openair3/SCTP/sctp_eNB_task.c
@@ -617,10 +617,7 @@ sctp_handle_new_association_req(
 }
 
 //------------------------------------------------------------------------------
-static void sctp_send_data(
-    instance_t       instance,
-    task_id_t        task_id,
-    sctp_data_req_t *sctp_data_req_p)
+static void sctp_send_data(sctp_data_req_t *sctp_data_req_p)
 {
     struct sctp_cnx_list_elm_s *sctp_cnx = NULL;
 
@@ -660,10 +657,7 @@ static void sctp_send_data(
 }
 
 //------------------------------------------------------------------------------
-static int sctp_close_association(
-    const instance_t instance,
-    const task_id_t  requestor,
-    sctp_close_association_t     *close_association_p)
+static int sctp_close_association(sctp_close_association_t *close_association_p)
 {
 
     struct sctp_cnx_list_elm_s *sctp_cnx = NULL;
@@ -1152,10 +1146,8 @@ static void sctp_eNB_process_itti_msg()
         break;
 
         case SCTP_CLOSE_ASSOCIATION:
-            sctp_close_association(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
-                                   ITTI_MSG_ORIGIN_ID(received_msg),
-                                   &received_msg->ittiMsg.sctp_close_association);
-            break;
+          sctp_close_association(&received_msg->ittiMsg.sctp_close_association);
+          break;
 
         case TERMINATE_MESSAGE:
             SCTP_WARN("*** Exiting SCTP thread\n");
@@ -1163,9 +1155,7 @@ static void sctp_eNB_process_itti_msg()
             break;
 
         case SCTP_DATA_REQ: {
-            sctp_send_data(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
-                           ITTI_MSG_ORIGIN_ID(received_msg),
-                           &received_msg->ittiMsg.sctp_data_req);
+          sctp_send_data(&received_msg->ittiMsg.sctp_data_req);
         }
         break;
 
diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp
index 635ba2e40bfe62d50bc1f0c31fbed4c32dcd6273..b598a29c16609e2aab2b4e20b9089a1de7e831bc 100644
--- a/openair3/ocp-gtpu/gtp_itf.cpp
+++ b/openair3/ocp-gtpu/gtp_itf.cpp
@@ -94,7 +94,6 @@ typedef struct Gtpv1uExtHeader {
 #define GTP_END_MARKER                                       (254)
 #define GTP_GPDU                                             (255)
 
-
 typedef struct gtpv1u_bearer_s {
   /* TEID used in dl and ul */
   teid_t          teid_incoming;                ///< eNB TEID
@@ -127,8 +126,7 @@ class gtpEndPoint {
   uint8_t foundAddr[20];
   int foundAddrLen;
   int ipVersion;
-  map<uint64_t,teidData_t> ue2te_mapping;
-  map<uint64_t,ueidData_t> te2ue_mapping;
+  map<uint64_t, teidData_t> ue2te_mapping;
   // we use the same port number for source and destination address
   // this allow using non standard gtp port number (different from 2152)
   // and so, for example tu run 4G and 5G cores on one system
@@ -142,7 +140,7 @@ class gtpEndPoints {
   pthread_mutex_t gtp_lock=PTHREAD_MUTEX_INITIALIZER;
   // the instance id will be the Linux socket handler, as this is uniq
   map<uint64_t, gtpEndPoint> instances;
-
+  map<uint64_t, ueidData_t> te2ue_mapping;
   gtpEndPoints() {
     unsigned int seed;
     fill_random(&seed, sizeof(seed));
@@ -593,22 +591,17 @@ teid_t newGtpuCreateTunnel(instance_t instance,
 
   teid_t incoming_teid=gtpv1uNewTeid();
 
-  while ( inst->te2ue_mapping.find(incoming_teid) != inst->te2ue_mapping.end() ) {
+  while (globGtp.te2ue_mapping.find(incoming_teid) != globGtp.te2ue_mapping.end()) {
     LOG_W(GTPU, "[%ld] generated a random Teid that exists, re-generating (%x)\n", instance, incoming_teid);
     incoming_teid=gtpv1uNewTeid();
   };
 
-  inst->te2ue_mapping[incoming_teid].ue_id=ue_id;
-
-  inst->te2ue_mapping[incoming_teid].incoming_rb_id= incoming_bearer_id;
-
-  inst->te2ue_mapping[incoming_teid].outgoing_teid= outgoing_teid;
-
-  inst->te2ue_mapping[incoming_teid].callBack=callBack;
-
-  inst->te2ue_mapping[incoming_teid].callBackSDAP = callBackSDAP;
-
-  inst->te2ue_mapping[incoming_teid].pdusession_id = (uint8_t)outgoing_bearer_id;
+  globGtp.te2ue_mapping[incoming_teid].ue_id = ue_id;
+  globGtp.te2ue_mapping[incoming_teid].incoming_rb_id = incoming_bearer_id;
+  globGtp.te2ue_mapping[incoming_teid].outgoing_teid = outgoing_teid;
+  globGtp.te2ue_mapping[incoming_teid].callBack = callBack;
+  globGtp.te2ue_mapping[incoming_teid].callBackSDAP = callBackSDAP;
+  globGtp.te2ue_mapping[incoming_teid].pdusession_id = (uint8_t)outgoing_bearer_id;
 
   gtpv1u_bearer_t *tmp=&inst->ue2te_mapping[ue_id].bearers[outgoing_bearer_id];
 
@@ -641,13 +634,14 @@ teid_t newGtpuCreateTunnel(instance_t instance,
   pthread_mutex_unlock(&globGtp.gtp_lock);
   char ip4[INET_ADDRSTRLEN];
   char ip6[INET6_ADDRSTRLEN];
-  LOG_I(GTPU, "[%ld] Created tunnel for UE ID %lu, teid for DL: %x, teid for UL %x to remote IPv4: %s, IPv6 %s\n",
+  LOG_I(GTPU,
+        "[%ld] Created tunnel for UE ID %lu, teid for incoming: %x, teid for outgoing %x to remote IPv4: %s, IPv6 %s\n",
         instance,
         ue_id,
         tmp->teid_incoming,
         tmp->teid_outgoing,
-        inet_ntop(AF_INET,(void *)&tmp->outgoing_ip_addr, ip4,INET_ADDRSTRLEN ),
-        inet_ntop(AF_INET6,(void *)&tmp->outgoing_ip6_addr.s6_addr, ip6, INET6_ADDRSTRLEN));
+        inet_ntop(AF_INET, (void *)&tmp->outgoing_ip_addr, ip4, INET_ADDRSTRLEN),
+        inet_ntop(AF_INET6, (void *)&tmp->outgoing_ip6_addr.s6_addr, ip6, INET6_ADDRSTRLEN));
   return incoming_teid;
 }
 
@@ -795,7 +789,7 @@ int newGtpuDeleteAllTunnels(instance_t instance, ue_id_t ue_id) {
   for (auto j=ptrUe->second.bearers.begin();
        j!=ptrUe->second.bearers.end();
        ++j) {
-    inst->te2ue_mapping.erase(j->second.teid_incoming);
+    globGtp.te2ue_mapping.erase(j->second.teid_incoming);
     nb++;
   }
 
@@ -826,7 +820,7 @@ int newGtpuDeleteTunnels(instance_t instance, ue_id_t ue_id, int nbTunnels, pdus
     if ( ptr2 == ptrUe->second.bearers.end() ) {
       LOG_E(GTPU,"[%ld] GTP-U instance: delete of not existing tunnel UE ID:RAB: %ld/%x\n", instance, ue_id, pdusession_id[i]);
     } else {
-      inst->te2ue_mapping.erase(ptr2->second.teid_incoming);
+      globGtp.te2ue_mapping.erase(ptr2->second.teid_incoming);
       nb++;
     }
   }
@@ -913,9 +907,9 @@ static int Gtpv1uHandleEndMarker(int h,
   // the socket Linux file handler is the instance id
   getInstRetInt(h);
 
-  auto tunnel=inst->te2ue_mapping.find(ntohl(msgHdr->teid));
+  auto tunnel = globGtp.te2ue_mapping.find(ntohl(msgHdr->teid));
 
-  if ( tunnel == inst->te2ue_mapping.end() ) {
+  if (tunnel == globGtp.te2ue_mapping.end()) {
     LOG_E(GTPU,"[%d] Received a incoming packet on unknown teid (%x) Dropping!\n", h, msgHdr->teid);
     pthread_mutex_unlock(&globGtp.gtp_lock);
     return GTPNOK;
@@ -973,10 +967,9 @@ static int Gtpv1uHandleGpdu(int h,
   pthread_mutex_lock(&globGtp.gtp_lock);
   // the socket Linux file handler is the instance id
   getInstRetInt(h);
+  auto tunnel = globGtp.te2ue_mapping.find(ntohl(msgHdr->teid));
 
-  auto tunnel=inst->te2ue_mapping.find(ntohl(msgHdr->teid));
-
-  if ( tunnel == inst->te2ue_mapping.end() ) {
+  if (tunnel == globGtp.te2ue_mapping.end()) {
     LOG_E(GTPU,"[%d] Received a incoming packet on unknown teid (%x) Dropping!\n", h, ntohl(msgHdr->teid));
     pthread_mutex_unlock(&globGtp.gtp_lock);
     return GTPNOK;
@@ -1143,10 +1136,7 @@ static int Gtpv1uHandleGpdu(int h,
      * according to TS 38.425: Fig. 5.5.2.2-1 and section 5.5.3.24*/
     extensionHeader->length  = 1+sizeof(DlDataDeliveryStatus_flagsT)+3+1+1;
     gtpv1uCreateAndSendMsg(
-        h, peerIp, peerPort, GTP_GPDU,
-        inst->te2ue_mapping[ntohl(msgHdr->teid)].outgoing_teid,
-        NULL, 0, false, false, 0, 0, NR_RAN_CONTAINER,
-        extensionHeader->buffer, extensionHeader->length);
+        h, peerIp, peerPort, GTP_GPDU, globGtp.te2ue_mapping[ntohl(msgHdr->teid)].outgoing_teid, NULL, 0, false, false, 0, 0, NR_RAN_CONTAINER, extensionHeader->buffer, extensionHeader->length);
   }
 
   LOG_D(GTPU,"[%d] Received a %d bytes packet for: teid:%x\n", h,