diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index dee34ef05df10ec5208400ab41c1b7ef23fa6213..732cfd289e2e2f1bd887ef2682e93f91c8605e57 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -469,7 +469,6 @@ endif(${X2AP_RELEASE} STREQUAL "R8")
 add_definitions(-DX2AP_VERSION=${X2AP_VERSION})
 set(X2AP_ASN_DIR ${X2AP_DIR}/MESSAGES/ASN1/${X2AP_RELEASE})
 set(X2AP_C_DIR ${asn1_generated_dir}/X2AP_${X2AP_RELEASE})
-
 # Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make
 execute_process(COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${X2AP_C_DIR}" "${X2AP_ASN_DIR}/${X2AP_ASN_FILES}"  "X2AP_" -fno-include-deps
                 RESULT_VARIABLE ret)
diff --git a/openair2/COMMON/x2ap_messages_def.h b/openair2/COMMON/x2ap_messages_def.h
index c588753ca8b8fbb42c1c32b3c7ed0163d7bde66f..6c2d56a942079e3f56dca5f966317470c0e226e5 100644
--- a/openair2/COMMON/x2ap_messages_def.h
+++ b/openair2/COMMON/x2ap_messages_def.h
@@ -47,3 +47,6 @@ MESSAGE_DEF(X2AP_HANDOVER_CANCEL                , MESSAGE_PRIORITY_MED, x2ap_han
 
 /* handover messages X2AP <-> S1AP */
 MESSAGE_DEF(X2AP_UE_CONTEXT_RELEASE             , MESSAGE_PRIORITY_MED, x2ap_ue_context_release_t        , x2ap_ue_context_release)
+
+/*Senb bearer addition messages X2AP <-> RRC */
+MESSAGE_DEF(X2AP_SENB_ADDITION_REQ              , MESSAGE_PRIORITY_MED, x2ap_senb_addition_req_t         , x2ap_senb_addition_req)
diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h
index 5f2a95f576611df8596103ee9652e94127cb08a7..e502191d2b9b5eef4175c9bc02f811efb578c4c8 100644
--- a/openair2/COMMON/x2ap_messages_types.h
+++ b/openair2/COMMON/x2ap_messages_types.h
@@ -28,16 +28,16 @@
 //-------------------------------------------------------------------------------------------//
 // Defines to access message fields.
 
-#define X2AP_REGISTER_ENB_REQ(mSGpTR)           (mSGpTR)->ittiMsg.x2ap_register_enb_req
-#define X2AP_SETUP_REQ(mSGpTR)                  (mSGpTR)->ittiMsg.x2ap_setup_req
-#define X2AP_SETUP_RESP(mSGpTR)                 (mSGpTR)->ittiMsg.x2ap_setup_resp
-#define X2AP_HANDOVER_REQ(mSGpTR)               (mSGpTR)->ittiMsg.x2ap_handover_req
-#define X2AP_HANDOVER_REQ_ACK(mSGpTR)           (mSGpTR)->ittiMsg.x2ap_handover_req_ack
-#define X2AP_REGISTER_ENB_CNF(mSGpTR)           (mSGpTR)->ittiMsg.x2ap_register_enb_cnf
-#define X2AP_DEREGISTERED_ENB_IND(mSGpTR)       (mSGpTR)->ittiMsg.x2ap_deregistered_enb_ind
-#define X2AP_UE_CONTEXT_RELEASE(mSGpTR)         (mSGpTR)->ittiMsg.x2ap_ue_context_release
-#define X2AP_HANDOVER_CANCEL(mSGpTR)            (mSGpTR)->ittiMsg.x2ap_handover_cancel
-
+#define X2AP_REGISTER_ENB_REQ(mSGpTR)           	(mSGpTR)->ittiMsg.x2ap_register_enb_req
+#define X2AP_SETUP_REQ(mSGpTR)                  	(mSGpTR)->ittiMsg.x2ap_setup_req
+#define X2AP_SETUP_RESP(mSGpTR)                 	(mSGpTR)->ittiMsg.x2ap_setup_resp
+#define X2AP_HANDOVER_REQ(mSGpTR)               	(mSGpTR)->ittiMsg.x2ap_handover_req
+#define X2AP_HANDOVER_REQ_ACK(mSGpTR)           	(mSGpTR)->ittiMsg.x2ap_handover_req_ack
+#define X2AP_REGISTER_ENB_CNF(mSGpTR)           	(mSGpTR)->ittiMsg.x2ap_register_enb_cnf
+#define X2AP_DEREGISTERED_ENB_IND(mSGpTR)       	(mSGpTR)->ittiMsg.x2ap_deregistered_enb_ind
+#define X2AP_UE_CONTEXT_RELEASE(mSGpTR)         	(mSGpTR)->ittiMsg.x2ap_ue_context_release
+#define X2AP_HANDOVER_CANCEL(mSGpTR)            	(mSGpTR)->ittiMsg.x2ap_handover_cancel
+#define X2AP_SENB_ADDITION_REQ(mSGpTR)              (mSGpTR)->ittiMsg.x2ap_senb_addition_req
 
 #define X2AP_MAX_NB_ENB_IP_ADDRESS 2
 
@@ -236,4 +236,71 @@ typedef struct x2ap_handover_req_ack_s {
   uint32_t mme_ue_s1ap_id;
 } x2ap_handover_req_ack_t;
 
+typedef struct x2ap_senb_addition_req_s {
+
+	/* MeNB UE X2AP ID*/
+	int x2_MeNB_UE_id;
+
+	/*SCG Bearer option*/
+	security_capabilities_t UE_security_capabilities;
+
+	/*SCG Bearer option*/
+	uint8_t SeNB_security_key[256];
+
+	/*SeNB UE aggregate maximum bitrate */
+	ambr_t SeNB_ue_ambr;
+
+	uint8_t total_nb_e_rabs_tobeadded;
+
+	uint8_t nb_sCG_e_rabs_tobeadded;
+
+	uint8_t nb_split_e_rabs_tobeadded;
+
+	/*list of total e_rabs (SCG or split) to be added*/
+    //e_rab_setup_t total_e_rabs_tobeadded[S1AP_MAX_E_RAB];
+
+	/* list of SCG e_rab to be added by RRC layers */
+	e_rab_setup_t e_sCG_rabs_tobeadded[S1AP_MAX_E_RAB];
+
+	/* list of split e_rab to be added by RRC layers */
+	e_rab_setup_t e_split_rabs_tobeadded[S1AP_MAX_E_RAB];
+
+	/* list of SCG e_rab to be added by RRC layers */
+	e_rab_t  e_sCG_rab_param[S1AP_MAX_E_RAB];
+
+	/* list of split e_rab to be added by RRC layers */
+	e_rab_t  e_split_rab_param[S1AP_MAX_E_RAB];
+
+	/*Used for the MeNB to SeNB Container to include the SCG-ConfigInfo as per 36.331*/
+	uint8_t rrc_buffer[1024 /* arbitrary, big enough */];
+
+	int rrc_buffer_size;
+
+}x2ap_senb_addition_req_t;
+
+
+
+
+//Panos: Have to see what should be the additional/different elements comparing to handover req ack
+typedef struct x2ap_senb_addition_req_ack_s {
+
+  int MeNB_UE_X2_id;
+
+  int SeNB_UE_X2_id;
+
+  uint8_t nb_sCG_e_rabs_tobeadded;
+
+  uint8_t nb_split_e_rabs_tobeadded;
+
+ /* list of SCG e_rab to be added by RRC layers */
+  e_rab_setup_t e_sCG_rabs_tobeadded[S1AP_MAX_E_RAB];
+
+  /* list of split e_rab to be added by RRC layers */
+  e_rab_setup_t e_split_rabs_tobeadded[S1AP_MAX_E_RAB];
+
+  uint8_t rrc_buffer[1024 /* arbitrary, big enough */];
+  int rrc_buffer_size;
+
+} x2ap_senb_addition_req_ack_t;
+
 #endif /* X2AP_MESSAGES_TYPES_H_ */
diff --git a/openair2/X2AP/MESSAGES/ASN1/R15/x2ap-15.1.0.asn1 b/openair2/X2AP/MESSAGES/ASN1/R15/x2ap-15.1.0.asn1
index 04de5ca5c5eefa62031d5df7cbd28429a57a67d9..e8a053a12c855b3b5bdd1af71aeaa5b3a9901979 100644
--- a/openair2/X2AP/MESSAGES/ASN1/R15/x2ap-15.1.0.asn1
+++ b/openair2/X2AP/MESSAGES/ASN1/R15/x2ap-15.1.0.asn1
@@ -4010,7 +4010,7 @@ NRNeighbour-Information-ExtIEs X2AP-PROTOCOL-EXTENSION ::= {
 	...
 }
 
-CellAssistanceInformation ::= CHOICE {
+CellAssistanceInformation ::= CHOICE {
 	limited-list				Limited-list,
 	full-list				ENUMERATED  {allServedNRcells, ...},
 	...
@@ -6094,7 +6094,7 @@ SgNBResourceCoordinationInformationExtIEs X2AP-PROTOCOL-EXTENSION ::= {
 	...
 }
 
-SgNB-UE-X2AP-ID ::= INTEGER (0..4294967295)
+SgNB-UE-X2AP-ID ::= INTEGER (0..4294967295)
 
 SIPTOBearerDeactivationIndication ::= ENUMERATED {
 	true,
diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c
index 8b11e469b2d03f1e86b74c8a94bf55778ab9a1d6..54b0020296b1f7057f0d56f11ae81cb515a96f6e 100644
--- a/openair2/X2AP/x2ap_eNB.c
+++ b/openair2/X2AP/x2ap_eNB.c
@@ -151,7 +151,8 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
   printf("x2ap_eNB_handle_sctp_association_resp at 4\n");
   dump_trees();
   /* Prepare new x2 Setup Request */
-  x2ap_eNB_generate_x2_setup_request(instance_p, x2ap_enb_data_p);
+  x2ap_eNB_generate_ENDC_x2_setup_request(instance_p, x2ap_enb_data_p);
+  //x2ap_eNB_generate_x2_setup_request(instance_p, x2ap_enb_data_p);
 }
 
 static
diff --git a/openair2/X2AP/x2ap_eNB_decoder.c b/openair2/X2AP/x2ap_eNB_decoder.c
index 3604aa03c8a75420b4638dd70967ddba52745e00..c7fc98763a656e0f97b06c76a197c1042c22cba7 100644
--- a/openair2/X2AP/x2ap_eNB_decoder.c
+++ b/openair2/X2AP/x2ap_eNB_decoder.c
@@ -59,6 +59,10 @@ static int x2ap_eNB_decode_initiating_message(X2AP_X2AP_PDU_t *pdu)
       X2AP_INFO("x2ap_eNB_decode_initiating_message!\n");
       break;
 
+    case X2AP_ProcedureCode_id_endcX2Setup:
+      X2AP_INFO("X2AP_ProcedureCode_id_endcX2Setup message!\n");
+      break;
+
     default:
       X2AP_ERROR("Unknown procedure ID (%d) for initiating message\n",
                   (int)pdu->choice.initiatingMessage.procedureCode);
@@ -85,6 +89,10 @@ static int x2ap_eNB_decode_successful_outcome(X2AP_X2AP_PDU_t *pdu)
       X2AP_INFO("x2ap_eNB_decode_successfuloutcome_message!\n");
       break;
 
+    case X2AP_ProcedureCode_id_endcX2Setup:
+    	X2AP_INFO("x2ap_eNB_decode_successfuloutcome_message!\n");
+    	break;
+
     default:
       X2AP_ERROR("Unknown procedure ID (%d) for successfull outcome message\n",
                   (int)pdu->choice.successfulOutcome.procedureCode);
@@ -126,9 +134,9 @@ int x2ap_eNB_decode_pdu(X2AP_X2AP_PDU_t *pdu, const uint8_t *const buffer, uint3
                         length,
                         0,
                         0);
-  if (asn1_xer_print) {
+  //if (asn1_xer_print) {
     xer_fprint(stdout, &asn_DEF_X2AP_X2AP_PDU, pdu);
-  }
+  //}
 
   if (dec_ret.code != RC_OK) {
     X2AP_ERROR("Failed to decode pdu\n");
diff --git a/openair2/X2AP/x2ap_eNB_defs.h b/openair2/X2AP/x2ap_eNB_defs.h
index 03d8216b5666a0904fac6492c264384eef0862bd..6ab62ebf98fff24817fad7838ca9bb120aded4b6 100644
--- a/openair2/X2AP/x2ap_eNB_defs.h
+++ b/openair2/X2AP/x2ap_eNB_defs.h
@@ -175,6 +175,12 @@ typedef struct x2ap_eNB_instance_s {
   uint32_t                fdd_earfcn_UL[MAX_NUM_CCs];
   uint32_t                subframeAssignment[MAX_NUM_CCs];
   uint32_t                specialSubframe[MAX_NUM_CCs];
+
+//#ifdef Rel15
+  uint32_t				  tdd_nRARFCN[MAX_NUM_CCs];
+  int16_t                 nr_SCS[MAX_NUM_CCs];
+//#endif
+
   int                     num_cc;
 
   net_ip_address_t target_enb_x2_ip_address[X2AP_MAX_NB_ENB_IP_ADDRESS];
diff --git a/openair2/X2AP/x2ap_eNB_encoder.c b/openair2/X2AP/x2ap_eNB_encoder.c
index 8b1c030d35d0b14d588475cf317d450f2fa3e686..392206e4d730653e76dfea07c299860347aaa625 100644
--- a/openair2/X2AP/x2ap_eNB_encoder.c
+++ b/openair2/X2AP/x2ap_eNB_encoder.c
@@ -44,9 +44,9 @@ int x2ap_eNB_encode_pdu(X2AP_X2AP_PDU_t *pdu, uint8_t **buffer, uint32_t *len)
   DevAssert(buffer != NULL);
   DevAssert(len != NULL);
 
-  if (asn1_xer_print) {
+  //if (asn1_xer_print) {
     xer_fprint(stdout, &asn_DEF_X2AP_X2AP_PDU, (void *)pdu);
-  }
+  //}
 
   encoded = aper_encode_to_new_buffer(&asn_DEF_X2AP_X2AP_PDU, 0, pdu, (void **)buffer);
 
diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c
index 38ebd732ac390c02832b9f9645c67b96e63fd84e..be3002c197f9728ea94e3da5eea6a233d8e5500f 100644
--- a/openair2/X2AP/x2ap_eNB_generate_messages.c
+++ b/openair2/X2AP/x2ap_eNB_generate_messages.c
@@ -323,6 +323,10 @@ int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_instance_t *instance_p, x2ap_eN
                                    &servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier);
 
         INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC);
+        X2AP_INFO("TAC: %d -> %02x%02x\n", instance_p->tac,
+       		  	  servedCellMember->servedCellInfo.tAC.buf[0],
+				  servedCellMember->servedCellInfo.tAC.buf[1]);
+
         plmn = (X2AP_PLMN_Identity_t *)calloc(1,sizeof(X2AP_PLMN_Identity_t));
         {
           MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn);
@@ -993,3 +997,519 @@ int x2ap_eNB_generate_x2_handover_cancel (x2ap_eNB_instance_t *instance_p, x2ap_
 
   return ret;
 }
+
+int x2ap_eNB_generate_senb_addition_request (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p
+                                             /* TODO: pass needed parameters */)
+{
+  X2AP_X2AP_PDU_t                pdu;
+  X2AP_SeNBAdditionRequest_t     *out;
+  X2AP_SeNBAdditionRequest_IEs_t *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  int       ret = 0;
+
+  DevAssert(instance_p != NULL);
+  DevAssert(x2ap_eNB_data_p != NULL);
+
+  /* Prepare the X2AP SeNB Addition Request message to encode */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage;
+  pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_seNBAdditionPreparation;
+  pdu.choice.initiatingMessage.criticality = X2AP_Criticality_reject;
+  pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_SeNBAdditionRequest;
+  out = &pdu.choice.initiatingMessage.value.choice.SeNBAdditionRequest;
+
+  /* id-MeNB-UE-X2AP-ID - mandatory - criticality reject */
+  ie = (X2AP_SeNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequest_IEs_t));
+  ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
+  ie->criticality = X2AP_Criticality_reject;
+  ie->value.present = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
+  ie->value.choice.UE_X2AP_ID = 0;                                   /* TODO */
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* id-UE-SecurityCapabilities - conditional - criticality reject */
+  /* TODO */
+
+  /* id-SeNBSecurityKey - conditional - criticality reject */
+  /* TODO */
+
+  /* id-SeNBUEAggregateMaximumBitRate - mandatory - criticality reject */
+  ie = (X2AP_SeNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequest_IEs_t));
+  ie->id = X2AP_ProtocolIE_ID_id_SeNBUEAggregateMaximumBitRate;
+  ie->criticality = X2AP_Criticality_reject;
+  ie->value.present = X2AP_ProtocolIE_ID_id_SeNBUEAggregateMaximumBitRate;
+  if (asn_imax2INTEGER(&ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink, 0) != 0) { /* TODO: right value */
+    LOG_E(X2AP, "%s:%d:%s: fatal asn1 error\n", __FILE__, __LINE__, __FUNCTION__);
+    exit(1);
+  }
+  if (asn_imax2INTEGER(&ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateUplink, 0) != 0) { /* TODO: right value */
+    LOG_E(X2AP, "%s:%d:%s: fatal asn1 error\n", __FILE__, __LINE__, __FUNCTION__);
+    exit(1);
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* id-ServingPLMN - optional - criticality ignore */
+  /* TODO */
+
+  /* id-E-RABs-ToBeAdded-List - mandatory - criticality reject */
+  ie = (X2AP_SeNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequest_IEs_t));
+  ie->id = X2AP_ProtocolIE_ID_id_SeNBUEAggregateMaximumBitRate;
+  ie->criticality = X2AP_Criticality_reject;
+  ie->value.present = X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_List;
+  /* TODO: set value of ie->value.choice.E_RABs_ToBeAdded_List.list */
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* id-MeNBtoSeNBContainer - mandatory - criticality reject */
+  ie = (X2AP_SeNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequest_IEs_t));
+  ie->id = X2AP_ProtocolIE_ID_id_MeNBtoSeNBContainer;
+  ie->criticality = X2AP_Criticality_reject;
+  ie->value.present = X2AP_ProtocolIE_ID_id_MeNBtoSeNBContainer;
+  /* TODO: set value of ie->value.choice.MeNBtoSeNBContainer */
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* id-CSGMembershipStatus - optional - criticality reject */
+  /* TODO */
+
+  /* id-SeNB-UE-X2AP-ID - optional - criticality reject */
+  /* TODO */
+
+  /* id-SeNB-UE-X2AP-ID-Extension - optional - criticality reject */
+  /* TODO */
+
+  /* id-ExpectedUEBehaviour - optional - criticality ignore */
+  /* TODO */
+
+  /* id-MeNB-UE-X2AP-ID-Extension - optional - criticality reject */
+  /* TODO */
+
+  if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
+    X2AP_ERROR("Failed to encode X2AP SeNB Addition Request\n");
+    abort();
+    return -1;
+  }
+
+  MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2SeNBAdditionRequest/initiatingMessage assoc_id %u", x2ap_eNB_data_p->assoc_id);
+
+  x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 1);
+
+  return ret;
+}
+
+//Panos:
+int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
+                                               x2ap_senb_addition_req_ack_t *x2ap_addition_req_ack)
+{
+
+  X2AP_X2AP_PDU_t                        pdu;
+  X2AP_SeNBAdditionRequestAcknowledge_t      *out;
+  X2AP_SeNBAdditionRequestAcknowledge_IEs_t  *ie;
+  X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs_t         *e_RABS_Admitted_ToBeAdded_ItemIEs;
+  X2AP_E_RABs_Admitted_ToBeAdded_Item_t            *e_RABs_Admitted_ToBeAdded_Item;
+  int                                    ue_id;
+  int                                    ue_id_MeNB;
+  int                                    ue_id_SeNB;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  int       ret = 0;
+
+  DevAssert(instance_p != NULL);
+  DevAssert(x2ap_eNB_data_p != NULL);
+
+  //Panos: The fact that we have separate IDs here is because the ID for a specific UE might be different
+  //between the 2 eNBs?
+  //ue_id     = x2ap_addition_req_ack->x2_id_target; //Panos: change name to master_x2...
+  //id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
+  //id_target = ue_id;
+
+  /* Prepare the X2AP addition req. ack. message to encode */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome;
+  pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_seNBAdditionPreparation;
+  //Panos: What does the criticality indicate here?
+  pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject;
+  pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_SeNBAdditionRequestAcknowledge;
+  out = &pdu.choice.successfulOutcome.value.choice.SeNBAdditionRequestAcknowledge;
+
+  /* mandatory */
+  ie = (X2AP_SeNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequestAcknowledge_IEs_t));
+  ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
+  ie->criticality = X2AP_Criticality_reject;
+  ie->value.present = X2AP_SeNBAdditionRequestAcknowledge_IEs__value_PR_UE_X2AP_ID;
+  ie->value.choice.UE_X2AP_ID = 0;
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  ie = (X2AP_SeNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequestAcknowledge_IEs_t));
+  ie->id = X2AP_ProtocolIE_ID_id_SeNB_UE_X2AP_ID;
+  //Panos: Why for the X2_HANDOVER_REQ_ACK here the criticality is ignore whereas in the specs it is reject?
+  ie->criticality = X2AP_Criticality_reject;
+  ie->value.present = X2AP_SeNBAdditionRequestAcknowledge_IEs__value_PR_UE_X2AP_ID_1;
+  ie->value.choice.UE_X2AP_ID_1 = 0;
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  ie = (X2AP_SeNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequestAcknowledge_IEs_t));
+  ie->id = X2AP_ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_List;
+  ie->criticality = X2AP_Criticality_ignore;
+  ie->value.present = X2AP_SeNBAdditionRequestAcknowledge_IEs__value_PR_E_RABs_Admitted_ToBeAdded_List;
+
+  {
+	  // SCG bearers to be added
+      for (int i=0;i<x2ap_addition_req_ack->nb_sCG_e_rabs_tobeadded;i++) {
+    	e_RABS_Admitted_ToBeAdded_ItemIEs = (X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs_t *)calloc(1,sizeof(X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs_t));
+    	e_RABS_Admitted_ToBeAdded_ItemIEs->id = X2AP_ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_Item;
+    	e_RABS_Admitted_ToBeAdded_ItemIEs->criticality = X2AP_Criticality_ignore;
+    	e_RABS_Admitted_ToBeAdded_ItemIEs->value.present = X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs__value_PR_E_RABs_Admitted_ToBeAdded_Item;
+    	e_RABs_Admitted_ToBeAdded_Item = &e_RABS_Admitted_ToBeAdded_ItemIEs->value.choice.E_RABs_Admitted_ToBeAdded_Item;
+        {
+    		e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.e_RAB_ID = x2ap_addition_req_ack->e_sCG_rabs_tobeadded[i].e_rab_id;
+    		INT32_TO_OCTET_STRING(x2ap_addition_req_ack->e_sCG_rabs_tobeadded[i].gtp_teid, &e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.s1_DL_GTPtunnelEndpoint.gTP_TEID);
+
+    		e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size 		= (uint8_t)(x2ap_addition_req_ack->e_sCG_rabs_tobeadded[i].eNB_addr.length/8);
+    		e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = x2ap_addition_req_ack->e_sCG_rabs_tobeadded[i].eNB_addr.length%8;
+    		e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf =
+    		                        calloc(1,e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size);
+
+    		        memcpy (e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf,
+    		        		x2ap_addition_req_ack->e_sCG_rabs_tobeadded[i].eNB_addr.buffer,
+    		        		e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size);
+
+        }
+        ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_ToBeAdded_List.list, e_RABS_Admitted_ToBeAdded_ItemIEs);
+      }
+
+      // Split bearers to be added
+      for (int i=0;i<x2ap_addition_req_ack->nb_split_e_rabs_tobeadded;i++) {
+    	  e_RABS_Admitted_ToBeAdded_ItemIEs = (X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs_t *)calloc(1,sizeof(X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs_t));
+    	  e_RABS_Admitted_ToBeAdded_ItemIEs->id = X2AP_ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_Item;
+    	  e_RABS_Admitted_ToBeAdded_ItemIEs->criticality = X2AP_Criticality_ignore;
+    	  e_RABS_Admitted_ToBeAdded_ItemIEs->value.present = X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs__value_PR_E_RABs_Admitted_ToBeAdded_Item;
+    	  e_RABs_Admitted_ToBeAdded_Item = &e_RABS_Admitted_ToBeAdded_ItemIEs->value.choice.E_RABs_Admitted_ToBeAdded_Item;
+    	  {
+    		  e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.e_RAB_ID = x2ap_addition_req_ack->e_split_rabs_tobeadded[i].e_rab_id;
+    		  INT32_TO_OCTET_STRING(x2ap_addition_req_ack->e_split_rabs_tobeadded[i].gtp_teid, &e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.seNB_GTPtunnelEndpoint.gTP_TEID);
+
+    		  e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.seNB_GTPtunnelEndpoint.transportLayerAddress.size 		= (uint8_t)(x2ap_addition_req_ack->e_split_rabs_tobeadded[i].eNB_addr.length/8);
+    		  e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.seNB_GTPtunnelEndpoint.transportLayerAddress.bits_unused = x2ap_addition_req_ack->e_split_rabs_tobeadded[i].eNB_addr.length%8;
+    		  e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.seNB_GTPtunnelEndpoint.transportLayerAddress.buf =
+    				  calloc(1,e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.seNB_GTPtunnelEndpoint.transportLayerAddress.size);
+
+    		  memcpy (e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.seNB_GTPtunnelEndpoint.transportLayerAddress.buf,
+    				  x2ap_addition_req_ack->e_split_rabs_tobeadded[i].eNB_addr.buffer,
+    				  e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.seNB_GTPtunnelEndpoint.transportLayerAddress.size);
+
+    		  }
+    	  ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_ToBeAdded_List.list, e_RABS_Admitted_ToBeAdded_ItemIEs);
+      }
+
+  }
+
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  ie = (X2AP_SeNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequestAcknowledge_IEs_t));
+  ie->id = X2AP_ProtocolIE_ID_id_SeNBtoMeNBContainer;
+  ie->criticality = X2AP_Criticality_reject;
+  ie->value.present = X2AP_SeNBAdditionRequestAcknowledge_IEs__value_PR_SeNBtoMeNBContainer;
+
+  OCTET_STRING_fromBuf(&ie->value.choice.SeNBtoMeNBContainer, (char*) x2ap_addition_req_ack->rrc_buffer, x2ap_addition_req_ack->rrc_buffer_size);
+
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
+    X2AP_ERROR("Failed to encode SeNB addition response\n");
+    abort();
+    return -1;
+  }
+
+  x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 1);
+
+  return ret;
+}
+
+/*setup request message from an eNB to a gNB*/
+int x2ap_eNB_generate_ENDC_x2_setup_request(
+  x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p)
+{
+	printf("In x2ap_eNB_generate_ENDC_x2_setup_request \n");
+  X2AP_X2AP_PDU_t                     	 pdu;
+  X2AP_ENDCX2SetupRequest_t              *out;
+  X2AP_ENDCX2SetupRequest_IEs_t          *ie;
+  X2AP_ENB_ENDCX2SetupReqIEs_t 			 *ie_ENB_ENDC;
+  X2AP_PLMN_Identity_t               	 *plmn;
+  ServedEUTRAcellsENDCX2ManagementList__Member                *servedCellMember;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  int       ret = 0;
+
+  DevAssert(instance_p != NULL);
+  DevAssert(x2ap_eNB_data_p != NULL);
+
+  x2ap_eNB_data_p->state = X2AP_ENB_STATE_WAITING;
+
+  /* Prepare the X2AP message to encode */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage;
+  pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_endcX2Setup;
+  pdu.choice.initiatingMessage.criticality = X2AP_Criticality_reject;
+  pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_ENDCX2SetupRequest;
+  out = &pdu.choice.initiatingMessage.value.choice.ENDCX2SetupRequest;
+
+  ie = (X2AP_ENDCX2SetupRequest_IEs_t *)calloc(1, sizeof(X2AP_ENDCX2SetupRequest_IEs_t));
+  ie->id = X2AP_ProtocolIE_ID_id_InitiatingNodeType_EndcX2Setup;
+  ie->value.present = X2AP_ENDCX2SetupRequest_IEs__value_PR_InitiatingNodeType_EndcX2Setup;
+  ie->value.choice.InitiatingNodeType_EndcX2Setup.present = X2AP_InitiatingNodeType_EndcX2Setup_PR_init_eNB;
+
+  ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqIEs_t *)calloc(1, sizeof(X2AP_ENB_ENDCX2SetupReqIEs_t));
+  ie_ENB_ENDC->id = X2AP_ProtocolIE_ID_id_GlobalENB_ID;
+  ie_ENB_ENDC->criticality = X2AP_Criticality_reject;
+  ie_ENB_ENDC->value.present = X2AP_ENB_ENDCX2SetupReqIEs__value_PR_GlobalENB_ID;
+  ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.present = X2AP_ENB_ID_PR_macro_eNB_ID;
+  MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id,
+                               &ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID);
+  MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+                      &ie_ENB_ENDC->value.choice.GlobalENB_ID.pLMN_Identity);
+
+  ASN_SEQUENCE_ADD(&ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list, ie_ENB_ENDC);
+
+  ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqIEs_t *)calloc(1, sizeof(X2AP_ENB_ENDCX2SetupReqIEs_t));
+  ie_ENB_ENDC->id = X2AP_ProtocolIE_ID_id_ServedEUTRAcellsENDCX2ManagementList;
+  ie_ENB_ENDC->criticality = X2AP_Criticality_reject;
+  ie_ENB_ENDC->value.present = X2AP_ENB_ENDCX2SetupReqIEs__value_PR_ServedEUTRAcellsENDCX2ManagementList;
+
+  {
+      for (int i = 0; i<instance_p->num_cc; i++){
+        servedCellMember = (ServedEUTRAcellsENDCX2ManagementList__Member *)calloc(1,sizeof(ServedEUTRAcellsENDCX2ManagementList__Member));
+        {
+          servedCellMember->servedEUTRACellInfo.pCI = instance_p->Nid_cell[i];
+
+          MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+                        &servedCellMember->servedEUTRACellInfo.cellId.pLMN_Identity);
+          MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,0,
+                                     &servedCellMember->servedEUTRACellInfo.cellId.eUTRANcellIdentifier);
+
+          INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedEUTRACellInfo.tAC);
+          plmn = (X2AP_PLMN_Identity_t *)calloc(1,sizeof(X2AP_PLMN_Identity_t));
+          {
+            MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn);
+            ASN_SEQUENCE_ADD(&servedCellMember->servedEUTRACellInfo.broadcastPLMNs.list, plmn);
+          }
+
+  	if (instance_p->frame_type[i] == FDD) {
+            servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_fDD;
+            servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i];
+            servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i];
+            switch (instance_p->N_RB_DL[i]) {
+              case 6:
+                servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6;
+                servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6;
+                break;
+              case 15:
+                servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15;
+                servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15;
+                break;
+              case 25:
+                servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25;
+                servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25;
+                break;
+              case 50:
+                servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50;
+                servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50;
+                break;
+              case 75:
+                servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75;
+                servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75;
+                break;
+              case 100:
+                servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100;
+                servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100;
+                break;
+              default:
+                AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
+                break;
+            }
+          }
+          else {
+            AssertFatal(0,"X2Setuprequest not supported for TDD!");
+          }
+        }
+        ASN_SEQUENCE_ADD(&ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list, servedCellMember);
+      }
+    }
+  ASN_SEQUENCE_ADD(&ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list, ie_ENB_ENDC);
+
+
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
+    X2AP_ERROR("Failed to encode X2 setup response\n");
+    return -1;
+  }
+
+  MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2Setup/initiatingMessage assoc_id %u", x2ap_eNB_data_p->assoc_id);
+
+  x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0);
+
+  return ret;
+}
+
+
+/*setup request message from an eNB to a gNB*/
+int x2ap_gNB_generate_ENDC_x2_setup_response(
+  x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p)
+{
+	X2AP_INFO("In x2ap_gNB_generate_ENDC_x2_setup_response ()!\n");
+  X2AP_X2AP_PDU_t                     	 pdu;
+  X2AP_ENDCX2SetupResponse_t              *out;
+  X2AP_ENDCX2SetupResponse_IEs_t          *ie;
+  X2AP_En_gNB_ENDCX2SetupReqAckIEs_t 			 *ie_GNB_ENDC;
+  X2AP_PLMN_Identity_t               	 *plmn;
+  ServedNRcellsENDCX2ManagementList__Member                *servedCellMember;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  int       ret = 0;
+
+  DevAssert(instance_p != NULL);
+  DevAssert(x2ap_eNB_data_p != NULL);
+
+  x2ap_eNB_data_p->state = X2AP_ENB_STATE_WAITING;
+
+  /* Prepare the X2AP message to encode */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome;
+  pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_endcX2Setup;
+  pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject;
+  pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_ENDCX2SetupResponse;
+  out = &pdu.choice.successfulOutcome.value.choice.ENDCX2SetupResponse;
+
+  ie = (X2AP_ENDCX2SetupResponse_IEs_t *)calloc(1, sizeof(X2AP_ENDCX2SetupResponse_IEs_t));
+  ie->id = X2AP_ProtocolIE_ID_id_RespondingNodeType_EndcX2Setup;
+  ie->value.present = X2AP_ENDCX2SetupResponse_IEs__value_PR_RespondingNodeType_EndcX2Setup;
+  ie->value.choice.RespondingNodeType_EndcX2Setup.present = X2AP_RespondingNodeType_EndcX2Setup_PR_respond_en_gNB;
+
+  ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqAckIEs_t *)calloc(1, sizeof(X2AP_En_gNB_ENDCX2SetupReqAckIEs_t));
+  ie_GNB_ENDC->id = X2AP_ProtocolIE_ID_id_Globalen_gNB_ID;
+  ie_GNB_ENDC->criticality = X2AP_Criticality_reject;
+  ie_GNB_ENDC->value.present = X2AP_En_gNB_ENDCX2SetupReqAckIEs__value_PR_GlobalGNB_ID;
+  ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.present = X2AP_GNB_ID_PR_gNB_ID;
+
+  INT32_TO_OCTET_STRING(instance_p->eNB_id,
+                               &ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID);
+
+  X2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id,
+		  ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.buf[0],
+		  ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.buf[1],
+		  ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.buf[2]);
+
+  MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+                      &ie_GNB_ENDC->value.choice.GlobalGNB_ID.pLMN_Identity);
+
+  ASN_SEQUENCE_ADD(&ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_en_gNB.list, ie_GNB_ENDC);
+
+  ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqAckIEs_t *)calloc(1, sizeof(X2AP_En_gNB_ENDCX2SetupReqAckIEs_t));
+  ie_GNB_ENDC->id = X2AP_ProtocolIE_ID_id_ServedNRcellsENDCX2ManagementList;
+  ie_GNB_ENDC->criticality = X2AP_Criticality_reject;
+  ie_GNB_ENDC->value.present = X2AP_En_gNB_ENDCX2SetupReqAckIEs__value_PR_ServedNRcellsENDCX2ManagementList;
+
+  {
+      for (int i = 0; i<instance_p->num_cc; i++){
+        servedCellMember = (ServedNRcellsENDCX2ManagementList__Member *)calloc(1,sizeof(ServedNRcellsENDCX2ManagementList__Member));
+        {
+          servedCellMember->servedNRCellInfo.nrpCI = instance_p->Nid_cell[i];
+
+          MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+                        &servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity);
+          NR_CELL_ID_TO_BIT_STRING(instance_p->eNB_id,
+                                     &servedCellMember->servedNRCellInfo.nrCellID.nRcellIdentifier);
+          servedCellMember->servedNRCellInfo.fiveGS_TAC = calloc(1, sizeof(X2AP_FiveGS_TAC_t));
+          if (servedCellMember->servedNRCellInfo.fiveGS_TAC == NULL)
+            exit(1);
+          NR_FIVEGS_TAC_ID_TO_BIT_STRING(instance_p->tac, servedCellMember->servedNRCellInfo.fiveGS_TAC);
+
+          X2AP_INFO("TAC: %d -> %02x%02x%02x\n", instance_p->tac,
+        		  	  servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[0],
+					  servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[1],
+					  servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[2]);
+
+          plmn = (X2AP_PLMN_Identity_t *)calloc(1,sizeof(X2AP_PLMN_Identity_t));
+          {
+            MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn);
+            ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.broadcastPLMNs.list, plmn);
+          }
+
+          if (instance_p->frame_type[i] == TDD) { // Panos: Remember to change that to TDD
+        	  servedCellMember->servedNRCellInfo.nrModeInfo.present = X2AP_ServedNRCell_Information__nrModeInfo_PR_tdd;
+        	  servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.nRARFCN = 0; //instance_p->tdd_nRARFCN[i];
+        	  /*Missing addition of Frequency Band List item here, can't find it...  */
+        	  switch (instance_p->N_RB_DL[i]) {
+        	  case 50:
+        		  //This is not correct. Just to be able to test X2 only using an eNB instead of gNB
+        		  servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb51;
+        		  break;
+        	  case 93 :
+        		  servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb93;
+        		  break;
+        	  case 106:
+        		  servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb106;
+        		  break;
+        	  case 121:
+        		  servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb121;
+        		  break;
+
+        		  /*More cases to be added */
+
+        	  default:
+        		  AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
+        		  break;
+        	  }
+
+        	  instance_p->nr_SCS[i] = 30; // Hardcoded for now. Normally this should originate from the gNB config file
+        	  switch (instance_p->nr_SCS[i]) {
+        	  case 15:
+        		  servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRSCS = X2AP_NRSCS_scs15;
+        		  break;
+        	  case 30:
+        		  servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRSCS = X2AP_NRSCS_scs30;
+        		  break;
+        	  case 60:
+        		  servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRSCS = X2AP_NRSCS_scs60;
+        		  break;
+        	  case 120:
+        		  servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRSCS = X2AP_NRSCS_scs120;
+        		  break;
+        	  default:
+        		  AssertFatal(0,"Failed: Check value for nr_SCS");
+        		  break;
+        	  }
+          }
+          else {
+        	  AssertFatal(0,"nr_X2Setupresponse not supported for FDD!");
+          }
+          /*Don't know where to extract the value of measurementTimingConfiguration from. Set it to 0 for now */
+          INT8_TO_OCTET_STRING(0, &servedCellMember->servedNRCellInfo.measurementTimingConfiguration);
+
+        }
+        ASN_SEQUENCE_ADD(&ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list, servedCellMember);
+      }
+    }
+  ASN_SEQUENCE_ADD(&ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_en_gNB.list, ie_GNB_ENDC);
+
+
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
+    X2AP_ERROR("Failed to encode X2 setup request\n");
+    return -1;
+  }
+
+  MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2Setup/initiatingMessage assoc_id %u", x2ap_eNB_data_p->assoc_id);
+
+  x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0);
+
+  return ret;
+}
+
diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.h b/openair2/X2AP/x2ap_eNB_generate_messages.h
index 1fcdf31f121e033f08e08b16e13af5bf044170e2..6b0cd9c2da21907efca3c48cac62af5adefc4d91 100644
--- a/openair2/X2AP/x2ap_eNB_generate_messages.h
+++ b/openair2/X2AP/x2ap_eNB_generate_messages.h
@@ -60,4 +60,14 @@ int x2ap_eNB_generate_x2_handover_cancel (x2ap_eNB_instance_t *instance_p, x2ap_
                                           int x2_ue_id,
                                           x2ap_handover_cancel_cause_t cause);
 
+int x2ap_eNB_generate_senb_addition_request (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p
+                                             /* TODO: pass needed parameters */);
+
+int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
+                                               x2ap_senb_addition_req_ack_t *x2ap_addition_req_ack);
+
+int x2ap_eNB_generate_ENDC_x2_setup_request(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p);
+
+int x2ap_gNB_generate_ENDC_x2_setup_response( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p);
+
 #endif /*  X2AP_ENB_GENERATE_MESSAGES_H_ */
diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c
index 33fd9c5295fb8ad890f297a4de96bb564f1f4b00..8e702a7e2e36b8398308aa98c91276f163f17347 100644
--- a/openair2/X2AP/x2ap_eNB_handler.c
+++ b/openair2/X2AP/x2ap_eNB_handler.c
@@ -84,6 +84,37 @@ int x2ap_eNB_handle_handover_cancel (instance_t instance,
                                      uint32_t stream,
                                      X2AP_X2AP_PDU_t *pdu);
 
+static
+int x2ap_eNB_handle_senb_addition_request (instance_t instance,
+                                           uint32_t assoc_id,
+                                           uint32_t stream,
+                                           X2AP_X2AP_PDU_t *pdu);
+
+
+static
+int x2ap_eNB_handle_senb_addition_request_ack (instance_t instance,
+                                                       uint32_t assoc_id,
+                                                       uint32_t stream,
+                                                       X2AP_X2AP_PDU_t *pdu);
+
+static
+int x2ap_eNB_handle_senb_addition_request_reject (instance_t instance,
+                                                  uint32_t assoc_id,
+                                                  uint32_t stream,
+                                                  X2AP_X2AP_PDU_t *pdu);
+
+int x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance,
+                                 uint32_t assoc_id,
+                                 uint32_t stream,
+                                 X2AP_X2AP_PDU_t *pdu);
+
+int
+x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance,
+                                 uint32_t assoc_id,
+                                 uint32_t stream,
+                                 X2AP_X2AP_PDU_t *pdu);
+
+
 /* Handlers matrix. Only eNB related procedure present here */
 x2ap_message_decoded_callback x2ap_messages_callback[][3] = {
   { x2ap_eNB_handle_handover_preparation, x2ap_eNB_handle_handover_response, 0 }, /* handoverPreparation */
@@ -105,14 +136,27 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = {
   { 0, 0, 0 }, /* x2Release */
   { 0, 0, 0 }, /* x2APMessageTransfer */
   { 0, 0, 0 }, /* x2Removal */
-  { 0, 0, 0 }, /* seNBAdditionPreparation */
+  { x2ap_eNB_handle_senb_addition_request, x2ap_eNB_handle_senb_addition_request_ack, x2ap_eNB_handle_senb_addition_request_reject }, /* seNBAdditionPreparation */
   { 0, 0, 0 }, /* seNBReconfigurationCompletion */
   { 0, 0, 0 }, /* meNBinitiatedSeNBModificationPreparation */
   { 0, 0, 0 }, /* seNBinitiatedSeNBModification */
   { 0, 0, 0 }, /* meNBinitiatedSeNBRelease */
   { 0, 0, 0 }, /* seNBinitiatedSeNBRelease */
   { 0, 0, 0 }, /* seNBCounterCheck */
-  { 0, 0, 0 }  /* retrieveUEContext */
+  { 0, 0, 0 },  /* retrieveUEContext */
+  { 0, 0, 0 },
+  { 0, 0, 0 },
+  { 0, 0, 0 },
+  { 0, 0, 0 },
+  { 0, 0, 0 },
+  { 0, 0, 0 },
+  { 0, 0, 0 },
+  { 0, 0, 0 },
+  { 0, 0, 0 },
+  { x2ap_gNB_handle_ENDC_x2_setup_request, x2ap_gNB_handle_ENDC_x2_setup_response, 0 },
+  { 0, 0, 0 },
+  { 0, 0, 0 },
+  { 0, 0, 0 }
 };
 
 char *x2ap_direction2String(int x2ap_dir) {
@@ -414,6 +458,7 @@ x2ap_eNB_handle_x2_setup_request(instance_t instance,
   return x2ap_eNB_generate_x2_setup_response(instance_p, x2ap_eNB_data);
 }
 
+
 static
 int x2ap_eNB_handle_x2_setup_response(instance_t instance,
                                       uint32_t assoc_id,
@@ -1073,3 +1118,508 @@ int x2ap_eNB_handle_handover_cancel (instance_t instance,
 
   return 0;
 }
+
+
+static
+int x2ap_eNB_handle_senb_addition_request (instance_t instance,
+                                           uint32_t assoc_id,
+                                           uint32_t stream,
+                                           X2AP_X2AP_PDU_t *pdu)
+{
+
+  X2AP_SeNBAdditionRequest_t             *x2SeNBAdditionRequest;
+  X2AP_SeNBAdditionRequest_IEs_t         *ie;
+
+  X2AP_E_RABs_ToBeAdded_ItemIEs_t    *e_RABS_ToBeAdded_ItemIEs;
+  X2AP_E_RABs_ToBeAdded_Item_t       *e_RABs_ToBeAdded_Item;
+
+  x2ap_eNB_instance_t                *instance_p;
+  x2ap_eNB_data_t                    *x2ap_eNB_data;
+  MessageDef                         *msg;
+  int                                ue_id;
+
+  DevAssert (pdu != NULL);
+  x2SeNBAdditionRequest = &pdu->choice.initiatingMessage.value.choice.SeNBAdditionRequest;
+
+  if (stream == 0) {
+	  X2AP_ERROR ("Received new x2 senb addition request on stream == 0\n");
+	  /* TODO: send a x2 failure response */
+      return 0;
+  }
+
+  X2AP_DEBUG ("Received a new X2 senb addition request\n");
+
+  //Panos: Do we need this for this message? Where is the x2ap_eNB_data used?
+  /*x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0);
+  DevAssert(x2ap_eNB_data != NULL);*/
+
+  instance_p = x2ap_eNB_get_instance(instance);
+  DevAssert(instance_p != NULL);
+
+  msg = itti_alloc_new_message(TASK_X2AP, X2AP_SENB_ADDITION_REQ);
+
+  /*MeNB_UE_X2AP_ID */
+  X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SeNBAdditionRequest_IEs_t, ie, x2SeNBAdditionRequest,
+		  X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID, true);
+  if (ie == NULL ) {
+	  X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+	  return -1;
+  }
+
+  //Panos: Here not sure which UE ID should be allocated to be forwarded to RRC...
+  /* allocate a new X2AP UE ID */
+  /*ue_id = x2ap_allocate_new_id(&instance_p->id_manager);
+  if (ue_id == -1) {
+	  X2AP_ERROR("could not allocate a new X2AP UE ID\n");
+      exit(1);
+  }
+
+  x2ap_set_ids(&instance_p->id_manager, ue_id, 0, ie->value.choice.UE_X2AP_ID, ue_id);
+  x2ap_id_set_state(&instance_p->id_manager, ue_id, X2ID_STATE_TARGET);*/
+
+  //For now we hardcode both MeNB and SeNB UE IDs values
+  X2AP_SENB_ADDITION_REQ(msg).x2_MeNB_UE_id = 0;
+
+  /* UESecurityCapabilities is specific to SCGBearerOption.*/
+  X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SeNBAdditionRequest_IEs_t, ie, x2SeNBAdditionRequest,
+		  X2AP_ProtocolIE_ID_id_UE_SecurityCapabilities, true);
+
+  if (ie == NULL ) {
+    	  X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+    	  return -1;
+  }
+
+
+  X2AP_SENB_ADDITION_REQ(msg).UE_security_capabilities.encryption_algorithms =
+  		  BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.encryptionAlgorithms);
+  X2AP_SENB_ADDITION_REQ(msg).UE_security_capabilities.integrity_algorithms =
+  		  BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.integrityProtectionAlgorithms);
+
+
+  /* SeNBSecurityKey is specific to SCGBearerOption.*/
+  X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SeNBAdditionRequest_IEs_t, ie, x2SeNBAdditionRequest,
+		  X2AP_ProtocolIE_ID_id_SeNBSecurityKey, true);
+
+  if (ie == NULL ) {
+	  X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+	  return -1;
+  }
+
+  memcpy(X2AP_SENB_ADDITION_REQ(msg).SeNB_security_key,
+		  &ie->value.choice.SeNBSecurityKey.buf,
+		  ie->value.choice.SeNBSecurityKey.size);
+
+  /* SeNB to UE Aggregate Maximum Bit Rate */
+  //Panos: SeNBUEAggregateMaximumBitRate: should it be added? It is not active in handover_req
+  /*X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SeNBAdditionRequest_IEs_t, ie, x2SeNBAdditionRequest,
+		  X2AP_ProtocolIE_ID_id_SeNBUEAggregateMaximumBitRate, true);*/
+
+
+  /* E-RABs_To Be Added List */
+  X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SeNBAdditionRequest_IEs_t, ie, x2SeNBAdditionRequest,
+		  X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_List, true);
+
+  if (ie == NULL ) {
+  	  X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+  	  return -1;
+    }
+
+  if (ie->value.choice.E_RABs_ToBeAdded_List.list.count > 0) {
+
+	  X2AP_SENB_ADDITION_REQ(msg).total_nb_e_rabs_tobeadded = ie->value.choice.E_RABs_ToBeAdded_List.list.count;
+      int sCG_Bearers_cnt = 0;
+      int split_Bearers_cnt = 0;
+	  for (int i=0;i<ie->value.choice.E_RABs_ToBeAdded_List.list.count;i++) {
+		  e_RABS_ToBeAdded_ItemIEs = (X2AP_E_RABs_ToBeAdded_ItemIEs_t *) ie->value.choice.E_RABs_ToBeAdded_List.list. array[i];
+		  e_RABs_ToBeAdded_Item = &e_RABS_ToBeAdded_ItemIEs->value.choice.E_RABs_ToBeAdded_Item;
+
+		  if(e_RABs_ToBeAdded_Item->present == X2AP_E_RABs_ToBeAdded_Item_PR_sCG_Bearer){
+
+			  X2AP_SENB_ADDITION_REQ(msg).e_sCG_rabs_tobeadded[sCG_Bearers_cnt].e_rab_id = e_RABs_ToBeAdded_Item->choice.sCG_Bearer.e_RAB_ID;
+
+			  memcpy(X2AP_SENB_ADDITION_REQ(msg).e_sCG_rabs_tobeadded[sCG_Bearers_cnt].eNB_addr.buffer,
+        		e_RABs_ToBeAdded_Item->choice.sCG_Bearer.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf,
+        		e_RABs_ToBeAdded_Item->choice.sCG_Bearer.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size);
+
+			  X2AP_SENB_ADDITION_REQ(msg).e_sCG_rabs_tobeadded[sCG_Bearers_cnt].eNB_addr.length =
+					  e_RABs_ToBeAdded_Item->choice.sCG_Bearer.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size * 8 - e_RABs_ToBeAdded_Item->choice.sCG_Bearer.s1_UL_GTPtunnelEndpoint.transportLayerAddress.bits_unused;
+
+			  OCTET_STRING_TO_INT32(&e_RABs_ToBeAdded_Item->choice.sCG_Bearer.s1_UL_GTPtunnelEndpoint.gTP_TEID,
+        		X2AP_SENB_ADDITION_REQ(msg).e_sCG_rabs_tobeadded[sCG_Bearers_cnt].gtp_teid);
+
+			  X2AP_SENB_ADDITION_REQ(msg).e_sCG_rab_param[sCG_Bearers_cnt].qos.qci = e_RABs_ToBeAdded_Item->choice.sCG_Bearer.e_RAB_Level_QoS_Parameters.qCI;
+			  X2AP_SENB_ADDITION_REQ(msg).e_sCG_rab_param[sCG_Bearers_cnt].qos.allocation_retention_priority.priority_level = e_RABs_ToBeAdded_Item->choice.sCG_Bearer.e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel;
+			  X2AP_SENB_ADDITION_REQ(msg).e_sCG_rab_param[sCG_Bearers_cnt].qos.allocation_retention_priority.pre_emp_capability = e_RABs_ToBeAdded_Item->choice.sCG_Bearer.e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability;
+			  X2AP_SENB_ADDITION_REQ(msg).e_sCG_rab_param[sCG_Bearers_cnt].qos.allocation_retention_priority.pre_emp_vulnerability = e_RABs_ToBeAdded_Item->choice.sCG_Bearer.e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability;
+			  sCG_Bearers_cnt++;
+		  }
+		  else if(e_RABs_ToBeAdded_Item->present == X2AP_E_RABs_ToBeAdded_Item_PR_split_Bearer){
+			  X2AP_SENB_ADDITION_REQ(msg).e_split_rabs_tobeadded[split_Bearers_cnt].e_rab_id = e_RABs_ToBeAdded_Item->choice.split_Bearer.e_RAB_ID;
+
+			  memcpy(X2AP_SENB_ADDITION_REQ(msg).e_split_rabs_tobeadded[split_Bearers_cnt].eNB_addr.buffer,
+					  e_RABs_ToBeAdded_Item->choice.split_Bearer.meNB_GTPtunnelEndpoint.transportLayerAddress.buf,
+					  e_RABs_ToBeAdded_Item->choice.split_Bearer.meNB_GTPtunnelEndpoint.transportLayerAddress.size);
+
+			  X2AP_SENB_ADDITION_REQ(msg).e_split_rabs_tobeadded[split_Bearers_cnt].eNB_addr.length =
+			  					  e_RABs_ToBeAdded_Item->choice.split_Bearer.meNB_GTPtunnelEndpoint.transportLayerAddress.size * 8 - e_RABs_ToBeAdded_Item->choice.split_Bearer.meNB_GTPtunnelEndpoint.transportLayerAddress.bits_unused;
+
+			  OCTET_STRING_TO_INT32(&e_RABs_ToBeAdded_Item->choice.split_Bearer.meNB_GTPtunnelEndpoint.gTP_TEID,
+			          		X2AP_SENB_ADDITION_REQ(msg).e_split_rabs_tobeadded[split_Bearers_cnt].gtp_teid);
+
+			  X2AP_SENB_ADDITION_REQ(msg).e_split_rab_param[split_Bearers_cnt].qos.qci = e_RABs_ToBeAdded_Item->choice.split_Bearer.e_RAB_Level_QoS_Parameters.qCI;
+			  X2AP_SENB_ADDITION_REQ(msg).e_split_rab_param[split_Bearers_cnt].qos.allocation_retention_priority.priority_level = e_RABs_ToBeAdded_Item->choice.split_Bearer.e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel;
+			  X2AP_SENB_ADDITION_REQ(msg).e_split_rab_param[split_Bearers_cnt].qos.allocation_retention_priority.pre_emp_capability = e_RABs_ToBeAdded_Item->choice.split_Bearer.e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability;
+			  X2AP_SENB_ADDITION_REQ(msg).e_split_rab_param[split_Bearers_cnt].qos.allocation_retention_priority.pre_emp_vulnerability = e_RABs_ToBeAdded_Item->choice.split_Bearer.e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability;
+			  split_Bearers_cnt++;
+		  }
+	  }
+
+  }
+  else {
+	  X2AP_ERROR ("Can't decode the e_RABs_ToBeAdded_List \n");
+  }
+
+  /*MeNB to SeNB Container */
+  X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SeNBAdditionRequest_IEs_t, ie, x2SeNBAdditionRequest,
+		  X2AP_ProtocolIE_ID_id_MeNBtoSeNBContainer, true);
+
+  if (ie == NULL ) {
+  	  X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+  	  return -1;
+  }
+
+  X2AP_MeNBtoSeNBContainer_t *c = &ie->value.choice.MeNBtoSeNBContainer;
+
+  if (c->size > 1024)
+  { printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); }
+
+  memcpy(X2AP_SENB_ADDITION_REQ(msg).rrc_buffer, c->buf, c->size);
+  X2AP_SENB_ADDITION_REQ(msg).rrc_buffer_size = c->size;
+
+
+  itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg);
+
+  return 0;
+}
+
+static
+int x2ap_eNB_handle_senb_addition_request_ack (instance_t instance,
+                                                       uint32_t assoc_id,
+                                                       uint32_t stream,
+                                                       X2AP_X2AP_PDU_t *pdu)
+{
+  printf("%s:%d:%s:TODO\n", __FILE__, __LINE__, __FUNCTION__);
+  return 0;
+}
+
+
+static
+int x2ap_eNB_handle_senb_addition_request_reject (instance_t instance,
+                                                  uint32_t assoc_id,
+                                                  uint32_t stream,
+                                                  X2AP_X2AP_PDU_t *pdu)
+{
+  printf("%s:%d:%s:TODO\n", __FILE__, __LINE__, __FUNCTION__);
+  return 0;
+}
+
+int
+x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance,
+                                 uint32_t assoc_id,
+                                 uint32_t stream,
+                                 X2AP_X2AP_PDU_t *pdu)
+{
+
+  X2AP_ENDCX2SetupRequest_t              *x2_ENDC_SetupRequest;
+  X2AP_ENDCX2SetupRequest_IEs_t          *ie;
+  X2AP_ENB_ENDCX2SetupReqIEs_t 			 *ie_ENB_ENDC;
+  ServedEUTRAcellsENDCX2ManagementList__Member                *servedCellMember;
+
+  x2ap_eNB_instance_t                *instance_p;
+  x2ap_eNB_data_t                    *x2ap_eNB_data;
+  uint32_t                           eNB_id = 0;
+
+  x2ap_eNB_data = NULL;
+  DevAssert (pdu != NULL);
+  x2_ENDC_SetupRequest = &pdu->choice.initiatingMessage.value.choice.ENDCX2SetupRequest;
+
+  /*
+   * We received a new valid X2 Setup Request on a stream != 0.
+   * * * * This should not happen -> reject eNB x2 setup request.
+   */
+
+  if (stream != 0) {
+    X2AP_ERROR("Received new x2 setup request on stream != 0\n");
+      /*
+       * Send a x2 setup failure with protocol cause unspecified
+       */
+    // Panos: Here we should be calling an ENDC specific setup_failure function instead
+    return x2ap_eNB_generate_x2_setup_failure (instance,
+                                               assoc_id,
+                                               X2AP_Cause_PR_protocol,
+                                               X2AP_CauseProtocol_unspecified,
+                                               -1);
+  }
+
+  X2AP_DEBUG("Received a new X2 setup request\n");
+
+  X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_ENDCX2SetupRequest_IEs_t, ie, x2_ENDC_SetupRequest,
+		  X2AP_ProtocolIE_ID_id_InitiatingNodeType_EndcX2Setup, true);
+
+
+
+  if (ie == NULL ) {
+    X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+    return -1;
+  } else {
+	  if (ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list.count > 0) {
+		  //Panos: Here the container parameter in X2AP_FIND_PROTOCOLIE_BY_ID should be the x2_ENDC_SetupRequest
+		  //message or the ie to which there are more nested information elements?
+		  for (int i=0; i<ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list.count;i++) {
+
+			  ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqIEs_t*) ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list.array[i];
+			  if (ie_ENB_ENDC == NULL ) {
+				  X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+				  return -1;
+			  }
+
+			  else if (ie_ENB_ENDC->id == X2AP_ProtocolIE_ID_id_GlobalENB_ID) {
+				  if (ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.present == X2AP_ENB_ID_PR_home_eNB_ID) {
+					  // Home eNB ID = 28 bits
+					  uint8_t  *eNB_id_buf = ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.home_eNB_ID.buf;
+					  if (ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 28) {
+						  //TODO: handle case were size != 28 -> notify ? reject ?
+					  }
+					  eNB_id = (eNB_id_buf[0] << 20) + (eNB_id_buf[1] << 12) + (eNB_id_buf[2] << 4) + ((eNB_id_buf[3] & 0xf0) >> 4);
+					  X2AP_DEBUG("Home eNB id: %07x\n", eNB_id);
+				  } else {
+					  // Macro eNB = 20 bits
+					  uint8_t *eNB_id_buf = ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf;
+					  if (ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 20) {
+							  //TODO: handle case were size != 20 -> notify ? reject ?
+					  }
+					  eNB_id = (eNB_id_buf[0] << 12) + (eNB_id_buf[1] << 4) + ((eNB_id_buf[2] & 0xf0) >> 4);
+					  X2AP_DEBUG("macro eNB id: %05x\n", eNB_id);
+				  }
+				  X2AP_DEBUG("Adding eNB to the list of associated eNBs\n");
+				  if ((x2ap_eNB_data = x2ap_is_eNB_id_in_list (eNB_id)) == NULL) {
+					  /*
+				       * eNB has not been found in list of associated eNB,
+				       * * * * Add it to the tail of list and initialize data
+				       */
+					  if ((x2ap_eNB_data = x2ap_is_eNB_assoc_id_in_list (assoc_id)) == NULL) {
+						  /*
+						   * ??
+						   */
+						  return -1;
+					  } else {
+						  x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING;
+						  x2ap_eNB_data->eNB_id = eNB_id;
+					  }
+				  } else {
+					  x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING;
+
+					  /*
+					   * eNB has been found in list, consider the x2 setup request as a reset connection,
+					   * * * * reseting any previous UE state if sctp association is != than the previous one
+					   */
+					  if (x2ap_eNB_data->assoc_id != assoc_id) {
+						  /*
+						   * ??: Send an overload cause...
+						   */
+						  X2AP_ERROR("Rejecting x2 setup request as eNB id %d is already associated to an active sctp association" "Previous known: %d, new one: %d\n", eNB_id, x2ap_eNB_data->assoc_id, assoc_id);
+
+						  // Panos: Here we should be calling an ENDC specific setup_failure function instead
+						  x2ap_eNB_generate_x2_setup_failure (instance,
+				                                          assoc_id,
+				                                          X2AP_Cause_PR_protocol,
+				                                          X2AP_CauseProtocol_unspecified,
+				                                          -1);
+						  return -1;
+					  }
+					  /*
+					   *  * TODO: call the reset procedure
+					   */
+				  }
+			  }
+			  else if (ie_ENB_ENDC->id == X2AP_ProtocolIE_ID_id_ServedEUTRAcellsENDCX2ManagementList){
+				  if (ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list.count > 0) {
+				      x2ap_eNB_data->num_cc = ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list.count;
+				      for (int i=0; i<ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list.count;i++) {
+				    	  servedCellMember = (ServedEUTRAcellsENDCX2ManagementList__Member *)ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list.array[i];
+				    	  x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedEUTRACellInfo.pCI;
+				      }
+				  }
+			  }
+		  }
+	  }
+	  else {
+		  X2AP_ERROR("%s %d: init_eNB list is empty \n",__FILE__,__LINE__);
+		  return -1;
+	  }
+  }
+
+  instance_p = x2ap_eNB_get_instance(instance);
+  DevAssert(instance_p != NULL);
+
+  // Panos: Here we should be calling an ENDC specific setup response function
+  return x2ap_gNB_generate_ENDC_x2_setup_response(instance_p, x2ap_eNB_data);
+  //return x2ap_eNB_generate_x2_setup_response(instance_p, x2ap_eNB_data);
+}
+
+int
+x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance,
+                                 uint32_t assoc_id,
+                                 uint32_t stream,
+                                 X2AP_X2AP_PDU_t *pdu)
+{
+
+  X2AP_ENDCX2SetupResponse_t              *x2_ENDC_SetupResponse;
+  X2AP_ENDCX2SetupResponse_IEs_t          *ie;
+  X2AP_En_gNB_ENDCX2SetupReqAckIEs_t 			 *ie_GNB_ENDC;
+  ServedNRcellsENDCX2ManagementList__Member                *servedCellMember;
+
+  x2ap_eNB_instance_t                *instance_p;
+  x2ap_eNB_data_t                    *x2ap_eNB_data;
+  uint32_t                           gNB_id = 0;
+
+  x2ap_eNB_data = NULL;
+  DevAssert (pdu != NULL);
+  x2_ENDC_SetupResponse = &pdu->choice.successfulOutcome.value.choice.ENDCX2SetupResponse;
+
+  /*
+   * We received a new valid X2 Setup Request on a stream != 0.
+   * * * * This should not happen -> reject eNB x2 setup request.
+   */
+
+  if (stream != 0) {
+    X2AP_ERROR("Received new x2 setup request on stream != 0\n");
+      /*
+       * Send a x2 setup failure with protocol cause unspecified
+       */
+    // Panos: Here we should be calling an ENDC specific setup_failure function instead
+    return x2ap_eNB_generate_x2_setup_failure (instance,
+                                               assoc_id,
+                                               X2AP_Cause_PR_protocol,
+                                               X2AP_CauseProtocol_unspecified,
+                                               -1);
+  }
+
+  X2AP_DEBUG("Received a new X2 setup request\n");
+
+  X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_ENDCX2SetupResponse_IEs_t, ie, x2_ENDC_SetupResponse,
+		  X2AP_ProtocolIE_ID_id_RespondingNodeType_EndcX2Setup, true);
+
+
+
+  if (ie == NULL ) {
+    X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+    return -1;
+  } else {
+	  if (ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_en_gNB.list.count > 0) {
+		  //Panos: Here the container parameter in X2AP_FIND_PROTOCOLIE_BY_ID should be the x2_ENDC_SetupRequest
+		  //message or the ie to which there are more nested information elements?
+		  for (int i=0; i<ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_en_gNB.list.count;i++) {
+
+			  ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqAckIEs_t*) ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_en_gNB.list.array[i];
+			  if (ie_GNB_ENDC == NULL ) {
+				  X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+				  return -1;
+			  }
+
+			  else if (ie_GNB_ENDC->id == X2AP_ProtocolIE_ID_id_Globalen_gNB_ID) {
+				  if (ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.size!= 28) {
+					  //TODO: handle case were size != 28 -> notify ? reject ?
+				  }
+				  OCTET_STRING_TO_INT32(&ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID,gNB_id);
+				  X2AP_DEBUG("gNB id: %07x\n", gNB_id);
+
+				  X2AP_DEBUG("Adding gNB to the list of associated gNBs\n");
+				  if ((x2ap_eNB_data = x2ap_is_eNB_id_in_list (gNB_id)) == NULL) {
+					  /*
+				       * eNB has not been found in list of associated eNB,
+				       * * * * Add it to the tail of list and initialize data
+				       */
+					  if ((x2ap_eNB_data = x2ap_is_eNB_assoc_id_in_list (assoc_id)) == NULL) {
+						  /*
+						   * ??
+						   */
+						  return -1;
+					  } else {
+						  x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING;
+						  x2ap_eNB_data->eNB_id = gNB_id;
+					  }
+				  } else {
+					  x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING;
+
+					  /*
+					   * eNB has been found in list, consider the x2 setup request as a reset connection,
+					   * * * * reseting any previous UE state if sctp association is != than the previous one
+					   */
+					  if (x2ap_eNB_data->assoc_id != assoc_id) {
+						  /*
+						   * ??: Send an overload cause...
+						   */
+						  X2AP_ERROR("Rejecting x2 setup request as eNB id %d is already associated to an active sctp association" "Previous known: %d, new one: %d\n", gNB_id, x2ap_eNB_data->assoc_id, assoc_id);
+
+						  // Panos: Here we should be calling an ENDC specific setup_failure function instead
+						  x2ap_eNB_generate_x2_setup_failure (instance,
+				                                          assoc_id,
+				                                          X2AP_Cause_PR_protocol,
+				                                          X2AP_CauseProtocol_unspecified,
+				                                          -1);
+						  return -1;
+					  }
+					  /*
+					   *  * TODO: call the reset procedure
+					   */
+				  }
+			  }
+			  else if (ie_GNB_ENDC->id == X2AP_ProtocolIE_ID_id_ServedNRcellsENDCX2ManagementList){
+				  if (ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.count > 0) {
+				      x2ap_eNB_data->num_cc = ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.count;
+				      for (int i=0; i<ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.count;i++) {
+				    	  servedCellMember = (ServedNRcellsENDCX2ManagementList__Member *)ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.array[i];
+				    	  x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedNRCellInfo.nrpCI;
+				    	  //servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[0]
+                                          if (servedCellMember->servedNRCellInfo.fiveGS_TAC != NULL) {
+				    	    X2AP_INFO("TAC: %02x%02x%02x\n",
+				    			    servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[0],
+				    			    servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[1],
+				    			    servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[2]);
+                                          } else {
+				    	    X2AP_INFO("TAC: (NULL)\n");
+                                          }
+
+				    	  X2AP_INFO("PLMN: %02x%02x%02x\n",
+				    			  servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[0],
+				    			  servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[1],
+				    			  servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[2]);
+				      }
+				  }
+			  }
+		  }
+	  }
+	  else {
+		  X2AP_ERROR("%s %d: init_eNB list is empty \n",__FILE__,__LINE__);
+		  return -1;
+	  }
+  }
+
+  /* Optionaly set the target eNB name */
+
+    /* The association is now ready as source and target eNBs know parameters of each other.
+     * Mark the association as connected.
+     */
+    x2ap_eNB_data->state = X2AP_ENB_STATE_READY;
+
+    instance_p = x2ap_eNB_get_instance(instance);
+    DevAssert(instance_p != NULL);
+
+    instance_p->x2_target_enb_associated_nb ++;
+    x2ap_handle_x2_setup_message(instance_p, x2ap_eNB_data, 0);
+
+    return 0;
+}
+
+
diff --git a/openair3/UTILS/conversions.h b/openair3/UTILS/conversions.h
index b4438b1aa5804c76383021c9c1ce0638d3874819..e39a841d96517078ec8f93de2b9a9565e33966a9 100644
--- a/openair3/UTILS/conversions.h
+++ b/openair3/UTILS/conversions.h
@@ -371,6 +371,26 @@ do {                                                    \
     (bITsTRING)->bits_unused = 4;                       \
 } while(0)
 
+/*
+#define INT16_TO_3_BYTE_BUFFER(x, buf) \
+do {                            \
+	(buf)[0] = 0x00; \
+    (buf)[1] = (x) >> 8;        \
+    (buf)[2] = (x);             \
+} while(0)
+*/
+
+#define NR_FIVEGS_TAC_ID_TO_BIT_STRING(x, aSN)      \
+do {                                                    \
+    (aSN)->buf = calloc(3, sizeof(uint8_t));    \
+    (aSN)->size = 3;              \
+    (aSN)->buf[0] = 0x00;		  \
+    (aSN)->buf[1] = (x) >> 8;        \
+    (aSN)->buf[2] = (x);             \
+} while(0)
+
+
+
 /* TS 38.473 v15.2.1 section 9.3.1.55:
  * MaskedIMEISV is BIT_STRING(64)
  */