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 2bf98984369b08696c79a92b013df6744eb02ca7..de9e773761a5c0f279fdc4057b00b4ad5c3ecd84 100644
--- a/openair2/X2AP/x2ap_eNB_decoder.c
+++ b/openair2/X2AP/x2ap_eNB_decoder.c
@@ -60,8 +60,8 @@ static int x2ap_eNB_decode_initiating_message(X2AP_X2AP_PDU_t *pdu)
       break;
 
     case X2AP_ProcedureCode_id_endcX2Setup:
-    	X2AP_INFO("X2AP_ProcedureCode_id_endcX2Setup message!\n");
-    	break;
+      X2AP_INFO("X2AP_ProcedureCode_id_endcX2Setup message!\n");
+      break;
 
     default:
       X2AP_ERROR("Unknown procedure ID (%d) for initiating message\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_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c
index 422f5904f650c4c9c874aed319a01b85fbe4c727..2a9406b632c71ec45acd14ed301e8f7f7decaadc 100644
--- a/openair2/X2AP/x2ap_eNB_generate_messages.c
+++ b/openair2/X2AP/x2ap_eNB_generate_messages.c
@@ -1225,9 +1225,11 @@ int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p
   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;
@@ -1349,3 +1351,145 @@ int x2ap_eNB_generate_ENDC_x2_setup_request(
 
   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_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_initiatingMessage;
+  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);
+  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);
+
+          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) {
+        	  servedCellMember->servedNRCellInfo.nrModeInfo.present = X2AP_ServedNRCell_Information__nrModeInfo_PR_tdd;
+        	  servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_ARFCN = 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 */
+          INT16_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 eb5b7f244972fc3c47010d85b9d0e98a262ad4be..6b0cd9c2da21907efca3c48cac62af5adefc4d91 100644
--- a/openair2/X2AP/x2ap_eNB_generate_messages.h
+++ b/openair2/X2AP/x2ap_eNB_generate_messages.h
@@ -68,4 +68,6 @@ int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p
 
 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 7e46be024ef3db68cd090e1c1742e8e49f2b1d7a..55d09e45b56b334230f1ba853e2fd1d60ddcbabb 100644
--- a/openair2/X2AP/x2ap_eNB_handler.c
+++ b/openair2/X2AP/x2ap_eNB_handler.c
@@ -108,6 +108,13 @@ int x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance,
                                  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 */
@@ -146,7 +153,7 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = {
   { 0, 0, 0 },
   { 0, 0, 0 },
   { 0, 0, 0 },
-  { x2ap_gNB_handle_ENDC_x2_setup_request, 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 }
@@ -1332,6 +1339,7 @@ x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance,
   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;
 
@@ -1445,6 +1453,10 @@ x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance,
 			  }
 		  }
 	  }
+	  else {
+		  X2AP_ERROR("%s %d: init_eNB list is empty \n",__FILE__,__LINE__);
+		  return -1;
+	  }
   }
 
   instance_p = x2ap_eNB_get_instance(instance);
@@ -1454,3 +1466,145 @@ x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance,
   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;
+				      }
+				  }
+			  }
+		  }
+	  }
+	  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;
+}
+
+