From ab04e0e469f48d03f1d299fa50fdd382dcf720b2 Mon Sep 17 00:00:00 2001
From: Javier Morgade <javier.morgade@ieee.org>
Date: Sat, 14 Sep 2019 13:45:27 +0200
Subject: [PATCH] 	M2AP 3GPP TS 36.443 interface implemented: 	1.MCE
 (Multicast Control Entity) entity developed (new dedicated task developed:
 TASK_MCE_APP) 	2.eNB side M2 interface procedures (new dedicated task
 developed: TASK_M2AP_ENB) 	3.MCE side M2 interface procedures (new
 dedicated task developed: TASK_M2AP_MCE) 	4.ASN1 bindings for
 m2ap-14.0.0.asn1 implemented and tested 	5.MCE config parameters

	ACKNOWLEDGEMENT:
 	1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS"
 	2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu)

	Signed-off-by: Javier Morgade <javier.morgade@ieee.org>
---
 openair2/M2AP/m2ap_MCE.c                      |  733 +++++++
 openair2/M2AP/m2ap_MCE.h                      |   55 +
 openair2/M2AP/m2ap_MCE_defs.h                 |  210 ++
 openair2/M2AP/m2ap_MCE_generate_messages.c    |  804 +++++++
 openair2/M2AP/m2ap_MCE_generate_messages.h    |   63 +
 openair2/M2AP/m2ap_MCE_handler.c              |  123 ++
 openair2/M2AP/m2ap_MCE_handler.h              |   43 +
 openair2/M2AP/m2ap_MCE_interface_management.c | 1905 +++++++++++++++++
 openair2/M2AP/m2ap_MCE_interface_management.h |  196 ++
 .../M2AP/m2ap_MCE_management_procedures.c     |  257 +++
 .../M2AP/m2ap_MCE_management_procedures.h     |   54 +
 openair2/M2AP/m2ap_common.h                   |    7 -
 openair2/M2AP/m2ap_decoder.c                  |  194 ++
 openair2/M2AP/m2ap_decoder.h                  |   35 +
 openair2/M2AP/m2ap_default_values.h           |   47 +
 openair2/M2AP/m2ap_eNB.c                      |  704 ++++++
 openair2/M2AP/m2ap_eNB.h                      |   55 +
 openair2/M2AP/m2ap_eNB_defs.h                 |  221 ++
 openair2/M2AP/m2ap_eNB_generate_messages.c    |  808 +++++++
 openair2/M2AP/m2ap_eNB_generate_messages.h    |   63 +
 openair2/M2AP/m2ap_eNB_handler.c              |  123 ++
 openair2/M2AP/m2ap_eNB_handler.h              |   43 +
 openair2/M2AP/m2ap_eNB_interface_management.c | 1385 ++++++++++++
 openair2/M2AP/m2ap_eNB_interface_management.h |  173 ++
 .../M2AP/m2ap_eNB_management_procedures.c     |  257 +++
 .../M2AP/m2ap_eNB_management_procedures.h     |   54 +
 openair2/M2AP/m2ap_encoder.c                  |   61 +
 openair2/M2AP/m2ap_encoder.h                  |   35 +
 openair2/M2AP/m2ap_handler.c                  |  123 ++
 openair2/M2AP/m2ap_handler.h                  |   43 +
 openair2/M2AP/m2ap_ids.c                      |  128 ++
 openair2/M2AP/m2ap_ids.h                      |   80 +
 openair2/M2AP/m2ap_itti_messaging.c           |   96 +
 openair2/M2AP/m2ap_itti_messaging.h           |   48 +
 openair2/M2AP/m2ap_timers.c                   |  105 +
 openair2/M2AP/m2ap_timers.h                   |   45 +
 openair2/MCE_APP/mce_app.c                    |  754 +++++++
 openair2/MCE_APP/mce_app.h                    |   41 +
 openair2/MCE_APP/mce_config.c                 |  512 +++++
 openair2/MCE_APP/mce_config.h                 |   71 +
 40 files changed, 10747 insertions(+), 7 deletions(-)
 create mode 100644 openair2/M2AP/m2ap_MCE.c
 create mode 100644 openair2/M2AP/m2ap_MCE.h
 create mode 100644 openair2/M2AP/m2ap_MCE_defs.h
 create mode 100644 openair2/M2AP/m2ap_MCE_generate_messages.c
 create mode 100644 openair2/M2AP/m2ap_MCE_generate_messages.h
 create mode 100644 openair2/M2AP/m2ap_MCE_handler.c
 create mode 100644 openair2/M2AP/m2ap_MCE_handler.h
 create mode 100644 openair2/M2AP/m2ap_MCE_interface_management.c
 create mode 100644 openair2/M2AP/m2ap_MCE_interface_management.h
 create mode 100644 openair2/M2AP/m2ap_MCE_management_procedures.c
 create mode 100644 openair2/M2AP/m2ap_MCE_management_procedures.h
 create mode 100644 openair2/M2AP/m2ap_decoder.c
 create mode 100644 openair2/M2AP/m2ap_decoder.h
 create mode 100644 openair2/M2AP/m2ap_default_values.h
 create mode 100644 openair2/M2AP/m2ap_eNB.c
 create mode 100644 openair2/M2AP/m2ap_eNB.h
 create mode 100644 openair2/M2AP/m2ap_eNB_defs.h
 create mode 100644 openair2/M2AP/m2ap_eNB_generate_messages.c
 create mode 100644 openair2/M2AP/m2ap_eNB_generate_messages.h
 create mode 100644 openair2/M2AP/m2ap_eNB_handler.c
 create mode 100644 openair2/M2AP/m2ap_eNB_handler.h
 create mode 100644 openair2/M2AP/m2ap_eNB_interface_management.c
 create mode 100644 openair2/M2AP/m2ap_eNB_interface_management.h
 create mode 100644 openair2/M2AP/m2ap_eNB_management_procedures.c
 create mode 100644 openair2/M2AP/m2ap_eNB_management_procedures.h
 create mode 100644 openair2/M2AP/m2ap_encoder.c
 create mode 100644 openair2/M2AP/m2ap_encoder.h
 create mode 100644 openair2/M2AP/m2ap_handler.c
 create mode 100644 openair2/M2AP/m2ap_handler.h
 create mode 100644 openair2/M2AP/m2ap_ids.c
 create mode 100644 openair2/M2AP/m2ap_ids.h
 create mode 100644 openair2/M2AP/m2ap_itti_messaging.c
 create mode 100644 openair2/M2AP/m2ap_itti_messaging.h
 create mode 100644 openair2/M2AP/m2ap_timers.c
 create mode 100644 openair2/M2AP/m2ap_timers.h
 create mode 100644 openair2/MCE_APP/mce_app.c
 create mode 100644 openair2/MCE_APP/mce_app.h
 create mode 100644 openair2/MCE_APP/mce_config.c
 create mode 100644 openair2/MCE_APP/mce_config.h

diff --git a/openair2/M2AP/m2ap_MCE.c b/openair2/M2AP/m2ap_MCE.c
new file mode 100644
index 0000000000..096f3cabee
--- /dev/null
+++ b/openair2/M2AP/m2ap_MCE.c
@@ -0,0 +1,733 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_MCE.c
+ * \brief m2ap tasks for MCE
+ * \author Javier Morgade  <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <arpa/inet.h>
+
+#include "intertask_interface.h"
+
+#include "m2ap_MCE.h"
+#include "m2ap_MCE_defs.h"
+#include "m2ap_MCE_management_procedures.h"
+#include "m2ap_MCE_handler.h"
+#include "m2ap_MCE_generate_messages.h"
+#include "m2ap_common.h"
+#include "m2ap_MCE_interface_management.h"
+#include "m2ap_ids.h"
+#include "m2ap_timers.h"
+
+#include "queue.h"
+#include "assertions.h"
+#include "conversions.h"
+
+struct m2ap_mce_map;
+struct m2ap_MCE_data_s;
+
+m2ap_setup_req_t *m2ap_mce_data_from_enb;
+
+RB_PROTOTYPE(m2ap_mce_map, m2ap_MCE_data_s, entry, m2ap_MCE_compare_assoc_id);
+
+static
+void m2ap_MCE_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind);
+
+static
+void m2ap_MCE_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp);
+
+static
+void m2ap_MCE_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind);
+
+static
+void m2ap_MCE_handle_register_MCE(instance_t instance,
+                                  m2ap_register_mce_req_t *m2ap_register_MCE);
+static
+void m2ap_MCE_register_MCE(m2ap_MCE_instance_t *instance_p,
+                           net_ip_address_t    *target_MCE_ip_addr,
+                           net_ip_address_t    *local_ip_addr,
+                           uint16_t             in_streams,
+                           uint16_t             out_streams,
+                           uint32_t             mce_port_for_M2C,
+                           int                  multi_sd);
+
+//static
+//void m2ap_MCE_handle_handover_req(instance_t instance,
+//                                  m2ap_handover_req_t *m2ap_handover_req);
+//
+//static
+//void m2ap_MCE_handle_handover_req_ack(instance_t instance,
+//                                      m2ap_handover_req_ack_t *m2ap_handover_req_ack);
+//
+//static
+//void m2ap_MCE_ue_context_release(instance_t instance,
+//                                 m2ap_ue_context_release_t *m2ap_ue_context_release);
+//
+
+static
+void m2ap_MCE_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) {
+  int result;
+  DevAssert(sctp_data_ind != NULL);
+  m2ap_MCE_handle_message(instance, sctp_data_ind->assoc_id, sctp_data_ind->stream,
+                          sctp_data_ind->buffer, sctp_data_ind->buffer_length);
+  result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer);
+  AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
+}
+
+static
+void m2ap_MCE_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) {
+
+   DevAssert(sctp_new_association_resp != NULL);
+
+  if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
+    LOG_W(M2AP, "Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n",
+              sctp_new_association_resp->sctp_state,
+              instance,
+              sctp_new_association_resp->ulp_cnx_id);
+
+    if (sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN)
+      //proto_agent_stop(instance);
+      //f1ap_handle_setup_message(instance, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
+    return; // exit -1 for debugging
+  }
+
+   // go to an init func
+  m2ap_mce_data_from_enb = (m2ap_setup_req_t *)calloc(1, sizeof(m2ap_setup_req_t));
+  // save the assoc id
+  m2ap_mce_data_from_enb->assoc_id         = sctp_new_association_resp->assoc_id;
+  m2ap_mce_data_from_enb->sctp_in_streams  = sctp_new_association_resp->in_streams;
+  m2ap_mce_data_from_enb->sctp_out_streams = sctp_new_association_resp->out_streams;
+
+
+
+ // m2ap_MCE_instance_t *instance_p;
+ // m2ap_MCE_data_t *m2ap_mce_data_p;
+ // DevAssert(sctp_new_association_resp != NULL);
+ // printf("m2ap_MCE_handle_sctp_association_resp at 1\n");
+ // dump_mce_trees_m2();
+ // instance_p = instance;//m2ap_MCE_get_instance(instance);
+ // DevAssert(instance_p != NULL);
+
+ // /* if the assoc_id is already known, it is certainly because an IND was received
+ //  * before. In this case, just update streams and return
+ //  */
+ // if (sctp_new_association_resp->assoc_id != -1) {
+ //   m2ap_mce_data_p = m2ap_get_MCE(instance_p, sctp_new_association_resp->assoc_id,
+ //                                  sctp_new_association_resp->ulp_cnx_id);
+
+ //   if (m2ap_mce_data_p != NULL) {
+ //     /* some sanity check - to be refined at some point */
+ //     if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
+ //       M2AP_ERROR("m2ap_mce_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED, what to do?\n");
+ //       abort();
+ //     }
+
+ //     m2ap_mce_data_p->in_streams  = sctp_new_association_resp->in_streams;
+ //     m2ap_mce_data_p->out_streams = sctp_new_association_resp->out_streams;
+ //     return;
+ //   }
+ // }
+
+ // m2ap_mce_data_p = m2ap_get_MCE(instance_p, -1,
+ //                                sctp_new_association_resp->ulp_cnx_id);
+ // DevAssert(m2ap_mce_data_p != NULL);
+ // printf("m2ap_MCE_handle_sctp_association_resp at 2\n");
+ // dump_mce_trees_m2();
+
+ // if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
+ //   M2AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n",
+ //             sctp_new_association_resp->sctp_state,
+ //             instance,
+ //             sctp_new_association_resp->ulp_cnx_id);
+ //   //m2ap_eNB_handle_m2_setup_message(instance_p, m2ap_mce_data_p,
+ //                                //sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
+ //   return;
+ // }
+
+ // printf("m2ap_MCE_handle_sctp_association_resp at 3\n");
+ // dump_mce_trees_m2();
+ // /* Update parameters */
+ // m2ap_mce_data_p->assoc_id    = sctp_new_association_resp->assoc_id;
+ // m2ap_mce_data_p->in_streams  = sctp_new_association_resp->in_streams;
+ // m2ap_mce_data_p->out_streams = sctp_new_association_resp->out_streams;
+ // printf("m2ap_MCE_handle_sctp_association_resp at 4\n");
+ // dump_mce_trees_m2();
+ // /* Prepare new m2 Setup Request */
+ // //m2ap_MCE_generate_m2_setup_request(instance_p, m2ap_mce_data_p);
+}
+
+static
+void m2ap_MCE_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind) {
+  //m2ap_MCE_instance_t *instance_p;
+  //m2ap_MCE_data_t *m2ap_mce_data_p;
+  //printf("m2ap_MCE_handle_sctp_association_ind at 1 (called for instance %d)\n", instance);
+  ///dump_mce_trees_m2();
+  ///DevAssert(sctp_new_association_ind != NULL);
+  ///instance_p = instance;//m2ap_MCE_get_instance(instance);
+  ///DevAssert(instance_p != NULL);
+  ///m2ap_mce_data_p = m2ap_get_MCE(instance_p, sctp_new_association_ind->assoc_id, -1);
+
+  ///if (m2ap_mce_data_p != NULL) abort();
+
+  /////  DevAssert(m2ap_enb_data_p != NULL);
+  ///if (m2ap_mce_data_p == NULL) {
+  ///  /* Create new MCE descriptor */
+  ///  m2ap_mce_data_p = calloc(1, sizeof(*m2ap_mce_data_p));
+  ///  DevAssert(m2ap_mce_data_p != NULL);
+  ///  m2ap_mce_data_p->cnx_id                = m2ap_MCE_fetch_add_global_cnx_id();
+  ///  m2ap_mce_data_p->m2ap_MCE_instance = instance_p;
+  ///  /* Insert the new descriptor in list of known MCE
+  ///   * but not yet associated.
+  ///   */
+  ///  RB_INSERT(m2ap_mce_map, &instance_p->m2ap_mce_head, m2ap_mce_data_p);
+  ///  m2ap_mce_data_p->state = M2AP_MCE_STATE_CONNECTED;
+  ///  instance_p->m2_target_mce_nb++;
+
+  ///  if (instance_p->m2_target_mce_pending_nb > 0) {
+  ///    instance_p->m2_target_mce_pending_nb--;
+  ///  }
+  ///} else {
+  ///  M2AP_WARN("m2ap_mce_data_p already exists\n");
+  ///}
+
+  ///printf("m2ap_MCE_handle_sctp_association_ind at 2\n");
+  ///dump_mce_trees_m2();
+  ////* Update parameters */
+  ///m2ap_mce_data_p->assoc_id    = sctp_new_association_ind->assoc_id;
+  ///m2ap_mce_data_p->in_streams  = sctp_new_association_ind->in_streams;
+  ///m2ap_mce_data_p->out_streams = sctp_new_association_ind->out_streams;
+  ///printf("m2ap_MCE_handle_sctp_association_ind at 3\n");
+  ///dump_mce_trees_m2();
+}
+
+int m2ap_MCE_init_sctp (m2ap_MCE_instance_t *instance_p,
+                        net_ip_address_t    *local_ip_addr,
+                        uint32_t mce_port_for_M2C) {
+  // Create and alloc new message
+  MessageDef                             *message;
+  sctp_init_t                            *sctp_init  = NULL;
+  DevAssert(instance_p != NULL);
+  DevAssert(local_ip_addr != NULL);
+  message = itti_alloc_new_message (TASK_M2AP_MCE, SCTP_INIT_MSG_MULTI_REQ);
+  sctp_init = &message->ittiMsg.sctp_init_multi;
+  sctp_init->port = mce_port_for_M2C;
+  sctp_init->ppid = M2AP_SCTP_PPID;
+  sctp_init->ipv4 = 1;
+  sctp_init->ipv6 = 0;
+  sctp_init->nb_ipv4_addr = 1;
+#if 0
+  memcpy(&sctp_init->ipv4_address,
+         local_ip_addr,
+         sizeof(*local_ip_addr));
+#endif
+  sctp_init->ipv4_address[0] = inet_addr(local_ip_addr->ipv4_address);
+  /*
+   * SR WARNING: ipv6 multi-homing fails sometimes for localhost.
+   * * * * Disable it for now.
+   */
+  sctp_init->nb_ipv6_addr = 0;
+  sctp_init->ipv6_address[0] = "0:0:0:0:0:0:0:1";
+  return itti_send_msg_to_task (TASK_SCTP, instance_p->instance, message);
+}
+
+static void m2ap_MCE_register_MCE(m2ap_MCE_instance_t *instance_p,
+                                  net_ip_address_t    *target_MCE_ip_address,
+                                  net_ip_address_t    *local_ip_addr,
+                                  uint16_t             in_streams,
+                                  uint16_t             out_streams,
+                                  uint32_t         mce_port_for_M2C,
+                                  int                  multi_sd) {
+  MessageDef                       *message                   = NULL;
+  sctp_new_association_req_multi_t *sctp_new_association_req  = NULL;
+  m2ap_MCE_data_t                  *m2ap_mce_data             = NULL;
+  DevAssert(instance_p != NULL);
+  DevAssert(target_MCE_ip_address != NULL);
+  message = itti_alloc_new_message(TASK_M2AP_MCE, SCTP_NEW_ASSOCIATION_REQ_MULTI);
+  sctp_new_association_req = &message->ittiMsg.sctp_new_association_req_multi;
+  sctp_new_association_req->port = mce_port_for_M2C;
+  sctp_new_association_req->ppid = M2AP_SCTP_PPID;
+  sctp_new_association_req->in_streams  = in_streams;
+  sctp_new_association_req->out_streams = out_streams;
+  sctp_new_association_req->multi_sd = multi_sd;
+  memcpy(&sctp_new_association_req->remote_address,
+         target_MCE_ip_address,
+         sizeof(*target_MCE_ip_address));
+  memcpy(&sctp_new_association_req->local_address,
+         local_ip_addr,
+         sizeof(*local_ip_addr));
+  /* Create new MCE descriptor */
+  m2ap_mce_data = calloc(1, sizeof(*m2ap_mce_data));
+  DevAssert(m2ap_mce_data != NULL);
+  m2ap_mce_data->cnx_id                = m2ap_MCE_fetch_add_global_cnx_id();
+  sctp_new_association_req->ulp_cnx_id = m2ap_mce_data->cnx_id;
+  m2ap_mce_data->assoc_id          = -1;
+  m2ap_mce_data->m2ap_MCE_instance = instance_p;
+  /* Insert the new descriptor in list of known MCE
+   * but not yet associated.
+   */
+  RB_INSERT(m2ap_mce_map, &instance_p->m2ap_mce_head, m2ap_mce_data);
+  m2ap_mce_data->state = M2AP_MCE_STATE_WAITING;
+  instance_p->m2_target_mce_nb ++;
+  instance_p->m2_target_mce_pending_nb ++;
+  itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message);
+}
+
+static
+void m2ap_MCE_handle_register_MCE(instance_t instance,
+                                  m2ap_register_mce_req_t *m2ap_register_MCE) {
+  m2ap_MCE_instance_t *new_instance;
+  DevAssert(m2ap_register_MCE != NULL);
+  /* Look if the provided instance already exists */
+  new_instance = m2ap_MCE_get_instance(instance);
+
+  if (new_instance != NULL) {
+    /* Checks if it is a retry on the same MCE */
+    DevCheck(new_instance->MCE_id == m2ap_register_MCE->MCE_id, new_instance->MCE_id, m2ap_register_MCE->MCE_id, 0);
+    DevCheck(new_instance->cell_type == m2ap_register_MCE->cell_type, new_instance->cell_type, m2ap_register_MCE->cell_type, 0);
+    DevCheck(new_instance->tac == m2ap_register_MCE->tac, new_instance->tac, m2ap_register_MCE->tac, 0);
+    DevCheck(new_instance->mcc == m2ap_register_MCE->mcc, new_instance->mcc, m2ap_register_MCE->mcc, 0);
+    DevCheck(new_instance->mnc == m2ap_register_MCE->mnc, new_instance->mnc, m2ap_register_MCE->mnc, 0);
+    M2AP_WARN("MCE[%d] already registered\n", instance);
+  } else {
+    new_instance = calloc(1, sizeof(m2ap_MCE_instance_t));
+    DevAssert(new_instance != NULL);
+    RB_INIT(&new_instance->m2ap_mce_head);
+    /* Copy usefull parameters */
+    new_instance->instance         = instance;
+    new_instance->MCE_name         = m2ap_register_MCE->MCE_name;
+    new_instance->MCE_id           = m2ap_register_MCE->MCE_id;
+    new_instance->cell_type        = m2ap_register_MCE->cell_type;
+    new_instance->tac              = m2ap_register_MCE->tac;
+    new_instance->mcc              = m2ap_register_MCE->mcc;
+    new_instance->mnc              = m2ap_register_MCE->mnc;
+    new_instance->mnc_digit_length = m2ap_register_MCE->mnc_digit_length;
+    new_instance->num_cc           = m2ap_register_MCE->num_cc;
+
+    m2ap_id_manager_init(&new_instance->id_manager);
+    m2ap_timers_init(&new_instance->timers,
+                     m2ap_register_MCE->t_reloc_prep,
+                     m2ap_register_MCE->tm2_reloc_overall);
+
+    for (int i = 0; i< m2ap_register_MCE->num_cc; i++) {
+      new_instance->eutra_band[i]              = m2ap_register_MCE->eutra_band[i];
+      new_instance->downlink_frequency[i]      = m2ap_register_MCE->downlink_frequency[i];
+      new_instance->uplink_frequency_offset[i] = m2ap_register_MCE->uplink_frequency_offset[i];
+      new_instance->Nid_cell[i]                = m2ap_register_MCE->Nid_cell[i];
+      new_instance->N_RB_DL[i]                 = m2ap_register_MCE->N_RB_DL[i];
+      new_instance->frame_type[i]              = m2ap_register_MCE->frame_type[i];
+      new_instance->fdd_earfcn_DL[i]           = m2ap_register_MCE->fdd_earfcn_DL[i];
+      new_instance->fdd_earfcn_UL[i]           = m2ap_register_MCE->fdd_earfcn_UL[i];
+    }
+
+    DevCheck(m2ap_register_MCE->nb_m2 <= M2AP_MAX_NB_MCE_IP_ADDRESS,
+             M2AP_MAX_NB_MCE_IP_ADDRESS, m2ap_register_MCE->nb_m2, 0);
+    memcpy(new_instance->target_mce_m2_ip_address,
+           m2ap_register_MCE->target_mce_m2_ip_address,
+           m2ap_register_MCE->nb_m2 * sizeof(net_ip_address_t));
+    new_instance->nb_m2             = m2ap_register_MCE->nb_m2;
+    new_instance->mce_m2_ip_address = m2ap_register_MCE->mce_m2_ip_address;
+    new_instance->sctp_in_streams   = m2ap_register_MCE->sctp_in_streams;
+    new_instance->sctp_out_streams  = m2ap_register_MCE->sctp_out_streams;
+    new_instance->mce_port_for_M2C  = m2ap_register_MCE->mce_port_for_M2C;
+    /* Add the new instance to the list of MCE (meaningfull in virtual mode) */
+    m2ap_MCE_insert_new_instance(new_instance);
+    M2AP_INFO("Registered new MCE[%d] and %s MCE id %u\n",
+              instance,
+              m2ap_register_MCE->cell_type == CELL_MACRO_ENB ? "macro" : "home",
+              m2ap_register_MCE->MCE_id);
+
+    /* initiate the SCTP listener */
+    if (m2ap_MCE_init_sctp(new_instance,&m2ap_register_MCE->mce_m2_ip_address,m2ap_register_MCE->mce_port_for_M2C) <  0 ) {
+      M2AP_ERROR ("Error while sending SCTP_INIT_MSG to SCTP \n");
+      return;
+    }
+
+    M2AP_INFO("MCE[%d] MCE id %u acting as a listner (server)\n",
+              instance, m2ap_register_MCE->MCE_id);
+  }
+}
+
+static
+void m2ap_MCE_handle_sctp_init_msg_multi_cnf(
+  instance_t instance_id,
+  sctp_init_msg_multi_cnf_t *m) {
+  m2ap_MCE_instance_t *instance;
+  int index;
+  DevAssert(m != NULL);
+  instance = m2ap_MCE_get_instance(instance_id);
+  DevAssert(instance != NULL);
+  instance->multi_sd = m->multi_sd;
+
+  /* Exit if CNF message reports failure.
+   * Failure means multi_sd < 0.
+   */
+  if (instance->multi_sd < 0) {
+    M2AP_ERROR("Error: be sure to properly configure M2 in your configuration file.\n");
+    DevAssert(instance->multi_sd >= 0);
+  }
+
+  /* Trying to connect to the provided list of MCE ip address */
+
+  for (index = 0; index < instance->nb_m2; index++) {
+    M2AP_INFO("MCE[%d] MCE id %u acting as an initiator (client)\n",
+              instance_id, instance->MCE_id);
+    m2ap_MCE_register_MCE(instance,
+                          &instance->target_mce_m2_ip_address[index],
+                          &instance->mce_m2_ip_address,
+                          instance->sctp_in_streams,
+                          instance->sctp_out_streams,
+                          instance->mce_port_for_M2C,
+                          instance->multi_sd);
+  }
+}
+
+//static
+//void m2ap_MCE_handle_handover_req(instance_t instance,
+//                                  m2ap_handover_req_t *m2ap_handover_req)
+//{
+//  m2ap_MCE_instance_t *instance_p;
+//  m2ap_MCE_data_t     *target;
+//  m2ap_id_manager     *id_manager;
+//  int                 ue_id;
+//
+//  int target_pci = m2ap_handover_req->target_physCellId;
+//
+//  instance_p = m2ap_MCE_get_instance(instance);
+//  DevAssert(instance_p != NULL);
+//
+//  target = m2ap_is_MCE_pci_in_list(target_pci);
+//  DevAssert(target != NULL);
+//
+//  /* allocate m2ap ID */
+//  id_manager = &instance_p->id_manager;
+//  ue_id = m2ap_allocate_new_id(id_manager);
+//  if (ue_id == -1) {
+//    M2AP_ERROR("could not allocate a new M2AP UE ID\n");
+//    /* TODO: cancel handover: send (to be defined) message to RRC */
+//    exit(1);
+//  }
+//  /* id_source is ue_id, id_target is unknown yet */
+//  m2ap_set_ids(id_manager, ue_id, m2ap_handover_req->rnti, ue_id, -1);
+//  m2ap_id_set_state(id_manager, ue_id, M2ID_STATE_SOURCE_PREPARE);
+//  m2ap_set_reloc_prep_timer(id_manager, ue_id,
+//                            m2ap_timer_get_tti(&instance_p->timers));
+//  m2ap_id_set_target(id_manager, ue_id, target);
+//
+//  m2ap_MCE_generate_m2_handover_request(instance_p, target, m2ap_handover_req, ue_id);
+//}
+
+//static
+//void m2ap_MCE_handle_handover_req_ack(instance_t instance,
+//                                      m2ap_handover_req_ack_t *m2ap_handover_req_ack)
+//{
+//  /* TODO: remove this hack (the goal is to find the correct
+//   * eNodeB structure for the other end) - we need a proper way for RRC
+//   * and M2AP to identify eNodeBs
+//   * RRC knows about mod_id and M2AP knows about MCE_id (MCE_ID in
+//   * the configuration file)
+//   * as far as I understand.. CROUX
+//   */
+//  m2ap_MCE_instance_t *instance_p;
+//  m2ap_MCE_data_t     *target;
+//  int source_assoc_id = m2ap_handover_req_ack->source_assoc_id;
+//  int                 ue_id;
+//  int                 id_source;
+//  int                 id_target;
+//
+//  instance_p = m2ap_MCE_get_instance(instance);
+//  DevAssert(instance_p != NULL);
+//
+//  target = m2ap_get_MCE(NULL, source_assoc_id, 0);
+//  DevAssert(target != NULL);
+//
+//  /* rnti is a new information, save it */
+//  ue_id     = m2ap_handover_req_ack->m2_id_target;
+//  id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id);
+//  id_target = ue_id;
+//  m2ap_set_ids(&instance_p->id_manager, ue_id, m2ap_handover_req_ack->rnti, id_source, id_target);
+//
+//  m2ap_MCE_generate_m2_handover_request_ack(instance_p, target, m2ap_handover_req_ack);
+//}
+//
+//static
+//void m2ap_MCE_ue_context_release(instance_t instance,
+//                                 m2ap_ue_context_release_t *m2ap_ue_context_release)
+//{
+//  m2ap_MCE_instance_t *instance_p;
+//  m2ap_MCE_data_t     *target;
+//  int source_assoc_id = m2ap_ue_context_release->source_assoc_id;
+//  int ue_id;
+//  instance_p = m2ap_MCE_get_instance(instance);
+//  DevAssert(instance_p != NULL);
+//
+//  target = m2ap_get_MCE(NULL, source_assoc_id, 0);
+//  DevAssert(target != NULL);
+//
+//  m2ap_MCE_generate_m2_ue_context_release(instance_p, target, m2ap_ue_context_release);
+//
+//  /* free the M2AP UE ID */
+//  ue_id = m2ap_find_id_from_rnti(&instance_p->id_manager, m2ap_ue_context_release->rnti);
+//  if (ue_id == -1) {
+//    M2AP_ERROR("could not find UE %x\n", m2ap_ue_context_release->rnti);
+//    exit(1);
+//  }
+//  m2ap_release_id(&instance_p->id_manager, ue_id);
+//}
+
+void MCE_task_send_sctp_init_req(instance_t enb_id, m2ap_mce_sctp_req_t * m2ap_mce_sctp_req) {
+  // 1. get the itti msg, and retrive the enb_id from the message
+  // 2. use RC.rrc[enb_id] to fill the sctp_init_t with the ip, port
+  // 3. creat an itti message to init
+
+  LOG_I(M2AP, "M2AP_SCTP_REQ(create socket)\n");
+  MessageDef  *message_p = NULL;
+
+  message_p = itti_alloc_new_message (TASK_M2AP_MCE, SCTP_INIT_MSG);
+
+ // if( m2ap_mce_sctp_req == NULL ){
+ //         message_p->ittiMsg.sctp_init.port = M2AP_PORT_NUMBER;
+ //         message_p->ittiMsg.sctp_init.ppid = M2AP_SCTP_PPID;
+ //         message_p->ittiMsg.sctp_init.ipv4 = 1;
+ //         message_p->ittiMsg.sctp_init.ipv6 = 0;
+ //         message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1;
+ //         //message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr);
+ //         message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr("127.0.0.7");
+ //         /*
+ //          * SR WARNING: ipv6 multi-homing fails sometimes for localhost.
+ //          * * * * Disable it for now.
+ //          */
+ //         message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0;
+ //         message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1";
+ // }else{
+	  message_p->ittiMsg.sctp_init.port = m2ap_mce_sctp_req->mce_port_for_M2C;
+	  message_p->ittiMsg.sctp_init.ppid = M2AP_SCTP_PPID;
+	  message_p->ittiMsg.sctp_init.ipv4 = 1;
+	  message_p->ittiMsg.sctp_init.ipv6 = 0;
+	  message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1;
+	  //message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr);
+	  message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(m2ap_mce_sctp_req->mce_m2_ip_address.ipv4_address);
+	  /*
+	   * SR WARNING: ipv6 multi-homing fails sometimes for localhost.
+	   * * * * Disable it for now.
+	   */
+	  message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0;
+	  message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1";
+ // }
+
+  itti_send_msg_to_task(TASK_SCTP, enb_id, message_p);
+}
+
+void *m2ap_MCE_task(void *arg) {
+  MessageDef *received_msg = NULL;
+  int         result;
+  M2AP_DEBUG("Starting M2AP layer\n");
+  m2ap_MCE_prepare_internal_data();
+  itti_mark_task_ready(TASK_M2AP_MCE);
+
+  //MCE_task_send_sctp_init_req(0,NULL);
+
+
+  while (1) {
+    itti_receive_msg(TASK_M2AP_MCE, &received_msg);
+
+    switch (ITTI_MSG_ID(received_msg)) {
+      case MESSAGE_TEST:
+	LOG_W(M2AP,"MCE Received MESSAGE_TEST Message\n");
+	//MessageDef * message_p = itti_alloc_new_message(TASK_M2AP_MCE, MESSAGE_TEST);
+        //itti_send_msg_to_task(TASK_M3AP, 1/*ctxt_pP->module_id*/, message_p);
+	break;
+      case TERMINATE_MESSAGE:
+        M2AP_WARN(" *** Exiting M2AP thread\n");
+        itti_exit_task();
+        break;
+
+      case M2AP_MCE_SCTP_REQ:
+	MCE_task_send_sctp_init_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+				     &M2AP_MCE_SCTP_REQ(received_msg));
+	break;
+
+      case M2AP_SUBFRAME_PROCESS:
+        m2ap_check_timers(ITTI_MESSAGE_GET_INSTANCE(received_msg));
+        break;
+
+      case M2AP_REGISTER_MCE_REQ:
+	LOG_I(M2AP,"MCE Received M2AP_REGISTER_MCE_REQ Message\n");
+        m2ap_MCE_handle_register_MCE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                     &M2AP_REGISTER_MCE_REQ(received_msg));
+        break;
+
+      case M2AP_SETUP_RESP:
+	LOG_I(M2AP,"MCE Received M2AP_SETUP_RESP Message\n");
+	MCE_send_M2_SETUP_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+				    &M2AP_SETUP_RESP(received_msg));
+	break;
+
+      case M2AP_SETUP_FAILURE:
+	LOG_I(M2AP,"MCE Received M2AP_SETUP_FAILURE Message\n");
+	MCE_send_M2_SETUP_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+				    &M2AP_SETUP_FAILURE(received_msg));
+	break;
+
+      case M2AP_MBMS_SCHEDULING_INFORMATION:
+	LOG_I(M2AP,"MCE Received M2AP_MBMS_SCHEDULING_INFORMATION Message\n");
+        MCE_send_MBMS_SCHEDULING_INFORMATION(0,
+						&M2AP_MBMS_SCHEDULING_INFORMATION(received_msg));
+	break;
+
+       case M2AP_MBMS_SESSION_START_REQ:
+	LOG_I(M2AP,"MCE Received M2AP_MBMS_SESSION_START_REQ Message\n");
+        MCE_send_MBMS_SESSION_START_REQUEST(0,
+						&M2AP_MBMS_SESSION_START_REQ(received_msg));
+	break;
+
+       case M2AP_MBMS_SESSION_STOP_REQ:
+	LOG_I(M2AP,"MCE Received M2AP_MBMS_SESSION_STOP_REQ Message\n");
+        MCE_send_MBMS_SESSION_STOP_REQUEST(0,
+						&M2AP_MBMS_SESSION_STOP_REQ(received_msg));
+	break;
+	
+       case M2AP_MBMS_SESSION_UPDATE_REQ:
+	LOG_I(M2AP,"MCE Received M2AP_MBMS_SESSION_UPDATE_REQ Message\n");
+        MCE_send_MBMS_SESSION_UPDATE_REQUEST(0,
+						&M2AP_MBMS_SESSION_UPDATE_REQ(received_msg));
+	break;
+
+       case M2AP_RESET:
+	LOG_I(M2AP,"MCE Received M2AP_RESET Message\n");
+        MCE_send_RESET(0,
+						&M2AP_RESET(received_msg));
+	break;
+
+       case M2AP_ENB_CONFIGURATION_UPDATE_ACK:
+	LOG_I(M2AP,"MCE Received M2AP_ENB_CONFIGURATION_UPDATE_ACK Message\n");
+        MCE_send_ENB_CONFIGURATION_UPDATE_ACKNOWLEDGE(0,
+						&M2AP_ENB_CONFIGURATION_UPDATE_ACK(received_msg));
+	break;
+
+       case M2AP_ENB_CONFIGURATION_UPDATE_FAILURE:
+	LOG_I(M2AP,"MCE Received M2AP_ENB_CONFIGURATION_UPDATE_FAILURE Message\n");
+        MCE_send_ENB_CONFIGURATION_UPDATE_FAILURE(0,
+						&M2AP_ENB_CONFIGURATION_UPDATE_FAILURE(received_msg));
+	break;
+
+
+       case M2AP_MCE_CONFIGURATION_UPDATE:
+	LOG_I(M2AP,"MCE Received M2AP_MCE_CONFIGURATION_UPDATE Message\n");
+        //MCE_send_MCE_CONFIGURATION_UPDATE(0,
+						//&M2AP_MCE_CONFIGURATION_UPDATE(received_msg));
+	break;
+
+
+//      case M2AP_HANDOVER_REQ:
+//        m2ap_MCE_handle_handover_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+//                                     &M2AP_HANDOVER_REQ(received_msg));
+//        break;
+//
+//      case M2AP_HANDOVER_REQ_ACK:
+//        m2ap_MCE_handle_handover_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+//                                         &M2AP_HANDOVER_REQ_ACK(received_msg));
+//        break;
+//
+//      case M2AP_UE_CONTEXT_RELEASE:
+//        m2ap_MCE_ue_context_release(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+//                                                &M2AP_UE_CONTEXT_RELEASE(received_msg));
+//        break;
+//
+      case SCTP_INIT_MSG_MULTI_CNF:
+        LOG_D(M2AP,"MCE Received SCTP_INIT_MSG_MULTI_CNF Message\n");
+        m2ap_MCE_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                                &received_msg->ittiMsg.sctp_init_msg_multi_cnf);
+        break;
+
+      case SCTP_NEW_ASSOCIATION_RESP:
+        LOG_D(M2AP,"MCE Received SCTP_NEW_ASSOCIATION_RESP Message\n");
+        m2ap_MCE_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                              &received_msg->ittiMsg.sctp_new_association_resp);
+        break;
+
+      case SCTP_NEW_ASSOCIATION_IND:
+        LOG_D(M2AP,"MCE Received SCTP_NEW_ASSOCIATION Message\n");
+        m2ap_MCE_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                             &received_msg->ittiMsg.sctp_new_association_ind);
+        break;
+
+      case SCTP_DATA_IND:
+        LOG_D(M2AP,"MCE Received SCTP_DATA_IND Message\n");
+        m2ap_MCE_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                      &received_msg->ittiMsg.sctp_data_ind);
+        break;
+
+      default:
+        M2AP_ERROR("MCE Received unhandled message: %d:%s\n",
+                   ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
+        break;
+    }
+
+    result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg);
+    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
+    received_msg = NULL;
+  }
+
+  return NULL;
+}
+
+#include "common/config/config_userapi.h"
+
+int is_m2ap_MCE_enabled(void)
+{
+  static volatile int config_loaded = 0;
+  static volatile int enabled = 0;
+  static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+
+  if (pthread_mutex_lock(&mutex)) goto mutex_error;
+
+  if (config_loaded) {
+    if (pthread_mutex_unlock(&mutex)) goto mutex_error;
+    return enabled;
+  }
+
+  char *enable_m2 = NULL;
+  paramdef_t p[] = {
+   { "enable_mce_m2", "yes/no", 0, strptr:&enable_m2, defstrval:"", TYPE_STRING, 0 }
+  };
+
+  /* TODO: do it per module - we check only first MCE */
+  config_get(p, sizeof(p)/sizeof(paramdef_t), "MCEs.[0]");
+  if (enable_m2 != NULL && strcmp(enable_m2, "yes") == 0)
+    enabled = 1;
+
+  config_loaded = 1;
+
+  if (pthread_mutex_unlock(&mutex)) goto mutex_error;
+
+  return enabled;
+
+mutex_error:
+  LOG_E(M2AP, "mutex error\n");
+  exit(1);
+}
diff --git a/openair2/M2AP/m2ap_MCE.h b/openair2/M2AP/m2ap_MCE.h
new file mode 100644
index 0000000000..563b860883
--- /dev/null
+++ b/openair2/M2AP/m2ap_MCE.h
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_MCE.h
+ * \brief m2ap tasks for MCE
+ * \author Javier Morgade <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+
+/** @defgroup _m2ap_impl_ M2AP Layer Reference Implementation
+ * @ingroup _ref_implementation_
+ * @{
+ */
+
+#ifndef M2AP_MCE_H_
+#define M2AP_MCE_H_
+
+#include "m2ap_MCE_defs.h"
+
+
+int m2ap_MCE_init_sctp (m2ap_MCE_instance_t *instance_p,
+                        net_ip_address_t    *local_ip_addr,
+                        uint32_t enb_port_for_M2C);
+
+void *m2ap_MCE_task(void *arg);
+
+int is_m2ap_MCE_enabled(void);
+
+#endif /* M2AP_MCE_H_ */
+
+/**
+ * @}
+ */
diff --git a/openair2/M2AP/m2ap_MCE_defs.h b/openair2/M2AP/m2ap_MCE_defs.h
new file mode 100644
index 0000000000..5267232d69
--- /dev/null
+++ b/openair2/M2AP/m2ap_MCE_defs.h
@@ -0,0 +1,210 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_MCE_defs.h
+ * \brief m2ap struct definitions for MCE
+ * \author Javier Morgade  <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#include <stdint.h>
+
+#include "queue.h"
+#include "tree.h"
+
+#include "sctp_eNB_defs.h"
+
+#include "m2ap_ids.h" //looks X2AP specific for HO
+#include "m2ap_timers.h"
+
+#ifndef M2AP_MCE_DEFS_H_
+#define M2AP_MCE_DEFS_H_
+
+#define M2AP_MCE_NAME_LENGTH_MAX    (150)
+
+typedef enum {
+  /* Disconnected state: initial state for any association. */
+  M2AP_MCE_STATE_DISCONNECTED = 0x0,
+
+  /* State waiting for m2 Setup response message if the target MCE accepts or
+   * M2 Setup failure if rejects the MCE.
+   */
+  M2AP_MCE_STATE_WAITING     = 0x1,
+
+  /* The MCE is successfully connected to another MCE. */
+  M2AP_MCE_STATE_CONNECTED   = 0x2,
+
+  /* M2AP is ready, and the MCE is successfully connected to another MCE. */
+  M2AP_MCE_STATE_READY             = 0x3,
+
+  M2AP_MCE_STATE_OVERLOAD          = 0x4,
+
+  M2AP_MCE_STATE_RESETTING         = 0x5,
+
+  /* Max number of states available */
+  M2AP_MCE_STATE_MAX,
+} m2ap_MCE_state_t;
+
+/* Served PLMN identity element */
+/*struct plmn_identity_s {
+  uint16_t mcc;
+  uint16_t mnc;
+  uint8_t  mnc_digit_length;
+  STAILQ_ENTRY(plmn_identity_s) next;
+};*/
+
+/* Served group id element */
+/*struct served_group_id_s {
+  uint16_t mce_group_id;
+  STAILQ_ENTRY(served_group_id_s) next;
+};*/
+
+/* Served enn code for a particular MCE */
+/*struct mce_code_s {
+  uint8_t mce_code;
+  STAILQ_ENTRY(mce_code_s) next;
+};*/
+
+struct m2ap_MCE_instance_s;
+
+/* This structure describes association of a MCE to another MCE */
+typedef struct m2ap_MCE_data_s {
+  /* MCE descriptors tree, ordered by sctp assoc id */
+  RB_ENTRY(m2ap_MCE_data_s) entry;
+
+  /* This is the optional name provided by the MME */
+  char *MCE_name;
+
+  /*  target MCE ID */
+  uint32_t MCE_id;
+
+  /* Current MCE load information (if any). */
+  //m2ap_load_state_t overload_state;
+
+  /* Current MCE->MCE M2AP association state */
+  m2ap_MCE_state_t state;
+
+  /* Next usable stream for UE signalling */
+  int32_t nextstream;
+
+  /* Number of input/ouput streams */
+  uint16_t in_streams;
+  uint16_t out_streams;
+
+  /* Connexion id used between SCTP/M2AP */
+  uint16_t cnx_id;
+
+  /* SCTP association id */
+  int32_t  assoc_id;
+
+  /* Nid cells */
+  uint32_t                Nid_cell[MAX_NUM_CCs];
+  int                     num_cc;
+
+  /* Only meaningfull in virtual mode */
+  struct m2ap_MCE_instance_s *m2ap_MCE_instance;
+} m2ap_MCE_data_t;
+
+typedef struct m2ap_MCE_instance_s {
+  /* used in simulation to store multiple MCE instances*/
+  STAILQ_ENTRY(m2ap_MCE_instance_s) m2ap_MCE_entries;
+
+  /* Number of target MCEs requested by MCE (tree size) */
+  uint32_t m2_target_mce_nb;
+  /* Number of target MCEs for which association is pending */
+  uint32_t m2_target_mce_pending_nb;
+  /* Number of target MCE successfully associated to MCE */
+  uint32_t m2_target_mce_associated_nb;
+  /* Tree of M2AP MCE associations ordered by association ID */
+  RB_HEAD(m2ap_mce_map, m2ap_MCE_data_s) m2ap_mce_head;
+
+  /* Tree of UE ordered by MCE_ue_m2ap_id's */
+  //  RB_HEAD(m2ap_ue_map, m2ap_MCE_ue_context_s) m2ap_ue_head;
+
+  /* For virtual mode, mod_id as defined in the rest of the L1/L2 stack */
+  instance_t instance;
+
+  /* Displayable name of MCE */
+  char *MCE_name;
+
+  /* Unique MCE_id to identify the MCE within EPC.
+   * In our case the MCE is a macro MCE so the id will be 20 bits long.
+   * For Home MCE id, this field should be 28 bits long.
+   */
+  uint32_t MCE_id;
+  /* The type of the cell */
+  cell_type_t cell_type;
+
+  /* Tracking area code */
+  uint16_t tac;
+
+  /* Mobile Country Code
+   * Mobile Network Code
+   */
+  uint16_t  mcc;
+  uint16_t  mnc;
+  uint8_t   mnc_digit_length;
+
+  /* CC params */
+  int16_t                 eutra_band[MAX_NUM_CCs];
+  uint32_t                downlink_frequency[MAX_NUM_CCs];
+  int32_t                 uplink_frequency_offset[MAX_NUM_CCs];
+  uint32_t                Nid_cell[MAX_NUM_CCs];
+  int16_t                 N_RB_DL[MAX_NUM_CCs];
+  lte_frame_type_t        frame_type[MAX_NUM_CCs];
+  uint32_t                fdd_earfcn_DL[MAX_NUM_CCs];
+  uint32_t                fdd_earfcn_UL[MAX_NUM_CCs];
+  int                     num_cc;
+
+  net_ip_address_t target_mce_m2_ip_address[M2AP_MAX_NB_MCE_IP_ADDRESS];
+  uint8_t          nb_m2;
+  net_ip_address_t mce_m2_ip_address;
+  uint16_t         sctp_in_streams;
+  uint16_t         sctp_out_streams;
+  uint32_t         mce_port_for_M2C;
+  int              multi_sd;
+
+  m2ap_id_manager  id_manager;
+  m2ap_timers_t    timers;
+} m2ap_MCE_instance_t;
+
+typedef struct {
+  /* List of served MCEs
+   * Only used for virtual mode
+   */
+  STAILQ_HEAD(m2ap_MCE_instances_head_s, m2ap_MCE_instance_s) m2ap_MCE_instances_head;
+  /* Nb of registered MCEs */
+  uint8_t nb_registered_MCEs;
+
+  /* Generate a unique connexion id used between M2AP and SCTP */
+  uint16_t global_cnx_id;
+} m2ap_MCE_internal_data_t;
+
+int m2ap_MCE_compare_assoc_id(struct m2ap_MCE_data_s *p1, struct m2ap_MCE_data_s *p2);
+
+/* Generate the tree management functions */
+struct m2ap_MCE_map;
+struct m2ap_MCE_data_s;
+RB_PROTOTYPE(m2ap_MCE_map, m2ap_MCE_data_s, entry, m2ap_MCE_compare_assoc_id);
+
+
+#endif /* M2AP_MCE_DEFS_H_ */
diff --git a/openair2/M2AP/m2ap_MCE_generate_messages.c b/openair2/M2AP/m2ap_MCE_generate_messages.c
new file mode 100644
index 0000000000..a28097cf1a
--- /dev/null
+++ b/openair2/M2AP/m2ap_MCE_generate_messages.c
@@ -0,0 +1,804 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_MCE_generate_messages.c
+ * \brief m2ap procedures for MCE
+ * \author Javier Morgade <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#include "intertask_interface.h"
+
+//#include "M2AP_LastVisitedCell-Item.h"
+
+#include "m2ap_common.h"
+#include "m2ap_MCE.h"
+#include "m2ap_MCE_generate_messages.h"
+#include "m2ap_encoder.h"
+#include "m2ap_decoder.h"
+#include "m2ap_ids.h"
+
+#include "m2ap_itti_messaging.h"
+
+#include "msc.h"
+#include "assertions.h"
+#include "conversions.h"
+
+int m2ap_MCE_generate_m2_setup_request(
+  m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p)
+{
+  M2AP_M2AP_PDU_t                     pdu;
+  M2AP_M2SetupRequest_t              *out;
+  M2AP_M2SetupRequest_Ies_t          *ie;
+  //M2AP_PLMN_Identity_t               *plmn;
+  //ServedCells__Member                *servedCellMember;
+  //M2AP_GU_Group_ID_t                 *gu;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  int       ret = 0;
+
+  DevAssert(instance_p != NULL);
+  DevAssert(m2ap_MCE_data_p != NULL);
+
+  m2ap_MCE_data_p->state = M2AP_MCE_STATE_WAITING;
+
+  /* Prepare the M2AP message to encode */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
+  pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_m2Setup;
+  pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject;
+  pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_M2SetupRequest;
+  out = &pdu.choice.initiatingMessage.value.choice.M2SetupRequest;
+
+  /* mandatory */
+  ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
+  //ie->id = M2AP_ProtocolIE_ID_id_GlobalMCE_ID;
+  //ie->criticality = M2AP_Criticality_reject;
+  //ie->value.present = M2AP_M2SetupRequest_IEs__value_PR_GlobalMCE_ID;
+  //MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+  //                  &ie->value.choice.GlobalMCE_ID.pLMN_Identity);
+  //ie->value.choice.GlobalMCE_ID.MCE_ID.present = M2AP_MCE_ID_PR_macro_MCE_ID;
+  //MACRO_MCE_ID_TO_BIT_STRING(instance_p->MCE_id,
+  //                           &ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID);
+  //M2AP_INFO("%d -> %02x%02x%02x\n", instance_p->MCE_id,
+  //          ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[0],
+  //          ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[1],
+  //          ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[2]);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
+  //ie->id = M2AP_ProtocolIE_ID_id_ServedCells;
+  //ie->criticality = M2AP_Criticality_reject;
+  //ie->value.present = M2AP_M2SetupRequest_IEs__value_PR_ServedCells;
+  //{
+  //  for (int i = 0; i<instance_p->num_cc; i++){
+  //    servedCellMember = (ServedCells__Member *)calloc(1,sizeof(ServedCells__Member));
+  //    {
+  //      servedCellMember->servedCellInfo.pCI = instance_p->Nid_cell[i];
+
+  //      MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+  //                    &servedCellMember->servedCellInfo.cellId.pLMN_Identity);
+  //      MACRO_MCE_ID_TO_CELL_IDENTITY(instance_p->MCE_id,0,
+  //                                 &servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier);
+
+  //      INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC);
+  //      plmn = (M2AP_PLMN_Identity_t *)calloc(1,sizeof(M2AP_PLMN_Identity_t));
+  //      {
+  //        MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn);
+  //        ASN_SEQUENCE_ADD(&servedCellMember->servedCellInfo.broadcastPLMNs.list, plmn);
+  //      }
+
+  //      if (instance_p->frame_type[i] == FDD) {
+  //        servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = M2AP_EUTRA_Mode_Info_PR_fDD;
+  //        servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i];
+  //        servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i];
+  //        switch (instance_p->N_RB_DL[i]) {
+  //          case 6:
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6;
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6;
+  //            break;
+  //          case 15:
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15;
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15;
+  //            break;
+  //          case 25:
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25;
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25;
+  //            break;
+  //          case 50:
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50;
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50;
+  //            break;
+  //          case 75:
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75;
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75;
+  //            break;
+  //          case 100:
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100;
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100;
+  //            break;
+  //          default:
+  //            AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
+  //            break;
+  //        }
+  //      }
+  //      else {
+  //        AssertFatal(0,"M2Setuprequest not supported for TDD!");
+  //      }
+  //    }
+  //    ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember);
+  //  }
+  //}
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
+  //ie->id = M2AP_ProtocolIE_ID_id_GUGroupIDList;
+  //ie->criticality = M2AP_Criticality_reject;
+  //ie->value.present = M2AP_M2SetupRequest_IEs__value_PR_GUGroupIDList;
+  //{
+  //  gu = (M2AP_GU_Group_ID_t *)calloc(1, sizeof(M2AP_GU_Group_ID_t));
+  //  {
+  //    MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+  //                  &gu->pLMN_Identity);
+  //    //@TODO: consider to update this value
+  //    INT16_TO_OCTET_STRING(0, &gu->mME_Group_ID);
+  //  }
+  //  ASN_SEQUENCE_ADD(&ie->value.choice.GUGroupIDList.list, gu);
+  //}
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    M2AP_ERROR("Failed to encode M2 setup request\n");
+    return -1;
+  }
+
+  //MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 M2Setup/initiatingMessage assoc_id %u", m2ap_MCE_data_p->assoc_id);
+
+  m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 0);
+
+  return ret;
+}
+
+int m2ap_MCE_generate_m2_setup_response(m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p)
+{
+  M2AP_M2AP_PDU_t                     pdu;
+  M2AP_M2SetupResponse_t              *out;
+  M2AP_M2SetupResponse_Ies_t          *ie;
+  //M2AP_PLMN_Identity_t                *plmn;
+  //ServedCells__Member                 *servedCellMember;
+  //M2AP_GU_Group_ID_t                  *gu;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  int       ret = 0;
+
+  DevAssert(instance_p != NULL);
+  DevAssert(m2ap_MCE_data_p != NULL);
+
+  /* Prepare the M2AP message to encode */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome;
+  pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup;
+  pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject;
+  pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_M2SetupResponse;
+  out = &pdu.choice.successfulOutcome.value.choice.M2SetupResponse;
+
+  /* mandatory */
+  ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t));
+  //ie->id = M2AP_ProtocolIE_ID_id_GlobalMCE_ID;
+  //ie->criticality = M2AP_Criticality_reject;
+  //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_GlobalMCE_ID;
+  //MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+  //                  &ie->value.choice.GlobalMCE_ID.pLMN_Identity);
+  //ie->value.choice.GlobalMCE_ID.MCE_ID.present = M2AP_MCE_ID_PR_macro_MCE_ID;
+  //MACRO_MCE_ID_TO_BIT_STRING(instance_p->MCE_id,
+  //                           &ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID);
+  //M2AP_INFO("%d -> %02x%02x%02x\n", instance_p->MCE_id,
+  //          ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[0],
+  //          ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[1],
+  //          ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[2]);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t));
+  //ie->id = M2AP_ProtocolIE_ID_id_ServedCells;
+  //ie->criticality = M2AP_Criticality_reject;
+  //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_ServedCells;
+  //{
+  //  for (int i = 0; i<instance_p->num_cc; i++){
+  //    servedCellMember = (ServedCells__Member *)calloc(1,sizeof(ServedCells__Member));
+  //    {
+  //      servedCellMember->servedCellInfo.pCI = instance_p->Nid_cell[i];
+
+  //      MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+  //                    &servedCellMember->servedCellInfo.cellId.pLMN_Identity);
+  //      MACRO_MCE_ID_TO_CELL_IDENTITY(instance_p->MCE_id,0,
+  //                                 &servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier);
+
+  //      INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC);
+  //      plmn = (M2AP_PLMN_Identity_t *)calloc(1,sizeof(M2AP_PLMN_Identity_t));
+  //      {
+  //        MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn);
+  //        ASN_SEQUENCE_ADD(&servedCellMember->servedCellInfo.broadcastPLMNs.list, plmn);
+  //      }
+
+  //      if (instance_p->frame_type[i] == FDD) {
+  //        servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = M2AP_EUTRA_Mode_Info_PR_fDD;
+  //        servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i];
+  //        servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i];
+  //        switch (instance_p->N_RB_DL[i]) {
+  //          case 6:
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6;
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6;
+  //            break;
+  //          case 15:
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15;
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15;
+  //            break;
+  //          case 25:
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25;
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25;
+  //            break;
+  //          case 50:
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50;
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50;
+  //            break;
+  //          case 75:
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75;
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75;
+  //            break;
+  //          case 100:
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100;
+  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100;
+  //            break;
+  //          default:
+  //            AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
+  //            break;
+  //        }
+  //      }
+  //      else {
+  //        AssertFatal(0,"M2Setupresponse not supported for TDD!");
+  //      }
+  //    }
+  //    ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember);
+  //  }
+  //}
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t));
+  //ie->id = M2AP_ProtocolIE_ID_id_GUGroupIDList;
+  //ie->criticality = M2AP_Criticality_reject;
+  //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_GUGroupIDList;
+  //{
+  //  gu = (M2AP_GU_Group_ID_t *)calloc(1, sizeof(M2AP_GU_Group_ID_t));
+  //  {
+  //    MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+  //                  &gu->pLMN_Identity);
+  //    //@TODO: consider to update this value
+  //    INT16_TO_OCTET_STRING(0, &gu->mME_Group_ID);
+  //  }
+  //  ASN_SEQUENCE_ADD(&ie->value.choice.GUGroupIDList.list, gu);
+  //}
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    M2AP_ERROR("Failed to encode M2 setup response\n");
+    return -1;
+  }
+
+  m2ap_MCE_data_p->state = M2AP_MCE_STATE_READY;
+
+  //MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 M2Setup/successfulOutcome assoc_id %u", m2ap_MCE_data_p->assoc_id);
+
+  m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 0);
+
+  return ret;
+}
+
+int m2ap_MCE_generate_m2_setup_failure(instance_t instance,
+                                       uint32_t assoc_id,
+                                       M2AP_Cause_PR cause_type,
+                                       long cause_value,
+                                       long time_to_wait)
+{
+  M2AP_M2AP_PDU_t                     pdu;
+  M2AP_M2SetupFailure_t              *out;
+  M2AP_M2SetupFailure_Ies_t          *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  int       ret = 0;
+
+  /* Prepare the M2AP message to encode */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = M2AP_M2AP_PDU_PR_unsuccessfulOutcome;
+  pdu.choice.unsuccessfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup;
+  pdu.choice.unsuccessfulOutcome.criticality = M2AP_Criticality_reject;
+  pdu.choice.unsuccessfulOutcome.value.present = M2AP_UnsuccessfulOutcome__value_PR_M2SetupFailure;
+  out = &pdu.choice.unsuccessfulOutcome.value.choice.M2SetupFailure;
+
+  /* mandatory */
+  ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t));
+  //ie->id = M2AP_ProtocolIE_ID_id_Cause;
+  //ie->criticality = M2AP_Criticality_ignore;
+  //ie->value.present = M2AP_M2SetupFailure_IEs__value_PR_Cause;
+
+  //m2ap_MCE_set_cause (&ie->value.choice.Cause, cause_type, cause_value);
+
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* optional: consider to handle this later */
+  ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t));
+  //ie->id = M2AP_ProtocolIE_ID_id_TimeToWait;
+  //ie->criticality = M2AP_Criticality_ignore;
+  //ie->value.present = M2AP_M2SetupFailure_IEs__value_PR_TimeToWait;
+
+  //if (time_to_wait > -1) {
+  //  ie->value.choice.TimeToWait = time_to_wait;
+  //}
+
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    M2AP_ERROR("Failed to encode M2 setup failure\n");
+    return -1;
+  }
+
+  //MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE,
+  //                    MSC_M2AP_TARGET_MCE, NULL, 0,
+  //                    "0 M2Setup/unsuccessfulOutcome  assoc_id %u cause %u value %u",
+  //                    assoc_id, cause_type, cause_value);
+
+  m2ap_MCE_itti_send_sctp_data_req(instance, assoc_id, buffer, len, 0);
+
+  return ret;
+}
+
+int m2ap_MCE_set_cause (M2AP_Cause_t * cause_p,
+                        M2AP_Cause_PR cause_type,
+                        long cause_value)
+{
+
+  DevAssert (cause_p != NULL);
+  cause_p->present = cause_type;
+
+  switch (cause_type) {
+  case M2AP_Cause_PR_radioNetwork:
+    cause_p->choice.misc = cause_value;
+    break;
+
+  case M2AP_Cause_PR_transport:
+    cause_p->choice.misc = cause_value;
+    break;
+
+  case M2AP_Cause_PR_protocol:
+    cause_p->choice.misc = cause_value;
+    break;
+
+  case M2AP_Cause_PR_misc:
+    cause_p->choice.misc = cause_value;
+    break;
+
+  default:
+    return -1;
+  }
+
+  return 0;
+}
+
+//int m2ap_MCE_generate_m2_handover_request (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
+//                                           m2ap_handover_req_t *m2ap_handover_req, int ue_id)
+//{
+//
+//  M2AP_M2AP_PDU_t                     pdu;
+//  M2AP_HandoverRequest_t              *out;
+//  M2AP_HandoverRequest_IEs_t          *ie;
+//  M2AP_E_RABs_ToBeSetup_ItemIEs_t     *e_RABS_ToBeSetup_ItemIEs;
+//  M2AP_E_RABs_ToBeSetup_Item_t        *e_RABs_ToBeSetup_Item;
+//  M2AP_LastVisitedCell_Item_t         *lastVisitedCell_Item;
+//
+//  uint8_t  *buffer;
+//  uint32_t  len;
+//  int       ret = 0;
+//
+//  DevAssert(instance_p != NULL);
+//  DevAssert(m2ap_MCE_data_p != NULL);
+//
+//  /* Prepare the M2AP handover message to encode */
+//  memset(&pdu, 0, sizeof(pdu));
+//  pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
+//  pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_handoverPreparation;
+//  pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject;
+//  pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_HandoverRequest;
+//  out = &pdu.choice.initiatingMessage.value.choice.HandoverRequest;
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_Old_MCE_UE_M2AP_ID;
+//  ie->criticality = M2AP_Criticality_reject;
+//  ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_M2AP_ID;
+//  ie->value.choice.UE_M2AP_ID = m2ap_id_get_id_source(&instance_p->id_manager, ue_id);
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_Cause;
+//  ie->criticality = M2AP_Criticality_ignore;
+//  ie->value.present = M2AP_HandoverRequest_IEs__value_PR_Cause;
+//  ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork;
+//  ie->value.choice.Cause.choice.radioNetwork = M2AP_CauseRadioNetwork_handover_desirable_for_radio_reasons;
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_TargetCell_ID;
+//  ie->criticality = M2AP_Criticality_reject;
+//  ie->value.present = M2AP_HandoverRequest_IEs__value_PR_ECGI;
+//  MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+//                       &ie->value.choice.ECGI.pLMN_Identity);
+//  MACRO_MCE_ID_TO_CELL_IDENTITY(m2ap_MCE_data_p->MCE_id, 0, &ie->value.choice.ECGI.eUTRANcellIdentifier);
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_GUMMEI_ID;
+//  ie->criticality = M2AP_Criticality_reject;
+//  ie->value.present = M2AP_HandoverRequest_IEs__value_PR_GUMMEI;
+//  MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+//                       &ie->value.choice.GUMMEI.gU_Group_ID.pLMN_Identity);
+//  //@TODO: consider to update these values
+//  INT16_TO_OCTET_STRING(m2ap_handover_req->ue_gummei.mme_group_id, &ie->value.choice.GUMMEI.gU_Group_ID.mME_Group_ID);
+//  MME_CODE_TO_OCTET_STRING(m2ap_handover_req->ue_gummei.mme_code, &ie->value.choice.GUMMEI.mME_Code);
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_UE_ContextInformation;
+//  ie->criticality = M2AP_Criticality_reject;
+//  ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_ContextInformation;
+//  //@TODO: consider to update this value
+//  ie->value.choice.UE_ContextInformation.mME_UE_S1AP_ID = m2ap_handover_req->mme_ue_s1ap_id;
+//
+//  KMCE_STAR_TO_BIT_STRING(m2ap_handover_req->kenb,&ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star);
+//
+//  if (m2ap_handover_req->kenb_ncc >=0) { // Check this condition
+//    ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = m2ap_handover_req->kenb_ncc;
+//  }
+//  else {
+//    ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = 1;
+//  }
+//
+//  ENCRALG_TO_BIT_STRING(m2ap_handover_req->security_capabilities.encryption_algorithms,
+//              &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms);
+//
+//  INTPROTALG_TO_BIT_STRING(m2ap_handover_req->security_capabilities.integrity_algorithms,
+//              &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms);
+//
+//  //@TODO: update with proper UEAMPR
+//  UEAGMAXBITRTD_TO_ASN_PRIMITIVES(3L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink);
+//  UEAGMAXBITRTU_TO_ASN_PRIMITIVES(6L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateUplink);
+//  {
+//    for (int i=0;i<m2ap_handover_req->nb_e_rabs_tobesetup;i++) {
+//      e_RABS_ToBeSetup_ItemIEs = (M2AP_E_RABs_ToBeSetup_ItemIEs_t *)calloc(1,sizeof(M2AP_E_RABs_ToBeSetup_ItemIEs_t));
+//      e_RABS_ToBeSetup_ItemIEs->id = M2AP_ProtocolIE_ID_id_E_RABs_ToBeSetup_Item;
+//      e_RABS_ToBeSetup_ItemIEs->criticality = M2AP_Criticality_ignore;
+//      e_RABS_ToBeSetup_ItemIEs->value.present = M2AP_E_RABs_ToBeSetup_ItemIEs__value_PR_E_RABs_ToBeSetup_Item;
+//      e_RABs_ToBeSetup_Item = &e_RABS_ToBeSetup_ItemIEs->value.choice.E_RABs_ToBeSetup_Item;
+//      {
+//        e_RABs_ToBeSetup_Item->e_RAB_ID = m2ap_handover_req->e_rabs_tobesetup[i].e_rab_id;
+//        e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.qCI = m2ap_handover_req->e_rab_param[i].qos.qci;
+//        e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.priority_level;
+//        e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability;
+//        e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability;
+//        e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size = (uint8_t)(m2ap_handover_req->e_rabs_tobesetup[i].MCE_addr.length/8);
+//        e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = m2ap_handover_req->e_rabs_tobesetup[i].MCE_addr.length%8;
+//        e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf =
+//                        calloc(1,e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size);
+//
+//        memcpy (e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf,
+//                        m2ap_handover_req->e_rabs_tobesetup[i].MCE_addr.buffer,
+//                        e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size);
+//
+//        INT32_TO_OCTET_STRING(m2ap_handover_req->e_rabs_tobesetup[i].gtp_teid,&e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.gTP_TEID);
+//      }
+//      ASN_SEQUENCE_ADD(&ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list, e_RABS_ToBeSetup_ItemIEs);
+//    }
+//  }
+//
+//  OCTET_STRING_fromBuf(&ie->value.choice.UE_ContextInformation.rRC_Context, (char*) m2ap_handover_req->rrc_buffer, m2ap_handover_req->rrc_buffer_size);
+//
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_UE_HistoryInformation;
+//  ie->criticality = M2AP_Criticality_ignore;
+//  ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_HistoryInformation;
+//  //@TODO: consider to update this value
+//  {
+//   lastVisitedCell_Item = (M2AP_LastVisitedCell_Item_t *)calloc(1, sizeof(M2AP_LastVisitedCell_Item_t));
+//   lastVisitedCell_Item->present = M2AP_LastVisitedCell_Item_PR_e_UTRAN_Cell;
+//   MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+//                       &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.pLMN_Identity);
+//   MACRO_MCE_ID_TO_CELL_IDENTITY(0, 0, &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.eUTRANcellIdentifier);
+//   lastVisitedCell_Item->choice.e_UTRAN_Cell.cellType.cell_Size = M2AP_Cell_Size_small;
+//   lastVisitedCell_Item->choice.e_UTRAN_Cell.time_UE_StayedInCell = 2;
+//   ASN_SEQUENCE_ADD(&ie->value.choice.UE_HistoryInformation.list, lastVisitedCell_Item);
+//  }
+//
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  if (m2ap_MCE_encode_pdu(&pdu, &buffer, &len) < 0) {
+//    M2AP_ERROR("Failed to encode X2 handover request\n");
+//    abort();
+//    return -1;
+//  }
+//
+//  MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 X2Handover/initiatingMessage assoc_id %u", m2ap_MCE_data_p->assoc_id);
+//
+//  m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 1);
+//
+//  return ret;
+//}
+//
+//int m2ap_MCE_generate_m2_handover_request_ack (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
+//                                               m2ap_handover_req_ack_t *m2ap_handover_req_ack)
+//{
+//
+//  M2AP_M2AP_PDU_t                        pdu;
+//  M2AP_HandoverRequestAcknowledge_t      *out;
+//  M2AP_HandoverRequestAcknowledge_IEs_t  *ie;
+//  M2AP_E_RABs_Admitted_ItemIEs_t         *e_RABS_Admitted_ItemIEs;
+//  M2AP_E_RABs_Admitted_Item_t            *e_RABs_Admitted_Item;
+//  int                                    ue_id;
+//  int                                    id_source;
+//  int                                    id_target;
+//
+//  uint8_t  *buffer;
+//  uint32_t  len;
+//  int       ret = 0;
+//
+//  DevAssert(instance_p != NULL);
+//  DevAssert(m2ap_MCE_data_p != NULL);
+//
+//  ue_id     = m2ap_handover_req_ack->m2_id_target;
+//  id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id);
+//  id_target = ue_id;
+//
+//  /* Prepare the M2AP handover message to encode */
+//  memset(&pdu, 0, sizeof(pdu));
+//  pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome;
+//  pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_handoverPreparation;
+//  pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject;
+//  pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_HandoverRequestAcknowledge;
+//  out = &pdu.choice.successfulOutcome.value.choice.HandoverRequestAcknowledge;
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_Old_MCE_UE_M2AP_ID;
+//  ie->criticality = M2AP_Criticality_ignore;
+//  ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M2AP_ID;
+//  ie->value.choice.UE_M2AP_ID = id_source;
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_New_MCE_UE_M2AP_ID;
+//  ie->criticality = M2AP_Criticality_ignore;
+//  ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M2AP_ID_1;
+//  ie->value.choice.UE_M2AP_ID_1 = id_target;
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_E_RABs_Admitted_List;
+//  ie->criticality = M2AP_Criticality_ignore;
+//  ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_E_RABs_Admitted_List;
+//
+//  {
+//      for (int i=0;i<m2ap_handover_req_ack->nb_e_rabs_tobesetup;i++) {
+//        e_RABS_Admitted_ItemIEs = (M2AP_E_RABs_Admitted_ItemIEs_t *)calloc(1,sizeof(M2AP_E_RABs_Admitted_ItemIEs_t));
+//        e_RABS_Admitted_ItemIEs->id = M2AP_ProtocolIE_ID_id_E_RABs_Admitted_Item;
+//        e_RABS_Admitted_ItemIEs->criticality = M2AP_Criticality_ignore;
+//        e_RABS_Admitted_ItemIEs->value.present = M2AP_E_RABs_Admitted_ItemIEs__value_PR_E_RABs_Admitted_Item;
+//        e_RABs_Admitted_Item = &e_RABS_Admitted_ItemIEs->value.choice.E_RABs_Admitted_Item;
+//        {
+//          e_RABs_Admitted_Item->e_RAB_ID = m2ap_handover_req_ack->e_rabs_tobesetup[i].e_rab_id;
+//        }
+//        ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_List.list, e_RABS_Admitted_ItemIEs);
+//      }
+//  }
+//
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_TargetMCEtoSource_MCETransparentContainer;
+//  ie->criticality = M2AP_Criticality_ignore;
+//  ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_TargetMCEtoSource_MCETransparentContainer;
+//
+//  OCTET_STRING_fromBuf(&ie->value.choice.TargetMCEtoSource_MCETransparentContainer, (char*) m2ap_handover_req_ack->rrc_buffer, m2ap_handover_req_ack->rrc_buffer_size);
+//
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  if (m2ap_MCE_encode_pdu(&pdu, &buffer, &len) < 0) {
+//    M2AP_ERROR("Failed to encode X2 handover response\n");
+//    abort();
+//    return -1;
+//  }
+//
+//  MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 X2Handover/successfulOutcome assoc_id %u", m2ap_MCE_data_p->assoc_id);
+//
+//  m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 1);
+//
+//  return ret;
+//}
+//
+//int m2ap_MCE_generate_m2_ue_context_release (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p, m2ap_ue_context_release_t *m2ap_ue_context_release)
+//{
+//
+//  M2AP_M2AP_PDU_t                pdu;
+//  M2AP_UEContextRelease_t        *out;
+//  M2AP_UEContextRelease_IEs_t    *ie;
+//  int                            ue_id;
+//  int                            id_source;
+//  int                            id_target;
+//
+//  uint8_t  *buffer;
+//  uint32_t  len;
+//  int       ret = 0;
+//
+//  DevAssert(instance_p != NULL);
+//  DevAssert(m2ap_MCE_data_p != NULL);
+//
+//  ue_id = m2ap_find_id_from_rnti(&instance_p->id_manager, m2ap_ue_context_release->rnti);
+//  if (ue_id == -1) {
+//    M2AP_ERROR("could not find UE %x\n", m2ap_ue_context_release->rnti);
+//    exit(1);
+//  }
+//  id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id);
+//  id_target = ue_id;
+//
+//  /* Prepare the M2AP ue context relase message to encode */
+//  memset(&pdu, 0, sizeof(pdu));
+//  pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
+//  pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_uEContextRelease;
+//  pdu.choice.initiatingMessage.criticality = M2AP_Criticality_ignore;
+//  pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_UEContextRelease;
+//  out = &pdu.choice.initiatingMessage.value.choice.UEContextRelease;
+//
+//  /* mandatory */
+//  ie = (M2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M2AP_UEContextRelease_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_Old_MCE_UE_M2AP_ID;
+//  ie->criticality = M2AP_Criticality_reject;
+//  ie->value.present = M2AP_UEContextRelease_IEs__value_PR_UE_M2AP_ID;
+//  ie->value.choice.UE_M2AP_ID = id_source;
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* mandatory */
+//  ie = (M2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M2AP_UEContextRelease_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_New_MCE_UE_M2AP_ID;
+//  ie->criticality = M2AP_Criticality_reject;
+//  ie->value.present = M2AP_UEContextRelease_IEs__value_PR_UE_M2AP_ID_1;
+//  ie->value.choice.UE_M2AP_ID_1 = id_target;
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  if (m2ap_MCE_encode_pdu(&pdu, &buffer, &len) < 0) {
+//    M2AP_ERROR("Failed to encode X2 UE Context Release\n");
+//    abort();
+//    return -1;
+//  }
+//
+//  MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 X2UEContextRelease/initiatingMessage assoc_id %u", m2ap_MCE_data_p->assoc_id);
+//
+//  m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 1);
+//
+//  return ret;
+//}
+//
+//int m2ap_MCE_generate_m2_handover_cancel (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
+//                                          int m2_ue_id,
+//                                          m2ap_handover_cancel_cause_t cause)
+//{
+//  M2AP_M2AP_PDU_t              pdu;
+//  M2AP_HandoverCancel_t        *out;
+//  M2AP_HandoverCancel_IEs_t    *ie;
+//  int                          ue_id;
+//  int                          id_source;
+//  int                          id_target;
+//
+//  uint8_t  *buffer;
+//  uint32_t  len;
+//  int       ret = 0;
+//
+//  DevAssert(instance_p != NULL);
+//  DevAssert(m2ap_MCE_data_p != NULL);
+//
+//  ue_id = m2_ue_id;
+//  id_source = ue_id;
+//  id_target = m2ap_id_get_id_target(&instance_p->id_manager, ue_id);
+//
+//  /* Prepare the M2AP handover cancel message to encode */
+//  memset(&pdu, 0, sizeof(pdu));
+//  pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
+//  pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_handoverCancel;
+//  pdu.choice.initiatingMessage.criticality = M2AP_Criticality_ignore;
+//  pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_HandoverCancel;
+//  out = &pdu.choice.initiatingMessage.value.choice.HandoverCancel;
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_Old_MCE_UE_M2AP_ID;
+//  ie->criticality = M2AP_Criticality_reject;
+//  ie->value.present = M2AP_HandoverCancel_IEs__value_PR_UE_M2AP_ID;
+//  ie->value.choice.UE_M2AP_ID = id_source;
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* optional */
+//  if (id_target != -1) {
+//    ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t));
+//    ie->id = M2AP_ProtocolIE_ID_id_New_MCE_UE_M2AP_ID;
+//    ie->criticality = M2AP_Criticality_ignore;
+//    ie->value.present = M2AP_HandoverCancel_IEs__value_PR_UE_M2AP_ID_1;
+//    ie->value.choice.UE_M2AP_ID_1 = id_target;
+//    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//  }
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_Cause;
+//  ie->criticality = M2AP_Criticality_ignore;
+//  ie->value.present = M2AP_HandoverCancel_IEs__value_PR_Cause;
+//  switch (cause) {
+//  case M2AP_T_RELOC_PREP_TIMEOUT:
+//    ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork;
+//    ie->value.choice.Cause.choice.radioNetwork =
+//      M2AP_CauseRadioNetwork_trelocprep_expiry;
+//    break;
+//  case M2AP_TX2_RELOC_OVERALL_TIMEOUT:
+//    ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork;
+//    ie->value.choice.Cause.choice.radioNetwork =
+//      M2AP_CauseRadioNetwork_tx2relocoverall_expiry;
+//    break;
+//  default:
+//    /* we can't come here */
+//    M2AP_ERROR("unhandled cancel cause\n");
+//    exit(1);
+//  }
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  if (m2ap_MCE_encode_pdu(&pdu, &buffer, &len) < 0) {
+//    M2AP_ERROR("Failed to encode X2 Handover Cancel\n");
+//    abort();
+//    return -1;
+//  }
+//
+//  MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 X2HandoverCancel/initiatingMessage assoc_id %u", m2ap_MCE_data_p->assoc_id);
+//
+//  m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 1);
+//
+//  return ret;
+//}
diff --git a/openair2/M2AP/m2ap_MCE_generate_messages.h b/openair2/M2AP/m2ap_MCE_generate_messages.h
new file mode 100644
index 0000000000..1632dc807a
--- /dev/null
+++ b/openair2/M2AP/m2ap_MCE_generate_messages.h
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_MCE_generate_messages.h
+ * \brief m2ap procedures for MCE
+ * \author Javier Morgade <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#ifndef M2AP_MCE_GENERATE_MESSAGES_H_
+#define M2AP_MCE_GENERATE_MESSAGES_H_
+
+#include "m2ap_MCE_defs.h"
+#include "m2ap_common.h"
+
+int m2ap_MCE_generate_m2_setup_request(m2ap_MCE_instance_t *instance_p,
+				       m2ap_MCE_data_t *m2ap_MCE_data_p);
+
+int m2ap_MCE_generate_m2_setup_response(m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p);
+
+int m2ap_MCE_generate_m2_setup_failure(instance_t instance,
+                                       uint32_t assoc_id,
+                                       M2AP_Cause_PR cause_type,
+                                       long cause_value,
+                                       long time_to_wait);
+
+int m2ap_MCE_set_cause (M2AP_Cause_t * cause_p,
+                        M2AP_Cause_PR cause_type,
+                        long cause_value);
+
+//int m2ap_MCE_generate_m2_handover_request (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
+//                                           m2ap_handover_req_t *m2ap_handover_req, int ue_id);
+//
+//int m2ap_MCE_generate_m2_handover_request_ack (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
+//                                               m2ap_handover_req_ack_t *m2ap_handover_req_ack);
+//
+//int m2ap_MCE_generate_m2_ue_context_release (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
+//                                             m2ap_ue_context_release_t *m2ap_ue_context_release);
+//
+//int m2ap_MCE_generate_m2_handover_cancel (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
+//                                          int m2_ue_id,
+//                                          m2ap_handover_cancel_cause_t cause);
+
+#endif /*  M2AP_MCE_GENERATE_MESSAGES_H_ */
diff --git a/openair2/M2AP/m2ap_MCE_handler.c b/openair2/M2AP/m2ap_MCE_handler.c
new file mode 100644
index 0000000000..85e342f996
--- /dev/null
+++ b/openair2/M2AP/m2ap_MCE_handler.c
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_MCE_handler.c
+ * \brief m2ap handler procedures for MCE
+ * \author Javier Morgade <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#include <stdint.h>
+
+#include "intertask_interface.h"
+
+#include "asn1_conversions.h"
+
+#include "m2ap_common.h"
+#include "m2ap_MCE_defs.h"
+#include "m2ap_MCE_handler.h"
+#include "m2ap_decoder.h"
+#include "m2ap_ids.h"
+
+//#include "m2ap_MCE_management_procedures.h"
+#include "m2ap_MCE_generate_messages.h"
+
+#include "m2ap_MCE_interface_management.h"
+//#include "m2ap_eNB_interface_management.h"
+
+#include "msc.h"
+#include "assertions.h"
+#include "conversions.h"
+
+/* Handlers matrix. Only eNB related procedure present here */
+m2ap_message_decoded_callback m2ap_MCE_messages_callback[][3] = {
+  { 0, MCE_handle_MBMS_SESSION_START_RESPONSE, 0 }, /* MBMSSessionStart  */
+  { 0, MCE_handle_MBMS_SESSION_STOP_RESPONSE, 0 }, /* MBMSSessionStop */
+  { 0, MCE_handle_MBMS_SCHEDULING_INFORMATION_RESPONSE, 0 }, /* MBMSSchedulingInformation */
+  { 0, 0, 0 }, /* Error Indication */
+  { 0, 0, 0 }, /* Reset */
+  { MCE_handle_M2_SETUP_REQUEST, 0, 0 }, /* M2 Setup */
+  { 0, 0, 0 }, /* eNBConfigurationUpdate */
+  { 0, 0, 0 }, /* MCEConfigurationUpdate */
+  { 0, 0, 0 }, /* privateMessage */
+  { 0, 0, 0 }, /* MBMSSessionUpdate */
+  { 0, 0, 0 }, /* MBMSServiceCounting */
+  { 0, 0, 0 }, /* MBMSServiceCountingResultReport */
+  { 0, 0, 0 } /* MBMSOverloadNotification */
+};
+
+static char *m2ap_direction2String(int m2ap_dir) {
+static char *m2ap_direction_String[] = {
+  "", /* Nothing */
+  "Originating message", /* originating message */
+  "Successfull outcome", /* successfull outcome */
+  "UnSuccessfull outcome", /* successfull outcome */
+};
+return(m2ap_direction_String[m2ap_dir]);
+}
+
+
+int m2ap_MCE_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
+                            const uint8_t * const data, const uint32_t data_length)
+{
+  M2AP_M2AP_PDU_t pdu;
+  int ret;
+
+  DevAssert(data != NULL);
+
+  memset(&pdu, 0, sizeof(pdu));
+
+  if (m2ap_decode_pdu(&pdu, data, data_length) < 0) {
+    LOG_E(M2AP, "Failed to decode PDU\n");
+    return -1;
+  }
+
+  /* Checking procedure Code and direction of message */
+  if (pdu.choice.initiatingMessage.procedureCode > sizeof(m2ap_MCE_messages_callback) / (3 * sizeof(
+        m2ap_MCE_message_decoded_callback))
+      || (pdu.present > M2AP_M2AP_PDU_PR_unsuccessfulOutcome)) {
+    LOG_E(M2AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n",
+               assoc_id, pdu.choice.initiatingMessage.procedureCode, pdu.present);
+    ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu);
+    return -1;
+  }
+
+  /* No handler present.
+   * This can mean not implemented or no procedure for eNB (wrong direction).
+   */
+  if (m2ap_MCE_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1] == NULL) {
+    LOG_E(M2AP, "[SCTP %d] No handler for procedureCode %ld in %s\n",
+                assoc_id, pdu.choice.initiatingMessage.procedureCode,
+               m2ap_direction2String(pdu.present - 1));
+    ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu);
+    return -1;
+  }
+  
+  /* Calling the right handler */
+  LOG_I(M2AP, "Calling handler with instance %d\n",instance);
+  ret = (*m2ap_MCE_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1])
+        (instance, assoc_id, stream, &pdu);
+  ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu);
+  return ret;
+}
+
+
diff --git a/openair2/M2AP/m2ap_MCE_handler.h b/openair2/M2AP/m2ap_MCE_handler.h
new file mode 100644
index 0000000000..e9faae8f5d
--- /dev/null
+++ b/openair2/M2AP/m2ap_MCE_handler.h
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_handler.h
+ * \brief m2ap handler procedures for MCE
+ * \author Javier Morgade <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#ifndef M2AP_MCE_HANDLERS_H_
+#define M2AP_MCE_HANDLERS_H_
+
+#include "m2ap_MCE_defs.h"
+
+//void m2ap_handle_m2_setup_message(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown);
+
+int m2ap_MCE_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
+                            const uint8_t * const data, const uint32_t data_length);
+
+//int m2ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
+                            //const uint8_t * const data, const uint32_t data_length);
+
+
+#endif /* M2AP_MCE_HANDLERS_H_ */
diff --git a/openair2/M2AP/m2ap_MCE_interface_management.c b/openair2/M2AP/m2ap_MCE_interface_management.c
new file mode 100644
index 0000000000..903e395197
--- /dev/null
+++ b/openair2/M2AP/m2ap_MCE_interface_management.c
@@ -0,0 +1,1905 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_MCE_interface_management.c
+ * \brief m2ap interface management for MCE
+ * \author Javier Morgade
+ * \date 2019
+ * \version 0.1
+ * \company Vicomtech
+ * \email: javier.morgade@ieee.org
+ * \note
+ * \warning
+ */
+
+#include "m2ap_common.h"
+#include "m2ap_encoder.h"
+#include "m2ap_decoder.h"
+#include "m2ap_itti_messaging.h"
+#include "m2ap_MCE_interface_management.h"
+
+#include "conversions.h"
+
+extern m2ap_setup_req_t *m2ap_mce_data_from_enb;
+
+/*
+ * MBMS Session start
+ */
+int MCE_send_MBMS_SESSION_START_REQUEST(instance_t instance/*, uint32_t assoc_id*/,m2ap_session_start_req_t* m2ap_session_start_req){
+
+  //AssertFatal(1==0,"Not implemented yet\n");
+    
+  //module_id_t enb_mod_idP=0;
+  //module_id_t du_mod_idP=0;
+
+  M2AP_M2AP_PDU_t          pdu; 
+  M2AP_SessionStartRequest_t       *out;
+  M2AP_SessionStartRequest_Ies_t   *ie;
+
+  uint8_t *buffer;
+  uint32_t len;
+  //int	   i=0; 
+  //int 	   j=0;
+
+  /* Create */
+  /* 0. pdu Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
+  //pdu.choice.initiatingMessage = (M2AP_InitiatingMessage_t *)calloc(1, sizeof(M2AP_InitiatingMessage_t));
+  pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_sessionStart;
+  pdu.choice.initiatingMessage.criticality   = M2AP_Criticality_reject;
+  pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_SessionStartRequest;
+  out = &pdu.choice.initiatingMessage.value.choice.SessionStartRequest;  
+
+  /* mandatory */
+  /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long
+  ie = (M2AP_SessionStartRequest_Ies_t *)calloc(1, sizeof(M2AP_SessionStartRequest_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_MCE_MBMS_M2AP_ID;
+  ie->criticality               = M2AP_Criticality_reject;
+  ie->value.present             = M2AP_SessionStartRequest_Ies__value_PR_MCE_MBMS_M2AP_ID;
+  //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //?
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c2. TMGI (integrer value) */
+  ie = (M2AP_SessionStartRequest_Ies_t *)calloc(1, sizeof(M2AP_SessionStartRequest_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_TMGI;
+  ie->criticality               = M2AP_Criticality_reject;
+  ie->value.present             = M2AP_SessionStartRequest_Ies__value_PR_TMGI;
+  MCC_MNC_TO_PLMNID(0,0,3,&ie->value.choice.TMGI.pLMNidentity);/*instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,*/
+  uint8_t TMGI[5] = {4,3,2,1,0};
+  OCTET_STRING_fromBuf(&ie->value.choice.TMGI.serviceID,(const char*)&TMGI[2],3);
+ 
+                       //&ie->choice.TMGI.pLMN_Identity);
+  //INT16_TO_OCTET_STRING(0,&ie->choice.TMGI.serviceId);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c3. MBMS_Session_ID (integrer value) */ //OCTET_STRING
+  if(0){
+	  ie = (M2AP_SessionStartRequest_Ies_t *)calloc(1, sizeof(M2AP_SessionStartRequest_Ies_t));
+	  ie->id                        = M2AP_ProtocolIE_ID_id_MBMS_Session_ID;
+	  ie->criticality               = M2AP_Criticality_reject;
+	  ie->value.present             = M2AP_SessionStartRequest_Ies__value_PR_MBMS_Session_ID;
+  	  //INT16_TO_OCTET_STRING(0,&ie->choice.MBMS_Session_ID);
+	  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* mandatory */
+  /* c5. MBMS_Service_Area (integrer value) */ //OCTET_STRING
+  ie = (M2AP_SessionStartRequest_Ies_t *)calloc(1, sizeof(M2AP_SessionStartRequest_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_MBMS_Service_Area; 
+  ie->criticality               = M2AP_Criticality_reject;
+  ie->value.present             = M2AP_SessionStartRequest_Ies__value_PR_MBMS_Service_Area;
+  //OCTET_STRING_fromBuf(&ie->value.choice.MBMS_Service_Area, m2ap_setup_resp->MCEname,
+                         //strlen(m2ap_setup_resp->MCEname));
+  //INT16_TO_OCTET_STRING(0,&ie->choice.TMGI.serviceId);
+  ie->value.choice.MBMS_Service_Area.buf = calloc(3,sizeof(uint8_t));
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+  /* mandatory */
+  /* c6. TNL_Information (integrer value) */
+  ie = (M2AP_SessionStartRequest_Ies_t *)calloc(1, sizeof(M2AP_SessionStartRequest_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_TNL_Information; 
+  ie->criticality               = M2AP_Criticality_reject;
+  ie->value.present             = M2AP_SessionStartRequest_Ies__value_PR_TNL_Information;
+  //ie->value.choice.TNL_Information.iPMCAddress.buf = calloc(4,sizeof(uint8_t));
+  //ie->value.choice.TNL_Information.iPSourceAddress.buf = calloc(4,sizeof(uint8_t));
+  //TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234,&ie->value.choice.TNL_Information.iPMCAddress);
+  //TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234,&ie->value.choice.TNL_Information.iPSourceAddress);
+  
+  OCTET_STRING_fromBuf(&ie->value.choice.TNL_Information.gTP_TEID, "1204",strlen("1234"));
+  OCTET_STRING_fromBuf(&ie->value.choice.TNL_Information.iPMCAddress, "1204",strlen("1234"));
+  OCTET_STRING_fromBuf(&ie->value.choice.TNL_Information.iPSourceAddress, "1204",strlen("1234"));
+  
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  if(0){
+	 // /* optional */
+	 // /* c7. TNL_Information_1 (integrer value) */
+	 // ie = (M2AP_SessionStartRequest_Ies_t *)calloc(1, sizeof(M2AP_SessionStartRequest_Ies_t));
+	 // ie->id                        = M2AP_ProtocolIE_ID_id_TNL_Information_1; 
+	 // ie->criticality               = M2AP_Criticality_reject;
+	 // ie->value.present             = M2AP_SessionStartRequest_Ies__value_PR_TNL_Information_1;
+	 // //asn_int642INTEGER(&ie->value.choice.MBMS_Session_ID, f1ap_du_data->MBMS_Session_ID); //?
+	 // ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+   
+
+  /* encode */
+  if (m2ap_encode_pdu(&pdu,&buffer,&len) < 0){
+	return -1;
+  }
+
+  //MCE_m2ap_itti_send_sctp_data_req(instance, m2ap_mce_data_from_mce->assoid,buffer,len,0); 
+  m2ap_MCE_itti_send_sctp_data_req(instance,m2ap_mce_data_from_enb->assoc_id,buffer,len,0);
+  return 0;
+
+}
+
+int MCE_handle_MBMS_SESSION_START_RESPONSE(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                M2AP_M2AP_PDU_t *pdu){
+  //AssertFatal(1==0,"Not implemented yet\n");
+  LOG_D(M2AP, "MCE_handle_MBMS_SESSION_START_RESPONSE\n");
+
+   AssertFatal(pdu->present == M2AP_M2AP_PDU_PR_successfulOutcome,
+	       "pdu->present != M2AP_M2AP_PDU_PR_successfulOutcome\n");
+   AssertFatal(pdu->choice.successfulOutcome.procedureCode  == M2AP_ProcedureCode_id_sessionStart,
+	       "pdu->choice.successfulOutcome->procedureCode != M2AP_ProcedureCode_id_sessionStart\n");
+   AssertFatal(pdu->choice.successfulOutcome.criticality  == M2AP_Criticality_reject,
+	       "pdu->choice.successfulOutcome->criticality != M2AP_Criticality_reject\n");
+   AssertFatal(pdu->choice.successfulOutcome.value.present  == M2AP_SuccessfulOutcome__value_PR_SessionStartResponse,
+	       "pdu->choice.successfulOutcome.value.present != M2AP_SuccessfulOutcome__value_PR_SessionStartResponse\n");
+
+
+  M2AP_SessionStartResponse_t    *in = &pdu->choice.successfulOutcome.value.choice.SessionStartResponse;
+  M2AP_SessionStartResponse_Ies_t  *ie;
+  int MCE_MBMS_M2AP_ID=-1;
+  int ENB_MBMS_M2AP_ID=-1;
+
+
+  MessageDef *msg_g = itti_alloc_new_message(TASK_M2AP_MCE,M2AP_MBMS_SESSION_START_RESP); //TODO
+
+  LOG_D(M2AP, "M2AP: SessionStart-Resp: protocolIEs.list.count %d\n",
+         in->protocolIEs.list.count);
+  for (int i=0;i < in->protocolIEs.list.count; i++) {
+     ie = in->protocolIEs.list.array[i];
+     switch (ie->id) {
+     case M2AP_ProtocolIE_ID_id_MCE_MBMS_M2AP_ID:
+       AssertFatal(ie->criticality == M2AP_Criticality_reject,
+                   "ie->criticality != M2AP_Criticality_reject\n");
+       AssertFatal(ie->value.present == M2AP_SessionStartResponse_Ies__value_PR_MCE_MBMS_M2AP_ID,
+                   "ie->value.present != M2AP_sessionStartResponse_IEs__value_PR_MCE_MBMS_M2AP_ID\n");
+       MCE_MBMS_M2AP_ID=ie->value.choice.MCE_MBMS_M2AP_ID;
+       LOG_D(M2AP, "M2AP: SessionStart-Resp: MCE_MBMS_M2AP_ID %d\n",
+             MCE_MBMS_M2AP_ID);
+       break;
+      case M2AP_ProtocolIE_ID_id_ENB_MBMS_M2AP_ID:
+       AssertFatal(ie->criticality == M2AP_Criticality_reject,
+                   "ie->criticality != M2AP_Criticality_reject\n");
+       AssertFatal(ie->value.present == M2AP_SessionStartResponse_Ies__value_PR_ENB_MBMS_M2AP_ID,
+                   "ie->value.present != M2AP_sessionStartResponse_Ies__value_PR_ENB_MBMS_M2AP_ID\n");
+       ENB_MBMS_M2AP_ID=ie->value.choice.ENB_MBMS_M2AP_ID;
+       LOG_D(M2AP, "M2AP: SessionStart-Resp: ENB_MBMS_M2AP_ID %d\n",
+             ENB_MBMS_M2AP_ID);
+       break;
+     }
+  }
+
+  AssertFatal(MCE_MBMS_M2AP_ID!=-1,"MCE_MBMS_M2AP_ID was not sent\n");
+  AssertFatal(ENB_MBMS_M2AP_ID!=-1,"ENB_MBMS_M2AP_ID was not sent\n");
+  //M2AP_SESSION_START_RESP(msg_p).
+//  MSC_LOG_RX_MESSAGE(
+//    MSC_M2AP_MCE,
+//    MSC_M2AP_ENB,
+	//return 0;
+//    0,
+//    0,
+//    MSC_AS_TIME_FMT" MCE_handle_M2_SESSION_START_RESPONSE successfulOutcome assoc_id %d",
+//    0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
+//    assoc_id);
+//
+   LOG_D(M2AP, "Sending M2AP_SESSION_START_RESP ITTI message to ENB_APP with assoc_id (%d->%d)\n",
+         assoc_id,ENB_MODULE_ID_TO_INSTANCE(assoc_id));
+   itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_g);
+   return 0;
+
+}
+int MCE_handle_MBMS_SESSION_START_FAILURE(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                M2AP_M2AP_PDU_t *pdu){
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+/*
+ * MBMS Session stop
+ */
+int MCE_send_MBMS_SESSION_STOP_REQUEST(instance_t instance, m2ap_session_stop_req_t* m2ap_session_stop_req){
+
+    
+ // module_id_t enb_mod_idP=0;
+  //module_id_t du_mod_idP=0;
+
+  M2AP_M2AP_PDU_t          pdu; 
+  M2AP_SessionStopRequest_t        *out;
+  M2AP_SessionStopRequest_Ies_t    *ie;
+
+  uint8_t *buffer;
+  uint32_t len;
+  //int	   i=0; 
+  //int 	   j=0;
+
+  /* Create */
+  /* 0. pdu Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
+  //pdu.choice.initiatingMessage = (M2AP_InitiatingMessage_t *)calloc(1, sizeof(M2AP_InitiatingMessage_t));
+  pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_sessionStop;
+  pdu.choice.initiatingMessage.criticality   = M2AP_Criticality_reject;
+  pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_SessionStopRequest;
+  out = &pdu.choice.initiatingMessage.value.choice.SessionStopRequest; 
+
+  /* mandatory */
+  /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long
+  ie = (M2AP_SessionStopRequest_Ies_t *)calloc(1, sizeof(M2AP_SessionStopRequest_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_MCE_MBMS_M2AP_ID;
+  ie->criticality               = M2AP_Criticality_reject;
+  ie->value.present             = M2AP_SessionStopRequest_Ies__value_PR_MCE_MBMS_M2AP_ID;
+  ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //?
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c2. ENB_MBMS_M2AP_ID (integer value) */ //long
+  ie = (M2AP_SessionStopRequest_Ies_t *)calloc(1, sizeof(M2AP_SessionStopRequest_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_ENB_MBMS_M2AP_ID;
+  ie->criticality               = M2AP_Criticality_reject;
+  ie->value.present             = M2AP_SessionStopRequest_Ies__value_PR_ENB_MBMS_M2AP_ID;
+  ie->value.choice.ENB_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //?
+
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+  /* encode */
+  if (m2ap_encode_pdu(&pdu,&buffer,&len) < 0){
+	return -1;
+  }
+
+  //MCE_m2ap_itti_send_sctp_data_req(instance, m2ap_mce_data_from_mce->assoid,buffer,len,0); 
+  m2ap_MCE_itti_send_sctp_data_req(instance, m2ap_mce_data_from_enb->assoc_id,buffer,len,0);
+  return 0;
+
+
+                        
+}
+
+int MCE_handle_MBMS_SESSION_STOP_RESPONSE(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                M2AP_M2AP_PDU_t *pdu){
+  //AssertFatal(1==0,"Not implemented yet\n");
+  LOG_D(M2AP, "MCE_handle_MBMS_SESSION_STOP_RESPONSE\n");
+
+   AssertFatal(pdu->present == M2AP_M2AP_PDU_PR_successfulOutcome,
+	       "pdu->present != M2AP_M2AP_PDU_PR_successfulOutcome\n");
+   AssertFatal(pdu->choice.successfulOutcome.procedureCode  == M2AP_ProcedureCode_id_sessionStop,
+	       "pdu->choice.successfulOutcome->procedureCode != M2AP_ProcedureCode_id_sessionStop\n");
+   AssertFatal(pdu->choice.successfulOutcome.criticality  == M2AP_Criticality_reject,
+	       "pdu->choice.successfulOutcome->criticality != M2AP_Criticality_reject\n");
+   AssertFatal(pdu->choice.successfulOutcome.value.present  == M2AP_SuccessfulOutcome__value_PR_SessionStopResponse,
+	       "pdu->choice.successfulOutcome->value.present != M2AP_SuccessfulOutcome__value_PR_SessionStopResponse\n");
+
+
+  M2AP_SessionStopResponse_t    *in = &pdu->choice.successfulOutcome.value.choice.SessionStopResponse;
+  M2AP_SessionStopResponse_Ies_t  *ie;
+  int MCE_MBMS_M2AP_ID=-1;
+  int ENB_MBMS_M2AP_ID=-1;
+
+
+  MessageDef *msg_g = itti_alloc_new_message(TASK_M2AP_MCE,M2AP_MBMS_SESSION_STOP_RESP); //TODO
+
+  LOG_D(M2AP, "M2AP: SessionStop-Resp: protocolIEs.list.count %d\n",
+         in->protocolIEs.list.count);
+  for (int i=0;i < in->protocolIEs.list.count; i++) {
+     ie = in->protocolIEs.list.array[i];
+     switch (ie->id) {
+     case M2AP_ProtocolIE_ID_id_MCE_MBMS_M2AP_ID:
+       AssertFatal(ie->criticality == M2AP_Criticality_reject,
+                   "ie->criticality != M2AP_Criticality_reject\n");
+       AssertFatal(ie->value.present == M2AP_SessionStopResponse_Ies__value_PR_MCE_MBMS_M2AP_ID,
+                   "ie->value.present != M2AP_SessionStopResponse_Ies__value_PR_MCE_MBMS_M2AP_ID\n");
+       MCE_MBMS_M2AP_ID=ie->value.choice.MCE_MBMS_M2AP_ID;
+       LOG_D(M2AP, "M2AP: SessionStop-Resp: MCE_MBMS_M2AP_ID %d\n",
+             MCE_MBMS_M2AP_ID);
+       break;
+      case M2AP_ProtocolIE_ID_id_ENB_MBMS_M2AP_ID:
+       AssertFatal(ie->criticality == M2AP_Criticality_reject,
+                   "ie->criticality != M2AP_Criticality_reject\n");
+       AssertFatal(ie->value.present == M2AP_SessionStopResponse_Ies__value_PR_ENB_MBMS_M2AP_ID,
+                   "ie->value.present != M2AP_SessionStopResponse_Ies__value_PR_ENB_MBMS_M2AP_ID\n");
+       ENB_MBMS_M2AP_ID=ie->value.choice.ENB_MBMS_M2AP_ID;
+       LOG_D(M2AP, "M2AP: SessionStop-Resp: ENB_MBMS_M2AP_ID %d\n",
+             ENB_MBMS_M2AP_ID);
+       break;
+     }
+  }
+
+  AssertFatal(MCE_MBMS_M2AP_ID!=-1,"MCE_MBMS_M2AP_ID was not sent\n");
+  AssertFatal(ENB_MBMS_M2AP_ID!=-1,"ENB_MBMS_M2AP_ID was not sent\n");
+ // M2AP_SESSION_STOP_RESP(msg_p).
+ // MSC_LOG_RX_MESSAGE(
+ //   MSC_M2AP_MCE,
+ //   MSC_M2AP_ENB,
+ //   0,
+ //   0,
+ //   MSC_AS_TIME_FMT" MCE_handle_M2_SESSION_STOP_RESPONSE successfulOutcome assoc_id %d",
+ //   0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
+ //   assoc_id);
+
+ //  LOG_D(M2AP, "Sending M2AP_SESSION_START_RESP ITTI message to ENB_APP with assoc_id (%d->%d)\n",
+ //        assoc_id,ENB_MODULE_ID_TO_INSTANCE(assoc_id));
+   itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_g);
+ //                      
+	return 0;
+}
+
+
+
+int MCE_handle_MBMS_SESSION_STOP_FAILURE(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                M2AP_M2AP_PDU_t *pdu){
+  AssertFatal(1==0,"Not implemented yet\n");
+                      
+}
+ typedef struct M2AP_MBSFN_Area_Configuration{
+	M2AP_PMCH_Configuration_List_t   PMCH_Configuration_List;
+        M2AP_MBSFN_Subframe_ConfigurationList_t  MBSFN_Subframe_ConfigurationList;
+        M2AP_Common_Subframe_Allocation_Period_t         Common_Subframe_Allocation_Period;
+        M2AP_MBSFN_Area_ID_t     MBSFN_Area_ID;
+        M2AP_MBMS_Suspension_Notification_List_t         MBMS_Suspension_Notification_List;
+  }M2AP_MBSFN_Area_Configuration_t;
+
+
+/*
+ * MBMS Scheduling Information
+ */
+ uint8_t m2ap_message[]    = {0x00, 0x02, 0x00, 0x3a, 0x00, 0x00, 0x02, 0x00, 0x19, 0x00, 0x01, 0x00, 0x00,
+                            0x0a, 0x00, 0x2e, 0x00, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x12, 0x10, 0x00, 0x0c,
+                            0x00, 0x0d, 0x00, 0x00, 0x3f, 0x13, 0x00, 0x00, 0x00, 0xf1, 0x10, 0x00, 0x00,
+                            0x01, 0x08, 0x00, 0x16, 0x00, 0x07, 0x00, 0x00, 0x17, 0x00, 0x02, 0x00, 0x40,
+                            0x00, 0x18, 0x00, 0x01, 0x80, 0x00, 0x1d, 0x00, 0x01, 0x01};
+
+
+int MCE_send_MBMS_SCHEDULING_INFORMATION(instance_t instance, /*uint32_t assoc_id,*/m2ap_mbms_scheduling_information_t * m2ap_mbms_scheduling_information){
+   
+  //module_id_t enb_mod_idP=0;
+  //module_id_t du_mod_idP=0;
+
+  M2AP_M2AP_PDU_t          pdu; 
+  M2AP_MbmsSchedulingInformation_t       *out;
+  M2AP_MbmsSchedulingInformation_Ies_t   *ie;
+
+  uint8_t *buffer/*,*buffer2*/;
+  uint32_t len/*,len2*/;
+  int	   i=0; 
+  int 	   j=0;
+  int 	   k=0;
+  //int 	   l=0;
+  //int 	   l=0;
+
+  /* Create */
+  /* 0. pdu Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
+  //pdu.choice.initiatingMessage = (M2AP_InitiatingMessage_t *)calloc(1, sizeof(M2AP_InitiatingMessage_t));
+  pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_mbmsSchedulingInformation;
+  pdu.choice.initiatingMessage.criticality   = M2AP_Criticality_reject;
+  pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_MbmsSchedulingInformation;
+  out = &pdu.choice.initiatingMessage.value.choice.MbmsSchedulingInformation; 
+
+  /* mandatory */
+  /* c1. MCCH_Update_Time */ //long
+  ie=(M2AP_MbmsSchedulingInformation_Ies_t*)calloc(1,sizeof(M2AP_MbmsSchedulingInformation_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_MCCH_Update_Time;
+  ie->criticality               = M2AP_Criticality_reject;
+  ie->value.present             = M2AP_MbmsSchedulingInformation_Ies__value_PR_MCCH_Update_Time;
+  //ie->value.choice.MCCH_Update_Time =  ; 
+  ie->value.choice.MCCH_Update_Time = m2ap_mbms_scheduling_information->mcch_update_time;
+
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);  
+
+  /* mandatory */
+  /* c2. MBSFN_Area_Configuration_List */ //long
+  ie=(M2AP_MbmsSchedulingInformation_Ies_t*)calloc(1,sizeof(M2AP_MbmsSchedulingInformation_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_MBSFN_Area_Configuration_List;
+  ie->criticality               = M2AP_Criticality_reject;
+  ie->value.present             = M2AP_MbmsSchedulingInformation_Ies__value_PR_MBSFN_Area_Configuration_List;
+
+  for(i=0; i < m2ap_mbms_scheduling_information->num_mbms_area_config_list; i++){ 
+      M2AP_MBSFN_Area_Configuration_List_t * m2ap_mbsfn_area_configuration_list = (M2AP_MBSFN_Area_Configuration_List_t*)calloc(1,sizeof(M2AP_MBSFN_Area_Configuration_List_t));
+      /*M2AP_MBSFN_Area_Configuration_Item_t*/
+      M2AP_MBSFN_Area_Configuration_Item_t *mbsfn_area_configuration_item_ie;
+      mbsfn_area_configuration_item_ie =(M2AP_MBSFN_Area_Configuration_Item_t*)calloc(1,sizeof(M2AP_MBSFN_Area_Configuration_Item_t)); 
+      mbsfn_area_configuration_item_ie->id = M2AP_ProtocolIE_ID_id_PMCH_Configuration_List;
+      mbsfn_area_configuration_item_ie->criticality = M2AP_Criticality_reject;
+      mbsfn_area_configuration_item_ie->value.present = M2AP_MBSFN_Area_Configuration_Item__value_PR_PMCH_Configuration_List;
+
+      for(j=0; j < m2ap_mbms_scheduling_information->mbms_area_config_list[i].num_pmch_config_list; j++){
+      
+      	M2AP_PMCH_Configuration_ItemIEs_t * pmch_configuration_item_ies = (M2AP_PMCH_Configuration_ItemIEs_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_ItemIEs_t));
+      	pmch_configuration_item_ies->id = M2AP_ProtocolIE_ID_id_PMCH_Configuration_Item;
+      	pmch_configuration_item_ies->criticality = M2AP_Criticality_reject;
+      	pmch_configuration_item_ies->value.present = M2AP_PMCH_Configuration_ItemIEs__value_PR_PMCH_Configuration_Item;
+
+      	M2AP_PMCH_Configuration_Item_t * pmch_configuration_item = (M2AP_PMCH_Configuration_Item_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_Item_t));
+      	pmch_configuration_item = &pmch_configuration_item_ies->value.choice.PMCH_Configuration_Item;
+      	{
+            pmch_configuration_item->pmch_Configuration.dataMCS = m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].data_mcs;
+            pmch_configuration_item->pmch_Configuration.mchSchedulingPeriod = m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mch_scheduling_period;
+	    pmch_configuration_item->pmch_Configuration.allocatedSubframesEnd = m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].allocated_sf_end;
+            for(k=0; k < m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].num_mbms_session_list; k++){
+            	MBMSsessionListPerPMCH_Item__Member *member;
+            	member = (MBMSsessionListPerPMCH_Item__Member*)calloc(1,sizeof(MBMSsessionListPerPMCH_Item__Member));
+            	MCC_MNC_TO_PLMNID(
+            			  m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].mcc,
+            			  m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].mnc,
+            			  m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].mnc_length
+            			,&member->tmgi.pLMNidentity);
+
+	  	//INT16_TO_OCTET_STRING(0,&imember->tmgi);
+		char buf[4];
+	        INT32_TO_BUFFER(m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].service_id,buf);
+            	//uint8_t TMGI[5] = {4,3,2,1,0};
+            	OCTET_STRING_fromBuf(&member->tmgi.serviceID,(const char*)&buf[1],3);
+
+            		//LOG_D(M2AP,"%p,%p,%p,%li,%ld,%ld\n",pmch_configuration_item,&pmch_configuration_item->mbms_Session_List.list,member, m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].lcid,sizeof(member->lcid),sizeof(m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].lcid)); 
+		//long kk = m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].lcid;
+		//uint64_t kk=(m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].lcid);
+		//memcpy(&member->lcid,&m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].lcid,sizeof(member->lcid));
+	//	member->lcid = 1;
+	//	for( l=2; l < 28;l++)
+	//		LOG_E(M2AP,"%di\n",l);
+	//		if(l ==  m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].lcid){
+        //    	member->lcid++;//m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].service_id;
+	//		break;
+	//	}
+                member->lcid = m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].lcid;
+		//member->lcid = (M2AP_LCID_t*)calloc(1,sizeof(M2AP_LCID_t));
+		
+            	ASN_SEQUENCE_ADD(&pmch_configuration_item->mbms_Session_List.list,member);
+            }
+      
+      	}
+      /*M2AP_MBSFN_Subframe_ConfigurationList_t*/
+      // M2AP_MBSFN_Area_Configuration_Item_t *mbsfn_area_configuration_item_ie2;
+      //(mbsfn_area_configuration_item_ie+1) =(M2AP_MBSFN_Area_Configuration_Item_t*)calloc(1,sizeof(M2AP_MBSFN_Area_Configuration_Item_t)); 
+
+      	ASN_SEQUENCE_ADD(&mbsfn_area_configuration_item_ie->value.choice.PMCH_Configuration_List.list,pmch_configuration_item_ies);
+
+      }
+
+      ASN_SEQUENCE_ADD(m2ap_mbsfn_area_configuration_list,mbsfn_area_configuration_item_ie);
+
+      /*M2AP_MBSFN_Area_Configuration_Item_t*/
+      M2AP_MBSFN_Area_Configuration_Item_t *mbsfn_area_configuration_item_ie_1;
+      mbsfn_area_configuration_item_ie_1 =(M2AP_MBSFN_Area_Configuration_Item_t*)calloc(1,sizeof(M2AP_MBSFN_Area_Configuration_Item_t)); 
+      (mbsfn_area_configuration_item_ie_1)->id = M2AP_ProtocolIE_ID_id_MBSFN_Subframe_Configuration_List;
+      (mbsfn_area_configuration_item_ie_1)->criticality = M2AP_Criticality_reject;
+      (mbsfn_area_configuration_item_ie_1)->value.present = M2AP_MBSFN_Area_Configuration_Item__value_PR_MBSFN_Subframe_ConfigurationList;
+
+      for(j=0; j < m2ap_mbms_scheduling_information->mbms_area_config_list[i].num_mbms_sf_config_list; j++){
+	   M2AP_MBSFN_Subframe_ConfigurationItem_t * mbsfn_subframe_configuration_item_ies = (M2AP_MBSFN_Subframe_ConfigurationItem_t*)calloc(1,sizeof(M2AP_MBSFN_Subframe_ConfigurationItem_t));
+	   mbsfn_subframe_configuration_item_ies->id = M2AP_ProtocolIE_ID_id_MBSFN_Subframe_Configuration_Item;
+	   mbsfn_subframe_configuration_item_ies->criticality = M2AP_Criticality_reject;
+	   mbsfn_subframe_configuration_item_ies->value.present = M2AP_MBSFN_Subframe_ConfigurationItem__value_PR_MBSFN_Subframe_Configuration;
+
+	   M2AP_MBSFN_Subframe_Configuration_t * mbsfn_subframe_configuration = (M2AP_MBSFN_Subframe_Configuration_t*)calloc(1,sizeof(M2AP_MBSFN_Subframe_Configuration_t));
+	   mbsfn_subframe_configuration = &mbsfn_subframe_configuration_item_ies->value.choice.MBSFN_Subframe_Configuration;
+	   {
+		   mbsfn_subframe_configuration->radioframeAllocationPeriod = m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_period;
+		   mbsfn_subframe_configuration->radioframeAllocationOffset = m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_offset;
+		   if(m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].is_four_sf){
+			   mbsfn_subframe_configuration->subframeAllocation.present = M2AP_MBSFN_Subframe_Configuration__subframeAllocation_PR_fourFrames;
+			   mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.buf = MALLOC(3);
+			   mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.buf[2] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation) & 0xFF);
+			   mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.buf[1] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation>>8) & 0xFF);
+			   mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.buf[0] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation>>16) & 0xFF);
+			   mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.size =3;
+			   mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.bits_unused = 0;
+
+		   }else{
+			   mbsfn_subframe_configuration->subframeAllocation.present = M2AP_MBSFN_Subframe_Configuration__subframeAllocation_PR_oneFrame;
+			   mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.buf = MALLOC(1);
+			   mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.size = 1;
+			   mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.bits_unused = 2;
+			   //mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.buf[0] = 0x38<<2;
+			   mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.buf[0] = (m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation & 0x3F)<<2;
+		   }
+
+		   ASN_SEQUENCE_ADD(&(mbsfn_area_configuration_item_ie_1)->value.choice.MBSFN_Subframe_ConfigurationList.list,mbsfn_subframe_configuration_item_ies);
+	   }
+       }
+
+       ASN_SEQUENCE_ADD(m2ap_mbsfn_area_configuration_list,mbsfn_area_configuration_item_ie_1);
+
+
+      /*M2AP_MBSFN_Area_Configuration_Item_t*/
+      M2AP_MBSFN_Area_Configuration_Item_t *mbsfn_area_configuration_item_ie_2;
+      mbsfn_area_configuration_item_ie_2 =(M2AP_MBSFN_Area_Configuration_Item_t*)calloc(1,sizeof(M2AP_MBSFN_Area_Configuration_Item_t)); 
+      (mbsfn_area_configuration_item_ie_2)->id = M2AP_ProtocolIE_ID_id_Common_Subframe_Allocation_Period;
+      (mbsfn_area_configuration_item_ie_2)->criticality = M2AP_Criticality_reject;
+      (mbsfn_area_configuration_item_ie_2)->value.present = M2AP_MBSFN_Area_Configuration_Item__value_PR_Common_Subframe_Allocation_Period;
+      (mbsfn_area_configuration_item_ie_2)->value.choice.Common_Subframe_Allocation_Period=m2ap_mbms_scheduling_information->mbms_area_config_list[i].common_sf_allocation_period;
+
+       ASN_SEQUENCE_ADD(m2ap_mbsfn_area_configuration_list,mbsfn_area_configuration_item_ie_2);
+
+
+      /*M2AP_MBSFN_Area_Configuration_Item_t*/
+      M2AP_MBSFN_Area_Configuration_Item_t *mbsfn_area_configuration_item_ie_3;
+      mbsfn_area_configuration_item_ie_3 =(M2AP_MBSFN_Area_Configuration_Item_t*)calloc(1,sizeof(M2AP_MBSFN_Area_Configuration_Item_t)); 
+      (mbsfn_area_configuration_item_ie_3)->id = M2AP_ProtocolIE_ID_id_MBSFN_Area_ID;
+      (mbsfn_area_configuration_item_ie_3)->criticality = M2AP_Criticality_reject;
+      (mbsfn_area_configuration_item_ie_3)->value.present = M2AP_MBSFN_Area_Configuration_Item__value_PR_MBSFN_Area_ID;
+      (mbsfn_area_configuration_item_ie_3)->value.choice.MBSFN_Area_ID = m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_area_id;
+
+      ASN_SEQUENCE_ADD(m2ap_mbsfn_area_configuration_list,mbsfn_area_configuration_item_ie_3);
+
+
+ASN_SET_ADD(&ie->value.choice.MBSFN_Area_Configuration_List,m2ap_mbsfn_area_configuration_list);
+//-------------
+
+
+
+
+//  ASN_SEQUENCE_ADD(&ie->value.choice.MBSFN_Area_Configuration_List.list,mbsfn_area_configuration_item_ie);
+//-------------
+//-------------
+
+// ASN_SEQUENCE_ADD(&ie->value.choice.MBSFN_Area_Configuration_List.list,mbsfn_area_configuration_item_ie+1);
+//-------------
+
+
+
+/* xer_fprint(stdout,&asn_DEF_M2AP_MBSFN_Area_Configuration_Item,mbsfn_area_configuration_item_ie);
+ xer_fprint(stdout,&asn_DEF_M2AP_MBSFN_Area_Configuration_Item,mbsfn_area_configuration_item_ie_1);
+ xer_fprint(stdout,&asn_DEF_M2AP_MBSFN_Area_Configuration_Item,mbsfn_area_configuration_item_ie_2);
+ xer_fprint(stdout,&asn_DEF_M2AP_MBSFN_Area_Configuration_Item,mbsfn_area_configuration_item_ie_3);
+ xer_fprint(stdout,&asn_DEF_M2AP_MBSFN_Area_Configuration_List, &ie->value.choice.MBSFN_Area_Configuration_List);*/
+
+  }
+
+
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);  
+
+ // LOG_D(M2AP,"%p\n",&pdu); 
+ // LOG_D(M2AP,"%p\n",out); 
+ // LOG_D(M2AP,"%p\n",ie); 
+ // LOG_D(M2AP,"%p\n",mbsfn_area_configuration_item_ie);
+ // LOG_D(M2AP,"%p\n",&mbsfn_area_configuration_item_ie->value.choice);
+ // {
+ //         /* PMCH_Configuration_List */
+ //        	
+ //         M2AP_PMCH_Configuration_ItemIEs_t * pmch_configuration_item_ies;
+ //         pmch_configuration_item_ies = (M2AP_PMCH_Configuration_ItemIEs_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_ItemIEs_t));
+ //         {
+ //       	pmch_configuration_item_ies->id = M2AP_ProtocolIE_ID_id_PMCH_Configuration_Item;
+ //       	pmch_configuration_item_ies->criticality = M2AP_Criticality_reject;
+ //       	pmch_configuration_item_ies->value.present = M2AP_PMCH_Configuration_ItemIEs__value_PR_PMCH_Configuration_Item;
+ //       	M2AP_PMCH_Configuration_Item_t * pmch_configuration_item;
+ //       	pmch_configuration_item = &pmch_configuration_item_ies->value.choice.PMCH_Configuration_Item;
+ //       	{
+ //       		//pmch_configuration_item->allocatedSubframesEnd;
+ //       		pmch_configuration_item->pmch_Configuration.dataMCS=13;
+ //       		//pmch_configuration_item->mchSchedulingPeriod;
+ //       		MBMSsessionListPerPMCH_Item__Member *member;
+ //       		member = (MBMSsessionListPerPMCH_Item__Member*)calloc(1,sizeof(MBMSsessionListPerPMCH_Item__Member));
+ // 			LOG_D(M2AP,"%p,%p,%p\n",pmch_configuration_item,&pmch_configuration_item->mbms_Session_List.list,member); 
+ //       		ASN_SEQUENCE_ADD(&pmch_configuration_item->mbms_Session_List.list,member);
+ //       	}
+ //       	////
+ //       	 // //ASN_SEQUENCE_ADD(mbsfn_area_configuration_item_ie,pmch_configuration_item_ies);
+ //       	
+ //         }
+ //    
+ //        M2AP_PMCH_Configuration_List_t * pmch_list = &mbsfn_area_configuration_item_ie->value.choice.PMCH_Configuration_List; 
+ //       	
+ //        ASN_SEQUENCE_ADD(&pmch_list->list,pmch_configuration_item_ies);
+ //        LOG_D(M2AP,"%p,%p\n",&mbsfn_area_configuration_item_ie->value.choice.PMCH_Configuration_List.list,pmch_configuration_item_ies);
+ //        //ASN_SEQUENCE_ADD(&mbsfn_area_configuration_item_ie->value.choice.PMCH_Configuration_List.list,pmch_configuration_item_ies);
+ //        //ASN_SET_ADD(&mbsfn_area_configuration_item_ie->value.choice.PMCH_Configuration_List.list,pmch_configuration_item_ies);
+ //        //ASN_SEQUENCE_ADD(mbsfn_area_configuration_item_ie,pmch_configuration_item_ies);
+
+ //       /* MBSFN_Subframe_ConfigurationList */
+ //         M2AP_MBSFN_Subframe_ConfigurationItem_t * mbsfn_subframe_configurationitem;
+ //         mbsfn_subframe_configurationitem =(M2AP_MBSFN_Subframe_ConfigurationItem_t*)calloc(1,sizeof(M2AP_MBSFN_Subframe_ConfigurationItem_t));
+ //         {
+ //       	mbsfn_subframe_configurationitem->id = M2AP_ProtocolIE_ID_id_MBSFN_Subframe_Configuration_Item;
+ //       	mbsfn_subframe_configurationitem->criticality = M2AP_Criticality_reject;
+ //       	mbsfn_subframe_configurationitem->value.present=M2AP_MBSFN_Subframe_ConfigurationItem__value_PR_MBSFN_Subframe_Configuration;
+ //         }
+ //
+ // 	  //ASN_SEQUENCE_ADD(&mbsfn_area_configuration_item_ie->value.choice.MBSFN_Subframe_ConfigurationList.list,mbsfn_subframe_configurationitem);
+ //        LOG_D(M2AP,"%p,%p\n",&mbsfn_area_configuration_item_ie->value.choice.PMCH_Configuration_List.list,mbsfn_subframe_configurationitem);
+ // 	  //ASN_SEQUENCE_ADD(&mbsfn_area_configuration_item_ie->value.choice.MBSFN_Subframe_ConfigurationList.list,mbsfn_subframe_configurationitem);
+////
+////	M2AP_Common_Subframe_Allocation_Period_t * common_subframe_allocation_period;
+////	M2AP_MBSFN_Area_ID_t * mbsfn_area_id;
+ // }
+ //        LOG_D(M2AP,"%p,%p\n",&ie->value.choice.MBSFN_Area_Configuration_List.list,mbsfn_area_configuration_item_ie);
+ // //ASN_SET_ADD(&ie->value.choice.MBSFN_Area_Configuration_List.list,mbsfn_area_configuration_item_ie);
+ // ASN_SET_ADD(&ie->value.choice.MBSFN_Area_Configuration_List.list,mbsfn_area_configuration_item_ie);
+
+ // M2AP_MBSFN_Area_Configuration_Item_t *mbsfn_area_configuration_item_ie_2;
+ // mbsfn_area_configuration_item_ie_2 =(M2AP_MBSFN_Area_Configuration_Item_t*)calloc(1,sizeof(M2AP_MBSFN_Area_Configuration_Item_t)); 
+ // {
+ //        // mbsfn_area_configuration_item_ie->value.present = M2AP_MBSFN_Area_Configuration_Item__value_PR_PMCH_Configuration_List;
+ //         /* PMCH_Configuration_List */
+ //        // M2AP_PMCH_Configuration_ItemIEs_t * pmch_configuration_item_ies;
+ //        // pmch_configuration_item_ies = (M2AP_PMCH_Configuration_ItemIEs_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_ItemIEs_t));
+ //        // pmch_configuration_item_ies->id = M2AP_ProtocolIE_ID_id_PMCH_Configuration_Item;
+ //        // pmch_configuration_item_ies->criticality = M2AP_Criticality_reject;
+ //        // pmch_configuration_item_ies->value.present = M2AP_PMCH_Configuration_ItemIEs__value_PR_PMCH_Configuration_Item;
+ //        // M2AP_PMCH_Configuration_Item_t * pmch_configuration_item;
+ //        // pmch_configuration_item = &pmch_configuration_item_ies->value.choice.PMCH_Configuration_Item;
+ //       ////
+ //        // ASN_SEQUENCE_ADD(mbsfn_area_configuration_item_ie,pmch_configuration_item_ies);
+
+ //       /* MBSFN_Subframe_ConfigurationList */
+ //         M2AP_MBSFN_Subframe_ConfigurationItem_t * mbsfn_subframe_configurationitem;
+ //         mbsfn_subframe_configurationitem =(M2AP_MBSFN_Subframe_ConfigurationItem_t*)calloc(1,sizeof(M2AP_MBSFN_Subframe_ConfigurationItem_t));
+ //         {
+ //       	mbsfn_subframe_configurationitem->id = M2AP_ProtocolIE_ID_id_MBSFN_Subframe_Configuration_Item;
+ //       	mbsfn_subframe_configurationitem->criticality = M2AP_Criticality_reject;
+ //       	mbsfn_subframe_configurationitem->value.present=M2AP_MBSFN_Subframe_ConfigurationItem__value_PR_MBSFN_Subframe_Configuration;
+ //       	//M2AP_MBSFN_Subframe_Configuration_t * mbsfn_subframe_configuration;
+ //       	//mbsfn_subframe_configuration = (M2AP_MBSFN_Subframe_Configuration_t*)calloc(1,sizeof(M2AP_MBSFN_Subframe_Configuration_t));
+ // 	  	//ASN_SEQUENCE_ADD(mbsfn_subframe_configurationitem,mbsfn_subframe_configuration);
+ //       	M2AP_MBSFN_Subframe_Configuration_t * mbsfn_subframe_configuration;
+ //       	mbsfn_subframe_configuration = &mbsfn_subframe_configurationitem->value.choice.MBSFN_Subframe_Configuration;
+ //         }
+ //
+ // 	  ASN_SEQUENCE_ADD(mbsfn_area_configuration_item_ie_2,mbsfn_subframe_configurationitem);
+
+ // }
+
+ // ASN_SEQUENCE_ADD(&ie->value.choice.MBSFN_Area_Configuration_List.list,mbsfn_area_configuration_item_ie_2);
+
+
+
+//  M2AP_MBSFN_Area_Configuration_List_t * m2ap_mbsfn_area_configuration_list;
+//  m2ap_mbsfn_area_configuration_list = &ie->value.choice.MBSFN_Area_Configuration_List;
+//  {
+//	M2AP_PMCH_Configuration_ItemIEs_t * pmch_configuration_item_ies;
+//	pmch_configuration_item_ies = (M2AP_PMCH_Configuration_ItemIEs_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_ItemIEs_t));
+//	pmch_configuration_item_ies->id = M2AP_ProtocolIE_ID_id_PMCH_Configuration_Item;
+//	pmch_configuration_item_ies->criticality = M2AP_Criticality_reject;
+//	pmch_configuration_item_ies->value.present = M2AP_PMCH_Configuration_ItemIEs__value_PR_PMCH_Configuration_Item;
+//	M2AP_PMCH_Configuration_Item_t * pmch_configuration_item;
+//	pmch_configuration_item = &pmch_configuration_item_ies->value.choice.PMCH_Configuration_Item;
+//
+//	ASN_SEQUENCE_ADD(&m2ap_mbsfn_area_configuration_list->PMCH_Configuration_List.list,pmch_configuration_item_ies);
+//  }
+//
+//  int num_mbsfn_available =0; // ?
+//  LOG_I(M2AP, "num_mbsfn_available = %d \n", num_mbsfn_available);
+//  for (i=0;
+//       i<num_mbsfn_available;
+//       i++) {
+//
+//        //M2AP_MBSFN_Area_Configuration_Item_t *mbms_mbsfn_area_configuration_item_ies;
+//        //mbms_mbsfn_area_configuration_item_ies = ( M2AP_MBSFN_Area_Configuration_Item_t *)calloc(1, sizeof(M2AP_MBSFN_Area_Configuration_Item_t ));
+//        //mbms_configuration_data_item_ies->id = M2AP_ProtocolIE_ID_id_MBSFN_Area_Configuration_Item;
+//        //mbms_configuration_data_item_ies>criticality = M2AP_Criticality_reject;
+//        //mbms_mbsfn_area_configuration_item_ies->value.present = M2AP_MBSFN_Area_Configuration_Item__value_PR_M2AP_MBSFN_Area_Configuration_Item;
+//	
+//	M2AP_MBSFN_Area_Configuration_Item_t * mbsfn_area_configuration_item;
+//	mbsfn_area_configuration_item = (M2AP_MBSFN_Area_Configuration_Item_t*)calloc(1,sizeof(M2AP_MBSFN_Area_Configuration_Item_t));
+//	//mbsfn_area_configuration_item = &mbms_mbsfn_area_configuration_item_ies->value.choice.M2AP_MBSFN_Area_Configuration_Item;
+//	mbsfn_area_configuration_item->value.present = M2AP_MBSFN_Area_Configuration_Item__value_PR_PMCH_Configuration_List;
+//
+//	M2AP_PMCH_Configuration_ItemIEs_t * pmch_configuration_item_ies;
+//	pmch_configuration_item_ies = (M2AP_PMCH_Configuration_ItemIEs_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_ItemIEs_t));
+//	pmch_configuration_item_ies->id = M2AP_ProtocolIE_ID_id_PMCH_Configuration_Item;
+//	pmch_configuration_item_ies->criticality = M2AP_Criticality_reject;
+//	pmch_configuration_item_ies->value.present = M2AP_PMCH_Configuration_ItemIEs__value_PR_PMCH_Configuration_Item;
+//	M2AP_PMCH_Configuration_Item_t * pmch_configuration_item;
+//	pmch_configuration_item = &pmch_configuration_item_ies->value.choice.PMCH_Configuration_Item;
+//	//memset((void*)&pmch_configuration_item,0,sizeof(M2AP_PMCH_Configuration_Item_t));
+//
+//	ASN_SEQUENCE_ADD(&mbsfn_area_configuration_item->value.choice.PMCH_Configuration_List.list,pmch_configuration_item_ies);
+////	if(0)
+////       {
+////	/* PMCH_Configuration_List */	
+////        LOG_I(M2AP, "num_pmch_available = %d \n", num_mbsfn_available);
+////  	int num_pmch_available =0; // ?
+////	for (j=0;
+////       	      j<num_pmch_available;
+////       	      j++) {
+////		M2AP_PMCH_Configuration_ItemIEs_t * pmch_configuration_item_ies;
+////		pmch_configuration_item_ies->id = (M2AP_PMCH_Configuration_ItemIEs_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_ItemIEs_t));
+////		pmch_configuration_item_ies->criticality = M2AP_Criticality_reject;
+////		pmch_configuration_item_ies->value.present = M2AP_PMCH_Configuration_ItemIEs__value_PR_PMCH_Configuration_Item;
+////
+////		M2AP_PMCH_Configuration_Item_t * pmch_configuration_item;
+////		//pmch_configuration_item = (M2AP_PMCH_Configuration_Item_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_Item_t));
+////		pmch_configuration_item = &pmch_configuration_item_ies->value.choice.PMCH_Configuration_Item;
+////		{
+////			/* PMCH_Configuration */
+////			/* allocateSubframesEnd */
+////			//pmch_configuration_item.pmch_Configuration.allocatedSubframesEnd=;
+////			/* dataMCS */
+////			//pmch_configuration_item.pmch_Configuration.dataMCS=;
+////			/* MCH_Scheduling_Period*/
+////			//pmch_configuration_item.pmch_Configuration.mchSchedulingPeriod=;
+////			
+////			/* MBMSsessionListPerPMCH */
+////			LOG_I(M2AP, "num_mbms_session_available = %d \n", num_mbsfn_available);
+////			int num_mbms_session_available =1; // ?
+////			for(k=0;
+////			    k<num_mbms_session_available;
+////			    k++){
+////				M2AP_MBMSsessionListPerPMCH_Item_t * session_list_per_pmch_item;
+////				session_list_per_pmch_item=(M2AP_MBMSsessionListPerPMCH_Item_t*)calloc(1,sizeof(M2AP_MBMSsessionListPerPMCH_Item_t));
+////				
+////				//session_list_per_pmch_item->tmgi=;
+////				//session_list_per_pmch_item->lcid=;
+////				//ASN_SEQUENCE_ADD(&pmch_configuration_item->mbms_Session_List.list,mbsfn_area_configuration_item);
+////			}
+////
+////		}
+////		ASN_SEQUENCE_ADD(&mbsfn_area_configuration_item->value.choice.PMCH_Configuration_List.list,pmch_configuration_item_ies);
+////	}
+////
+////	/* MBSFN_Subframe_ConfigurationList */
+////	int num_mbsfn_subframe_available=0;
+////	for(j=0;
+////	    j<num_mbsfn_subframe_available;
+////	    j++){
+////		M2AP_MBSFN_Subframe_ConfigurationItem_t * mbsfn_subframe_configuration_item;
+////		mbsfn_subframe_configuration_item = (M2AP_MBSFN_Subframe_ConfigurationItem_t*)calloc(1,sizeof(M2AP_MBSFN_Subframe_ConfigurationItem_t));
+////		//mbsfn_subframe_configuration_item->MBSFN_Subframe_Configuration.radioframeAllocationPeriod=;
+////		//mbsfn_subframe_configuration_item->MBSFN_Subframe_Configuration.radioframeAllocationOffset=;
+////		//mbsfn_subframe_configuration_item->MBSFN_Subframe_Configuration.subframeAllocation.oneFrame=;
+////		//mbsfn_subframe_configuration_item->MBSFN_Subframe_Configuration.subframeAllocation.fourFrames=;
+////		
+////		ASN_SEQUENCE_ADD(&mbsfn_area_configuration_item->value.choice.MBSFN_Subframe_ConfigurationList.list,mbsfn_subframe_configuration_item);
+////		
+////	}
+////	/* Common_subframe_Allocation_Period */
+////	mbsfn_area_configuration_item->value.choice.Common_Subframe_Allocation_Period=0;
+////	/* MBSFN_Area_ID */
+////	mbsfn_area_configuration_item->value.choice.MBSFN_Area_ID=0;
+////	/*MBMS_Suspension_Notification_List*/ 
+////	//TODO
+////        }
+//	//ASN_SEQUENCE_ADD(&ie->value.choice.MBSFN_Area_Configuration_List.list,mbsfn_area_configuration_item);
+//	ASN_SEQUENCE_ADD(&m2ap_mbsfn_area_configuration_list->list,mbsfn_area_configuration_item);
+//	
+//  }
+
+  
+ 
+  /* encode */
+  if (m2ap_encode_pdu(&pdu,&buffer,&len) < 0){
+	return -1;
+ }
+  /*if (m2ap_encode_pdu(&pdu,&buffer,&len) < 0){
+	return -1;
+  }*/
+
+  /*buffer = &m2ap_message[0];
+  len = 62;
+ for(int i=0; i < len; i++ )
+	printf("%02X",buffer[i]);
+  printf("\n");*/
+
+
+  //printf("m2ap_mce_data_from_enb %p %p %d\n",m2ap_mce_data_from_enb, buffer, len);
+
+  m2ap_MCE_itti_send_sctp_data_req(instance,m2ap_mce_data_from_enb->assoc_id,buffer,len,0);
+  return 0;
+
+
+// buffer2 = &m2ap_message[0];
+// len2 = 62;
+// for(int i=0; i < len2; i++ )
+//	printf("%02X",buffer2[i]);
+//  printf("\n");
+//
+//  M2AP_M2AP_PDU_t pdu2;
+//  memset(&pdu2, 0, sizeof(pdu2));
+//  if (m2ap_decode_pdu(&pdu2, buffer2, len2) < 0) {
+//    LOG_E(M2AP, "SCHEDULING Failed to decode PDU\n");
+//    //return -1;
+//  }else{
+//    LOG_D(M2AP, "SCHEDULING OK to decode PDU\n");
+//  }
+//
+//
+//  M2AP_MbmsSchedulingInformation_t *container2;
+//  M2AP_MbmsSchedulingInformation_Ies_t   *ie2;
+//  int i2 = 0;
+//  container2 = &pdu2.choice.initiatingMessage.value.choice.MbmsSchedulingInformation;
+//  M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_MbmsSchedulingInformation_Ies_t, ie2, container2,M2AP_ProtocolIE_ID_id_MCCH_Update_Time ,true);
+//  LOG_D(M2AP, "SCHEDULING id %d\n",ie2->id);
+//  M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_MbmsSchedulingInformation_Ies_t, ie2, container2,M2AP_ProtocolIE_ID_id_MBSFN_Area_Configuration_List ,true);
+//  LOG_D(M2AP, "SCHEDULING id %d\n",ie2->id);
+//
+//
+//  
+//  //M2AP_MBSFN_Area_Configuration_Item_t  * kk  = &ie->value.choice.MBSFN_Area_Configuration_List.list.array[0];
+//  //printf("M2AP_MBSFN_Area_Configuration_Item %d\n",kk->id);
+//
+//  const asn_anonymous_sequence_ *list = _A_CSEQUENCE_FROM_VOID((void*)&ie2->value.choice.MBSFN_Area_Configuration_List);
+//  void * memb_ptr = list->array[0];
+//  const asn_anonymous_sequence_ *list2 = _A_CSEQUENCE_FROM_VOID((void*)memb_ptr);
+//
+//
+//  void * memb_ptr1 = list2->array[0];
+//  M2AP_MBSFN_Area_Configuration_Item_t * m2ap_mbsfn_area_configuration_item1 = (M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr1;
+//  M2AP_PMCH_Configuration_Item_t * m2ap_pmchconfiguration_item =&(((M2AP_PMCH_Configuration_ItemIEs_t*)m2ap_mbsfn_area_configuration_item1->value.choice.PMCH_Configuration_List.list.array[0])->value.choice.PMCH_Configuration_Item);
+//  printf("dataMCS %d\n",m2ap_pmchconfiguration_item->pmch_Configuration.dataMCS);
+//  m2ap_pmchconfiguration_item->pmch_Configuration.dataMCS=4;
+//  printf("allocatedSubframesEnd %d\n",m2ap_pmchconfiguration_item->pmch_Configuration.allocatedSubframesEnd);
+//  M2AP_PMCH_Configuration_t * m2ap_pmchconfiguration = &m2ap_pmchconfiguration_item->pmch_Configuration;
+//  printf("M2AP_PMCH_Configuration_t dataMCS %d\n",m2ap_pmchconfiguration->dataMCS);
+//  printf("M2AP_PMCH_Configuration_t allocatedSubframesEnd %d\n",m2ap_pmchconfiguration->allocatedSubframesEnd);
+//  M2AP_MBMSsessionListPerPMCH_Item_t * m2ap_mbsfnsessionlistperPMCH = &m2ap_pmchconfiguration_item->mbms_Session_List;
+//  M2AP_TMGI_t * tmgi  =  &m2ap_mbsfnsessionlistperPMCH->list.array[0]->tmgi;
+//  M2AP_PLMN_Identity_t * pLMNidentity = &tmgi->pLMNidentity;
+//  MCC_MNC_TO_PLMNID(0,1,3/*instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,*/
+//  ,pLMNidentity);
+//
+//
+//  OCTET_STRING_t * serviceID = &tmgi->serviceID; 
+//  M2AP_LCID_t * lcid  =  &m2ap_mbsfnsessionlistperPMCH->list.array[0]->lcid; //long
+//
+//
+//  void * memb_ptr2 = list2->array[1];
+//  M2AP_MBSFN_Area_Configuration_Item_t * m2ap_mbsfn_area_configuration_item2 = (M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr2;
+//  M2AP_MBSFN_Subframe_Configuration_t * m2ap_mbsfn_subframe_configuration_item =&(((M2AP_MBSFN_Subframe_ConfigurationItem_t*)m2ap_mbsfn_area_configuration_item2->value.choice.MBSFN_Subframe_ConfigurationList.list.array[0])->value.choice.MBSFN_Subframe_Configuration);
+//  //M2AP_MBSFN_Subframe_Configuration_t * m2ap_mbsfn_subframe_configuration = &m2ap_mbsfn_subframe_configuration_item->value.choice.MBSFN_Subframe_Configuration;
+//  printf("oneframe ? %d\n",(m2ap_mbsfn_subframe_configuration_item->subframeAllocation.present == M2AP_MBSFN_Subframe_Configuration__subframeAllocation_PR_oneFrame));
+//
+//	
+// void * memb_ptr3 = list2->array[2];
+// M2AP_MBSFN_Area_Configuration_Item_t * m2ap_mbsfn_area_configuration_item3 = (M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr3;
+// M2AP_Common_Subframe_Allocation_Period_t * m2ap_mbsfn_common_subframe_allocation_period = (M2AP_Common_Subframe_Allocation_Period_t*)m2ap_mbsfn_area_configuration_item3->value.choice.Common_Subframe_Allocation_Period;
+//
+// void * memb_ptr4 = list2->array[3];
+// M2AP_MBSFN_Area_Configuration_Item_t * m2ap_mbsfn_area_configuration_item4 = (M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr4;
+// M2AP_MBSFN_Area_ID_t * m2ap_mbsfn_area_id = (M2AP_MBSFN_Area_ID_t*)m2ap_mbsfn_area_configuration_item4->value.choice.MBSFN_Area_ID;
+//
+//
+//
+// //ASN_SEQUENCE_ADD(&ie->value.choice.MBSFN_Area_Configuration_List,list);
+// ASN_SEQUENCE_ADD(&ie->value.choice.MBSFN_Area_Configuration_List,m2ap_mbsfn_area_configuration_list);
+//
+// LOG_D(M2AP,"Morgade\n");
+// xer_fprint(stdout,&asn_DEF_M2AP_MBSFN_Area_Configuration_List, &ie->value.choice.MBSFN_Area_Configuration_List);
+//
+// /* encode */
+//  if (m2ap_encode_pdu(&pdu2,&buffer,&len) < 0){
+//	return -1; 
+//   }
+//
+//  //MCE_m2ap_itti_send_sctp_data_req(instance, m2ap_mce_data_from_mce->assoid,buffer,len,0); 
+//  m2ap_MCE_itti_send_sctp_data_req(instance,assoc_id,buffer,len,0);
+//  return 0;
+//
+//
+                        
+}
+
+int MCE_handle_MBMS_SCHEDULING_INFORMATION_RESPONSE(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                M2AP_M2AP_PDU_t *pdu){
+
+  LOG_D(M2AP, "MCE_handle_MBMS_SCHEDULING_INFORMATION_RESPONSE\n");
+
+   AssertFatal(pdu->present == M2AP_M2AP_PDU_PR_successfulOutcome,
+	       "pdu->present != M2AP_M2AP_PDU_PR_successfulOutcome\n");
+   AssertFatal(pdu->choice.successfulOutcome.procedureCode  == M2AP_ProcedureCode_id_mbmsSchedulingInformation,
+	       "pdu->choice.successfulOutcome->procedureCode != M2AP_ProcedureCode_id_mbmsSchedulingInformation\n");
+   AssertFatal(pdu->choice.successfulOutcome.criticality  == M2AP_Criticality_reject,
+	       "pdu->choice.successfulOutcome->criticality != M2AP_Criticality_reject\n");
+   AssertFatal(pdu->choice.successfulOutcome.value.present  == M2AP_SuccessfulOutcome__value_PR_MbmsSchedulingInformationResponse,
+	       "pdu->choice.successfulOutcome->value.present != M2AP_SuccessfulOutcome__value_PR_MbmsSchedulingInformationResponse\n");
+
+
+  //M2AP_MbmsSchedulingInformationResponse_t    *in = &pdu->choice.successfulOutcome.value.choice.MbmsSchedulingInformationResponse;
+  //M2AP_MbmsSchedulingInformationResponse_Ies_t  *ie;
+  //int MCE_MBMS_M2AP_ID=-1;
+  //int ENB_MBMS_M2AP_ID=-1;
+
+
+  MessageDef *msg_g = itti_alloc_new_message(TASK_M2AP_MCE,M2AP_MBMS_SCHEDULING_INFORMATION_RESP); //TODO
+
+//  LOG_D(M2AP, "M2AP: SessionStop-Resp: protocolIEs.list.count %d\n",
+//         in->protocolIEs.list.count);
+//  for (int i=0;i < in->protocolIEs.list.count; i++) {
+//     ie = in->protocolIEs.list.array[i];
+//     //switch (ie->id) {
+//     //case M2AP_ProtocolIE_ID_id_MCE_MBMS_M2AP_ID:
+//     //  AssertFatal(ie->criticality == M2AP_Criticality_reject,
+//     //              "ie->criticality != M2AP_Criticality_reject\n");
+//     //  AssertFatal(ie->value.present == M2AP_sessionStopIEs__value_PR_MCE_MBMS_M2AP_ID,
+//     //              "ie->value.present != M2AP_sessionStopIEs__value_PR_MCE_MBMS_M2AP_ID\n");
+//     //  TransactionId=ie->value.choice.MCE_MBMS_M2AP_ID;
+//     //  LOG_D(M2AP, "M2AP: SessionStop-Resp: MCE_MBMS_M2AP_ID %d\n",
+//     //        MCE_MBMS_M2AP_ID);
+//     //  break;
+//     // case M2AP_ProtocolIE_ID_id_ENB_MBMS_M2AP_ID:
+//     //  AssertFatal(ie->criticality == M2AP_Criticality_reject,
+//     //              "ie->criticality != M2AP_Criticality_reject\n");
+//     //  AssertFatal(ie->value.present == M2AP_sessionStopIEs__value_PR_ENB_MBMS_M2AP_ID,
+//     //              "ie->value.present != M2AP_sessionStopIEs__value_PR_ENB_MBMS_M2AP_ID\n");
+//     //  TransactionId=ie->value.choice.ENB_MBMS_M2AP_ID;
+//     //  LOG_D(M2AP, "M2AP: SessionStop-Resp: ENB_MBMS_M2AP_ID %d\n",
+//     //        ENB_MBMS_M2AP_ID);
+//     //  break;
+//     //}
+//  }
+//
+//  M2AP_SESSION_STOP_RESP(msg_p).
+//  MSC_LOG_RX_MESSAGE(
+//    MSC_M2AP_MCE,
+//    MSC_M2AP_ENB,
+//    0,
+//    0,
+//    MSC_AS_TIME_FMT" MCE_handle_M2_SCHEDULING_INFORMATION_RESPONSE successfulOutcome assoc_id %d",
+//    0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
+//    assoc_id);
+//
+//   LOG_D(M2AP, "Sending M2AP_SCHEDULING_INFO_RESP ITTI message to ENB_APP with assoc_id (%d->%d)\n",
+//         assoc_id,ENB_MODULE_ID_TO_INSTANCE(assoc_id));
+//   itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p);
+
+    itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(instance), msg_g);
+//
+   return 0;
+                       
+}
+
+/*
+ * Reset
+ */
+
+int MCE_send_RESET(instance_t instance, m2ap_reset_t * m2ap_reset) {
+  AssertFatal(1==0,"Not implemented yet\n");
+  //M2AP_Reset_t     Reset;
+                        
+}
+
+
+int MCE_handle_RESET_ACKKNOWLEDGE(instance_t instance,
+                                  uint32_t assoc_id,
+                                  uint32_t stream,
+                                  M2AP_M2AP_PDU_t *pdu) {
+  AssertFatal(1==0,"Not implemented yet\n");
+
+}
+
+int MCE_handle_RESET(instance_t instance,
+                     uint32_t assoc_id,
+                     uint32_t stream,
+                     M2AP_M2AP_PDU_t *pdu) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+int MCE_send_RESET_ACKNOWLEDGE(instance_t instance, M2AP_ResetAcknowledge_t *ResetAcknowledge) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+/*
+ *    M2 Setup
+ */
+int MCE_handle_M2_SETUP_REQUEST(instance_t instance,
+                               uint32_t assoc_id,
+                               uint32_t stream,
+                               M2AP_M2AP_PDU_t *pdu)
+{
+  LOG_D(M2AP, "MCE_handle_M2_SETUP_REQUEST assoc_id %d\n",assoc_id);
+
+  MessageDef                         *message_p;
+  M2AP_M2SetupRequest_t              *container;
+  M2AP_M2SetupRequest_Ies_t           *ie;
+  int i = 0,j=0;
+
+  DevAssert(pdu != NULL);
+
+  container = &pdu->choice.initiatingMessage.value.choice.M2SetupRequest;
+
+  /* M2 Setup Request == Non UE-related procedure -> stream 0 */
+  if (stream != 0) {
+    LOG_D(M2AP, "[SCTP %d] Received m2 setup request on stream != 0 (%d)\n",
+              assoc_id, stream);
+  }
+
+  message_p = itti_alloc_new_message(TASK_MCE_APP, M2AP_SETUP_REQ); 
+  
+  /* assoc_id */
+  M2AP_SETUP_REQ(message_p).assoc_id = assoc_id;
+
+ /* GlobalENB_id */
+ // this function exits if the ie is mandatory
+  M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_M2SetupRequest_Ies_t, ie, container,
+                             M2AP_ProtocolIE_ID_id_GlobalENB_ID, true);
+  //asn_INTEGER2ulong(&ie->value.choice.GlobalENB_ID.eNB_ID, &M2AP_SETUP_REQ(message_p).GlobalENB_ID);
+  if(ie->value.choice.GlobalENB_ID.eNB_ID.present == M2AP_ENB_ID_PR_macro_eNB_ID){
+  }else if(ie->value.choice.GlobalENB_ID.eNB_ID.present == M2AP_ENB_ID_PR_short_Macro_eNB_ID){
+  }else if(ie->value.choice.GlobalENB_ID.eNB_ID.present == M2AP_ENB_ID_PR_long_Macro_eNB_ID){
+  }
+
+  LOG_D(M2AP, "M2AP_SETUP_REQ(message_p).GlobalENB_ID %lu \n", M2AP_SETUP_REQ(message_p).GlobalENB_ID);
+
+  /* ENB_name */
+  M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_M2SetupRequest_Ies_t, ie, container,
+                              M2AP_ProtocolIE_ID_id_ENBname, false);
+  if(ie!=NULL){
+	  M2AP_SETUP_REQ(message_p).ENBname = calloc(ie->value.choice.ENBname.size + 1, sizeof(char));
+	  memcpy(M2AP_SETUP_REQ(message_p).ENBname, ie->value.choice.ENBname.buf,
+		 ie->value.choice.ENBname.size);
+
+	  /* Convert the mme name to a printable string */
+	  M2AP_SETUP_REQ(message_p).ENBname[ie->value.choice.ENBname.size] = '\0';
+	  LOG_D(M2AP, "M2AP_SETUP_REQ(message_p).gNB_DU_name %s \n", M2AP_SETUP_REQ(message_p).ENBname);
+  }
+   /* ENB_MBMS_Configuration_data_List */
+
+
+  M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_M2SetupRequest_Ies_t, ie, container,
+                              M2AP_ProtocolIE_ID_id_ENB_MBMS_Configuration_data_List, true);
+  M2AP_SETUP_REQ(message_p).num_mbms_available = ie->value.choice.ENB_MBMS_Configuration_data_List.list.count;
+  LOG_D(M2AP, "M2AP_SETUP_REQ(message_p).num_mbms_available %d \n",
+        M2AP_SETUP_REQ(message_p).num_mbms_available);
+  int num_mbms_available = M2AP_SETUP_REQ(message_p).num_mbms_available;
+  for (i=0; i<num_mbms_available; i++) {
+	 M2AP_ENB_MBMS_Configuration_data_Item_t *mbms_configuration_item_p;
+         mbms_configuration_item_p = &(((M2AP_ENB_MBMS_Configuration_data_ItemIEs_t *)ie->value.choice.ENB_MBMS_Configuration_data_List.list.array[i])->value.choice.ENB_MBMS_Configuration_data_Item);
+    /* eCGI */
+       //mbms_configuration_item_p->eCGI ... (M2AP_ECGI_t)
+
+    OCTET_STRING_TO_INT16(&(mbms_configuration_item_p->eCGI.pLMN_Identity),M2AP_SETUP_REQ(message_p).plmn_identity[i]);
+    //OCTET_STRING_TO_INT16(&(mbms_configuration_item_p->eCGI.eUTRANcellIdentifier),M2AP_SETUP_REQ(message_p).eutran_cell_identifier[i]);
+    /* mbsfnSynchronisationArea */
+       //mbms_configuration_item_p->mbsfnSynchronisationArea ... (M2AP_MBSFN_SynchronisationArea_ID_t)
+
+    M2AP_SETUP_REQ(message_p).mbsfn_synchronization_area[i]=mbms_configuration_item_p->mbsfnSynchronisationArea;
+    /* mbmsServiceAreaList */
+       //mbms_configuration_item_p->mbmsServiceAreaList ... (M2AP_MBMS_Service_Area_ID_List_t)
+   for(j=0;j<1;j++){
+   	//OCTET_STRING_TO_INT16(&(mbms_configuration_item_p->mbmsServiceAreaList.list.array[j]), M2AP_SETUP_REQ(message_p).service_area_id[i][j]);
+   }
+
+ }
+    
+//    /* tac */
+//    OCTET_STRING_TO_INT16(&(served_celles_item_p->served_Cell_Information.fiveGS_TAC), M2AP_SETUP_REQ(message_p).tac[i]);
+//    LOG_D(M2AP, "M2AP_SETUP_REQ(message_p).tac[%d] %d \n",
+//          i, M2AP_SETUP_REQ(message_p).tac[i]);
+//
+//    /* - nRCGI */
+//    TBCD_TO_MCC_MNC(&(served_celles_item_p->served_Cell_Information.nRCGI.pLMN_Identity), M2AP_SETUP_REQ(message_p).mcc[i],
+//                    M2AP_SETUP_REQ(message_p).mnc[i],
+//                    M2AP_SETUP_REQ(message_p).mnc_digit_length[i]);
+//    
+//    
+//    // NR cellID
+//    BIT_STRING_TO_NR_CELL_IDENTITY(&served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity,
+//				   M2AP_SETUP_REQ(message_p).nr_cellid[i]);
+//    LOG_D(M2AP, "[SCTP %d] Received nRCGI: MCC %d, MNC %d, CELL_ID %llu\n", assoc_id,
+//          M2AP_SETUP_REQ(message_p).mcc[i],
+//          M2AP_SETUP_REQ(message_p).mnc[i],
+//          (long long unsigned int)M2AP_SETUP_REQ(message_p).nr_cellid[i]);
+//    LOG_D(M2AP, "nr_cellId : %x %x %x %x %x\n",
+//          served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[0],
+//          served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[1],
+//          served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[2],
+//          served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[3],
+//          served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[4]);
+//    /* - nRPCI */
+//    M2AP_SETUP_REQ(message_p).nr_pci[i] = served_celles_item_p->served_Cell_Information.nRPCI;
+//    LOG_D(M2AP, "M2AP_SETUP_REQ(message_p).nr_pci[%d] %d \n",
+//          i, M2AP_SETUP_REQ(message_p).nr_pci[i]);
+//  
+//    // System Information
+//    /* mib */
+//    M2AP_SETUP_REQ(message_p).mib[i] = calloc(served_celles_item_p->gNB_DU_System_Information->mIB_message.size + 1, sizeof(char));
+//    memcpy(M2AP_SETUP_REQ(message_p).mib[i], served_celles_item_p->gNB_DU_System_Information->mIB_message.buf,
+//           served_celles_item_p->gNB_DU_System_Information->mIB_message.size);
+//    /* Convert the mme name to a printable string */
+//    M2AP_SETUP_REQ(message_p).mib[i][served_celles_item_p->gNB_DU_System_Information->mIB_message.size] = '\0';
+//    M2AP_SETUP_REQ(message_p).mib_length[i] = served_celles_item_p->gNB_DU_System_Information->mIB_message.size;
+//    LOG_D(M2AP, "M2AP_SETUP_REQ(message_p).mib[%d] %s , len = %d \n",
+//          i, M2AP_SETUP_REQ(message_p).mib[i], M2AP_SETUP_REQ(message_p).mib_length[i]);
+//
+//    /* sib1 */
+//    M2AP_SETUP_REQ(message_p).sib1[i] = calloc(served_celles_item_p->gNB_DU_System_Information->sIB1_message.size + 1, sizeof(char));
+//    memcpy(M2AP_SETUP_REQ(message_p).sib1[i], served_celles_item_p->gNB_DU_System_Information->sIB1_message.buf,
+//           served_celles_item_p->gNB_DU_System_Information->sIB1_message.size);
+//    /* Convert the mme name to a printable string */
+//    M2AP_SETUP_REQ(message_p).sib1[i][served_celles_item_p->gNB_DU_System_Information->sIB1_message.size] = '\0';
+//    M2AP_SETUP_REQ(message_p).sib1_length[i] = served_celles_item_p->gNB_DU_System_Information->sIB1_message.size;
+//    LOG_D(M2AP, "M2AP_SETUP_REQ(message_p).sib1[%d] %s , len = %d \n",
+//          i, M2AP_SETUP_REQ(message_p).sib1[i], M2AP_SETUP_REQ(message_p).sib1_length[i]);
+//  }
+
+
+  //printf("m2ap_mce_data_from_enb->assoc_id %d %d\n",m2ap_mce_data_from_enb->assoc_id,assoc_id);
+
+  *m2ap_mce_data_from_enb = M2AP_SETUP_REQ(message_p);
+  //printf("m2ap_mce_data_from_enb->assoc_id %d %d\n",m2ap_mce_data_from_enb->assoc_id,assoc_id);
+
+//  MSC_LOG_TX_MESSAGE(
+//  MSC_M2AP_MCE,
+//  MSC_RRC_ENB,
+//  0,
+//  0,
+//  MSC_AS_TIME_FMT" MCE_handle_M2_SETUP_REQUEST",
+//  0,0//MSC_AS_TIME_ARGS(ctxt_pP),
+//  );
+//
+  if (num_mbms_available > 0) {
+    itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p);
+  } else {
+       //MCE_send_M2_SETUP_FAILURE(instance);
+       return -1;
+  }
+//  return 0;
+    //TEST POINT MCE -> eNB
+//    if(1){
+//	printf("instance %d\n",instance);
+//	//MCE_send_M2_SETUP_RESPONSE(instance,assoc_id,m2ap_mce_data_from_enb->assoc_id);
+//	//MCE_send_MBMS_SESSION_START_REQUEST(instance,assoc_id);
+//	//MCE_send_MBMS_SESSION_STOP_REQUEST(instance,assoc_id);
+//	//MCE_send_MBMS_SCHEDULING_INFORMATION(instance,assoc_id,NULL); //TODO
+//    }
+//    else 
+//	MCE_send_M2_SETUP_FAILURE(instance,assoc_id);
+
+    return 0;
+}
+
+int MCE_send_M2_SETUP_RESPONSE(instance_t instance, /*uint32_t assoc_id,*/
+                               m2ap_setup_resp_t *m2ap_setup_resp) {
+  
+  //module_id_t mce_mod_idP;
+  //module_id_t enb_mod_idP;
+
+  // This should be fixed
+  //enb_mod_idP = (module_id_t)0;
+  //mce_mod_idP  = (module_id_t)0;
+
+  M2AP_M2AP_PDU_t           pdu;
+  M2AP_M2SetupResponse_t    *out;
+  M2AP_M2SetupResponse_Ies_t *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  int       i = 0;
+  //int       j = 0;
+
+  AssertFatal(m2ap_setup_resp!=NULL,"m2ap_setup_resp = NULL\n");
+
+  /* Create */
+  /* 0. Message Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome;
+  //pdu.choice.successfulOutcome = (M2AP_SuccessfulOutcome_t *)calloc(1, sizeof(M2AP_SuccessfulOutcome_t));
+  pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup;
+  pdu.choice.successfulOutcome.criticality   = M2AP_Criticality_reject;
+  pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_M2SetupResponse;
+  out = &pdu.choice.successfulOutcome.value.choice.M2SetupResponse;
+  
+  /* mandatory */
+  /* c1. GlobalMCE ID (integer value)*/
+  ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_GlobalMCE_ID;
+  ie->criticality               = M2AP_Criticality_reject; //?
+  ie->value.present             = M2AP_M2SetupResponse_Ies__value_PR_GlobalMCE_ID;
+  //ie->value.choice.TransactionID = M2AP_get_next_transaction_identifier(enb_mod_idP, cu_mod_idP);
+  MCC_MNC_TO_PLMNID(m2ap_setup_resp->mcc, m2ap_setup_resp->mnc, m2ap_setup_resp->mnc_digit_length,
+  		&ie->value.choice.GlobalMCE_ID.pLMN_Identity);
+
+  ie->value.choice.GlobalMCE_ID.mCE_ID.buf =calloc(2, sizeof(uint8_t));
+  ie->value.choice.GlobalMCE_ID.mCE_ID.buf[0] = (m2ap_setup_resp->MCE_id) >> 8;
+  ie->value.choice.GlobalMCE_ID.mCE_ID.buf[1] = ((m2ap_setup_resp->MCE_id) & 0x0ff); 
+  ie->value.choice.GlobalMCE_ID.mCE_ID.size=2;
+  //ie->value.choice.GlobalMCE_ID.mCE_ID.bits_unused=0;
+
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+ 
+  /* optional */
+  /* c2. MCEname */
+  if (m2ap_setup_resp->MCE_name != NULL) {
+    ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t));
+    ie->id                        = M2AP_ProtocolIE_ID_id_MCEname;
+    ie->criticality               = M2AP_Criticality_ignore;
+    ie->value.present             = M2AP_M2SetupResponse_Ies__value_PR_MCEname;
+    OCTET_STRING_fromBuf(&ie->value.choice.MCEname, m2ap_setup_resp->MCE_name,
+                         strlen(m2ap_setup_resp->MCE_name));
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* mandatory */
+  /* c3. cells to be Activated list */
+  ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_MCCHrelatedBCCH_ConfigPerMBSFNArea;
+  ie->criticality               = M2AP_Criticality_reject;
+  ie->value.present             = M2AP_M2SetupResponse_Ies__value_PR_MCCHrelatedBCCH_ConfigPerMBSFNArea;
+
+  for( i=0; i < m2ap_setup_resp->num_mcch_config_per_mbsfn; i++) 
+  {
+
+	  M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_ItemIEs_t * mcch_related_bcch_config_per_mbsfn_area_item_ies;
+	  mcch_related_bcch_config_per_mbsfn_area_item_ies = (M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_ItemIEs_t*)calloc(1,sizeof(M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_ItemIEs_t));
+	  mcch_related_bcch_config_per_mbsfn_area_item_ies->id=M2AP_ProtocolIE_ID_id_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item;
+	  mcch_related_bcch_config_per_mbsfn_area_item_ies->criticality = M2AP_Criticality_ignore;
+	  mcch_related_bcch_config_per_mbsfn_area_item_ies->value.present=M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_ItemIEs__value_PR_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item;
+
+	  
+	  M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item_t * config_per_mbsfn_area_item;
+	  config_per_mbsfn_area_item = &mcch_related_bcch_config_per_mbsfn_area_item_ies->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea_Item;
+	  {
+		config_per_mbsfn_area_item->pdcchLength=m2ap_setup_resp->mcch_config_per_mbsfn[i].pdcch_length;//M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item__pdcchLength_s1;
+		config_per_mbsfn_area_item->offset=m2ap_setup_resp->mcch_config_per_mbsfn[i].offset;//0;
+		config_per_mbsfn_area_item->repetitionPeriod=m2ap_setup_resp->mcch_config_per_mbsfn[i].repetition_period;//M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item__repetitionPeriod_rf32;
+		config_per_mbsfn_area_item->modificationPeriod=m2ap_setup_resp->mcch_config_per_mbsfn[i].modification_period;//M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item__modificationPeriod_rf512;
+		config_per_mbsfn_area_item->subframeAllocationInfo.buf = MALLOC(1); 
+		config_per_mbsfn_area_item->subframeAllocationInfo.size=1;
+		/*char * t;
+		int bits=7;
+		for( t = m2ap_setup_resp->mcch_config_per_mbsfn[i].subframe_allocation_info; *t != '\0'; t++,bits--){
+			if(*t=='1'){
+				config_per_mbsfn_area_item->subframeAllocationInfo.buf[0] |= (uint8_t)(0x1<<bits);
+			}
+                }*/
+		config_per_mbsfn_area_item->subframeAllocationInfo.buf[0] = (uint8_t)((m2ap_setup_resp->mcch_config_per_mbsfn[i].subframe_allocation_info & 0x3F)<<2);
+
+		//config_per_mbsfn_area_item->subframeAllocationInfo.buf[0]=0x1<<7;
+		config_per_mbsfn_area_item->subframeAllocationInfo.bits_unused=2;
+		
+		//memset(&config_per_mbsfn_area_item->subframeAllocationInfo,0,sizeof(BIT_STRING_t));
+		
+		config_per_mbsfn_area_item->modulationAndCodingScheme = m2ap_setup_resp->mcch_config_per_mbsfn[i].mcs;//M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item__modulationAndCodingScheme_n2;
+		ASN_SEQUENCE_ADD(&ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea.list,mcch_related_bcch_config_per_mbsfn_area_item_ies);
+	  }
+
+  }
+  
+  //config_per_mbsfn_area_item->cellInformationList = ;//(M2AP_Cell_Information_List*)calloc(1,sizeof(M2AP_Cell_Information_List));
+  
+  
+  //config_per_mbsfn_area_item->subframeAllocationInfo.bits_unused = 4;
+  
+  //ASN_SEQUENCE_ADD(&ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea.list,config_per_mbsfn_area_item);
+  //config_per_mbsfn_area_item = &ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea;
+  //{
+	
+  //}
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  
+  /* M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_t */ 
+  //...
+
+//  int num_cells_to_activate = f1ap_setup_resp->num_cells_to_activate;
+//  LOG_D(M2AP, "num_cells_to_activate = %d \n", num_cells_to_activate);
+//  for (i=0;
+//       i<num_cells_to_activate;
+//       i++) {
+//
+//    M2AP_Cells_to_be_Activated_List_ItemIEs_t *cells_to_be_activated_list_item_ies;
+//    cells_to_be_activated_list_item_ies = (M2AP_Cells_to_be_Activated_List_ItemIEs_t *)calloc(1, sizeof(M2AP_Cells_to_be_Activated_List_ItemIEs_t));
+//    cells_to_be_activated_list_item_ies->id = M2AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item;
+//    cells_to_be_activated_list_item_ies->criticality = M2AP_Criticality_reject;
+//    cells_to_be_activated_list_item_ies->value.present = M2AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item;
+//
+//    /* 3.1 cells to be Activated list item */
+//    M2AP_Cells_to_be_Activated_List_Item_t cells_to_be_activated_list_item;
+//    memset((void *)&cells_to_be_activated_list_item, 0, sizeof(M2AP_Cells_to_be_Activated_List_Item_t));
+//
+//    /* - nRCGI */
+//    M2AP_NRCGI_t nRCGI;
+//    MCC_MNC_TO_PLMNID(f1ap_setup_resp->mcc[i], f1ap_setup_resp->mnc[i], f1ap_setup_resp->mnc_digit_length[i],
+//                                     &nRCGI.pLMN_Identity);
+//    NR_CELL_ID_TO_BIT_STRING(f1ap_setup_resp->nr_cellid[i], &nRCGI.nRCellIdentity);
+//    cells_to_be_activated_list_item.nRCGI = nRCGI;
+//
+//    /* optional */
+//    /* - nRPCI */
+//    if (1) {
+//      cells_to_be_activated_list_item.nRPCI = (M2AP_NRPCI_t *)calloc(1, sizeof(M2AP_NRPCI_t));
+//      *cells_to_be_activated_list_item.nRPCI = f1ap_setup_resp->nrpci[i];  // int 0..1007
+//    }
+//
+//    /* optional */
+//    /* - gNB-MCE System Information */
+//    if (1) {
+//      /* 3.1.2 gNB-MCESystem Information */
+//      M2AP_Cells_to_be_Activated_List_ItemExtIEs_t *cells_to_be_activated_list_itemExtIEs;
+//      cells_to_be_activated_list_itemExtIEs = (M2AP_Cells_to_be_Activated_List_ItemExtIEs_t *)calloc(1, sizeof(M2AP_Cells_to_be_Activated_List_ItemExtIEs_t));
+//      cells_to_be_activated_list_itemExtIEs->id                     = M2AP_ProtocolIE_ID_id_gNB_MCESystemInformation;
+//      cells_to_be_activated_list_itemExtIEs->criticality            = M2AP_Criticality_reject;
+//      cells_to_be_activated_list_itemExtIEs->extensionValue.present = M2AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_GNB_MCESystemInformation;
+//
+//      M2AP_GNB_MCESystemInformation_t *gNB_MCESystemInformation = (M2AP_GNB_MCESystemInformation_t *)calloc(1, sizeof(M2AP_GNB_MCESystemInformation_t));
+//      //LOG_I(M2AP, "%s() SI %d size %d: ", __func__, i, f1ap_setup_resp->SI_container_length[i][0]);
+//      //for (int n = 0; n < f1ap_setup_resp->SI_container_length[i][0]; n++)
+//      //  printf("%02x ", f1ap_setup_resp->SI_container[i][0][n]);
+//      //printf("\n");
+//      OCTET_STRING_fromBuf(&gNB_MCESystemInformation->sImessage,
+//                           (const char*)f1ap_setup_resp->SI_container[i][0], 
+//                           f1ap_setup_resp->SI_container_length[i][0]);
+//
+//      LOG_D(M2AP, "f1ap_setup_resp->SI_container_length = %d \n", f1ap_setup_resp->SI_container_length[0][0]);
+//      cells_to_be_activated_list_itemExtIEs->extensionValue.choice.GNB_MCESystemInformation = *gNB_MCESystemInformation;
+//
+//
+//      M2AP_ProtocolExtensionContainer_160P9_t p_160P9_t;
+//      memset((void *)&p_160P9_t, 0, sizeof(M2AP_ProtocolExtensionContainer_160P9_t));
+//
+//      ASN_SEQUENCE_ADD(&p_160P9_t.list,
+//                      cells_to_be_activated_list_itemExtIEs);
+//      cells_to_be_activated_list_item.iE_Extensions = (struct M2AP_ProtocolExtensionContainer*)&p_160P9_t;
+//
+//    }
+//    /* ADD */
+//    cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item = cells_to_be_activated_list_item;
+//    ASN_SEQUENCE_ADD(&ie->value.choice.Cells_to_be_Activated_List.list,
+//                  cells_to_be_activated_list_item_ies);
+//  }
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* encode */
+  if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(M2AP, "Failed to encode M2 response\n");
+    return -1;
+  }
+
+  //MCE_m2ap_itti_send_sctp_data_req(instance, m2ap_mce_data_from_du->assoc_id, buffer, len, 0);
+ //printf(",m2ap_mce_data_from_enb->assoc_id %d\n",m2ap_mce_data_from_enb->assoc_id);
+
+
+  m2ap_MCE_itti_send_sctp_data_req(instance,m2ap_mce_data_from_enb->assoc_id,buffer,len,0);
+
+  return 0;
+}
+
+int MCE_send_M2_SETUP_FAILURE(instance_t instance,m2ap_setup_failure_t* m2ap_setup_failure) {
+  
+ // module_id_t enb_mod_idP;
+  //module_id_t mce_mod_idP;
+
+  // This should be fixed
+  //enb_mod_idP = (module_id_t)0;
+  //mce_mod_idP  = (module_id_t)0;
+
+  M2AP_M2AP_PDU_t           pdu;
+  M2AP_M2SetupFailure_t    *out;
+  M2AP_M2SetupFailure_Ies_t *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+
+  /* Create */
+  /* 0. Message Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = M2AP_M2AP_PDU_PR_unsuccessfulOutcome;
+  //pdu.choice.unsuccessfulOutcome = (M2AP_UnsuccessfulOutcome_t *)calloc(1, sizeof(M2AP_UnsuccessfulOutcome_t));
+  pdu.choice.unsuccessfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup;
+  pdu.choice.unsuccessfulOutcome.criticality   = M2AP_Criticality_reject;
+  pdu.choice.unsuccessfulOutcome.value.present = M2AP_UnsuccessfulOutcome__value_PR_M2SetupFailure;
+  out = &pdu.choice.unsuccessfulOutcome.value.choice.M2SetupFailure;
+
+  /* mandatory */
+  /* c1. Transaction ID (integer value)*/
+ // ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t));
+ // ie->id                        = M2AP_ProtocolIE_ID_id_GlobalENB_ID;
+ // ie->criticality               = M2AP_Criticality_reject;
+ // ie->value.present             = M2AP_M2SetupFailure_Ies__value_PR_GlobalENB_ID;
+ // ie->value.choice.GlobalENB_ID = M2AP_get_next_transaction_identifier(enb_mod_idP, mce_mod_idP);
+ // ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c2. Cause */
+  ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_Cause;
+  ie->criticality               = M2AP_Criticality_ignore;
+  ie->value.present             = M2AP_M2SetupFailure_Ies__value_PR_Cause;
+  ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork;
+  ie->value.choice.Cause.choice.radioNetwork = M2AP_CauseRadioNetwork_unspecified;
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* optional */
+  /* c3. TimeToWait */
+  if (0) {
+    ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t));
+    ie->id                        = M2AP_ProtocolIE_ID_id_TimeToWait;
+    ie->criticality               = M2AP_Criticality_ignore;
+    ie->value.present             = M2AP_M2SetupFailure_Ies__value_PR_TimeToWait;
+    ie->value.choice.TimeToWait = M2AP_TimeToWait_v10s;
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* optional */
+  /* c4. CriticalityDiagnostics*/
+  if (0) {
+    ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t));
+    ie->id                        = M2AP_ProtocolIE_ID_id_CriticalityDiagnostics;
+    ie->criticality               = M2AP_Criticality_ignore;
+    ie->value.present             = M2AP_M2SetupFailure_Ies__value_PR_CriticalityDiagnostics;
+    ie->value.choice.CriticalityDiagnostics.procedureCode = (M2AP_ProcedureCode_t *)calloc(1, sizeof(M2AP_ProcedureCode_t));
+    *ie->value.choice.CriticalityDiagnostics.procedureCode = M2AP_ProcedureCode_id_m2Setup;
+    ie->value.choice.CriticalityDiagnostics.triggeringMessage = (M2AP_TriggeringMessage_t *)calloc(1, sizeof(M2AP_TriggeringMessage_t));
+    *ie->value.choice.CriticalityDiagnostics.triggeringMessage = M2AP_TriggeringMessage_initiating_message;
+    ie->value.choice.CriticalityDiagnostics.procedureCriticality = (M2AP_Criticality_t *)calloc(1, sizeof(M2AP_Criticality_t));
+    *ie->value.choice.CriticalityDiagnostics.procedureCriticality = M2AP_Criticality_reject;
+    //ie->value.choice.CriticalityDiagnostics.transactionID = (M2AP_TransactionID_t *)calloc(1, sizeof(M2AP_TransactionID_t));
+    //*ie->value.choice.CriticalityDiagnostics.transactionID = 0;
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* encode */
+  if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(M2AP, "Failed to encode M2 setup request\n");
+    return -1;
+  }
+
+  //mce_m2ap_itti_send_sctp_data_req(instance, m2ap_mce_data_from_enb->assoc_id, buffer, len, 0);
+  m2ap_MCE_itti_send_sctp_data_req(instance,m2ap_mce_data_from_enb->assoc_id,buffer,len,0);
+
+  return 0;
+}
+
+/*
+ * MCE Configuration Update
+ */
+
+int MCE_send_MCE_CONFIGURATION_UPDATE(instance_t instance, module_id_t du_mod_idP){
+  AssertFatal(1==0,"Not implemented yet\n");
+
+  
+  M2AP_M2AP_PDU_t          pdu;
+  M2AP_MCEConfigurationUpdate_t    *out;
+  M2AP_MCEConfigurationUpdate_Ies_t *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  //int       i = 0;
+  //int       j = 0;
+
+  /* Create */
+  /* 0. pdu Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
+  //pdu.choice.initiatingMessage = (M2AP_InitiatingMessage_t *)calloc(1, sizeof(M2AP_InitiatingMessage_t));
+  pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_mCEConfigurationUpdate;
+  pdu.choice.initiatingMessage.criticality   = M2AP_Criticality_reject;
+  pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_MCEConfigurationUpdate;
+  out = &pdu.choice.initiatingMessage.value.choice.MCEConfigurationUpdate;
+ 
+  /* mandatory */
+  /* c1. Transaction ID (integer value)*/
+  ie = (M2AP_MCEConfigurationUpdate_Ies_t *)calloc(1, sizeof(M2AP_MCEConfigurationUpdate_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_GlobalMCE_ID;
+  ie->criticality               = M2AP_Criticality_reject; //?
+  ie->value.present             = M2AP_MCEConfigurationUpdate_Ies__value_PR_GlobalMCE_ID;
+  //ie->value.choice.TransactionID = M2AP_get_next_transaction_identifier(enb_mod_idP, cu_mod_idP);
+  MCC_MNC_TO_PLMNID(0,0,3/*instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,*/
+  ,&ie->value.choice.GlobalMCE_ID.pLMN_Identity);
+
+  ie->value.choice.GlobalMCE_ID.mCE_ID.buf =calloc(2, sizeof(uint8_t));
+  ie->value.choice.GlobalMCE_ID.mCE_ID.size=2;
+  //ie->value.choice.GlobalMCE_ID.mCE_ID.bits_unused=6;
+
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+ 
+  /* optional */
+  /* c2. MCEname */
+  //if (m2ap_setup_resp->MCEname != NULL) {
+  //  ie = (M2AP_MCEConfigurationUpdate_Ies_t *)calloc(1, sizeof(M2AP_MCEConfigurationUpdate_Ies_t));
+  //  ie->id                        = M2AP_ProtocolIE_ID_id_MCEname;
+  //  ie->criticality               = M2AP_Criticality_ignore;
+  //  ie->value.present             = M2AP_MCEConfigurationUpdate_Ies__value_PR_MCEname;
+  //  OCTET_STRING_fromBuf(&ie->value.choice.MCEname, m2ap_setup_resp->MCEname,
+  //                       strlen(m2ap_setup_resp->MCEname));
+  //  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  //}
+
+  /* mandatory */
+  /* c3. cells to be Activated list */
+  ie = (M2AP_MCEConfigurationUpdate_Ies_t *)calloc(1, sizeof(M2AP_MCEConfigurationUpdate_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_MCCHrelatedBCCH_ConfigPerMBSFNArea;
+  ie->criticality               = M2AP_Criticality_reject;
+  ie->value.present             = M2AP_MCEConfigurationUpdate_Ies__value_PR_MCCHrelatedBCCH_ConfigPerMBSFNArea;
+
+  M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_ItemIEs_t * mcch_related_bcch_config_per_mbsfn_area_item_ies;
+  mcch_related_bcch_config_per_mbsfn_area_item_ies = (M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_ItemIEs_t*)calloc(1,sizeof(M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_ItemIEs_t));
+  mcch_related_bcch_config_per_mbsfn_area_item_ies->id=M2AP_ProtocolIE_ID_id_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item;
+  mcch_related_bcch_config_per_mbsfn_area_item_ies->criticality = M2AP_Criticality_ignore;
+  mcch_related_bcch_config_per_mbsfn_area_item_ies->value.present=M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_ItemIEs__value_PR_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item;
+
+  M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item_t * config_per_mbsfn_area_item;
+  config_per_mbsfn_area_item = &mcch_related_bcch_config_per_mbsfn_area_item_ies->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea_Item;
+  {
+	config_per_mbsfn_area_item->pdcchLength=M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item__pdcchLength_s1;
+	config_per_mbsfn_area_item->offset=0;
+	config_per_mbsfn_area_item->repetitionPeriod=M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item__repetitionPeriod_rf32;
+	config_per_mbsfn_area_item->modificationPeriod=M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item__modificationPeriod_rf512;
+  	config_per_mbsfn_area_item->subframeAllocationInfo.buf = MALLOC(1); 
+  	config_per_mbsfn_area_item->subframeAllocationInfo.size=1;
+  	//config_per_mbsfn_area_item->subframeAllocationInfo.buf[0]=0x1<<7;
+  	config_per_mbsfn_area_item->subframeAllocationInfo.bits_unused=2;
+	
+	//memset(&config_per_mbsfn_area_item->subframeAllocationInfo,0,sizeof(BIT_STRING_t));
+	
+        config_per_mbsfn_area_item->modulationAndCodingScheme = M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item__modulationAndCodingScheme_n2;
+	ASN_SEQUENCE_ADD(&ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea.list,mcch_related_bcch_config_per_mbsfn_area_item_ies);
+  }
+  
+  //config_per_mbsfn_area_item->cellInformationList = ;//(M2AP_Cell_Information_List*)calloc(1,sizeof(M2AP_Cell_Information_List));
+  
+  
+  //config_per_mbsfn_area_item->subframeAllocationInfo.bits_unused = 4;
+  
+  //ASN_SEQUENCE_ADD(&ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea.list,config_per_mbsfn_area_item);
+  //config_per_mbsfn_area_item = &ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea;
+  //{
+	
+  //}
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  
+  /* M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_t */ 
+  //...
+
+//  int num_cells_to_activate = f1ap_setup_resp->num_cells_to_activate;
+//  LOG_D(M2AP, "num_cells_to_activate = %d \n", num_cells_to_activate);
+//  for (i=0;
+//       i<num_cells_to_activate;
+//       i++) {
+//
+//    M2AP_Cells_to_be_Activated_List_ItemIEs_t *cells_to_be_activated_list_item_ies;
+//    cells_to_be_activated_list_item_ies = (M2AP_Cells_to_be_Activated_List_ItemIEs_t *)calloc(1, sizeof(M2AP_Cells_to_be_Activated_List_ItemIEs_t));
+//    cells_to_be_activated_list_item_ies->id = M2AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item;
+//    cells_to_be_activated_list_item_ies->criticality = M2AP_Criticality_reject;
+//    cells_to_be_activated_list_item_ies->value.present = M2AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item;
+//
+//    /* 3.1 cells to be Activated list item */
+//    M2AP_Cells_to_be_Activated_List_Item_t cells_to_be_activated_list_item;
+//    memset((void *)&cells_to_be_activated_list_item, 0, sizeof(M2AP_Cells_to_be_Activated_List_Item_t));
+//
+//    /* - nRCGI */
+//    M2AP_NRCGI_t nRCGI;
+//    MCC_MNC_TO_PLMNID(f1ap_setup_resp->mcc[i], f1ap_setup_resp->mnc[i], f1ap_setup_resp->mnc_digit_length[i],
+//                                     &nRCGI.pLMN_Identity);
+//    NR_CELL_ID_TO_BIT_STRING(f1ap_setup_resp->nr_cellid[i], &nRCGI.nRCellIdentity);
+//    cells_to_be_activated_list_item.nRCGI = nRCGI;
+//
+//    /* optional */
+//    /* - nRPCI */
+//    if (1) {
+//      cells_to_be_activated_list_item.nRPCI = (M2AP_NRPCI_t *)calloc(1, sizeof(M2AP_NRPCI_t));
+//      *cells_to_be_activated_list_item.nRPCI = f1ap_setup_resp->nrpci[i];  // int 0..1007
+//    }
+//
+//    /* optional */
+//    /* - gNB-MCE System Information */
+//    if (1) {
+//      /* 3.1.2 gNB-MCESystem Information */
+//      M2AP_Cells_to_be_Activated_List_ItemExtIEs_t *cells_to_be_activated_list_itemExtIEs;
+//      cells_to_be_activated_list_itemExtIEs = (M2AP_Cells_to_be_Activated_List_ItemExtIEs_t *)calloc(1, sizeof(M2AP_Cells_to_be_Activated_List_ItemExtIEs_t));
+//      cells_to_be_activated_list_itemExtIEs->id                     = M2AP_ProtocolIE_ID_id_gNB_MCESystemInformation;
+//      cells_to_be_activated_list_itemExtIEs->criticality            = M2AP_Criticality_reject;
+//      cells_to_be_activated_list_itemExtIEs->extensionValue.present = M2AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_GNB_MCESystemInformation;
+//
+//      M2AP_GNB_MCESystemInformation_t *gNB_MCESystemInformation = (M2AP_GNB_MCESystemInformation_t *)calloc(1, sizeof(M2AP_GNB_MCESystemInformation_t));
+//      //LOG_I(M2AP, "%s() SI %d size %d: ", __func__, i, f1ap_setup_resp->SI_container_length[i][0]);
+//      //for (int n = 0; n < f1ap_setup_resp->SI_container_length[i][0]; n++)
+//      //  printf("%02x ", f1ap_setup_resp->SI_container[i][0][n]);
+//      //printf("\n");
+//      OCTET_STRING_fromBuf(&gNB_MCESystemInformation->sImessage,
+//                           (const char*)f1ap_setup_resp->SI_container[i][0], 
+//                           f1ap_setup_resp->SI_container_length[i][0]);
+//
+//      LOG_D(M2AP, "f1ap_setup_resp->SI_container_length = %d \n", f1ap_setup_resp->SI_container_length[0][0]);
+//      cells_to_be_activated_list_itemExtIEs->extensionValue.choice.GNB_MCESystemInformation = *gNB_MCESystemInformation;
+//
+//
+//      M2AP_ProtocolExtensionContainer_160P9_t p_160P9_t;
+//      memset((void *)&p_160P9_t, 0, sizeof(M2AP_ProtocolExtensionContainer_160P9_t));
+//
+//      ASN_SEQUENCE_ADD(&p_160P9_t.list,
+//                      cells_to_be_activated_list_itemExtIEs);
+//      cells_to_be_activated_list_item.iE_Extensions = (struct M2AP_ProtocolExtensionContainer*)&p_160P9_t;
+//
+//    }
+//    /* ADD */
+//    cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item = cells_to_be_activated_list_item;
+//    ASN_SEQUENCE_ADD(&ie->value.choice.Cells_to_be_Activated_List.list,
+//                  cells_to_be_activated_list_item_ies);
+//  }
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* encode */
+  if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(M2AP, "Failed to encode M2 response\n");
+    return -1;
+  }
+
+  //MCE_m2ap_itti_send_sctp_data_req(instance, m2ap_mce_data_from_du->assoc_id, buffer, len, 0);
+ //printf(",m2ap_mce_data_from_enb->assoc_id %d\n",m2ap_mce_data_from_enb->assoc_id);
+
+  m2ap_MCE_itti_send_sctp_data_req(instance,m2ap_mce_data_from_enb->assoc_id,buffer,len,0);
+
+
+
+  
+}
+
+
+int MCE_handle_MCE_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
+                                                  uint32_t assoc_id,
+                                                  uint32_t stream,
+                                                  M2AP_M2AP_PDU_t *pdu){
+  AssertFatal(1==0,"Not implemented yet\n");
+
+    LOG_D(M2AP, "MCE_handle_MCE_CONFIGURATION_UPDATE_FAILURE\n");
+
+  M2AP_MCEConfigurationUpdateFailure_t    *in = &pdu->choice.unsuccessfulOutcome.value.choice.MCEConfigurationUpdateFailure;
+
+
+   //M2AP_MCEConfigurationUpdateFailure_Ies_t *ie;
+
+
+  MessageDef *msg_p = itti_alloc_new_message (TASK_M2AP_MCE, M2AP_MCE_CONFIGURATION_UPDATE_FAILURE);
+
+   LOG_D(M2AP, "M2AP: MCEConfigurationUpdate-Failure: protocolIEs.list.count %d\n",
+         in->protocolIEs.list.count);
+  // for (int i=0;i < in->protocolIEs.list.count; i++) {
+  //   ie = in->protocolIEs.list.array[i];
+  //  // switch (ie->id) {
+  //  // case M2AP_ProtocolIE_ID_id_TimeToWait:
+  //  //   AssertFatal(ie->criticality == M2AP_Criticality_ignore,
+  //  //             "ie->criticality != M2AP_Criticality_ignore\n");
+  //  //   AssertFatal(ie->value.present == M2AP_M2SetupFailure_Ies__value_PR_TimeToWait,
+  //  //             "ie->value.present != M2AP_M2SetupFailure_Ies__value_PR_TimeToWait\n");
+  //  //   LOG_D(M2AP, "M2AP: M2Setup-Failure: TimeToWait %d\n");/*,
+  //  //         GlobalMCE_ID);*/
+  //  //   break;
+  //  // }
+  // }
+   //AssertFatal(GlobalMCE_ID!=-1,"GlobalMCE_ID was not sent\n");
+   //AssertFatal(num_cells_to_activate>0,"No cells activated\n");
+   //M2AP_SETUP_RESP (msg_p).num_cells_to_activate = num_cells_to_activate;
+
+   //for (int i=0;i<num_cells_to_activate;i++)
+   //  AssertFatal(M2AP_SETUP_RESP (msg_p).num_SI[i] > 0, "System Information %d is missing",i);
+
+   //MSC_LOG_RX_MESSAGE(
+   // MSC_M2AP_eNB,
+   // MSC_M2AP_CU,
+   // 0,
+   // 0,
+   // MSC_AS_TIME_FMT" eNB_handle_M2_SETUP_RESPONSE successfulOutcome assoc_id %d",
+   // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
+   // assoc_id);
+
+   //LOG_D(M2AP, "Sending M2AP_SETUP_RESP ITTI message to ENB_APP with assoc_id (%d->%d)\n",
+   //      assoc_id,ENB_MOeNBLE_ID_TO_INSTANCE(assoc_id));
+
+   itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p);
+
+   return 0;
+
+}
+
+
+int MCE_handle_MCE_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
+                                                      uint32_t assoc_id,
+                                                      uint32_t stream,
+                                                      M2AP_M2AP_PDU_t *pdu){
+  AssertFatal(1==0,"Not implemented yet\n");
+  LOG_D(M2AP, "MCE_handle_MCE_CONFIGURATION_UPDATE_ACKNOWLEDGE assoc_id %d\n",assoc_id);
+
+  MessageDef                         *message_p;
+  //M2AP_MCEConfigurationUpdateAcknowledge_t              *container;
+  //M2AP_MCEConfigurationUpdateAcknowledge_Ies_t           *ie;
+  //int i = 0;
+
+  DevAssert(pdu != NULL);
+
+  //container = &pdu->choice.initiatingMessage.value.choice.MCEConfigurationUpdate;
+
+  /* M2 Setup Request == Non UE-related procedure -> stream 0 */
+  if (stream != 0) {
+    LOG_D(M2AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n",
+              assoc_id, stream);
+  }
+
+  message_p  = itti_alloc_new_message (TASK_M2AP_MCE, M2AP_MCE_CONFIGURATION_UPDATE_ACK);
+
+
+  itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p);
+
+  return 0;
+
+}
+
+
+/*
+ * ENB Configuration Update
+ */
+
+
+int MCE_handle_ENB_CONFIGURATION_UPDATE(instance_t instance,
+                                          uint32_t assoc_id,
+                                          uint32_t stream,
+                                          M2AP_M2AP_PDU_t *pdu){
+  AssertFatal(1==0,"Not implemented yet\n");
+  LOG_D(M2AP, "MCE_handle_MCE_CONFIGURATION_UPDATE_ACKNOWLEDGE assoc_id %d\n",assoc_id);
+
+  MessageDef                         *message_p;
+  //M2AP_MCEConfigurationUpdateAcknowledge_t              *container;
+  //M2AP_MCEConfigurationUpdateAcknowledge_Ies_t           *ie;
+  //int i = 0;
+
+  DevAssert(pdu != NULL);
+
+  //container = &pdu->choice.initiatingMessage.value.choice.MCEConfigurationUpdate;
+
+  /* M2 Setup Request == Non UE-related procedure -> stream 0 */
+  if (stream != 0) {
+    LOG_D(M2AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n",
+              assoc_id, stream);
+  }
+
+  message_p  = itti_alloc_new_message (TASK_M2AP_MCE, M2AP_MCE_CONFIGURATION_UPDATE_ACK);
+
+
+  itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p);
+
+   return 0;
+
+}
+
+
+int MCE_send_ENB_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
+                    m2ap_enb_configuration_update_failure_t * m2ap_enb_configuration_update_failure){
+  AssertFatal(1==0,"Not implemented yet\n");
+
+}
+
+
+int MCE_send_ENB_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
+                    m2ap_enb_configuration_update_ack_t *m2ap_enb_configuration_update_ack){
+  AssertFatal(1==0,"Not implemented yet\n");
+
+}
+
+
+/*
+ * Error Indication
+ */
+
+int MCE_handle_ERROR_INDICATION(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                M2AP_M2AP_PDU_t *pdu) {
+  AssertFatal(1==0,"Not implemented yet\n");
+
+
+}
+
+int MCE_send_ERROR_INDICATION(instance_t instance, M2AP_ErrorIndication_t *ErrorIndication) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+
+
+
+/*
+ * Session Update Request
+ */
+int MCE_send_MBMS_SESSION_UPDATE_REQUEST(instance_t instance, m2ap_mbms_session_update_req_t * m2ap_mbms_session_update_req){
+  AssertFatal(1==0,"Not implemented yet\n");
+  //M2AP_SessionUpdateRequest_t      SessionUpdateRequest;
+}
+
+
+
+int MCE_handle_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance,
+                                                  uint32_t assoc_id,
+                                                  uint32_t stream,
+                                                  M2AP_M2AP_PDU_t *pdu){
+  AssertFatal(1==0,"Not implemented yet\n");
+
+}
+
+
+
+int MCE_handle_MBMS_SESSION_UPDATE_FAILURE(instance_t instance,
+                                                      uint32_t assoc_id,
+                                                      uint32_t stream,
+                                                      M2AP_M2AP_PDU_t *pdu){
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+/*
+ * Service Counting Request
+ */
+int MCE_send_MBMS_SERVICE_COUNTING_REQUEST(instance_t instance, module_id_t du_mod_idP){
+  AssertFatal(1==0,"Not implemented yet\n");
+  //M2AP_MbmsServiceCountingRequest_t        MbmsServiceCountingRequest;
+}
+
+
+
+int MCE_handle_MBMS_SERVICE_COUNTING_RESPONSE(instance_t instance,
+                                                  uint32_t assoc_id,
+                                                  uint32_t stream,
+                                                  M2AP_M2AP_PDU_t *pdu){
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+
+
+int MCE_handle_MBMS_SESSION_COUNTING_FAILURE(instance_t instance,
+                                                      uint32_t assoc_id,
+                                                      uint32_t stream,
+                                                      M2AP_M2AP_PDU_t *pdu){
+  AssertFatal(1==0,"Not implemented yet\n");
+
+}
+
+
+/*
+ * Service Counting Results Report
+ */
+
+int MCE_handle_MBMS_SESSION_COUNTING_RESULTS_REPORT(instance_t instance,
+                                                      uint32_t assoc_id,
+                                                      uint32_t stream,
+                                                      M2AP_M2AP_PDU_t *pdu){
+  AssertFatal(1==0,"Not implemented yet\n");
+
+}
+
+
+/*
+ * Overload Notification
+ */
+int MCE_handle_MBMS_OVERLOAD_NOTIFICATION(instance_t instance,
+                                                      uint32_t assoc_id,
+                                                      uint32_t stream,
+                                                      M2AP_M2AP_PDU_t *pdu){
+  AssertFatal(1==0,"Not implemented yet\n");
+ 
+}
+
+
+
+
diff --git a/openair2/M2AP/m2ap_MCE_interface_management.h b/openair2/M2AP/m2ap_MCE_interface_management.h
new file mode 100644
index 0000000000..6b899e9ea2
--- /dev/null
+++ b/openair2/M2AP/m2ap_MCE_interface_management.h
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_MCE_interface_management.h
+ * \brief m2ap interface management for MCE
+ * \author Javier Morgade
+ * \date 2019
+ * \version 0.1
+ * \company Vicomtech
+ * \email: javier.morgade@ieee.org
+ * \note
+ * \warning
+ */
+
+#ifndef M2AP_MCE_INTERFACE_MANAGEMENT_H_
+#define M2AP_MCE_INTERFACE_MANAGEMENT_H_
+/*
+ * MBMS Session start
+ */
+int MCE_send_MBMS_SESSION_START_REQUEST(instance_t instance/*,
+                                uint32_t assoc_id*/,m2ap_session_start_req_t* m2ap_session_start_req);
+int MCE_handle_MBMS_SESSION_START_RESPONSE(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                M2AP_M2AP_PDU_t *pdu);
+
+int MCE_handle_MBMS_SESSION_START_FAILURE(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                M2AP_M2AP_PDU_t *pdu);
+/*
+ * MBMS Session stop
+ */
+int MCE_send_MBMS_SESSION_STOP_REQUEST(instance_t instance,
+                                m2ap_session_stop_req_t* m2ap_session_stop_req);
+
+int MCE_handle_MBMS_SESSION_STOP_RESPONSE(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                M2AP_M2AP_PDU_t *pdu);
+
+/*
+ * MBMS Scheduling Information
+ */
+int MCE_send_MBMS_SCHEDULING_INFORMATION(instance_t instance,
+                                /*uint32_t assoc_id,*/ m2ap_mbms_scheduling_information_t * m2ap_mbms_scheduling_information );
+
+int MCE_handle_MBMS_SCHEDULING_INFORMATION_RESPONSE(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                M2AP_M2AP_PDU_t *pdu);
+
+
+
+/*
+ * Reset
+ */
+int MCE_send_RESET(instance_t instance, m2ap_reset_t * m2ap_reset);
+
+int MCE_handle_RESET_ACKKNOWLEDGE(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                M2AP_M2AP_PDU_t *pdu);
+
+int MCE_handle_RESET(instance_t instance,
+                    uint32_t assoc_id,
+                    uint32_t stream,
+                    M2AP_M2AP_PDU_t *pdu);
+int MCE_send_RESET_ACKNOWLEDGE(instance_t instance, M2AP_ResetAcknowledge_t *ResetAcknowledge);
+
+/*
+ * M2AP Setup
+ */
+int MCE_handle_M2_SETUP_REQUEST(instance_t instance,
+                               uint32_t assoc_id,
+                               uint32_t stream,
+                               M2AP_M2AP_PDU_t *pdu);
+
+int MCE_send_M2_SETUP_RESPONSE(instance_t instance,/*uint32_t assoc_id,*/  m2ap_setup_resp_t *m2ap_setup_resp);
+
+int MCE_send_M2_SETUP_FAILURE(instance_t instance, /*uint32_t assoc_id*/ m2ap_setup_failure_t * m2ap_setup_failure);
+
+
+/*
+ * MCE Configuration Update
+ */
+
+int MCE_send_MCE_CONFIGURATION_UPDATE(instance_t instance, module_id_t du_mod_idP);
+
+int MCE_handle_MCE_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
+                                                  uint32_t assoc_id,
+                                                  uint32_t stream,
+                                                  M2AP_M2AP_PDU_t *pdu);
+
+int MCE_handle_MCE_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
+                                                      uint32_t assoc_id,
+                                                      uint32_t stream,
+                                                      M2AP_M2AP_PDU_t *pdu);
+
+/*
+ * ENB Configuration Update
+ */
+
+
+int MCE_handle_ENB_CONFIGURATION_UPDATE(instance_t instance,
+                                          uint32_t assoc_id,
+                                          uint32_t stream,
+                                          M2AP_M2AP_PDU_t *pdu);
+
+int MCE_send_ENB_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
+                    m2ap_enb_configuration_update_failure_t *m2ap_enb_configuration_update_failure);
+
+int MCE_send_ENB_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
+                    m2ap_enb_configuration_update_ack_t *m2ap_enb_configuration_update_ack);
+/*
+ * Error Indication
+ */
+int MCE_handle_ERROR_INDICATION(instance_t instance,
+                               uint32_t assoc_id,
+                               uint32_t stream,
+                               M2AP_M2AP_PDU_t *pdu);
+int MCE_send_ERROR_INDICATION(instance_t instance, M2AP_ErrorIndication_t *ErrorIndication);
+
+
+/*
+ * Session Update Request
+ */
+int MCE_send_MBMS_SESSION_UPDATE_REQUEST(instance_t instance, m2ap_mbms_session_update_req_t * m2ap_mbms_session_update_req);
+
+int MCE_handle_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance,
+                                                  uint32_t assoc_id,
+                                                  uint32_t stream,
+                                                  M2AP_M2AP_PDU_t *pdu);
+
+int MCE_handle_MBMS_SESSION_UPDATE_FAILURE(instance_t instance,
+                                                      uint32_t assoc_id,
+                                                      uint32_t stream,
+                                                      M2AP_M2AP_PDU_t *pdu);
+
+/*
+ * Service Counting Request
+ */
+int MCE_send_MBMS_SERVICE_COUNTING_REQUEST(instance_t instance, module_id_t du_mod_idP);
+
+int MCE_handle_MBMS_SERVICE_COUNTING_RESPONSE(instance_t instance,
+                                                  uint32_t assoc_id,
+                                                  uint32_t stream,
+                                                  M2AP_M2AP_PDU_t *pdu);
+
+int MCE_handle_MBMS_SESSION_COUNTING_FAILURE(instance_t instance,
+                                                      uint32_t assoc_id,
+                                                      uint32_t stream,
+                                                      M2AP_M2AP_PDU_t *pdu);
+/*
+ * Service Counting Results Report
+ */
+
+int MCE_handle_MBMS_SESSION_COUNTING_RESULTS_REPORT(instance_t instance,
+                                                      uint32_t assoc_id,
+                                                      uint32_t stream,
+                                                      M2AP_M2AP_PDU_t *pdu);
+
+/*
+ * Overload Notification
+ */
+int MCE_handle_MBMS_OVERLOAD_NOTIFICATION(instance_t instance,
+                                                      uint32_t assoc_id,
+                                                      uint32_t stream,
+                                                      M2AP_M2AP_PDU_t *pdu);
+
+
+
+
+
+#endif /* M2AP_MCE_INTERFACE_MANAGEMENT_H_ */
+
+
+
diff --git a/openair2/M2AP/m2ap_MCE_management_procedures.c b/openair2/M2AP/m2ap_MCE_management_procedures.c
new file mode 100644
index 0000000000..007340501a
--- /dev/null
+++ b/openair2/M2AP/m2ap_MCE_management_procedures.c
@@ -0,0 +1,257 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_MCE_management_procedures.c
+ * \brief m2ap tasks for MCE
+ * \author Javier Morgade  <javier.morade@ieee.org>
+ * \date 2018
+ * \version 1.0
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "intertask_interface.h"
+
+#include "assertions.h"
+#include "conversions.h"
+
+#include "m2ap_common.h"
+#include "m2ap_MCE_defs.h"
+#include "m2ap_MCE.h"
+
+
+#define M2AP_DEBUG_LIST
+#ifdef M2AP_DEBUG_LIST
+#  define M2AP_MCE_LIST_OUT(x, args...) M2AP_DEBUG("[MCE]%*s"x"\n", 4*indent, "", ##args)
+#else
+#  define M2AP_MCE_LIST_OUT(x, args...)
+#endif
+
+static int                  indent = 0;
+
+
+m2ap_MCE_internal_data_t m2ap_MCE_internal_data;
+
+RB_GENERATE(m2ap_mce_map, m2ap_MCE_data_s, entry, m2ap_MCE_compare_assoc_id);
+
+int m2ap_MCE_compare_assoc_id(
+  struct m2ap_MCE_data_s *p1, struct m2ap_MCE_data_s *p2)
+{
+  if (p1->assoc_id == -1) {
+    if (p1->cnx_id < p2->cnx_id) {
+      return -1;
+    }
+
+    if (p1->cnx_id > p2->cnx_id) {
+      return 1;
+    }
+  } else {
+    if (p1->assoc_id < p2->assoc_id) {
+      return -1;
+    }
+
+    if (p1->assoc_id > p2->assoc_id) {
+      return 1;
+    }
+  }
+
+  /* Matching reference */
+  return 0;
+}
+
+uint16_t m2ap_MCE_fetch_add_global_cnx_id(void)
+{
+  return ++m2ap_MCE_internal_data.global_cnx_id;
+}
+
+void m2ap_MCE_prepare_internal_data(void)
+{
+  memset(&m2ap_MCE_internal_data, 0, sizeof(m2ap_MCE_internal_data));
+  STAILQ_INIT(&m2ap_MCE_internal_data.m2ap_MCE_instances_head);
+}
+
+void m2ap_MCE_insert_new_instance(m2ap_MCE_instance_t *new_instance_p)
+{
+  DevAssert(new_instance_p != NULL);
+
+  STAILQ_INSERT_TAIL(&m2ap_MCE_internal_data.m2ap_MCE_instances_head,
+                     new_instance_p, m2ap_MCE_entries);
+}
+
+void dump_mce_tree_m2(m2ap_MCE_data_t *t)
+{
+  if (t == NULL) return;
+  printf("-----------------------\n");
+  printf("MCE id %d %s\n", t->MCE_id, t->MCE_name);
+  printf("state %d\n", t->state);
+  printf("nextstream %d\n", t->nextstream);
+  printf("in_streams %d out_streams %d\n", t->in_streams, t->out_streams);
+  printf("cnx_id %d assoc_id %d\n", t->cnx_id, t->assoc_id);
+  dump_mce_tree_m2(t->entry.rbe_left);
+  dump_mce_tree_m2(t->entry.rbe_right);
+}
+
+void dump_mce_trees_m2(void)
+{
+m2ap_MCE_instance_t *zz;
+STAILQ_FOREACH(zz, &m2ap_MCE_internal_data.m2ap_MCE_instances_head,
+               m2ap_MCE_entries) {
+printf("here comes the tree (instance %d):\n---------------------------------------------\n", zz->instance);
+dump_mce_tree_m2(zz->m2ap_mce_head.rbh_root);
+printf("---------------------------------------------\n");
+}
+}
+
+struct m2ap_MCE_data_s *m2ap_get_MCE(m2ap_MCE_instance_t *instance_p,
+				     int32_t assoc_id,
+				     uint16_t cnx_id)
+{
+  struct m2ap_MCE_data_s  temp;
+  struct m2ap_MCE_data_s *found;
+
+printf("m2ap_get_MCE at 1 (looking for assoc_id %d cnx_id %d)\n", assoc_id, cnx_id);
+dump_mce_trees_m2();
+
+  memset(&temp, 0, sizeof(struct m2ap_MCE_data_s));
+
+  temp.assoc_id = assoc_id;
+  temp.cnx_id   = cnx_id;
+
+  if (instance_p == NULL) {
+    STAILQ_FOREACH(instance_p, &m2ap_MCE_internal_data.m2ap_MCE_instances_head,
+                   m2ap_MCE_entries) {
+      found = RB_FIND(m2ap_mce_map, &instance_p->m2ap_mce_head, &temp);
+
+      if (found != NULL) {
+        return found;
+      }
+    }
+  } else {
+    return RB_FIND(m2ap_mce_map, &instance_p->m2ap_mce_head, &temp);
+  }
+
+  return NULL;
+}
+
+
+m2ap_MCE_instance_t *m2ap_MCE_get_instance(instance_t instance)
+{
+  m2ap_MCE_instance_t *temp = NULL;
+
+  STAILQ_FOREACH(temp, &m2ap_MCE_internal_data.m2ap_MCE_instances_head,
+                 m2ap_MCE_entries) {
+    if (temp->instance == instance) {
+      /* Matching occurence */
+      return temp;
+    }
+  }
+
+  return NULL;
+}
+
+/// utility functions
+
+void m2ap_dump_MCE (m2ap_MCE_data_t  * MCE_ref);
+
+void
+m2ap_dump_MCE_list (void) {
+   m2ap_MCE_instance_t *inst = NULL;
+   struct m2ap_MCE_data_s *found = NULL;
+   struct m2ap_MCE_data_s temp;
+
+   memset(&temp, 0, sizeof(struct m2ap_MCE_data_s));
+
+  STAILQ_FOREACH (inst, &m2ap_MCE_internal_data.m2ap_MCE_instances_head,  m2ap_MCE_entries) {
+    found = RB_FIND(m2ap_mce_map, &inst->m2ap_mce_head, &temp);
+    m2ap_dump_MCE (found);
+  }
+}
+
+void m2ap_dump_MCE (m2ap_MCE_data_t  * MCE_ref) {
+
+  if (MCE_ref == NULL) {
+    return;
+  }
+
+  M2AP_MCE_LIST_OUT ("");
+  M2AP_MCE_LIST_OUT ("MCE name:          %s", MCE_ref->MCE_name == NULL ? "not present" : MCE_ref->MCE_name);
+  M2AP_MCE_LIST_OUT ("MCE STATE:         %07x", MCE_ref->state);
+  M2AP_MCE_LIST_OUT ("MCE ID:            %07x", MCE_ref->MCE_id);
+  indent++;
+  M2AP_MCE_LIST_OUT ("SCTP cnx id:     %d", MCE_ref->cnx_id);
+  M2AP_MCE_LIST_OUT ("SCTP assoc id:     %d", MCE_ref->assoc_id);
+  M2AP_MCE_LIST_OUT ("SCTP instreams:    %d", MCE_ref->in_streams);
+  M2AP_MCE_LIST_OUT ("SCTP outstreams:   %d", MCE_ref->out_streams);
+  indent--;
+}
+
+m2ap_MCE_data_t  * m2ap_is_MCE_pci_in_list (const uint32_t pci)
+{
+  m2ap_MCE_instance_t    *inst;
+  struct m2ap_MCE_data_s *elm;
+
+  STAILQ_FOREACH(inst, &m2ap_MCE_internal_data.m2ap_MCE_instances_head, m2ap_MCE_entries) {
+    RB_FOREACH(elm, m2ap_mce_map, &inst->m2ap_mce_head) {
+      for (int i = 0; i<elm->num_cc; i++) {
+        if (elm->Nid_cell[i] == pci) {
+          return elm;
+        }
+      }
+    }
+  }
+  return NULL;
+}
+
+m2ap_MCE_data_t  * m2ap_is_MCE_id_in_list (const uint32_t MCE_id)
+{
+  m2ap_MCE_instance_t    *inst;
+  struct m2ap_MCE_data_s *elm;
+
+  STAILQ_FOREACH(inst, &m2ap_MCE_internal_data.m2ap_MCE_instances_head, m2ap_MCE_entries) {
+    RB_FOREACH(elm, m2ap_mce_map, &inst->m2ap_mce_head) {
+      if (elm->MCE_id == MCE_id)
+        return elm;
+    }
+  }
+  return NULL;
+}
+
+m2ap_MCE_data_t  * m2ap_is_MCE_assoc_id_in_list (const uint32_t sctp_assoc_id)
+{
+  m2ap_MCE_instance_t    *inst;
+  struct m2ap_MCE_data_s *found;
+  struct m2ap_MCE_data_s temp;
+
+  temp.assoc_id = sctp_assoc_id;
+  temp.cnx_id = -1;
+
+  STAILQ_FOREACH(inst, &m2ap_MCE_internal_data.m2ap_MCE_instances_head, m2ap_MCE_entries) {
+    found = RB_FIND(m2ap_mce_map, &inst->m2ap_mce_head, &temp);
+    if (found != NULL){
+      if (found->assoc_id == sctp_assoc_id) {
+	return found;
+      }
+    }
+  }
+  return NULL;
+}
diff --git a/openair2/M2AP/m2ap_MCE_management_procedures.h b/openair2/M2AP/m2ap_MCE_management_procedures.h
new file mode 100644
index 0000000000..9e13e723c9
--- /dev/null
+++ b/openair2/M2AP/m2ap_MCE_management_procedures.h
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_eNB_management_procedures.h
+ * \brief m2ap tasks for eNB
+ * \author Javier Morgade <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#ifndef M2AP_MCE_MANAGEMENT_PROCEDURES_H_
+#define M2AP_MCE_MANAGEMENT_PROCEDURES_H
+
+void m2ap_MCE_prepare_internal_data(void);
+
+void dump_trees_m2(void);
+
+void m2ap_MCE_insert_new_instance(m2ap_MCE_instance_t *new_instance_p);
+
+m2ap_MCE_instance_t *m2ap_MCE_get_instance(uint8_t mod_id);
+
+uint16_t m2ap_MCE_fetch_add_global_cnx_id(void);
+
+void m2ap_MCE_prepare_internal_data(void);
+
+m2ap_MCE_data_t* m2ap_is_MCE_id_in_list(uint32_t MCE_id);
+
+m2ap_MCE_data_t* m2ap_is_MCE_assoc_id_in_list(uint32_t sctp_assoc_id);
+
+m2ap_MCE_data_t* m2ap_is_MCE_pci_in_list (const uint32_t pci);
+
+struct m2ap_MCE_data_s *m2ap_get_MCE(m2ap_MCE_instance_t *instance_p,
+                                     int32_t assoc_id,
+                                     uint16_t cnx_id);
+
+#endif /* M2AP_MCE_MANAGEMENT_PROCEDURES_H_ */
diff --git a/openair2/M2AP/m2ap_common.h b/openair2/M2AP/m2ap_common.h
index 3c8fcbc462..95da064b4a 100644
--- a/openair2/M2AP/m2ap_common.h
+++ b/openair2/M2AP/m2ap_common.h
@@ -41,13 +41,6 @@
 #ifndef M2AP_COMMON_H_
 #define M2AP_COMMON_H_
 
-/*! \file m2ap_common.h
- * \brief m2ap procedures for both eNB and MCE
- * \author Javier Morgade  <javier.morgade@ieee.org>
- * \date 2019
- * \version 0.1
- */
-
 /** @defgroup _m2ap_impl_ M2AP Layer Reference Implementation
  * @ingroup _ref_implementation_
  * @{
diff --git a/openair2/M2AP/m2ap_decoder.c b/openair2/M2AP/m2ap_decoder.c
new file mode 100644
index 0000000000..1237c4ec8e
--- /dev/null
+++ b/openair2/M2AP/m2ap_decoder.c
@@ -0,0 +1,194 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_decoder.c
+ * \brief m2ap decoder procedures 
+ * \author Javier Morgade <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#include <stdio.h>
+
+#include "assertions.h"
+#include "intertask_interface.h"
+#include "m2ap_common.h"
+#include "m2ap_decoder.h"
+
+static int m2ap_decode_initiating_message(M2AP_M2AP_PDU_t *pdu)
+{
+  DevAssert(pdu != NULL);
+
+  switch(pdu->choice.initiatingMessage.procedureCode) {
+    case M2AP_ProcedureCode_id_sessionStart:
+      //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
+      M2AP_INFO("m2ap__decode_initiating_message!\n");
+      break;
+    case M2AP_ProcedureCode_id_sessionStop:
+      //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
+      M2AP_INFO("m2ap__decode_initiating_message!\n");
+      break;
+    case M2AP_ProcedureCode_id_m2Setup:
+      //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
+      M2AP_INFO("m2ap__decode_initiating_message!\n");
+      break;
+    case M2AP_ProcedureCode_id_mbmsSchedulingInformation:
+      //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
+      M2AP_INFO("m2ap__decode_initiating_message!\n");
+      break;
+
+
+   
+//    case M2AP_ProcedureCode_id_handoverPreparation:
+//      //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
+//      M2AP_INFO("m2ap__decode_initiating_message!\n");
+//      break;
+//
+//    case M2AP_ProcedureCode_id_uEContextRelease:
+//      //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
+//      M2AP_INFO("m2ap__decode_initiating_message!\n");
+//      break;
+//
+//    case M2AP_ProcedureCode_id_handoverCancel:
+//      //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
+//      M2AP_INFO("m2ap__decode_initiating_message!\n");
+//      break;
+//
+    default:
+      M2AP_ERROR("Unknown procedure ID (%d) for initiating message\n",
+                  (int)pdu->choice.initiatingMessage.procedureCode);
+      AssertFatal( 0, "Unknown procedure ID (%d) for initiating message\n",
+                   (int)pdu->choice.initiatingMessage.procedureCode);
+      return -1;
+  }
+
+  return 0;
+}
+
+static int m2ap_decode_successful_outcome(M2AP_M2AP_PDU_t *pdu)
+{
+  DevAssert(pdu != NULL);
+
+  switch(pdu->choice.successfulOutcome.procedureCode) {
+    case M2AP_ProcedureCode_id_sessionStart:
+      //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
+      M2AP_INFO("m2ap__decode_successfuloutcome_message!\n");
+      break;
+    case M2AP_ProcedureCode_id_sessionStop:
+      //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
+      M2AP_INFO("m2ap__decode_succesfuloutcome_message!\n");
+      break;
+    case M2AP_ProcedureCode_id_m2Setup:
+      //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
+      M2AP_INFO("m2ap__decode_succesfuloutcome_message!\n");
+      break;
+    case M2AP_ProcedureCode_id_mbmsSchedulingInformation:
+      //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
+      M2AP_INFO("m2ap__decode_succesfuloutcome_message!\n");
+      break;
+
+
+//    case M2AP_ProcedureCode_id_handoverPreparation:
+//      //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
+//      M2AP_INFO("m2ap__decode_successfuloutcome_message!\n");
+//      break;
+//
+    default:
+      M2AP_ERROR("Unknown procedure ID (%d) for successfull outcome message\n",
+                  (int)pdu->choice.successfulOutcome.procedureCode);
+      return -1;
+  }
+
+  return 0;
+}
+
+static int m2ap_decode_unsuccessful_outcome(M2AP_M2AP_PDU_t *pdu)
+{
+  DevAssert(pdu != NULL);
+
+  switch(pdu->choice.unsuccessfulOutcome.procedureCode) {
+    case M2AP_ProcedureCode_id_sessionStart:
+      //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
+      M2AP_INFO("m2ap__decode_initiating_message!\n");
+      break;
+    case M2AP_ProcedureCode_id_sessionStop:
+      //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
+      M2AP_INFO("m2ap__decode_initiating_message!\n");
+      break;
+    case M2AP_ProcedureCode_id_m2Setup:
+      //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
+      M2AP_INFO("m2ap__decode_initiating_message!\n");
+      break;
+    case M2AP_ProcedureCode_id_mbmsSchedulingInformation:
+      //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
+      M2AP_INFO("m2ap__decode_initiating_message!\n");
+      break;
+
+
+    default:
+       M2AP_ERROR("Unknown procedure ID (%d) for unsuccessfull outcome message\n",
+                  (int)pdu->choice.unsuccessfulOutcome.procedureCode);
+      return -1;
+  }
+
+  return 0;
+}
+
+int m2ap_decode_pdu(M2AP_M2AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length)
+{
+  asn_dec_rval_t dec_ret;
+
+  DevAssert(buffer != NULL);
+
+  dec_ret = aper_decode(NULL,
+                        &asn_DEF_M2AP_M2AP_PDU,
+                        (void **)&pdu,
+                        buffer,
+                        length,
+                        0,
+                        0);
+  if (asn1_xer_print) {
+    xer_fprint(stdout, &asn_DEF_M2AP_M2AP_PDU, pdu);
+  }
+
+  if (dec_ret.code != RC_OK) {
+    M2AP_ERROR("Failed to decode pdu\n");
+    return -1;
+  }
+
+  switch(pdu->present) {
+    case M2AP_M2AP_PDU_PR_initiatingMessage:
+      return m2ap_decode_initiating_message(pdu);
+
+    case M2AP_M2AP_PDU_PR_successfulOutcome:
+      return m2ap_decode_successful_outcome(pdu);
+
+    case M2AP_M2AP_PDU_PR_unsuccessfulOutcome:
+      return m2ap_decode_unsuccessful_outcome(pdu);
+
+    default:
+      M2AP_DEBUG("Unknown presence (%d) or not implemented\n", (int)pdu->present);
+      break;
+  }
+
+
+  return -1;
+}
diff --git a/openair2/M2AP/m2ap_decoder.h b/openair2/M2AP/m2ap_decoder.h
new file mode 100644
index 0000000000..6ab01fe703
--- /dev/null
+++ b/openair2/M2AP/m2ap_decoder.h
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_decoder.h
+ * \brief m2ap decoder procedures for eNB
+ * \author Javier Morgade <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#ifndef M2AP_DECODER_H_
+#define M2AP_DECODER_H_
+
+int m2ap_decode_pdu(M2AP_M2AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length)
+__attribute__ ((warn_unused_result));
+
+#endif /* M2AP_DECODER_H_ */
diff --git a/openair2/M2AP/m2ap_default_values.h b/openair2/M2AP/m2ap_default_values.h
new file mode 100644
index 0000000000..baae4b963c
--- /dev/null
+++ b/openair2/M2AP/m2ap_default_values.h
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_default_values.h
+ * \brief default values for m2ap procedures
+ * \author Javier Morgade
+ * \date 2019
+ * \version 0.1
+ * \company Vicomtech
+ * \email: javier.morgade@ieee.org
+ * \note
+ * \warning
+ */
+
+#ifndef M2AP_DEFAULT_VALUES_H_
+#define M2AP_DEFAULT_VALUES_H_
+
+#define ENB_TAC (1)
+#define ENB_MCC (208)
+#define ENB_MNC (92)
+
+#define ENB_NAME        "Eurecom ENB"
+#define ENB_NAME_FORMAT (ENB_NAME" %u")
+
+#define M2AP_PORT_NUMBER        (36443)
+#define M2AP_SCTP_PPID          (43)
+
+#endif /* M2AP_DEFAULT_VALUES_H_ */
+
diff --git a/openair2/M2AP/m2ap_eNB.c b/openair2/M2AP/m2ap_eNB.c
new file mode 100644
index 0000000000..206b7cf8ca
--- /dev/null
+++ b/openair2/M2AP/m2ap_eNB.c
@@ -0,0 +1,704 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_eNB.c
+ * \brief m2ap tasks for eNB
+ * \author Javier Morgade  <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <arpa/inet.h>
+
+#include "intertask_interface.h"
+
+#include "m2ap_eNB.h"
+#include "m2ap_eNB_defs.h"
+#include "m2ap_eNB_management_procedures.h"
+#include "m2ap_eNB_handler.h"
+#include "m2ap_eNB_generate_messages.h"
+#include "m2ap_common.h"
+#include "m2ap_eNB_interface_management.h"
+#include "m2ap_ids.h"
+#include "m2ap_timers.h"
+
+#include "queue.h"
+#include "assertions.h"
+#include "conversions.h"
+
+struct m2ap_enb_map;
+struct m2ap_eNB_data_s;
+
+m2ap_setup_req_t * m2ap_enb_data_g;
+
+RB_PROTOTYPE(m2ap_enb_map, m2ap_eNB_data_s, entry, m2ap_eNB_compare_assoc_id);
+
+static
+void m2ap_eNB_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind);
+
+static
+void m2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp);
+
+static
+void m2ap_eNB_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind);
+
+static
+void m2ap_eNB_handle_register_eNB(instance_t instance,
+                                  m2ap_register_enb_req_t *m2ap_register_eNB);
+static
+void m2ap_eNB_register_eNB(m2ap_eNB_instance_t *instance_p,
+                           net_ip_address_t    *target_eNB_ip_addr,
+                           net_ip_address_t    *local_ip_addr,
+                           uint16_t             in_streams,
+                           uint16_t             out_streams,
+                           uint32_t             enb_port_for_M2C,
+                           int                  multi_sd);
+
+//static
+//void m2ap_eNB_handle_handover_req(instance_t instance,
+//                                  m2ap_handover_req_t *m2ap_handover_req);
+//
+//static
+//void m2ap_eNB_handle_handover_req_ack(instance_t instance,
+//                                      m2ap_handover_req_ack_t *m2ap_handover_req_ack);
+//
+//static
+//void m2ap_eNB_ue_context_release(instance_t instance,
+//                                 m2ap_ue_context_release_t *m2ap_ue_context_release);
+//
+
+static
+void m2ap_eNB_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) {
+  int result;
+  DevAssert(sctp_data_ind != NULL);
+  m2ap_eNB_handle_message(instance, sctp_data_ind->assoc_id, sctp_data_ind->stream,
+                          sctp_data_ind->buffer, sctp_data_ind->buffer_length);
+  result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer);
+  AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
+}
+
+static
+void m2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) {
+  m2ap_eNB_instance_t *instance_p;
+  m2ap_eNB_data_t *m2ap_enb_data_p;
+  DevAssert(sctp_new_association_resp != NULL);
+ // printf("m2ap_eNB_handle_sctp_association_resp at 1\n");
+ // dump_trees_m2();
+  instance_p = m2ap_eNB_get_instance(instance);
+  DevAssert(instance_p != NULL);
+
+  /* if the assoc_id is already known, it is certainly because an IND was received
+   * before. In this case, just update streams and return
+   */
+  if (sctp_new_association_resp->assoc_id != -1) {
+    m2ap_enb_data_p = m2ap_get_eNB(instance_p, sctp_new_association_resp->assoc_id,
+                                   sctp_new_association_resp->ulp_cnx_id);
+
+    if (m2ap_enb_data_p != NULL) {
+      /* some sanity check - to be refined at some point */
+      if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
+        M2AP_ERROR("m2ap_enb_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED, what to do?\n");
+        abort();
+      }
+
+      m2ap_enb_data_p->in_streams  = sctp_new_association_resp->in_streams;
+      m2ap_enb_data_p->out_streams = sctp_new_association_resp->out_streams;
+      return;
+    }
+  }
+
+  m2ap_enb_data_p = m2ap_get_eNB(instance_p, -1,
+                                 sctp_new_association_resp->ulp_cnx_id);
+  DevAssert(m2ap_enb_data_p != NULL);
+  //printf("m2ap_eNB_handle_sctp_association_resp at 2\n");
+  //dump_trees_m2();
+
+  if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
+    M2AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n",
+              sctp_new_association_resp->sctp_state,
+              instance,
+              sctp_new_association_resp->ulp_cnx_id);
+    //m2ap_handle_m2_setup_message(instance_p, m2ap_enb_data_p,
+    //                             sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
+    return;
+  }
+
+  //printf("m2ap_eNB_handle_sctp_association_resp at 3\n");
+  //dump_trees_m2();
+  /* Update parameters */
+  m2ap_enb_data_p->assoc_id    = sctp_new_association_resp->assoc_id;
+  m2ap_enb_data_p->in_streams  = sctp_new_association_resp->in_streams;
+  m2ap_enb_data_p->out_streams = sctp_new_association_resp->out_streams;
+  //printf("m2ap_eNB_handle_sctp_association_resp at 4\n");
+  //dump_trees_m2();
+
+  m2ap_enb_data_g->assoc_id    = sctp_new_association_resp->assoc_id;
+  m2ap_enb_data_g->sctp_in_streams  = sctp_new_association_resp->in_streams;
+  m2ap_enb_data_g->sctp_out_streams = sctp_new_association_resp->out_streams;
+
+  /* Prepare new m2 Setup Request */
+  //m2ap_eNB_generate_m2_setup_request(instance_p, m2ap_enb_data_p);
+  eNB_send_M2_SETUP_REQUEST(instance_p, m2ap_enb_data_p);
+  //eNB_send_M2_SETUP_REQUEST(instance_p, m2ap_enb_data_g);
+  
+}
+
+static
+void m2ap_eNB_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind) {
+  m2ap_eNB_instance_t *instance_p;
+  m2ap_eNB_data_t *m2ap_enb_data_p;
+  //printf("m2ap_eNB_handle_sctp_association_ind at 1 (called for instance %d)\n", instance);
+  //dump_trees_m2();
+  DevAssert(sctp_new_association_ind != NULL);
+  instance_p = m2ap_eNB_get_instance(instance);
+  DevAssert(instance_p != NULL);
+  m2ap_enb_data_p = m2ap_get_eNB(instance_p, sctp_new_association_ind->assoc_id, -1);
+
+  if (m2ap_enb_data_p != NULL) abort();
+
+  //  DevAssert(m2ap_enb_data_p != NULL);
+  if (m2ap_enb_data_p == NULL) {
+    /* Create new eNB descriptor */
+    m2ap_enb_data_p = calloc(1, sizeof(*m2ap_enb_data_p));
+    DevAssert(m2ap_enb_data_p != NULL);
+    m2ap_enb_data_p->cnx_id                = m2ap_eNB_fetch_add_global_cnx_id();
+    m2ap_enb_data_p->m2ap_eNB_instance = instance_p;
+    /* Insert the new descriptor in list of known eNB
+     * but not yet associated.
+     */
+    RB_INSERT(m2ap_enb_map, &instance_p->m2ap_enb_head, m2ap_enb_data_p);
+    m2ap_enb_data_p->state = M2AP_ENB_STATE_CONNECTED;
+    instance_p->m2_target_enb_nb++;
+
+    if (instance_p->m2_target_enb_pending_nb > 0) {
+      instance_p->m2_target_enb_pending_nb--;
+    }
+  } else {
+    M2AP_WARN("m2ap_enb_data_p already exists\n");
+  }
+
+  //printf("m2ap_eNB_handle_sctp_association_ind at 2\n");
+  //dump_trees_m2();
+  /* Update parameters */
+  m2ap_enb_data_p->assoc_id    = sctp_new_association_ind->assoc_id;
+  m2ap_enb_data_p->in_streams  = sctp_new_association_ind->in_streams;
+  m2ap_enb_data_p->out_streams = sctp_new_association_ind->out_streams;
+  //printf("m2ap_eNB_handle_sctp_association_ind at 3\n");
+  //dump_trees_m2();
+}
+
+int m2ap_eNB_init_sctp (m2ap_eNB_instance_t *instance_p,
+                        net_ip_address_t    *local_ip_addr,
+                        uint32_t enb_port_for_M2C) {
+  // Create and alloc new message
+  MessageDef                             *message;
+  sctp_init_t                            *sctp_init  = NULL;
+  DevAssert(instance_p != NULL);
+  DevAssert(local_ip_addr != NULL);
+  message = itti_alloc_new_message (TASK_M2AP_ENB, SCTP_INIT_MSG_MULTI_REQ);
+  sctp_init = &message->ittiMsg.sctp_init_multi;
+  sctp_init->port = enb_port_for_M2C;
+  sctp_init->ppid = M2AP_SCTP_PPID;
+  sctp_init->ipv4 = 1;
+  sctp_init->ipv6 = 0;
+  sctp_init->nb_ipv4_addr = 1;
+#if 0
+  memcpy(&sctp_init->ipv4_address,
+         local_ip_addr,
+         sizeof(*local_ip_addr));
+#endif
+  sctp_init->ipv4_address[0] = inet_addr(local_ip_addr->ipv4_address);
+  /*
+   * SR WARNING: ipv6 multi-homing fails sometimes for localhost.
+   * * * * Disable it for now.
+   */
+  sctp_init->nb_ipv6_addr = 0;
+  sctp_init->ipv6_address[0] = "0:0:0:0:0:0:0:1";
+  return itti_send_msg_to_task (TASK_SCTP, instance_p->instance, message);
+}
+
+static void m2ap_eNB_register_eNB(m2ap_eNB_instance_t *instance_p,
+                                  net_ip_address_t    *target_eNB_ip_address,
+                                  net_ip_address_t    *local_ip_addr,
+                                  uint16_t             in_streams,
+                                  uint16_t             out_streams,
+                                  uint32_t         enb_port_for_M2C,
+                                  int                  multi_sd) {
+  MessageDef                       *message                   = NULL;
+  sctp_new_association_req_multi_t *sctp_new_association_req  = NULL;
+  m2ap_eNB_data_t                  *m2ap_enb_data             = NULL;
+  DevAssert(instance_p != NULL);
+  DevAssert(target_eNB_ip_address != NULL);
+  message = itti_alloc_new_message(TASK_M2AP_ENB, SCTP_NEW_ASSOCIATION_REQ_MULTI);
+  sctp_new_association_req = &message->ittiMsg.sctp_new_association_req_multi;
+  sctp_new_association_req->port = enb_port_for_M2C;
+  sctp_new_association_req->ppid = M2AP_SCTP_PPID;
+  sctp_new_association_req->in_streams  = in_streams;
+  sctp_new_association_req->out_streams = out_streams;
+  sctp_new_association_req->multi_sd = multi_sd;
+  memcpy(&sctp_new_association_req->remote_address,
+         target_eNB_ip_address,
+         sizeof(*target_eNB_ip_address));
+  memcpy(&sctp_new_association_req->local_address,
+         local_ip_addr,
+         sizeof(*local_ip_addr));
+  /* Create new eNB descriptor */
+  m2ap_enb_data = calloc(1, sizeof(*m2ap_enb_data));
+  DevAssert(m2ap_enb_data != NULL);
+  m2ap_enb_data->cnx_id                = m2ap_eNB_fetch_add_global_cnx_id();
+  sctp_new_association_req->ulp_cnx_id = m2ap_enb_data->cnx_id;
+  m2ap_enb_data->assoc_id          = -1;
+  m2ap_enb_data->m2ap_eNB_instance = instance_p;
+
+
+  m2ap_enb_data_g = (m2ap_setup_req_t*)calloc(1,sizeof(m2ap_setup_req_t));
+  
+
+  //
+  m2ap_enb_data->eNB_name = "enb_name";
+  /* Insert the new descriptor in list of known eNB
+   * but not yet associated.
+   */
+  RB_INSERT(m2ap_enb_map, &instance_p->m2ap_enb_head, m2ap_enb_data);
+  m2ap_enb_data->state = M2AP_ENB_STATE_WAITING;
+  instance_p->m2_target_enb_nb ++;
+  instance_p->m2_target_enb_pending_nb ++;
+  itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message);
+}
+
+static
+void m2ap_eNB_handle_register_eNB(instance_t instance,
+                                  m2ap_register_enb_req_t *m2ap_register_eNB) {
+  m2ap_eNB_instance_t *new_instance;
+  DevAssert(m2ap_register_eNB != NULL);
+  /* Look if the provided instance already exists */
+  new_instance = m2ap_eNB_get_instance(instance);
+
+  if (new_instance != NULL) {
+    /* Checks if it is a retry on the same eNB */
+    DevCheck(new_instance->eNB_id == m2ap_register_eNB->eNB_id, new_instance->eNB_id, m2ap_register_eNB->eNB_id, 0);
+    DevCheck(new_instance->cell_type == m2ap_register_eNB->cell_type, new_instance->cell_type, m2ap_register_eNB->cell_type, 0);
+    DevCheck(new_instance->tac == m2ap_register_eNB->tac, new_instance->tac, m2ap_register_eNB->tac, 0);
+    DevCheck(new_instance->mcc == m2ap_register_eNB->mcc, new_instance->mcc, m2ap_register_eNB->mcc, 0);
+    DevCheck(new_instance->mnc == m2ap_register_eNB->mnc, new_instance->mnc, m2ap_register_eNB->mnc, 0);
+    M2AP_WARN("eNB[%d] already registered\n", instance);
+  } else {
+    new_instance = calloc(1, sizeof(m2ap_eNB_instance_t));
+    DevAssert(new_instance != NULL);
+    RB_INIT(&new_instance->m2ap_enb_head);
+    /* Copy usefull parameters */
+    new_instance->instance         = instance;
+    new_instance->eNB_name         = m2ap_register_eNB->eNB_name;
+    new_instance->eNB_id           = m2ap_register_eNB->eNB_id;
+    new_instance->cell_type        = m2ap_register_eNB->cell_type;
+    new_instance->tac              = m2ap_register_eNB->tac;
+    new_instance->mcc              = m2ap_register_eNB->mcc;
+    new_instance->mnc              = m2ap_register_eNB->mnc;
+    new_instance->mnc_digit_length = m2ap_register_eNB->mnc_digit_length;
+    new_instance->num_cc           = m2ap_register_eNB->num_cc;
+
+    m2ap_id_manager_init(&new_instance->id_manager);
+    m2ap_timers_init(&new_instance->timers,
+                     m2ap_register_eNB->t_reloc_prep,
+                     m2ap_register_eNB->tm2_reloc_overall);
+
+    for (int i = 0; i< m2ap_register_eNB->num_cc; i++) {
+      new_instance->eutra_band[i]              = m2ap_register_eNB->eutra_band[i];
+      new_instance->downlink_frequency[i]      = m2ap_register_eNB->downlink_frequency[i];
+      new_instance->uplink_frequency_offset[i] = m2ap_register_eNB->uplink_frequency_offset[i];
+      new_instance->Nid_cell[i]                = m2ap_register_eNB->Nid_cell[i];
+      new_instance->N_RB_DL[i]                 = m2ap_register_eNB->N_RB_DL[i];
+      new_instance->frame_type[i]              = m2ap_register_eNB->frame_type[i];
+      new_instance->fdd_earfcn_DL[i]           = m2ap_register_eNB->fdd_earfcn_DL[i];
+      new_instance->fdd_earfcn_UL[i]           = m2ap_register_eNB->fdd_earfcn_UL[i];
+    }
+
+    DevCheck(m2ap_register_eNB->nb_m2 <= M2AP_MAX_NB_ENB_IP_ADDRESS,
+             M2AP_MAX_NB_ENB_IP_ADDRESS, m2ap_register_eNB->nb_m2, 0);
+    memcpy(new_instance->target_mce_m2_ip_address,
+           m2ap_register_eNB->target_mce_m2_ip_address,
+           m2ap_register_eNB->nb_m2 * sizeof(net_ip_address_t));
+    new_instance->nb_m2             = m2ap_register_eNB->nb_m2;
+    new_instance->enb_m2_ip_address = m2ap_register_eNB->enb_m2_ip_address;
+    new_instance->sctp_in_streams   = m2ap_register_eNB->sctp_in_streams;
+    new_instance->sctp_out_streams  = m2ap_register_eNB->sctp_out_streams;
+    new_instance->enb_port_for_M2C  = m2ap_register_eNB->enb_port_for_M2C;
+
+
+    new_instance->num_mbms_configuration_data_list = m2ap_register_eNB->num_mbms_configuration_data_list;
+    for(int j=0; j < m2ap_register_eNB->num_mbms_configuration_data_list;j++){
+	    new_instance->mbms_configuration_data_list[j].num_mbms_service_area_list = m2ap_register_eNB->mbms_configuration_data_list[j].num_mbms_service_area_list;
+	    for(int i=0; i <  m2ap_register_eNB->mbms_configuration_data_list[j].num_mbms_service_area_list; i++ ){
+		//strcpy(&new_instance->mbms_configuration_data_list[j].mbms_service_area_list[i],&m2ap_register_eNB->mbms_configuration_data_list[j].mbms_service_area_list[i]);
+		new_instance->mbms_configuration_data_list[j].mbms_service_area_list[i]=m2ap_register_eNB->mbms_configuration_data_list[j].mbms_service_area_list[i];
+	    }
+    }
+
+    /* Add the new instance to the list of eNB (meaningfull in virtual mode) */
+    m2ap_eNB_insert_new_instance(new_instance);
+    M2AP_INFO("Registered new eNB[%d] and %s eNB id %u\n",
+              instance,
+              m2ap_register_eNB->cell_type == CELL_MACRO_ENB ? "macro" : "home",
+              m2ap_register_eNB->eNB_id);
+
+    /* initiate the SCTP listener */
+    if (m2ap_eNB_init_sctp(new_instance,&m2ap_register_eNB->enb_m2_ip_address,m2ap_register_eNB->enb_port_for_M2C) <  0 ) {
+      M2AP_ERROR ("Error while sending SCTP_INIT_MSG to SCTP \n");
+      return;
+    }
+
+    M2AP_INFO("eNB[%d] eNB id %u acting as a listner (server)\n",
+              instance, m2ap_register_eNB->eNB_id);
+  }
+}
+
+static
+void m2ap_eNB_handle_sctp_init_msg_multi_cnf(
+  instance_t instance_id,
+  sctp_init_msg_multi_cnf_t *m) {
+  m2ap_eNB_instance_t *instance;
+  int index;
+  DevAssert(m != NULL);
+  instance = m2ap_eNB_get_instance(instance_id);
+  DevAssert(instance != NULL);
+  instance->multi_sd = m->multi_sd;
+
+  /* Exit if CNF message reports failure.
+   * Failure means multi_sd < 0.
+   */
+  if (instance->multi_sd < 0) {
+    M2AP_ERROR("Error: be sure to properly configure M2 in your configuration file.\n");
+    DevAssert(instance->multi_sd >= 0);
+  }
+
+  /* Trying to connect to the provided list of eNB ip address */
+
+  for (index = 0; index < instance->nb_m2; index++) {
+    M2AP_INFO("eNB[%d] eNB id %u acting as an initiator (client)\n",
+              instance_id, instance->eNB_id);
+    m2ap_eNB_register_eNB(instance,
+                          &instance->target_mce_m2_ip_address[index],
+                          &instance->enb_m2_ip_address,
+                          instance->sctp_in_streams,
+                          instance->sctp_out_streams,
+                          instance->enb_port_for_M2C,
+                          instance->multi_sd);
+  }
+}
+
+//static
+//void m2ap_eNB_handle_handover_req(instance_t instance,
+//                                  m2ap_handover_req_t *m2ap_handover_req)
+//{
+//  m2ap_eNB_instance_t *instance_p;
+//  m2ap_eNB_data_t     *target;
+//  m2ap_id_manager     *id_manager;
+//  int                 ue_id;
+//
+//  int target_pci = m2ap_handover_req->target_physCellId;
+//
+//  instance_p = m2ap_eNB_get_instance(instance);
+//  DevAssert(instance_p != NULL);
+//
+//  target = m2ap_is_eNB_pci_in_list(target_pci);
+//  DevAssert(target != NULL);
+//
+//  /* allocate m2ap ID */
+//  id_manager = &instance_p->id_manager;
+//  ue_id = m2ap_allocate_new_id(id_manager);
+//  if (ue_id == -1) {
+//    M2AP_ERROR("could not allocate a new M2AP UE ID\n");
+//    /* TODO: cancel handover: send (to be defined) message to RRC */
+//    exit(1);
+//  }
+//  /* id_source is ue_id, id_target is unknown yet */
+//  m2ap_set_ids(id_manager, ue_id, m2ap_handover_req->rnti, ue_id, -1);
+//  m2ap_id_set_state(id_manager, ue_id, M2ID_STATE_SOURCE_PREPARE);
+//  m2ap_set_reloc_prep_timer(id_manager, ue_id,
+//                            m2ap_timer_get_tti(&instance_p->timers));
+//  m2ap_id_set_target(id_manager, ue_id, target);
+//
+//  m2ap_eNB_generate_m2_handover_request(instance_p, target, m2ap_handover_req, ue_id);
+//}
+
+//static
+//void m2ap_eNB_handle_handover_req_ack(instance_t instance,
+//                                      m2ap_handover_req_ack_t *m2ap_handover_req_ack)
+//{
+//  /* TODO: remove this hack (the goal is to find the correct
+//   * eNodeB structure for the other end) - we need a proper way for RRC
+//   * and M2AP to identify eNodeBs
+//   * RRC knows about mod_id and M2AP knows about eNB_id (eNB_ID in
+//   * the configuration file)
+//   * as far as I understand.. CROUX
+//   */
+//  m2ap_eNB_instance_t *instance_p;
+//  m2ap_eNB_data_t     *target;
+//  int source_assoc_id = m2ap_handover_req_ack->source_assoc_id;
+//  int                 ue_id;
+//  int                 id_source;
+//  int                 id_target;
+//
+//  instance_p = m2ap_eNB_get_instance(instance);
+//  DevAssert(instance_p != NULL);
+//
+//  target = m2ap_get_eNB(NULL, source_assoc_id, 0);
+//  DevAssert(target != NULL);
+//
+//  /* rnti is a new information, save it */
+//  ue_id     = m2ap_handover_req_ack->m2_id_target;
+//  id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id);
+//  id_target = ue_id;
+//  m2ap_set_ids(&instance_p->id_manager, ue_id, m2ap_handover_req_ack->rnti, id_source, id_target);
+//
+//  m2ap_eNB_generate_m2_handover_request_ack(instance_p, target, m2ap_handover_req_ack);
+//}
+//
+//static
+//void m2ap_eNB_ue_context_release(instance_t instance,
+//                                 m2ap_ue_context_release_t *m2ap_ue_context_release)
+//{
+//  m2ap_eNB_instance_t *instance_p;
+//  m2ap_eNB_data_t     *target;
+//  int source_assoc_id = m2ap_ue_context_release->source_assoc_id;
+//  int ue_id;
+//  instance_p = m2ap_eNB_get_instance(instance);
+//  DevAssert(instance_p != NULL);
+//
+//  target = m2ap_get_eNB(NULL, source_assoc_id, 0);
+//  DevAssert(target != NULL);
+//
+//  m2ap_eNB_generate_m2_ue_context_release(instance_p, target, m2ap_ue_context_release);
+//
+//  /* free the M2AP UE ID */
+//  ue_id = m2ap_find_id_from_rnti(&instance_p->id_manager, m2ap_ue_context_release->rnti);
+//  if (ue_id == -1) {
+//    M2AP_ERROR("could not find UE %x\n", m2ap_ue_context_release->rnti);
+//    exit(1);
+//  }
+//  m2ap_release_id(&instance_p->id_manager, ue_id);
+//}
+
+//void MCE_task_send_sctp_init_req(instance_t enb_id) {
+//  // 1. get the itti msg, and retrive the enb_id from the message
+//  // 2. use RC.rrc[enb_id] to fill the sctp_init_t with the ip, port
+//  // 3. creat an itti message to init
+//
+//  LOG_I(M2AP, "M2AP_SCTP_REQ(create socket)\n");
+//  MessageDef  *message_p = NULL;
+//
+//  message_p = itti_alloc_new_message (M2AP, SCTP_INIT_MSG);
+//  message_p->ittiMsg.sctp_init.port = M2AP_PORT_NUMBER;
+//  message_p->ittiMsg.sctp_init.ppid = M2AP_SCTP_PPID;
+//  message_p->ittiMsg.sctp_init.ipv4 = 1;
+//  message_p->ittiMsg.sctp_init.ipv6 = 0;
+//  message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1;
+//  //message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr);
+//  message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr("127.0.0.7");
+//  /*
+//   * SR WARNING: ipv6 multi-homing fails sometimes for localhost.
+//   * * * * Disable it for now.
+//   */
+//  message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0;
+//  message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1";
+//
+//  itti_send_msg_to_task(TASK_SCTP, enb_id, message_p);
+//}
+//
+void *m2ap_eNB_task(void *arg) {
+  MessageDef *received_msg = NULL;
+  int         result;
+  M2AP_DEBUG("Starting M2AP layer\n");
+  m2ap_eNB_prepare_internal_data();
+
+  itti_mark_task_ready(TASK_M2AP_ENB);
+
+ // MCE_task_send_sctp_init_req(0);
+
+  while (1) {
+    itti_receive_msg(TASK_M2AP_ENB, &received_msg);
+
+    switch (ITTI_MSG_ID(received_msg)) {
+      case MESSAGE_TEST:
+	LOG_D(M2AP,"eNB Received MESSAGE_TEST Message %s\n",itti_get_task_name(ITTI_MSG_ORIGIN_ID(received_msg)));
+	//MessageDef * message_p = itti_alloc_new_message(TASK_M2AP_ENB, MESSAGE_TEST);
+        //itti_send_msg_to_task(TASK_M3AP, 1/*ctxt_pP->module_id*/, message_p);
+	break;
+      case TERMINATE_MESSAGE:
+        M2AP_WARN(" *** Exiting M2AP thread\n");
+        itti_exit_task();
+        break;
+
+      case M2AP_SUBFRAME_PROCESS:
+        m2ap_check_timers(ITTI_MESSAGE_GET_INSTANCE(received_msg));
+        break;
+
+      case M2AP_REGISTER_ENB_REQ:
+	LOG_I(M2AP,"eNB Received M2AP_REGISTER_ENB_REQ Message\n");
+        m2ap_eNB_handle_register_eNB(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                     &M2AP_REGISTER_ENB_REQ(received_msg));
+        break;
+
+
+      case M2AP_MBMS_SCHEDULING_INFORMATION_RESP:
+	LOG_I(M2AP,"eNB M2AP_MBMS_SCHEDULING_INFORMATION_RESP Message\n");
+        eNB_send_MBMS_SCHEDULING_INFORMATION_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                     &M2AP_MBMS_SCHEDULING_INFORMATION_RESP(received_msg));
+	break;
+      case M2AP_MBMS_SESSION_START_RESP:
+	LOG_I(M2AP,"eNB M2AP_MBMS_SESSION_START_RESP Message\n");
+        eNB_send_MBMS_SESSION_START_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                     &M2AP_MBMS_SESSION_START_RESP(received_msg));
+	break;
+      case M2AP_MBMS_SESSION_START_FAILURE:
+	LOG_I(M2AP,"eNB M2AP_MBMS_SESSION_START_FAILURE Message\n");
+        eNB_send_MBMS_SESSION_START_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                     &M2AP_MBMS_SESSION_START_FAILURE(received_msg));
+	break;
+      case M2AP_MBMS_SESSION_STOP_RESP:
+	LOG_I(M2AP,"eNB M2AP_MBMS_SESSION_STOP_RESP Message\n");
+        eNB_send_MBMS_SESSION_STOP_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                     &M2AP_MBMS_SESSION_STOP_RESP(received_msg));
+	break;
+      case M2AP_ENB_CONFIGURATION_UPDATE:
+	LOG_I(M2AP,"eNB M2AP_ENB_CONFIGURATION_UPDATE Message\n");
+        eNB_send_eNB_CONFIGURATION_UPDATE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                     &M2AP_ENB_CONFIGURATION_UPDATE(received_msg));
+	break;
+      case M2AP_MCE_CONFIGURATION_UPDATE_ACK:
+	LOG_I(M2AP,"eNB M2AP_MCE_CONFIGURATION_UPDATE_ACK Message\n");
+        //eNB_send_MCE_CONFIGURATION_UPDATE_ACKNOWLEDGE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+         //                            &M2AP_MCE_CONFIGURATION_UPDATE_ACK(received_msg));
+	break;
+      case M2AP_MCE_CONFIGURATION_UPDATE_FAILURE:
+	LOG_I(M2AP,"eNB M2AP_MCE_CONFIGURATION_UPDATE_FAILURE Message\n");
+        //(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                     //&M2AP_MCE_CONFIGURATION_UPDATE_FAILURE(received_msg));
+	break;
+      case M2AP_MBMS_SESSION_UPDATE_RESP:
+	LOG_I(M2AP,"eNB M2AP_MBMS_SESSION_UPDATE_RESP Message\n");
+        eNB_send_MBMS_SESSION_UPDATE_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                     &M2AP_MBMS_SESSION_UPDATE_RESP(received_msg));
+	break;
+      case M2AP_MBMS_SESSION_UPDATE_FAILURE:
+	LOG_I(M2AP,"eNB M2AP_MBMS_SESSION_UPDATE_FAILURE Message\n");
+        eNB_send_MBMS_SESSION_UPDATE_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                     &M2AP_MBMS_SESSION_UPDATE_FAILURE(received_msg));
+	break;
+      case M2AP_MBMS_SERVICE_COUNTING_REPORT:
+	LOG_I(M2AP,"eNB M2AP_MBMS_SERVICE_COUNTING_REPORT Message\n");
+        eNB_send_MBMS_SERVICE_COUNTING_REPORT(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                     &M2AP_MBMS_SERVICE_COUNTING_REPORT(received_msg));
+	break;
+      case M2AP_MBMS_OVERLOAD_NOTIFICATION:
+	LOG_I(M2AP,"eNB M2AP_MBMS_OVERLOAD_NOTIFICATION Message\n");
+        eNB_send_MBMS_OVERLOAD_NOTIFICATION(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                     &M2AP_MBMS_OVERLOAD_NOTIFICATION(received_msg));
+	break;
+      case M2AP_MBMS_SERVICE_COUNTING_RESP:
+	LOG_I(M2AP,"eNB M2AP_MBMS_SERVICE_COUNTING_RESP Message\n");
+        eNB_send_MBMS_SERVICE_COUNTING_RESP(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                     &M2AP_MBMS_SERVICE_COUNTING_RESP(received_msg));
+	break;
+      case M2AP_MBMS_SERVICE_COUNTING_FAILURE:
+	LOG_I(M2AP,"eNB  Message\n");
+        eNB_send_MBMS_SERVICE_COUNTING_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                     &M2AP_MBMS_SERVICE_COUNTING_FAILURE(received_msg));
+	break;
+
+
+      case SCTP_INIT_MSG_MULTI_CNF:
+	LOG_I(M2AP,"eNB Received SCTP_INIT_MSG_MULTI_CNF Message\n");
+        m2ap_eNB_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                                &received_msg->ittiMsg.sctp_init_msg_multi_cnf);
+        break;
+
+      case SCTP_NEW_ASSOCIATION_RESP:
+	LOG_I(M2AP,"eNB Received SCTP_NEW_ASSOCIATION_RESP Message\n");
+        m2ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                              &received_msg->ittiMsg.sctp_new_association_resp);
+        break;
+
+      case SCTP_NEW_ASSOCIATION_IND:
+	LOG_I(M2AP,"eNB Received SCTP_NEW_ASSOCIATION Message\n");
+        m2ap_eNB_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                             &received_msg->ittiMsg.sctp_new_association_ind);
+        break;
+
+      case SCTP_DATA_IND:
+	LOG_I(M2AP,"eNB Received SCTP_DATA_IND Message\n");
+        m2ap_eNB_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                      &received_msg->ittiMsg.sctp_data_ind);
+        break;
+
+      default:
+        M2AP_ERROR("eNB Received unhandled message: %d:%s\n",
+                   ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
+        break;
+    }
+
+    result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg);
+    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
+    received_msg = NULL;
+  }
+
+  return NULL;
+}
+
+#include "common/config/config_userapi.h"
+
+int is_m2ap_eNB_enabled(void)
+{
+  static volatile int config_loaded = 0;
+  static volatile int enabled = 0;
+  static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+
+  if (pthread_mutex_lock(&mutex)) goto mutex_error;
+
+  if (config_loaded) {
+    if (pthread_mutex_unlock(&mutex)) goto mutex_error;
+    return enabled;
+  }
+
+  char *enable_m2 = NULL;
+  paramdef_t p[] = {
+   { "enable_enb_m2", "yes/no", 0, strptr:&enable_m2, defstrval:"", TYPE_STRING, 0 }
+  };
+
+  /* TODO: do it per module - we check only first eNB */
+  config_get(p, sizeof(p)/sizeof(paramdef_t), "eNBs.[0]");
+  if (enable_m2 != NULL && strcmp(enable_m2, "yes") == 0)
+    enabled = 1;
+
+  config_loaded = 1;
+
+  if (pthread_mutex_unlock(&mutex)) goto mutex_error;
+
+  return enabled;
+
+mutex_error:
+  LOG_E(M2AP, "mutex error\n");
+  exit(1);
+}
diff --git a/openair2/M2AP/m2ap_eNB.h b/openair2/M2AP/m2ap_eNB.h
new file mode 100644
index 0000000000..608da07e7e
--- /dev/null
+++ b/openair2/M2AP/m2ap_eNB.h
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_eNB.h
+ * \brief m2ap tasks for eNB
+ * \author Konstantinos Alexandris <Konstantinos.Alexandris@eurecom.fr>, Cedric Roux <Cedric.Roux@eurecom.fr>, Navid Nikaein <Navid.Nikaein@eurecom.fr>
+ * \date 2018
+ * \version 1.0
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+
+/** @defgroup _m2ap_impl_ M2AP Layer Reference Implementation
+ * @ingroup _ref_implementation_
+ * @{
+ */
+
+#ifndef M2AP_ENB_H_
+#define M2AP_ENB_H_
+
+#include "m2ap_eNB_defs.h"
+
+
+int m2ap_eNB_init_sctp (m2ap_eNB_instance_t *instance_p,
+                        net_ip_address_t    *local_ip_addr,
+                        uint32_t enb_port_for_M2C);
+
+void *m2ap_eNB_task(void *arg);
+
+int is_m2ap_eNB_enabled(void);
+
+#endif /* M2AP_ENB_H_ */
+
+/**
+ * @}
+ */
diff --git a/openair2/M2AP/m2ap_eNB_defs.h b/openair2/M2AP/m2ap_eNB_defs.h
new file mode 100644
index 0000000000..b8f7e4b3c6
--- /dev/null
+++ b/openair2/M2AP/m2ap_eNB_defs.h
@@ -0,0 +1,221 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_eNB_defs.h
+ * \brief m2ap struct definitions for eNB
+ * \author Javier Morgade  <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#include <stdint.h>
+
+#include "queue.h"
+#include "tree.h"
+
+#include "sctp_eNB_defs.h"
+
+#include "m2ap_ids.h" //looks X2AP specific for HO
+#include "m2ap_timers.h"
+
+#ifndef M2AP_ENB_DEFS_H_
+#define M2AP_ENB_DEFS_H_
+
+#define M2AP_ENB_NAME_LENGTH_MAX    (150)
+
+typedef enum {
+  /* Disconnected state: initial state for any association. */
+  M2AP_ENB_STATE_DISCONNECTED = 0x0,
+
+  /* State waiting for m2 Setup response message if the target eNB accepts or
+   * M2 Setup failure if rejects the eNB.
+   */
+  M2AP_ENB_STATE_WAITING     = 0x1,
+
+  /* The eNB is successfully connected to another eNB. */
+  M2AP_ENB_STATE_CONNECTED   = 0x2,
+
+  /* M2AP is ready, and the eNB is successfully connected to another eNB. */
+  M2AP_ENB_STATE_READY             = 0x3,
+
+  M2AP_ENB_STATE_OVERLOAD          = 0x4,
+
+  M2AP_ENB_STATE_RESETTING         = 0x5,
+
+  /* Max number of states available */
+  M2AP_ENB_STATE_MAX,
+} m2ap_eNB_state_t;
+
+/* Served PLMN identity element */
+/*struct plmn_identity_s {
+  uint16_t mcc;
+  uint16_t mnc;
+  uint8_t  mnc_digit_length;
+  STAILQ_ENTRY(plmn_identity_s) next;
+};*/
+
+/* Served group id element */
+/*struct served_group_id_s {
+  uint16_t enb_group_id;
+  STAILQ_ENTRY(served_group_id_s) next;
+};*/
+
+/* Served enn code for a particular eNB */
+/*struct enb_code_s {
+  uint8_t enb_code;
+  STAILQ_ENTRY(enb_code_s) next;
+};*/
+
+struct m2ap_eNB_instance_s;
+
+/* This structure describes association of a eNB to another eNB */
+typedef struct m2ap_eNB_data_s {
+  /* eNB descriptors tree, ordered by sctp assoc id */
+  RB_ENTRY(m2ap_eNB_data_s) entry;
+
+  /* This is the optional name provided by the MME */
+  char *eNB_name;
+
+  /*  target eNB ID */
+  uint32_t eNB_id;
+
+  /* Current eNB load information (if any). */
+  //m2ap_load_state_t overload_state;
+
+  /* Current eNB->eNB M2AP association state */
+  m2ap_eNB_state_t state;
+
+  /* Next usable stream for UE signalling */
+  int32_t nextstream;
+
+  /* Number of input/ouput streams */
+  uint16_t in_streams;
+  uint16_t out_streams;
+
+  /* Connexion id used between SCTP/M2AP */
+  uint16_t cnx_id;
+
+  /* SCTP association id */
+  int32_t  assoc_id;
+
+  /* Nid cells */
+  uint32_t                Nid_cell[MAX_NUM_CCs];
+  int                     num_cc;
+
+  /* Only meaningfull in virtual mode */
+  struct m2ap_eNB_instance_s *m2ap_eNB_instance;
+} m2ap_eNB_data_t;
+
+typedef struct m2ap_eNB_instance_s {
+  /* used in simulation to store multiple eNB instances*/
+  STAILQ_ENTRY(m2ap_eNB_instance_s) m2ap_eNB_entries;
+
+  /* Number of target eNBs requested by eNB (tree size) */
+  uint32_t m2_target_enb_nb;
+  /* Number of target eNBs for which association is pending */
+  uint32_t m2_target_enb_pending_nb;
+  /* Number of target eNB successfully associated to eNB */
+  uint32_t m2_target_enb_associated_nb;
+  /* Tree of M2AP eNB associations ordered by association ID */
+  RB_HEAD(m2ap_enb_map, m2ap_eNB_data_s) m2ap_enb_head;
+
+  /* Tree of UE ordered by eNB_ue_m2ap_id's */
+  //  RB_HEAD(m2ap_ue_map, m2ap_eNB_ue_context_s) m2ap_ue_head;
+
+  /* For virtual mode, mod_id as defined in the rest of the L1/L2 stack */
+  instance_t instance;
+
+  /* Displayable name of eNB */
+  char *eNB_name;
+
+  /* Unique eNB_id to identify the eNB within EPC.
+   * In our case the eNB is a macro eNB so the id will be 20 bits long.
+   * For Home eNB id, this field should be 28 bits long.
+   */
+  uint32_t eNB_id;
+  /* The type of the cell */
+  cell_type_t cell_type;
+
+  //uint16_t num_mbms_service_area_list;
+  //uint16_t mbms_service_area_list[8];
+
+  struct{
+          uint16_t mbsfn_sync_area;
+          uint16_t mbms_service_area_list[8];
+          uint16_t num_mbms_service_area_list;
+  }mbms_configuration_data_list[8];
+  uint8_t num_mbms_configuration_data_list;
+
+
+  /* Tracking area code */
+  uint16_t tac;
+
+  /* Mobile Country Code
+   * Mobile Network Code
+   */
+  uint16_t  mcc;
+  uint16_t  mnc;
+  uint8_t   mnc_digit_length;
+
+  /* CC params */
+  int16_t                 eutra_band[MAX_NUM_CCs];
+  uint32_t                downlink_frequency[MAX_NUM_CCs];
+  int32_t                 uplink_frequency_offset[MAX_NUM_CCs];
+  uint32_t                Nid_cell[MAX_NUM_CCs];
+  int16_t                 N_RB_DL[MAX_NUM_CCs];
+  lte_frame_type_t        frame_type[MAX_NUM_CCs];
+  uint32_t                fdd_earfcn_DL[MAX_NUM_CCs];
+  uint32_t                fdd_earfcn_UL[MAX_NUM_CCs];
+  int                     num_cc;
+
+  net_ip_address_t target_mce_m2_ip_address[M2AP_MAX_NB_ENB_IP_ADDRESS];
+  uint8_t          nb_m2;
+  net_ip_address_t enb_m2_ip_address;
+  uint16_t         sctp_in_streams;
+  uint16_t         sctp_out_streams;
+  uint32_t         enb_port_for_M2C;
+  int              multi_sd;
+
+  m2ap_id_manager  id_manager;
+  m2ap_timers_t    timers;
+} m2ap_eNB_instance_t;
+
+typedef struct {
+  /* List of served eNBs
+   * Only used for virtual mode
+   */
+  STAILQ_HEAD(m2ap_eNB_instances_head_s, m2ap_eNB_instance_s) m2ap_eNB_instances_head;
+  /* Nb of registered eNBs */
+  uint8_t nb_registered_eNBs;
+
+  /* Generate a unique connexion id used between M2AP and SCTP */
+  uint16_t global_cnx_id;
+} m2ap_eNB_internal_data_t;
+
+int m2ap_eNB_compare_assoc_id(struct m2ap_eNB_data_s *p1, struct m2ap_eNB_data_s *p2);
+
+/* Generate the tree management functions */
+struct m2ap_eNB_map;
+struct m2ap_eNB_data_s;
+RB_PROTOTYPE(m2ap_eNB_map, m2ap_eNB_data_s, entry, m2ap_eNB_compare_assoc_id);
+
+
+#endif /* M2AP_ENB_DEFS_H_ */
diff --git a/openair2/M2AP/m2ap_eNB_generate_messages.c b/openair2/M2AP/m2ap_eNB_generate_messages.c
new file mode 100644
index 0000000000..b6c821e1ce
--- /dev/null
+++ b/openair2/M2AP/m2ap_eNB_generate_messages.c
@@ -0,0 +1,808 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_eNB_generate_messages.c
+ * \brief m2ap procedures for eNB
+ * \author Javier Morgade <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#include "intertask_interface.h"
+
+//#include "M2AP_LastVisitedCell-Item.h"
+
+#include "m2ap_common.h"
+#include "m2ap_eNB.h"
+#include "m2ap_eNB_generate_messages.h"
+#include "m2ap_encoder.h"
+#include "m2ap_decoder.h"
+#include "m2ap_ids.h"
+
+#include "m2ap_itti_messaging.h"
+
+#include "msc.h"
+#include "assertions.h"
+#include "conversions.h"
+
+//int m2ap_eNB_generate_m2_setup_request(
+//  m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p)
+//{
+//  module_id_t enb_mod_idP=0;
+//  module_id_t du_mod_idP=0;
+//
+//  M2AP_M2AP_PDU_t          pdu;
+//  M2AP_M2SetupRequest_t    *out;
+//  M2AP_M2SetupRequest_Ies_t *ie;
+//
+//  uint8_t  *buffer;
+//  uint32_t  len;
+//  int       i = 0;
+//  int       j = 0;
+//
+//  /* Create */
+//  /* 0. pdu Type */
+//  memset(&pdu, 0, sizeof(pdu));
+//  pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
+//  //pdu.choice.initiatingMessage = (M2AP_InitiatingMessage_t *)calloc(1, sizeof(M2AP_InitiatingMessage_t));
+//  pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_m2Setup;
+//  pdu.choice.initiatingMessage.criticality   = M2AP_Criticality_reject;
+//  pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_M2SetupRequest;
+//  out = &pdu.choice.initiatingMessage.value.choice.M2SetupRequest;
+//
+//  /* mandatory */
+//  /* c1. GlobalENB_ID (integer value) */
+//  ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
+//  ie->id                        = M2AP_ProtocolIE_ID_id_GlobalENB_ID;
+//  ie->criticality               = M2AP_Criticality_reject;
+//  ie->value.present             = M2AP_M2SetupRequest_Ies__value_PR_GlobalENB_ID;
+//  //ie->value.choice.GlobalENB_ID.eNB_ID = 1;//M2AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);
+//  MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+//                  &ie->value.choice.GlobalENB_ID.pLMN_Identity);
+//  ie->value.choice.GlobalENB_ID.eNB_ID.present = M2AP_ENB_ID_PR_macro_eNB_ID;
+//  MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id,
+//                           &ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID);
+//  M2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id,
+//          ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0],
+//          ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1],
+//          ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]);
+//
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  ///* mandatory */
+//  ///* c2. GNB_eNB_ID (integrer value) */
+//  //ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
+//  //ie->id                        = M2AP_ProtocolIE_ID_id_gNB_eNB_ID;
+//  //ie->criticality               = M2AP_Criticality_reject;
+//  //ie->value.present             = M2AP_M2SetupRequestIEs__value_PR_GNB_eNB_ID;
+//  //asn_int642INTEGER(&ie->value.choice.GNB_eNB_ID, f1ap_du_data->gNB_eNB_id);
+//  //ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* optional */
+//  /* c3. ENBname */
+//  if (m2ap_eNB_data_p->eNB_name != NULL) {
+//    ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
+//    ie->id                        = M2AP_ProtocolIE_ID_id_ENBname;
+//    ie->criticality               = M2AP_Criticality_ignore;
+//    ie->value.present             = M2AP_M2SetupRequest_Ies__value_PR_ENBname;
+//    //OCTET_STRING_fromBuf(&ie->value.choice.ENB_Name, m2ap_eNB_data_p->eNB_name,
+//                         //strlen(m2ap_eNB_data_p->eNB_name));
+//    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//  }
+//
+//  /* mandatory */
+//  /* c4. serverd cells list */
+//  ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
+//  ie->id                        = M2AP_ProtocolIE_ID_id_ENB_MBMS_Configuration_data_List;
+//  ie->criticality               = M2AP_Criticality_reject;
+//  ie->value.present             = M2AP_M2SetupRequest_Ies__value_PR_ENB_MBMS_Configuration_data_List;
+//
+//  int num_mbms_available = 1;//m2ap_du_data->num_mbms_available;
+//  LOG_D(M2AP, "num_mbms_available = %d \n", num_mbms_available);
+//
+// for (i=0;
+//       i<num_mbms_available;
+//       i++) {
+//        /* mandatory */
+//        /* 4.1 serverd cells item */
+//
+//        M2AP_ENB_MBMS_Configuration_data_ItemIEs_t *mbms_configuration_data_list_item_ies;
+//        mbms_configuration_data_list_item_ies = (M2AP_ENB_MBMS_Configuration_data_ItemIEs_t *)calloc(1, sizeof(M2AP_ENB_MBMS_Configuration_data_ItemIEs_t));
+//        mbms_configuration_data_list_item_ies->id = M2AP_ProtocolIE_ID_id_ENB_MBMS_Configuration_data_Item;
+//        mbms_configuration_data_list_item_ies->criticality = M2AP_Criticality_reject;
+//        mbms_configuration_data_list_item_ies->value.present = M2AP_ENB_MBMS_Configuration_data_ItemIEs__value_PR_ENB_MBMS_Configuration_data_Item;
+//
+//	M2AP_ENB_MBMS_Configuration_data_Item_t *mbms_configuration_data_item;
+//	mbms_configuration_data_item = &mbms_configuration_data_list_item_ies->value.choice.ENB_MBMS_Configuration_data_Item;
+//	{
+//		MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+//                  &mbms_configuration_data_item->eCGI.pLMN_Identity);
+//        	MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,0,
+//                                   &mbms_configuration_data_item->eCGI.eUTRANcellIdentifier);
+//		M2AP_MBMS_Service_Area_t * mbms_service_area;
+//		mbms_service_area = (M2AP_MBMS_Service_Area_t*)calloc(1,sizeof(M2AP_MBMS_Service_Area_t));
+//		ASN_SEQUENCE_ADD(&mbms_configuration_data_item->mbmsServiceAreaList.list,mbms_service_area);
+//
+//
+//	}
+//
+//
+//        //M2AP_ENB_MBMS_Configuration_data_Item_t mbms_configuration_data_item;
+//        //memset((void *)&mbms_configuration_data_item, 0, sizeof(M2AP_ENB_MBMS_Configuration_data_Item_t));
+//	
+//	//M2AP_ECGI_t      eCGI;
+//		//M2AP_PLMN_Identity_t     pLMN_Identity;
+//		//M2AP_EUTRANCellIdentifier_t      eUTRANcellIdentifier
+//	//M2AP_MBSFN_SynchronisationArea_ID_t      mbsfnSynchronisationArea;
+//	//M2AP_MBMS_Service_Area_ID_List_t         mbmsServiceAreaList;
+//
+//
+//	ASN_SEQUENCE_ADD(&ie->value.choice.ENB_MBMS_Configuration_data_List.list,mbms_configuration_data_list_item_ies);
+//
+// }
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  LOG_W(M2AP,"m2ap_eNB_data_p->assoc_id %d\n",m2ap_eNB_data_p->assoc_id);
+//  /* encode */
+//  if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+//    LOG_E(M2AP, "Failed to encode M2 setup request\n");
+//    return -1;
+//  }
+//
+// 
+//  LOG_W(M2AP,"pdu.present %d\n",pdu.present);
+// // MSC_LOG_TX_MESSAGE(
+// // MSC_M2AP_eNB,
+// // MSC_M2AP_MCE,
+// // (const char *)buffer,
+// // len,
+// // MSC_AS_TIME_FMT" M2_SETUP_REQUEST initiatingMessage MCEname %s",
+// // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
+// // m2ap_eNB_data_p->ENBname);
+//
+//  m2ap_eNB_itti_send_sctp_data_req(instance_p, m2ap_eNB_data_p->assoc_id, buffer, len, 0);
+//
+//  return 0;
+//
+//
+//}
+
+//int m2ap_MCE_generate_m2_setup_response(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p)
+//{
+//  M2AP_M2AP_PDU_t                     pdu;
+//  M2AP_M2SetupResponse_t              *out;
+//  M2AP_M2SetupResponse_Ies_t          *ie;
+//  //M2AP_PLMN_Identity_t                *plmn;
+//  //ServedCells__Member                 *servedCellMember;
+//  //M2AP_GU_Group_ID_t                  *gu;
+//
+//  uint8_t  *buffer;
+//  uint32_t  len;
+//  int       ret = 0;
+//
+//  DevAssert(instance_p != NULL);
+//  DevAssert(m2ap_eNB_data_p != NULL);
+//
+//  /* Prepare the M2AP message to encode */
+//  memset(&pdu, 0, sizeof(pdu));
+//  pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome;
+//  pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup;
+//  pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject;
+//  pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_M2SetupResponse;
+//  out = &pdu.choice.successfulOutcome.value.choice.M2SetupResponse;
+//
+//  /* mandatory */
+//  ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t));
+//  //ie->id = M2AP_ProtocolIE_ID_id_GlobalENB_ID;
+//  //ie->criticality = M2AP_Criticality_reject;
+//  //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_GlobalENB_ID;
+//  //MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+//  //                  &ie->value.choice.GlobalENB_ID.pLMN_Identity);
+//  //ie->value.choice.GlobalENB_ID.eNB_ID.present = M2AP_ENB_ID_PR_macro_eNB_ID;
+//  //MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id,
+//  //                           &ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID);
+//  //M2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id,
+//  //          ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0],
+//  //          ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1],
+//  //          ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]);
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* mandatory */
+//  ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t));
+//  //ie->id = M2AP_ProtocolIE_ID_id_ServedCells;
+//  //ie->criticality = M2AP_Criticality_reject;
+//  //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_ServedCells;
+//  //{
+//  //  for (int i = 0; i<instance_p->num_cc; i++){
+//  //    servedCellMember = (ServedCells__Member *)calloc(1,sizeof(ServedCells__Member));
+//  //    {
+//  //      servedCellMember->servedCellInfo.pCI = instance_p->Nid_cell[i];
+//
+//  //      MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+//  //                    &servedCellMember->servedCellInfo.cellId.pLMN_Identity);
+//  //      MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,0,
+//  //                                 &servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier);
+//
+//  //      INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC);
+//  //      plmn = (M2AP_PLMN_Identity_t *)calloc(1,sizeof(M2AP_PLMN_Identity_t));
+//  //      {
+//  //        MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn);
+//  //        ASN_SEQUENCE_ADD(&servedCellMember->servedCellInfo.broadcastPLMNs.list, plmn);
+//  //      }
+//
+//  //      if (instance_p->frame_type[i] == FDD) {
+//  //        servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = M2AP_EUTRA_Mode_Info_PR_fDD;
+//  //        servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i];
+//  //        servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i];
+//  //        switch (instance_p->N_RB_DL[i]) {
+//  //          case 6:
+//  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6;
+//  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6;
+//  //            break;
+//  //          case 15:
+//  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15;
+//  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15;
+//  //            break;
+//  //          case 25:
+//  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25;
+//  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25;
+//  //            break;
+//  //          case 50:
+//  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50;
+//  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50;
+//  //            break;
+//  //          case 75:
+//  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75;
+//  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75;
+//  //            break;
+//  //          case 100:
+//  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100;
+//  //            servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100;
+//  //            break;
+//  //          default:
+//  //            AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
+//  //            break;
+//  //        }
+//  //      }
+//  //      else {
+//  //        AssertFatal(0,"M2Setupresponse not supported for TDD!");
+//  //      }
+//  //    }
+//  //    ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember);
+//  //  }
+//  //}
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* mandatory */
+//  ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t));
+//  //ie->id = M2AP_ProtocolIE_ID_id_GUGroupIDList;
+//  //ie->criticality = M2AP_Criticality_reject;
+//  //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_GUGroupIDList;
+//  //{
+//  //  gu = (M2AP_GU_Group_ID_t *)calloc(1, sizeof(M2AP_GU_Group_ID_t));
+//  //  {
+//  //    MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+//  //                  &gu->pLMN_Identity);
+//  //    //@TODO: consider to update this value
+//  //    INT16_TO_OCTET_STRING(0, &gu->mME_Group_ID);
+//  //  }
+//  //  ASN_SEQUENCE_ADD(&ie->value.choice.GUGroupIDList.list, gu);
+//  //}
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+//    M2AP_ERROR("Failed to encode M2 setup response\n");
+//    return -1;
+//  }
+//
+//  m2ap_eNB_data_p->state = M2AP_ENB_STATE_READY;
+//
+//  //MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 M2Setup/successfulOutcome assoc_id %u", m2ap_eNB_data_p->assoc_id);
+//
+//  m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 0);
+//
+//  return ret;
+//}
+
+//int m2ap_MCE_generate_m2_setup_failure(instance_t instance,
+//                                       uint32_t assoc_id,
+//                                       M2AP_Cause_PR cause_type,
+//                                       long cause_value,
+//                                       long time_to_wait)
+//{
+//  M2AP_M2AP_PDU_t                     pdu;
+//  M2AP_M2SetupFailure_t              *out;
+//  M2AP_M2SetupFailure_Ies_t          *ie;
+//
+//  uint8_t  *buffer;
+//  uint32_t  len;
+//  int       ret = 0;
+//
+//  /* Prepare the M2AP message to encode */
+//  memset(&pdu, 0, sizeof(pdu));
+//  pdu.present = M2AP_M2AP_PDU_PR_unsuccessfulOutcome;
+//  pdu.choice.unsuccessfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup;
+//  pdu.choice.unsuccessfulOutcome.criticality = M2AP_Criticality_reject;
+//  pdu.choice.unsuccessfulOutcome.value.present = M2AP_UnsuccessfulOutcome__value_PR_M2SetupFailure;
+//  out = &pdu.choice.unsuccessfulOutcome.value.choice.M2SetupFailure;
+//
+//  /* mandatory */
+//  ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t));
+//  //ie->id = M2AP_ProtocolIE_ID_id_Cause;
+//  //ie->criticality = M2AP_Criticality_ignore;
+//  //ie->value.present = M2AP_M2SetupFailure_IEs__value_PR_Cause;
+//
+//  //m2ap_eNB_set_cause (&ie->value.choice.Cause, cause_type, cause_value);
+//
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* optional: consider to handle this later */
+//  ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t));
+//  //ie->id = M2AP_ProtocolIE_ID_id_TimeToWait;
+//  //ie->criticality = M2AP_Criticality_ignore;
+//  //ie->value.present = M2AP_M2SetupFailure_IEs__value_PR_TimeToWait;
+//
+//  //if (time_to_wait > -1) {
+//  //  ie->value.choice.TimeToWait = time_to_wait;
+//  //}
+//
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+//    M2AP_ERROR("Failed to encode M2 setup failure\n");
+//    return -1;
+//  }
+//
+//  //MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB,
+//  //                    MSC_M2AP_TARGET_ENB, NULL, 0,
+//  //                    "0 M2Setup/unsuccessfulOutcome  assoc_id %u cause %u value %u",
+//  //                    assoc_id, cause_type, cause_value);
+//
+//  m2ap_eNB_itti_send_sctp_data_req(instance, assoc_id, buffer, len, 0);
+//
+//  return ret;
+//}
+
+int m2ap_eNB_set_cause (M2AP_Cause_t * cause_p,
+                        M2AP_Cause_PR cause_type,
+                        long cause_value)
+{
+
+  DevAssert (cause_p != NULL);
+  cause_p->present = cause_type;
+
+  switch (cause_type) {
+  case M2AP_Cause_PR_radioNetwork:
+    cause_p->choice.misc = cause_value;
+    break;
+
+  case M2AP_Cause_PR_transport:
+    cause_p->choice.misc = cause_value;
+    break;
+
+  case M2AP_Cause_PR_protocol:
+    cause_p->choice.misc = cause_value;
+    break;
+
+  case M2AP_Cause_PR_misc:
+    cause_p->choice.misc = cause_value;
+    break;
+
+  default:
+    return -1;
+  }
+
+  return 0;
+}
+
+//int m2ap_eNB_generate_m2_handover_request (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
+//                                           m2ap_handover_req_t *m2ap_handover_req, int ue_id)
+//{
+//
+//  M2AP_M2AP_PDU_t                     pdu;
+//  M2AP_HandoverRequest_t              *out;
+//  M2AP_HandoverRequest_IEs_t          *ie;
+//  M2AP_E_RABs_ToBeSetup_ItemIEs_t     *e_RABS_ToBeSetup_ItemIEs;
+//  M2AP_E_RABs_ToBeSetup_Item_t        *e_RABs_ToBeSetup_Item;
+//  M2AP_LastVisitedCell_Item_t         *lastVisitedCell_Item;
+//
+//  uint8_t  *buffer;
+//  uint32_t  len;
+//  int       ret = 0;
+//
+//  DevAssert(instance_p != NULL);
+//  DevAssert(m2ap_eNB_data_p != NULL);
+//
+//  /* Prepare the M2AP handover message to encode */
+//  memset(&pdu, 0, sizeof(pdu));
+//  pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
+//  pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_handoverPreparation;
+//  pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject;
+//  pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_HandoverRequest;
+//  out = &pdu.choice.initiatingMessage.value.choice.HandoverRequest;
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_Old_eNB_UE_M2AP_ID;
+//  ie->criticality = M2AP_Criticality_reject;
+//  ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_M2AP_ID;
+//  ie->value.choice.UE_M2AP_ID = m2ap_id_get_id_source(&instance_p->id_manager, ue_id);
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_Cause;
+//  ie->criticality = M2AP_Criticality_ignore;
+//  ie->value.present = M2AP_HandoverRequest_IEs__value_PR_Cause;
+//  ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork;
+//  ie->value.choice.Cause.choice.radioNetwork = M2AP_CauseRadioNetwork_handover_desirable_for_radio_reasons;
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_TargetCell_ID;
+//  ie->criticality = M2AP_Criticality_reject;
+//  ie->value.present = M2AP_HandoverRequest_IEs__value_PR_ECGI;
+//  MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+//                       &ie->value.choice.ECGI.pLMN_Identity);
+//  MACRO_ENB_ID_TO_CELL_IDENTITY(m2ap_eNB_data_p->eNB_id, 0, &ie->value.choice.ECGI.eUTRANcellIdentifier);
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_GUMMEI_ID;
+//  ie->criticality = M2AP_Criticality_reject;
+//  ie->value.present = M2AP_HandoverRequest_IEs__value_PR_GUMMEI;
+//  MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+//                       &ie->value.choice.GUMMEI.gU_Group_ID.pLMN_Identity);
+//  //@TODO: consider to update these values
+//  INT16_TO_OCTET_STRING(m2ap_handover_req->ue_gummei.mme_group_id, &ie->value.choice.GUMMEI.gU_Group_ID.mME_Group_ID);
+//  MME_CODE_TO_OCTET_STRING(m2ap_handover_req->ue_gummei.mme_code, &ie->value.choice.GUMMEI.mME_Code);
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_UE_ContextInformation;
+//  ie->criticality = M2AP_Criticality_reject;
+//  ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_ContextInformation;
+//  //@TODO: consider to update this value
+//  ie->value.choice.UE_ContextInformation.mME_UE_S1AP_ID = m2ap_handover_req->mme_ue_s1ap_id;
+//
+//  KENB_STAR_TO_BIT_STRING(m2ap_handover_req->kenb,&ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star);
+//
+//  if (m2ap_handover_req->kenb_ncc >=0) { // Check this condition
+//    ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = m2ap_handover_req->kenb_ncc;
+//  }
+//  else {
+//    ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = 1;
+//  }
+//
+//  ENCRALG_TO_BIT_STRING(m2ap_handover_req->security_capabilities.encryption_algorithms,
+//              &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms);
+//
+//  INTPROTALG_TO_BIT_STRING(m2ap_handover_req->security_capabilities.integrity_algorithms,
+//              &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms);
+//
+//  //@TODO: update with proper UEAMPR
+//  UEAGMAXBITRTD_TO_ASN_PRIMITIVES(3L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink);
+//  UEAGMAXBITRTU_TO_ASN_PRIMITIVES(6L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateUplink);
+//  {
+//    for (int i=0;i<m2ap_handover_req->nb_e_rabs_tobesetup;i++) {
+//      e_RABS_ToBeSetup_ItemIEs = (M2AP_E_RABs_ToBeSetup_ItemIEs_t *)calloc(1,sizeof(M2AP_E_RABs_ToBeSetup_ItemIEs_t));
+//      e_RABS_ToBeSetup_ItemIEs->id = M2AP_ProtocolIE_ID_id_E_RABs_ToBeSetup_Item;
+//      e_RABS_ToBeSetup_ItemIEs->criticality = M2AP_Criticality_ignore;
+//      e_RABS_ToBeSetup_ItemIEs->value.present = M2AP_E_RABs_ToBeSetup_ItemIEs__value_PR_E_RABs_ToBeSetup_Item;
+//      e_RABs_ToBeSetup_Item = &e_RABS_ToBeSetup_ItemIEs->value.choice.E_RABs_ToBeSetup_Item;
+//      {
+//        e_RABs_ToBeSetup_Item->e_RAB_ID = m2ap_handover_req->e_rabs_tobesetup[i].e_rab_id;
+//        e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.qCI = m2ap_handover_req->e_rab_param[i].qos.qci;
+//        e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.priority_level;
+//        e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability;
+//        e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability;
+//        e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size = (uint8_t)(m2ap_handover_req->e_rabs_tobesetup[i].eNB_addr.length/8);
+//        e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = m2ap_handover_req->e_rabs_tobesetup[i].eNB_addr.length%8;
+//        e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf =
+//                        calloc(1,e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size);
+//
+//        memcpy (e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf,
+//                        m2ap_handover_req->e_rabs_tobesetup[i].eNB_addr.buffer,
+//                        e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size);
+//
+//        INT32_TO_OCTET_STRING(m2ap_handover_req->e_rabs_tobesetup[i].gtp_teid,&e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.gTP_TEID);
+//      }
+//      ASN_SEQUENCE_ADD(&ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list, e_RABS_ToBeSetup_ItemIEs);
+//    }
+//  }
+//
+//  OCTET_STRING_fromBuf(&ie->value.choice.UE_ContextInformation.rRC_Context, (char*) m2ap_handover_req->rrc_buffer, m2ap_handover_req->rrc_buffer_size);
+//
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_UE_HistoryInformation;
+//  ie->criticality = M2AP_Criticality_ignore;
+//  ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_HistoryInformation;
+//  //@TODO: consider to update this value
+//  {
+//   lastVisitedCell_Item = (M2AP_LastVisitedCell_Item_t *)calloc(1, sizeof(M2AP_LastVisitedCell_Item_t));
+//   lastVisitedCell_Item->present = M2AP_LastVisitedCell_Item_PR_e_UTRAN_Cell;
+//   MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+//                       &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.pLMN_Identity);
+//   MACRO_ENB_ID_TO_CELL_IDENTITY(0, 0, &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.eUTRANcellIdentifier);
+//   lastVisitedCell_Item->choice.e_UTRAN_Cell.cellType.cell_Size = M2AP_Cell_Size_small;
+//   lastVisitedCell_Item->choice.e_UTRAN_Cell.time_UE_StayedInCell = 2;
+//   ASN_SEQUENCE_ADD(&ie->value.choice.UE_HistoryInformation.list, lastVisitedCell_Item);
+//  }
+//
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  if (m2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
+//    M2AP_ERROR("Failed to encode X2 handover request\n");
+//    abort();
+//    return -1;
+//  }
+//
+//  MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 X2Handover/initiatingMessage assoc_id %u", m2ap_eNB_data_p->assoc_id);
+//
+//  m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 1);
+//
+//  return ret;
+//}
+//
+//int m2ap_eNB_generate_m2_handover_request_ack (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
+//                                               m2ap_handover_req_ack_t *m2ap_handover_req_ack)
+//{
+//
+//  M2AP_M2AP_PDU_t                        pdu;
+//  M2AP_HandoverRequestAcknowledge_t      *out;
+//  M2AP_HandoverRequestAcknowledge_IEs_t  *ie;
+//  M2AP_E_RABs_Admitted_ItemIEs_t         *e_RABS_Admitted_ItemIEs;
+//  M2AP_E_RABs_Admitted_Item_t            *e_RABs_Admitted_Item;
+//  int                                    ue_id;
+//  int                                    id_source;
+//  int                                    id_target;
+//
+//  uint8_t  *buffer;
+//  uint32_t  len;
+//  int       ret = 0;
+//
+//  DevAssert(instance_p != NULL);
+//  DevAssert(m2ap_eNB_data_p != NULL);
+//
+//  ue_id     = m2ap_handover_req_ack->m2_id_target;
+//  id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id);
+//  id_target = ue_id;
+//
+//  /* Prepare the M2AP handover message to encode */
+//  memset(&pdu, 0, sizeof(pdu));
+//  pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome;
+//  pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_handoverPreparation;
+//  pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject;
+//  pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_HandoverRequestAcknowledge;
+//  out = &pdu.choice.successfulOutcome.value.choice.HandoverRequestAcknowledge;
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_Old_eNB_UE_M2AP_ID;
+//  ie->criticality = M2AP_Criticality_ignore;
+//  ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M2AP_ID;
+//  ie->value.choice.UE_M2AP_ID = id_source;
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_New_eNB_UE_M2AP_ID;
+//  ie->criticality = M2AP_Criticality_ignore;
+//  ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M2AP_ID_1;
+//  ie->value.choice.UE_M2AP_ID_1 = id_target;
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_E_RABs_Admitted_List;
+//  ie->criticality = M2AP_Criticality_ignore;
+//  ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_E_RABs_Admitted_List;
+//
+//  {
+//      for (int i=0;i<m2ap_handover_req_ack->nb_e_rabs_tobesetup;i++) {
+//        e_RABS_Admitted_ItemIEs = (M2AP_E_RABs_Admitted_ItemIEs_t *)calloc(1,sizeof(M2AP_E_RABs_Admitted_ItemIEs_t));
+//        e_RABS_Admitted_ItemIEs->id = M2AP_ProtocolIE_ID_id_E_RABs_Admitted_Item;
+//        e_RABS_Admitted_ItemIEs->criticality = M2AP_Criticality_ignore;
+//        e_RABS_Admitted_ItemIEs->value.present = M2AP_E_RABs_Admitted_ItemIEs__value_PR_E_RABs_Admitted_Item;
+//        e_RABs_Admitted_Item = &e_RABS_Admitted_ItemIEs->value.choice.E_RABs_Admitted_Item;
+//        {
+//          e_RABs_Admitted_Item->e_RAB_ID = m2ap_handover_req_ack->e_rabs_tobesetup[i].e_rab_id;
+//        }
+//        ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_List.list, e_RABS_Admitted_ItemIEs);
+//      }
+//  }
+//
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer;
+//  ie->criticality = M2AP_Criticality_ignore;
+//  ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_TargeteNBtoSource_eNBTransparentContainer;
+//
+//  OCTET_STRING_fromBuf(&ie->value.choice.TargeteNBtoSource_eNBTransparentContainer, (char*) m2ap_handover_req_ack->rrc_buffer, m2ap_handover_req_ack->rrc_buffer_size);
+//
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  if (m2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
+//    M2AP_ERROR("Failed to encode X2 handover response\n");
+//    abort();
+//    return -1;
+//  }
+//
+//  MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 X2Handover/successfulOutcome assoc_id %u", m2ap_eNB_data_p->assoc_id);
+//
+//  m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 1);
+//
+//  return ret;
+//}
+//
+//int m2ap_eNB_generate_m2_ue_context_release (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p, m2ap_ue_context_release_t *m2ap_ue_context_release)
+//{
+//
+//  M2AP_M2AP_PDU_t                pdu;
+//  M2AP_UEContextRelease_t        *out;
+//  M2AP_UEContextRelease_IEs_t    *ie;
+//  int                            ue_id;
+//  int                            id_source;
+//  int                            id_target;
+//
+//  uint8_t  *buffer;
+//  uint32_t  len;
+//  int       ret = 0;
+//
+//  DevAssert(instance_p != NULL);
+//  DevAssert(m2ap_eNB_data_p != NULL);
+//
+//  ue_id = m2ap_find_id_from_rnti(&instance_p->id_manager, m2ap_ue_context_release->rnti);
+//  if (ue_id == -1) {
+//    M2AP_ERROR("could not find UE %x\n", m2ap_ue_context_release->rnti);
+//    exit(1);
+//  }
+//  id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id);
+//  id_target = ue_id;
+//
+//  /* Prepare the M2AP ue context relase message to encode */
+//  memset(&pdu, 0, sizeof(pdu));
+//  pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
+//  pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_uEContextRelease;
+//  pdu.choice.initiatingMessage.criticality = M2AP_Criticality_ignore;
+//  pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_UEContextRelease;
+//  out = &pdu.choice.initiatingMessage.value.choice.UEContextRelease;
+//
+//  /* mandatory */
+//  ie = (M2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M2AP_UEContextRelease_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_Old_eNB_UE_M2AP_ID;
+//  ie->criticality = M2AP_Criticality_reject;
+//  ie->value.present = M2AP_UEContextRelease_IEs__value_PR_UE_M2AP_ID;
+//  ie->value.choice.UE_M2AP_ID = id_source;
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* mandatory */
+//  ie = (M2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M2AP_UEContextRelease_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_New_eNB_UE_M2AP_ID;
+//  ie->criticality = M2AP_Criticality_reject;
+//  ie->value.present = M2AP_UEContextRelease_IEs__value_PR_UE_M2AP_ID_1;
+//  ie->value.choice.UE_M2AP_ID_1 = id_target;
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  if (m2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
+//    M2AP_ERROR("Failed to encode X2 UE Context Release\n");
+//    abort();
+//    return -1;
+//  }
+//
+//  MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 X2UEContextRelease/initiatingMessage assoc_id %u", m2ap_eNB_data_p->assoc_id);
+//
+//  m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 1);
+//
+//  return ret;
+//}
+//
+//int m2ap_eNB_generate_m2_handover_cancel (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
+//                                          int m2_ue_id,
+//                                          m2ap_handover_cancel_cause_t cause)
+//{
+//  M2AP_M2AP_PDU_t              pdu;
+//  M2AP_HandoverCancel_t        *out;
+//  M2AP_HandoverCancel_IEs_t    *ie;
+//  int                          ue_id;
+//  int                          id_source;
+//  int                          id_target;
+//
+//  uint8_t  *buffer;
+//  uint32_t  len;
+//  int       ret = 0;
+//
+//  DevAssert(instance_p != NULL);
+//  DevAssert(m2ap_eNB_data_p != NULL);
+//
+//  ue_id = m2_ue_id;
+//  id_source = ue_id;
+//  id_target = m2ap_id_get_id_target(&instance_p->id_manager, ue_id);
+//
+//  /* Prepare the M2AP handover cancel message to encode */
+//  memset(&pdu, 0, sizeof(pdu));
+//  pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
+//  pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_handoverCancel;
+//  pdu.choice.initiatingMessage.criticality = M2AP_Criticality_ignore;
+//  pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_HandoverCancel;
+//  out = &pdu.choice.initiatingMessage.value.choice.HandoverCancel;
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_Old_eNB_UE_M2AP_ID;
+//  ie->criticality = M2AP_Criticality_reject;
+//  ie->value.present = M2AP_HandoverCancel_IEs__value_PR_UE_M2AP_ID;
+//  ie->value.choice.UE_M2AP_ID = id_source;
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  /* optional */
+//  if (id_target != -1) {
+//    ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t));
+//    ie->id = M2AP_ProtocolIE_ID_id_New_eNB_UE_M2AP_ID;
+//    ie->criticality = M2AP_Criticality_ignore;
+//    ie->value.present = M2AP_HandoverCancel_IEs__value_PR_UE_M2AP_ID_1;
+//    ie->value.choice.UE_M2AP_ID_1 = id_target;
+//    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//  }
+//
+//  /* mandatory */
+//  ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t));
+//  ie->id = M2AP_ProtocolIE_ID_id_Cause;
+//  ie->criticality = M2AP_Criticality_ignore;
+//  ie->value.present = M2AP_HandoverCancel_IEs__value_PR_Cause;
+//  switch (cause) {
+//  case M2AP_T_RELOC_PREP_TIMEOUT:
+//    ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork;
+//    ie->value.choice.Cause.choice.radioNetwork =
+//      M2AP_CauseRadioNetwork_trelocprep_expiry;
+//    break;
+//  case M2AP_TX2_RELOC_OVERALL_TIMEOUT:
+//    ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork;
+//    ie->value.choice.Cause.choice.radioNetwork =
+//      M2AP_CauseRadioNetwork_tx2relocoverall_expiry;
+//    break;
+//  default:
+//    /* we can't come here */
+//    M2AP_ERROR("unhandled cancel cause\n");
+//    exit(1);
+//  }
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+//  if (m2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
+//    M2AP_ERROR("Failed to encode X2 Handover Cancel\n");
+//    abort();
+//    return -1;
+//  }
+//
+//  MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 X2HandoverCancel/initiatingMessage assoc_id %u", m2ap_eNB_data_p->assoc_id);
+//
+//  m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 1);
+//
+//  return ret;
+//}
diff --git a/openair2/M2AP/m2ap_eNB_generate_messages.h b/openair2/M2AP/m2ap_eNB_generate_messages.h
new file mode 100644
index 0000000000..49247405f7
--- /dev/null
+++ b/openair2/M2AP/m2ap_eNB_generate_messages.h
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_eNB_generate_messages.h
+ * \brief m2ap procedures for eNB
+ * \author Javier Morgade <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#ifndef M2AP_ENB_GENERATE_MESSAGES_H_
+#define M2AP_ENB_GENERATE_MESSAGES_H_
+
+#include "m2ap_eNB_defs.h"
+#include "m2ap_common.h"
+
+//int m2ap_eNB_generate_m2_setup_request(m2ap_eNB_instance_t *instance_p,
+//				       m2ap_eNB_data_t *m2ap_eNB_data_p);
+//
+//int m2ap_MCE_generate_m2_setup_response(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p);
+//
+/*int m2ap_MCE_generate_m2_setup_failure(instance_t instance,
+                                       uint32_t assoc_id,
+                                       M2AP_Cause_PR cause_type,
+                                       long cause_value,
+                                       long time_to_wait);*/
+
+int m2ap_eNB_set_cause (M2AP_Cause_t * cause_p,
+                        M2AP_Cause_PR cause_type,
+                        long cause_value);
+
+//int m2ap_eNB_generate_m2_handover_request (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
+//                                           m2ap_handover_req_t *m2ap_handover_req, int ue_id);
+//
+//int m2ap_eNB_generate_m2_handover_request_ack (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
+//                                               m2ap_handover_req_ack_t *m2ap_handover_req_ack);
+//
+//int m2ap_eNB_generate_m2_ue_context_release (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
+//                                             m2ap_ue_context_release_t *m2ap_ue_context_release);
+//
+//int m2ap_eNB_generate_m2_handover_cancel (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
+//                                          int m2_ue_id,
+//                                          m2ap_handover_cancel_cause_t cause);
+
+#endif /*  M2AP_ENB_GENERATE_MESSAGES_H_ */
diff --git a/openair2/M2AP/m2ap_eNB_handler.c b/openair2/M2AP/m2ap_eNB_handler.c
new file mode 100644
index 0000000000..fe0059f0a5
--- /dev/null
+++ b/openair2/M2AP/m2ap_eNB_handler.c
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_eNB_handler.c
+ * \brief m2ap handler procedures for eNB
+ * \author Javier Morgade <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#include <stdint.h>
+
+#include "intertask_interface.h"
+
+#include "asn1_conversions.h"
+
+#include "m2ap_common.h"
+#include "m2ap_eNB_defs.h"
+#include "m2ap_eNB_handler.h"
+#include "m2ap_decoder.h"
+#include "m2ap_ids.h"
+
+#include "m2ap_eNB_management_procedures.h"
+#include "m2ap_eNB_generate_messages.h"
+
+//#include "m2ap_MCE_interface_management.h"
+#include "m2ap_eNB_interface_management.h"
+
+#include "msc.h"
+#include "assertions.h"
+#include "conversions.h"
+
+/* Handlers matrix. Only eNB related procedure present here */
+m2ap_eNB_message_decoded_callback m2ap_eNB_messages_callback[][3] = {
+  { eNB_handle_MBMS_SESSION_START_REQUEST, 0, 0 }, /* MBMSSessionStart  */
+  { eNB_handle_MBMS_SESSION_STOP_REQUEST, 0, 0 }, /* MBMSSessionStop */
+  { eNB_handle_MBMS_SCHEDULING_INFORMATION, 0, 0 }, /* MBMSSchedulingInformation */
+  { 0, 0, 0 }, /* Error Indication */
+  { 0, 0, 0 }, /* Reset */
+  { 0,eNB_handle_M2_SETUP_RESPONSE,eNB_handle_M2_SETUP_FAILURE }, /* M2 Setup */
+  { 0, 0, 0 }, /* eNBConfigurationUpdate */
+  { 0, 0, 0 }, /* MCEConfigurationUpdate */
+  { 0, 0, 0 }, /* privateMessage */
+  { 0, 0, 0 }, /* MBMSSessionUpdate */
+  { 0, 0, 0 }, /* MBMSServiceCounting */
+  { 0, 0, 0 }, /* MBMSServiceCountingResultReport */
+  { 0, 0, 0 } /* MBMSOverloadNotification */
+};
+
+static char *m2ap_direction2String(int m2ap_dir) {
+static char *m2ap_direction_String[] = {
+  "", /* Nothing */
+  "Originating message", /* originating message */
+  "Successfull outcome", /* successfull outcome */
+  "UnSuccessfull outcome", /* successfull outcome */
+};
+return(m2ap_direction_String[m2ap_dir]);
+}
+
+
+int m2ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
+                            const uint8_t * const data, const uint32_t data_length)
+{
+  M2AP_M2AP_PDU_t pdu;
+  int ret;
+
+  DevAssert(data != NULL);
+
+  memset(&pdu, 0, sizeof(pdu));
+
+  if (m2ap_decode_pdu(&pdu, data, data_length) < 0) {
+    LOG_E(M2AP, "Failed to decode PDU\n");
+    return -1;
+  }
+
+  /* Checking procedure Code and direction of message */
+  if (pdu.choice.initiatingMessage.procedureCode > sizeof(m2ap_eNB_messages_callback) / (3 * sizeof(
+        m2ap_message_decoded_callback))
+      || (pdu.present > M2AP_M2AP_PDU_PR_unsuccessfulOutcome)) {
+    LOG_E(M2AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n",
+               assoc_id, pdu.choice.initiatingMessage.procedureCode, pdu.present);
+    ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu);
+    return -1;
+  }
+
+  /* No handler present.
+   * This can mean not implemented or no procedure for eNB (wrong direction).
+   */
+  if (m2ap_eNB_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1] == NULL) {
+    LOG_E(M2AP, "[SCTP %d] No handler for procedureCode %ld in %s\n",
+                assoc_id, pdu.choice.initiatingMessage.procedureCode,
+               m2ap_direction2String(pdu.present - 1));
+    ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu);
+    return -1;
+  }
+  
+  /* Calling the right handler */
+  LOG_I(M2AP, "Calling handler with instance %d\n",instance);
+  ret = (*m2ap_eNB_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1])
+        (instance, assoc_id, stream, &pdu);
+  ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu);
+  return ret;
+}
+
+
diff --git a/openair2/M2AP/m2ap_eNB_handler.h b/openair2/M2AP/m2ap_eNB_handler.h
new file mode 100644
index 0000000000..ea4231a6e3
--- /dev/null
+++ b/openair2/M2AP/m2ap_eNB_handler.h
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_handler.h
+ * \brief m2ap handler procedures for eNB
+ * \author Javier Morgade <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#ifndef M2AP_ENB_HANDLERS_H_
+#define M2AP_ENB_HANDLERS_H_
+
+#include "m2ap_eNB_defs.h"
+
+//void m2ap_handle_m2_setup_message(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown);
+
+int m2ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
+                            const uint8_t * const data, const uint32_t data_length);
+
+//int m2ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
+                            //const uint8_t * const data, const uint32_t data_length);
+
+
+#endif /* M2AP_ENB_HANDLERS_H_ */
diff --git a/openair2/M2AP/m2ap_eNB_interface_management.c b/openair2/M2AP/m2ap_eNB_interface_management.c
new file mode 100644
index 0000000000..c2659da59d
--- /dev/null
+++ b/openair2/M2AP/m2ap_eNB_interface_management.c
@@ -0,0 +1,1385 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_MCE_interface_management.c
+ * \brief m2ap interface management for MCE
+ * \author Javier Morgade
+ * \date 2019
+ * \version 0.1
+ * \company Vicomtech, Spain
+ * \email: javier.morgade@ieee.org
+ * \note
+ * \warning
+ */
+
+#include "intertask_interface.h"
+
+#include "m2ap_common.h"
+#include "m2ap_eNB.h"
+#include "m2ap_eNB_generate_messages.h"
+#include "m2ap_encoder.h"
+#include "m2ap_decoder.h"
+#include "m2ap_ids.h"
+
+#include "m2ap_eNB_interface_management.h"
+
+
+#include "m2ap_itti_messaging.h"
+
+#include "msc.h"
+#include "assertions.h"
+#include "conversions.h"
+
+#include "M2AP_MBSFN-Area-Configuration-List.h" 
+
+//#include "m2ap_common.h"
+//#include "m2ap_encoder.h"
+//#include "m2ap_decoder.h"
+//#include "m2ap_itti_messaging.h"
+//#include "m2ap_eNB_interface_management.h"
+//#include "assertions.h"
+
+extern m2ap_setup_req_t *m2ap_enb_data_g;
+
+
+//extern m2ap_setup_req_t *m2ap_mce_data_from_enb;
+int eNB_handle_MBMS_SCHEDULING_INFORMATION(instance_t instance,
+                                        uint32_t assoc_id,
+                                        uint32_t stream,
+                                        M2AP_M2AP_PDU_t *pdu){
+  LOG_D(M2AP, "eNB_handle_MBMS_SCHEDULING_INFORMATION assoc_id %d\n",assoc_id);
+
+  MessageDef                         *message_p/*,*message_p2*/;
+  M2AP_MbmsSchedulingInformation_t *container;
+  M2AP_MbmsSchedulingInformation_Ies_t   *ie;
+  int i = 0;
+  int j = 0;
+  int k = 0;
+  //int m = 0;
+
+  DevAssert(pdu != NULL);
+
+  container = &pdu->choice.initiatingMessage.value.choice.MbmsSchedulingInformation;
+
+  /* M2 Setup Request == Non UE-related procedure -> stream 0 */
+  if (stream != 0) {
+    LOG_D(M2AP, "[SCTP %d] Received MMBS scheduling information on stream != 0 (%d)\n",
+              assoc_id, stream);
+  }
+
+  message_p  = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MBMS_SCHEDULING_INFORMATION);
+  //message_p2  = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MBMS_SCHEDULING_INFORMATION);
+
+
+
+
+
+  M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_MbmsSchedulingInformation_Ies_t, ie, container,M2AP_ProtocolIE_ID_id_MCCH_Update_Time ,true);
+  //printf("id %d\n",ie->id);
+
+  M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_MbmsSchedulingInformation_Ies_t, ie, container,M2AP_ProtocolIE_ID_id_MBSFN_Area_Configuration_List ,true);
+
+  if(ie){
+
+	  //printf("id %d\n",ie->id);
+	  //printf("MBSFN_Area_Configuration_List  %p\n",ie->value.choice.MBSFN_Area_Configuration_List.list.array);
+	  /*M2AP_MBSFN_Area_Configuration_Item_t  * kk  = &ie->value.choice.MBSFN_Area_Configuration_List.list.array[0];
+	  printf("M2AP_MBSFN_Area_Configuration_Item %p\n",kk);
+	  printf("M2AP_MBSFN_Area_Configuration_Item %d\n",kk->id);*/
+
+	  const asn_anonymous_sequence_ *list = _A_CSEQUENCE_FROM_VOID((void*)&ie->value.choice.MBSFN_Area_Configuration_List);
+	  if(list->count > 0 ){
+		M2AP_MBMS_SCHEDULING_INFORMATION(message_p).num_mbms_area_config_list = list->count;
+	  }
+	  for(i=0; i < list->count; i++ ){
+		  void * memb_ptr = list->array[i];
+		  //printf("%p %d\n", memb_ptr,list->count);
+		  const asn_anonymous_sequence_ *list1 = _A_CSEQUENCE_FROM_VOID((void*)memb_ptr);
+		  void * memb_ptr1 = list1->array[0];
+		  //printf("%p %d\n", memb_ptr1,list1->count);
+		  void * memb_ptr2 = list1->array[1];
+		  void * memb_ptr3 = list1->array[2];
+		  void * memb_ptr4 = list1->array[3];
+
+		  //printf("%lu\n", ((M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr1)->id);
+		  M2AP_MBSFN_Area_Configuration_Item_t * m2ap_mbsfn_area_configuration_item = (M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr1;
+		  //printf("count %d\n",m2ap_mbsfn_area_configuration_item->value.choice.PMCH_Configuration_List.list.count);
+		  if(m2ap_mbsfn_area_configuration_item->value.choice.PMCH_Configuration_List.list.count > 0){
+			M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].num_pmch_config_list = m2ap_mbsfn_area_configuration_item->value.choice.PMCH_Configuration_List.list.count;
+		  }
+		  for(j=0; j < m2ap_mbsfn_area_configuration_item->value.choice.PMCH_Configuration_List.list.count; j++){
+			  M2AP_PMCH_Configuration_Item_t * m2ap_pmchconfiguration_item =&(((M2AP_PMCH_Configuration_ItemIEs_t*)m2ap_mbsfn_area_configuration_item->value.choice.PMCH_Configuration_List.list.array[j])->value.choice.PMCH_Configuration_Item);
+			  M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].data_mcs = m2ap_pmchconfiguration_item->pmch_Configuration.dataMCS;
+			  M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].mch_scheduling_period = m2ap_pmchconfiguration_item->pmch_Configuration.mchSchedulingPeriod;
+			  M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].allocated_sf_end = m2ap_pmchconfiguration_item->pmch_Configuration.allocatedSubframesEnd;
+			  //printf("dataMCS %lu\n",m2ap_pmchconfiguration_item->pmch_Configuration.dataMCS);
+			  //printf("allocatedSubframesEnd %lu\n",m2ap_pmchconfiguration_item->pmch_Configuration.allocatedSubframesEnd);
+			  if(m2ap_pmchconfiguration_item->mbms_Session_List.list.count > 0){
+				M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].num_mbms_session_list = m2ap_pmchconfiguration_item->mbms_Session_List.list.count;
+			  }
+			  for(k=0; k < m2ap_pmchconfiguration_item->mbms_Session_List.list.count; k++){
+				//long mnc,mcc,mnc_length;
+				PLMNID_TO_MCC_MNC(&m2ap_pmchconfiguration_item->mbms_Session_List.list.array[k]->tmgi.pLMNidentity,
+				M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].mcc,
+				M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].mnc,
+				M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].mnc_length);
+				//char buf[4];
+				
+				//BUFFER_TO_INT32(buf,);
+				M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].service_id = ((m2ap_pmchconfiguration_item->mbms_Session_List.list.array[k]->tmgi.serviceID.buf[0]<<16) | (m2ap_pmchconfiguration_item->mbms_Session_List.list.array[k]->tmgi.serviceID.buf[1]<<8) | (m2ap_pmchconfiguration_item->mbms_Session_List.list.array[k]->tmgi.serviceID.buf[2])); //
+				M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].lcid = m2ap_pmchconfiguration_item->mbms_Session_List.list.array[k]->lcid; //*/
+				//LOG_E(M2AP,"buf[0]:%d buf[1]:%d buf[2]:%d\n",m2ap_pmchconfiguration_item->mbms_Session_List.list.array[k]->tmgi.serviceID.buf[0],m2ap_pmchconfiguration_item->mbms_Session_List.list.array[k]->tmgi.serviceID.buf[1],m2ap_pmchconfiguration_item->mbms_Session_List.list.array[k]->tmgi.serviceID.buf[2]);
+			  }
+		  }
+
+		  //printf("%lu\n", ((M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr2)->id);
+		  M2AP_MBSFN_Area_Configuration_Item_t * m2ap_mbsfn_area_configuration_item2 = (M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr2;
+		  //printf("count %d\n",m2ap_mbsfn_area_configuration_item2->value.choice.MBSFN_Subframe_ConfigurationList.list.count);
+		  if(m2ap_mbsfn_area_configuration_item2->value.choice.MBSFN_Subframe_ConfigurationList.list.count > 0){
+			M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].num_mbms_sf_config_list = m2ap_mbsfn_area_configuration_item2->value.choice.MBSFN_Subframe_ConfigurationList.list.count;
+		  }
+		  for(j=0; j < m2ap_mbsfn_area_configuration_item2->value.choice.MBSFN_Subframe_ConfigurationList.list.count; j++){
+			  M2AP_MBSFN_Subframe_Configuration_t * m2ap_mbsfn_sf_configuration = &(((M2AP_MBSFN_Subframe_ConfigurationItem_t*)m2ap_mbsfn_area_configuration_item2->value.choice.MBSFN_Subframe_ConfigurationList.list.array[j])->value.choice.MBSFN_Subframe_Configuration);
+			  //printf("radioframe_allocation_period %lu\n",m2ap_mbsfn_sf_configuration->radioframeAllocationPeriod);
+			  //printf("radioframe_allocation_offset %lu\n",m2ap_mbsfn_sf_configuration->radioframeAllocationOffset);
+			  M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_period = m2ap_mbsfn_sf_configuration->radioframeAllocationPeriod;
+			  M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_offset = m2ap_mbsfn_sf_configuration->radioframeAllocationOffset;
+			  if( m2ap_mbsfn_sf_configuration->subframeAllocation.present == M2AP_MBSFN_Subframe_Configuration__subframeAllocation_PR_fourFrames ) {
+				M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation = m2ap_mbsfn_sf_configuration->subframeAllocation.choice.oneFrame.buf[0] | (m2ap_mbsfn_sf_configuration->subframeAllocation.choice.oneFrame.buf[1]<<8) | (m2ap_mbsfn_sf_configuration->subframeAllocation.choice.oneFrame.buf[0]<<16);
+			  }else{
+				M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation = (m2ap_mbsfn_sf_configuration->subframeAllocation.choice.oneFrame.buf[0] >> 2) & 0x3F;
+			  }
+                  }
+		
+
+		  //printf("%lu\n", ((M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr3)->id);
+		  M2AP_MBSFN_Area_Configuration_Item_t * m2ap_mbsfn_area_configuration_item3 = (M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr3;
+		  //printf("count %d\n",m2ap_mbsfn_area_configuration_item2->value.choice.MBSFN_Subframe_ConfigurationList.list.count);
+		  //printf("Common_Subframe_Allocation_Period %lu\n",m2ap_mbsfn_area_configuration_item3->value.choice.Common_Subframe_Allocation_Period);
+		  M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].common_sf_allocation_period = m2ap_mbsfn_area_configuration_item3->value.choice.Common_Subframe_Allocation_Period;
+
+		  //printf("%lu\n", ((M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr4)->id);
+		  M2AP_MBSFN_Area_Configuration_Item_t * m2ap_mbsfn_area_configuration_item4 = (M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr4;
+		  //printf("MBMS_Area_ID %lu\n",m2ap_mbsfn_area_configuration_item4->value.choice.MBSFN_Area_ID);
+		  M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].mbms_area_id = m2ap_mbsfn_area_configuration_item4->value.choice.MBSFN_Area_ID;
+	  } 
+	
+
+	  //const asn_anonymous_sequence_ *list3 = _A_CSEQUENCE_FROM_VOID((void*)memb_ptr2);
+	  //void * memb_ptr3 = list3->array[0];
+	  //printf("%p\n", memb_ptr3);
+
+
+
+
+	  //xer_fprint(stdout, &asn_DEF_M2AP_MBSFN_Area_Configuration_List,  &ie->value.choice.MBSFN_Area_Configuration_List);
+	
+  }
+  //asn_DEF_M2AP_MBSFN_Area_Configuration_List
+ 
+  // void * sptr = (void*)&ie->value.choice.MBSFN_Area_Configuration_List;
+  // asn_TYPE_descriptor_t * td = &asn_DEF_M2AP_MBSFN_Area_Configuration_List;
+  // asn_enc_rval_t er;
+  // const asn_SET_OF_specifics_t *specs = (const asn_SET_OF_specifics_t *)td->specifics;
+  // const asn_TYPE_member_t *elm = td->elements;
+  // const asn_anonymous_sequence_ *list = _A_CSEQUENCE_FROM_VOID(sptr);
+  // const char *mname = specs->as_XMLValueList
+  //                          ? 0
+  //                          : ((*elm->name) ? elm->name : elm->type->xml_tag);
+  //  size_t mlen = mname ? strlen(mname) : 0;
+  //  //int xcan = (flags & XER_F_CANONICAL);
+  //  //int i;
+
+  //  if(!sptr) ASN__ENCODE_FAILED;
+
+  //  er.encoded = 0;
+
+  //  for(i = 0; i < list->count; i++) {
+  //      asn_enc_rval_t tmper;
+  //      void *memb_ptr = list->array[i];
+  //      if(!memb_ptr) continue;
+
+  //      if(mname) {
+  //          //if(!xcan) ASN__TEXT_INDENT(1, ilevel);
+  //          //ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);
+  //      }
+
+  //      tmper = elm->type->op->xer_encoder(elm->type, memb_ptr, ilevel + 1,
+  //                                         flags, cb, app_key);
+  //      if(tmper.encoded == -1) return tmper;
+  //      er.encoded += tmper.encoded;
+  //      if(tmper.encoded == 0 && specs->as_XMLValueList) {
+  //          const char *name = elm->type->xml_tag;
+  //          size_t len = strlen(name);
+  //          //if(!xcan) ASN__TEXT_INDENT(1, ilevel + 1);
+  //          //ASN__CALLBACK3("<", 1, name, len, "/>", 2);
+  //      }
+
+  //      if(mname) {
+  //          ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);
+  //      }
+  //  }
+
+
+  
+
+  
+
+  
+  //M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_MBSFN_Area_Configuration_Item_t, &ie->value.choice.MBSFN_Area_Configuration_List.list, container2,M2AP_ProtocolIE_ID_id_PMCH_Configuration_List ,true);
+
+  //printf("count %d\n",((M2AP_MBSFN_Area_Configuration_Item_t*)ie->value.choice.MBSFN_Area_Configuration_List.list.array[0])->value.choice.PMCH_Configuration_List.list.count);
+ 
+
+//  M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_M2SetupRequest_Ies_t, ie, container,
+//                             M2AP_ProtocolIE_ID_id_GlobalEND_ID, true);
+
+
+  //itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p2);
+  itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), message_p);
+
+//  if(1){
+//	printf("m2ap_enb_data_g->assoc_id %d %d\n",m2ap_enb_data_g->assoc_id,assoc_id);
+//	eNB_send_MBMS_SCHEDULING_INFORMATION_RESPONSE(instance,NULL);
+//  }else
+//	//eNB_send_MBMS_SESSION_START_FAILURE(instance,assoc_id);
+  return 0;
+  
+}
+int eNB_send_MBMS_SCHEDULING_INFORMATION_RESPONSE(instance_t instance, m2ap_mbms_scheduling_information_resp_t * m2ap_mbms_scheduling_information_resp){
+//	module_id_t mce_mod_idP;
+  //module_id_t enb_mod_idP;
+
+  // This should be fixed
+ // enb_mod_idP = (module_id_t)0;
+ // mce_mod_idP  = (module_id_t)0;
+
+  M2AP_M2AP_PDU_t           pdu;
+  //M2AP_MbmsSchedulingInformationResponse_t    *out;
+  //M2AP_MbmsSchedulingInformationResponse_Ies_t *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  //int       i = 0;
+
+  /* Create */
+  /* 0. Message Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome;
+  //pdu.choice.successfulOutcome = (M2AP_SuccessfulOutcome_t *)calloc(1, sizeof(M2AP_SuccessfulOutcome_t));
+  pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_mbmsSchedulingInformation;
+  pdu.choice.successfulOutcome.criticality   = M2AP_Criticality_reject;
+  pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_MbmsSchedulingInformationResponse;
+  //out = &pdu.choice.successfulOutcome.value.choice.MbmsSchedulingInformationResponse;
+  
+
+//  /* mandatory */
+//  /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long
+//  ie = (M2AP_MbmsSchedulingInformationResponse_Ies_t *)calloc(1, sizeof(M2AP_MbmsSchedulingInformationResponse_Ies_t));
+//  ie->id                        = M2AP_ProtocolIE_ID_id_MCE_MBMS_M2AP_ID;
+//  ie->criticality               = M2AP_Criticality_reject;
+//  ie->value.present             = M2AP_MbmsSchedulingInformationResponse_Ies__value_PR_MCE_MBMS_M2AP_ID;
+//  //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //?
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+// /* mandatory */
+//  /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long
+//  ie = (M2AP_SessionStartResponse_Ies_t *)calloc(1, sizeof(M2AP_SessionStartResponse_Ies_t));
+//  ie->id                        = M2AP_ProtocolIE_ID_id_ENB_MBMS_M2AP_ID;
+//  ie->criticality               = M2AP_Criticality_reject;
+//  ie->value.present             = M2AP_MbmsSchedulingInformationResponse_Ies__value_PR_ENB_MBMS_M2AP_ID;
+//  //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //?
+//  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+//
+
+  if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(M2AP, "Failed to encode M2 SessionStart Response\n");
+    return -1;
+  }
+
+
+  LOG_D(M2AP,"pdu.present %d\n",pdu.present);
+ // MSC_LOG_TX_MESSAGE(
+ // MSC_M2AP_eNB,
+ // MSC_M2AP_MCE,
+ // (const char *)buffer,
+ // len,
+ // MSC_AS_TIME_FMT" M2_SETUP_REQUEST initiatingMessage MCEname %s",
+ // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
+ // m2ap_eNB_data_p->ENBname);
+
+  m2ap_eNB_itti_send_sctp_data_req(instance, m2ap_enb_data_g->assoc_id, buffer, len, 0);
+  return 0;
+}
+
+
+
+
+int eNB_handle_MBMS_SESSION_START_REQUEST(instance_t instance,
+                                        uint32_t assoc_id,
+                                        uint32_t stream,
+                                        M2AP_M2AP_PDU_t *pdu){
+  LOG_D(M2AP, "eNB_handle_MBMS_SESSION_START_REQUEST assoc_id %d\n",assoc_id);
+
+  MessageDef                         *message_p;
+  //M2AP_SessionStartRequest_t              *container;
+  //M2AP_SessionStartRequest_Ies_t           *ie;
+  //int i = 0;
+
+  DevAssert(pdu != NULL);
+
+  //container = &pdu->choice.initiatingMessage.value.choice.SessionStartRequest;
+
+  /* M2 Setup Request == Non UE-related procedure -> stream 0 */
+  if (stream != 0) {
+    LOG_D(M2AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n",
+              assoc_id, stream);
+  }
+
+  message_p  = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MBMS_SESSION_START_REQ);
+
+
+  itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), message_p);
+
+
+//  if(1){
+//	eNB_send_MBMS_SESSION_START_RESPONSE(instance,NULL);
+//  }else
+//	eNB_send_MBMS_SESSION_START_FAILURE(instance,NULL);
+  return 0;
+  
+}
+
+int eNB_send_MBMS_SESSION_START_RESPONSE(instance_t instance, m2ap_session_start_resp_t * m2ap_session_start_resp){
+//	module_id_t mce_mod_idP;
+//  module_id_t enb_mod_idP;
+
+  // This should be fixed
+//  enb_mod_idP = (module_id_t)0;
+//  mce_mod_idP  = (module_id_t)0;
+
+  M2AP_M2AP_PDU_t           pdu;
+  M2AP_SessionStartResponse_t    *out;
+  M2AP_SessionStartResponse_Ies_t *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  //int       i = 0;
+
+  /* Create */
+  /* 0. Message Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome;
+  //pdu.choice.successfulOutcome = (M2AP_SuccessfulOutcome_t *)calloc(1, sizeof(M2AP_SuccessfulOutcome_t));
+  pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_sessionStart;
+  pdu.choice.successfulOutcome.criticality   = M2AP_Criticality_reject;
+  pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_SessionStartResponse;
+  out = &pdu.choice.successfulOutcome.value.choice.SessionStartResponse;
+  
+
+  /* mandatory */
+  /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long
+  ie = (M2AP_SessionStartResponse_Ies_t *)calloc(1, sizeof(M2AP_SessionStartResponse_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_MCE_MBMS_M2AP_ID;
+  ie->criticality               = M2AP_Criticality_reject;
+  ie->value.present             = M2AP_SessionStartResponse_Ies__value_PR_MCE_MBMS_M2AP_ID;
+  //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //?
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+ /* mandatory */
+  /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long
+  ie = (M2AP_SessionStartResponse_Ies_t *)calloc(1, sizeof(M2AP_SessionStartResponse_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_ENB_MBMS_M2AP_ID;
+  ie->criticality               = M2AP_Criticality_reject;
+  ie->value.present             = M2AP_SessionStartResponse_Ies__value_PR_ENB_MBMS_M2AP_ID;
+  //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //?
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+  if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(M2AP, "Failed to encode M2 SessionStart Response\n");
+    return -1;
+  }
+
+
+  LOG_D(M2AP,"pdu.present %d\n",pdu.present);
+ // MSC_LOG_TX_MESSAGE(
+ // MSC_M2AP_eNB,
+ // MSC_M2AP_MCE,
+ // (const char *)buffer,
+ // len,
+ // MSC_AS_TIME_FMT" M2_SETUP_REQUEST initiatingMessage MCEname %s",
+ // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
+ // m2ap_eNB_data_p->ENBname);
+
+  m2ap_eNB_itti_send_sctp_data_req(instance, m2ap_enb_data_g->assoc_id, buffer, len, 0);
+  return 0;
+}
+
+
+int eNB_send_MBMS_SESSION_START_FAILURE(instance_t instance, m2ap_session_start_failure_t * m2ap_session_start_failure){
+  //module_id_t enb_mod_idP;
+  //module_id_t mce_mod_idP;
+
+  // This should be fixed
+  //enb_mod_idP = (module_id_t)0;
+ // mce_mod_idP  = (module_id_t)0;
+
+  M2AP_M2AP_PDU_t           pdu;
+  M2AP_SessionStartFailure_t    *out;
+  M2AP_SessionStartFailure_Ies_t *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+
+  /* Create */
+  /* 0. Message Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = M2AP_M2AP_PDU_PR_unsuccessfulOutcome;
+  //pdu.choice.unsuccessfulOutcome = (M2AP_UnsuccessfulOutcome_t *)calloc(1, sizeof(M2AP_UnsuccessfulOutcome_t));
+  pdu.choice.unsuccessfulOutcome.procedureCode = M2AP_ProcedureCode_id_sessionStart;
+  pdu.choice.unsuccessfulOutcome.criticality   = M2AP_Criticality_reject;
+  pdu.choice.unsuccessfulOutcome.value.present = M2AP_UnsuccessfulOutcome__value_PR_SessionStartFailure;
+  out = &pdu.choice.unsuccessfulOutcome.value.choice.SessionStartFailure;
+
+  /* mandatory */
+  /* c1. Transaction ID (integer value)*/
+ // ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t));
+ // ie->id                        = M2AP_ProtocolIE_ID_id_GlobalENB_ID;
+ // ie->criticality               = M2AP_Criticality_reject;
+ // ie->value.present             = M2AP_M2SetupFailure_Ies__value_PR_GlobalENB_ID;
+ // ie->value.choice.GlobalENB_ID = M2AP_get_next_transaction_identifier(enb_mod_idP, mce_mod_idP);
+ // ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+ /* mandatory */
+  /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long
+  ie = (M2AP_SessionStartFailure_Ies_t *)calloc(1, sizeof(M2AP_SessionStartFailure_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_MCE_MBMS_M2AP_ID;
+  ie->criticality               = M2AP_Criticality_reject;
+  ie->value.present             = M2AP_SessionStartFailure_Ies__value_PR_MCE_MBMS_M2AP_ID;
+  //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //?
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+
+  /* mandatory */
+  /* c2. Cause */
+  ie = (M2AP_SessionStartFailure_Ies_t *)calloc(1, sizeof(M2AP_SessionStartFailure_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_Cause;
+  ie->criticality               = M2AP_Criticality_ignore;
+  ie->value.present             = M2AP_SessionStartFailure_Ies__value_PR_Cause;
+  ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork;
+  ie->value.choice.Cause.choice.radioNetwork = M2AP_CauseRadioNetwork_unspecified;
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+     /* encode */
+  if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(M2AP, "Failed to encode M2 setup request\n");
+    return -1;
+  }
+
+  //mce_m2ap_itti_send_sctp_data_req(instance, m2ap_mce_data_from_enb->assoc_id, buffer, len, 0);
+  m2ap_eNB_itti_send_sctp_data_req(instance,m2ap_enb_data_g->assoc_id,buffer,len,0);
+
+
+  return 0;
+}
+
+int eNB_handle_MBMS_SESSION_STOP_REQUEST(instance_t instance,
+                                        uint32_t assoc_id,
+                                        uint32_t stream,
+                                        M2AP_M2AP_PDU_t *pdu){
+  LOG_D(M2AP, "eNB_handle_MBMS_SESSION_STOP_REQUEST assoc_id %d\n",assoc_id);
+
+  MessageDef                         *message_p;
+  //M2AP_SessionStopRequest_t              *container;
+  //M2AP_SessionStopRequest_Ies_t           *ie;
+  //int i = 0;
+
+  DevAssert(pdu != NULL);
+
+  //container = &pdu->choice.initiatingMessage.value.choice.SessionStopRequest;
+
+  /* M2 Setup Request == Non UE-related procedure -> stream 0 */
+  if (stream != 0) {
+    LOG_D(M2AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n",
+              assoc_id, stream);
+  }
+
+  message_p  = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MBMS_SESSION_STOP_REQ);
+
+
+  itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p);
+
+
+
+
+//  if(1){
+//	eNB_send_MBMS_SESSION_STOP_RESPONSE(instance,NULL);
+//  }else
+//	eNB_send_MBMS_SESSION_STOP_FAILURE(instance,NULL);
+  return 0;
+  
+}
+int eNB_send_MBMS_SESSION_STOP_RESPONSE(instance_t instance, m2ap_session_stop_resp_t * m2ap_session_stop_resp){
+	//module_id_t mce_mod_idP;
+  //module_id_t enb_mod_idP;
+
+  // This should be fixed
+  //enb_mod_idP = (module_id_t)0;
+  //mce_mod_idP  = (module_id_t)0;
+
+  M2AP_M2AP_PDU_t           pdu;
+  M2AP_SessionStopResponse_t    *out;
+  M2AP_SessionStopResponse_Ies_t *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  //int       i = 0;
+
+  /* Create */
+  /* 0. Message Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome;
+  //pdu.choice.successfulOutcome = (M2AP_SuccessfulOutcome_t *)calloc(1, sizeof(M2AP_SuccessfulOutcome_t));
+  pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_sessionStop;
+  pdu.choice.successfulOutcome.criticality   = M2AP_Criticality_reject;
+  pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_SessionStopResponse;
+  out = &pdu.choice.successfulOutcome.value.choice.SessionStopResponse;
+  
+
+  /* mandatory */
+  /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long
+  ie = (M2AP_SessionStopResponse_Ies_t *)calloc(1, sizeof(M2AP_SessionStopResponse_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_MCE_MBMS_M2AP_ID;
+  ie->criticality               = M2AP_Criticality_reject;
+  ie->value.present             = M2AP_SessionStopResponse_Ies__value_PR_MCE_MBMS_M2AP_ID;
+  //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //?
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+ /* mandatory */
+  /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long
+  ie = (M2AP_SessionStopResponse_Ies_t *)calloc(1, sizeof(M2AP_SessionStopResponse_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_ENB_MBMS_M2AP_ID;
+  ie->criticality               = M2AP_Criticality_reject;
+  ie->value.present             = M2AP_SessionStopResponse_Ies__value_PR_ENB_MBMS_M2AP_ID;
+  //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //?
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+  if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(M2AP, "Failed to encode M2 SessionStop Response\n");
+    return -1;
+  }
+
+
+  LOG_D(M2AP,"pdu.present %d\n",pdu.present);
+ // MSC_LOG_TX_MESSAGE(
+ // MSC_M2AP_eNB,
+ // MSC_M2AP_MCE,
+ // (const char *)buffer,
+ // len,
+ // MSC_AS_TIME_FMT" M2_SETUP_REQUEST initiatingMessage MCEname %s",
+ // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
+ // m2ap_eNB_data_p->ENBname);
+
+  m2ap_eNB_itti_send_sctp_data_req(instance, m2ap_enb_data_g->assoc_id, buffer, len, 0);
+  return 0;
+}
+
+ uint8_t bytes [] = {0x00, 0x05, /* .....+.. */
+0x00, 0x24, 0x00, 0x00, 0x02, 0x00, 0x0d, 0x00, /* .$...... */
+0x08, 0x00, 0x02, 0xf8, 0x39, 0x00, 0x00, 0xe0, /* ....9... */
+0x00, 0x00, 0x0f, 0x00, 0x11, 0x00, 0x00, 0x10, /* ........ */
+0x00, 0x0c, 0x00, 0x02, 0xf8, 0x39, 0x00, 0xe0, /* .....9.. */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ 
+
+/*
+    M2 Setup
+*/
+
+// SETUP REQUEST
+int eNB_send_M2_SETUP_REQUEST(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t* m2ap_eNB_data_p) {
+ // module_id_t enb_mod_idP=0;
+ // module_id_t du_mod_idP=0;
+
+  M2AP_M2AP_PDU_t          pdu;
+  M2AP_M2SetupRequest_t    *out;
+  M2AP_M2SetupRequest_Ies_t *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  int       i = 0;
+  int       j = 0;
+
+  /* Create */
+  /* 0. pdu Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
+  //pdu.choice.initiatingMessage = (M2AP_InitiatingMessage_t *)calloc(1, sizeof(M2AP_InitiatingMessage_t));
+  pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_m2Setup;
+  pdu.choice.initiatingMessage.criticality   = M2AP_Criticality_reject;
+  pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_M2SetupRequest;
+  out = &pdu.choice.initiatingMessage.value.choice.M2SetupRequest;
+
+  /* mandatory */
+  /* c1. GlobalENB_ID (integer value) */
+  ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_GlobalENB_ID;
+  ie->criticality               = M2AP_Criticality_reject;
+  ie->value.present             = M2AP_M2SetupRequest_Ies__value_PR_GlobalENB_ID;
+  //ie->value.choice.GlobalENB_ID.eNB_ID = 1;//M2AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);
+  MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+                  &ie->value.choice.GlobalENB_ID.pLMN_Identity);
+  ie->value.choice.GlobalENB_ID.eNB_ID.present = M2AP_ENB_ID_PR_macro_eNB_ID;
+  MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id,
+                           &ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID);
+  M2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id,
+          ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0],
+          ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1],
+          ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]);
+
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  ///* mandatory */
+  ///* c2. GNB_eNB_ID (integrer value) */
+  //ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
+  //ie->id                        = M2AP_ProtocolIE_ID_id_gNB_eNB_ID;
+  //ie->criticality               = M2AP_Criticality_reject;
+  //ie->value.present             = M2AP_M2SetupRequestIEs__value_PR_GNB_eNB_ID;
+  //asn_int642INTEGER(&ie->value.choice.GNB_eNB_ID, f1ap_du_data->gNB_eNB_id);
+  //ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+     /* optional */
+  /* c3. ENBname */
+  if (m2ap_eNB_data_p->eNB_name != NULL) {
+    ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
+    ie->id                        = M2AP_ProtocolIE_ID_id_ENBname;
+    ie->criticality               = M2AP_Criticality_ignore;
+    ie->value.present             = M2AP_M2SetupRequest_Ies__value_PR_ENBname;
+    OCTET_STRING_fromBuf(&ie->value.choice.ENBname, m2ap_eNB_data_p->eNB_name,
+                         strlen(m2ap_eNB_data_p->eNB_name));
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* mandatory */
+  /* c4. serverd cells list */
+  ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_ENB_MBMS_Configuration_data_List;
+  ie->criticality               = M2AP_Criticality_reject;
+  ie->value.present             = M2AP_M2SetupRequest_Ies__value_PR_ENB_MBMS_Configuration_data_List;
+
+  int num_mbms_available = instance_p->num_mbms_configuration_data_list;
+  LOG_D(M2AP, "num_mbms_available = %d \n", num_mbms_available);
+
+ for (i=0;
+       i<num_mbms_available;
+       i++) {
+        /* mandatory */
+        /* 4.1 serverd cells item */
+
+        M2AP_ENB_MBMS_Configuration_data_ItemIEs_t *mbms_configuration_data_list_item_ies;
+        mbms_configuration_data_list_item_ies = (M2AP_ENB_MBMS_Configuration_data_ItemIEs_t *)calloc(1, sizeof(M2AP_ENB_MBMS_Configuration_data_ItemIEs_t));
+        mbms_configuration_data_list_item_ies->id = M2AP_ProtocolIE_ID_id_ENB_MBMS_Configuration_data_Item;
+        mbms_configuration_data_list_item_ies->criticality = M2AP_Criticality_reject;
+        mbms_configuration_data_list_item_ies->value.present = M2AP_ENB_MBMS_Configuration_data_ItemIEs__value_PR_ENB_MBMS_Configuration_data_Item;
+
+        M2AP_ENB_MBMS_Configuration_data_Item_t *mbms_configuration_data_item;
+        mbms_configuration_data_item = &mbms_configuration_data_list_item_ies->value.choice.ENB_MBMS_Configuration_data_Item;
+        {
+		/* M2AP_ECGI_t eCGI */
+                MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
+                  &mbms_configuration_data_item->eCGI.pLMN_Identity);
+                MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,0,
+                                   &mbms_configuration_data_item->eCGI.eUTRANcellIdentifier);
+		/* M2AP_MBSFN_SynchronisationArea_ID_t mbsfnSynchronisationArea */ 
+		mbms_configuration_data_item->mbsfnSynchronisationArea=instance_p->mbms_configuration_data_list[i].mbsfn_sync_area; //? long
+		/* M2AP_MBMS_Service_Area_ID_List_t mbmsServiceAreaList */
+		for(j=0;j<instance_p->mbms_configuration_data_list[i].num_mbms_service_area_list;j++){
+			M2AP_MBMS_Service_Area_t * mbms_service_area = (M2AP_MBMS_Service_Area_t*)calloc(1,sizeof(M2AP_MBMS_Service_Area_t));
+			
+			char buf[2];
+			INT16_TO_BUFFER(instance_p->mbms_configuration_data_list[i].mbms_service_area_list[j],buf);
+			OCTET_STRING_fromBuf(mbms_service_area,buf,2);
+			//LOG_D(M2AP,"%s\n",instance_p->mbms_configuration_data_list[i].mbms_service_area_list[j]);
+			//OCTET_STRING_fromBuf(mbms_service_area,"03",2);
+                	ASN_SEQUENCE_ADD(&mbms_configuration_data_item->mbmsServiceAreaList.list,mbms_service_area);
+		}
+                /*M2AP_MBMS_Service_Area_t * mbms_service_area,*mbms_service_area2;
+                mbms_service_area = (M2AP_MBMS_Service_Area_t*)calloc(1,sizeof(M2AP_MBMS_Service_Area_t));
+                mbms_service_area2 = (M2AP_MBMS_Service_Area_t*)calloc(1,sizeof(M2AP_MBMS_Service_Area_t));
+		//memset(mbms_service_area,0,sizeof(OCTET_STRING_t));
+		OCTET_STRING_fromBuf(mbms_service_area,"01",2);
+                ASN_SEQUENCE_ADD(&mbms_configuration_data_item->mbmsServiceAreaList.list,mbms_service_area);
+		OCTET_STRING_fromBuf(mbms_service_area2,"02",2);
+                ASN_SEQUENCE_ADD(&mbms_configuration_data_item->mbmsServiceAreaList.list,mbms_service_area2);*/
+
+
+        }
+
+
+        //M2AP_ENB_MBMS_Configuration_data_Item_t mbms_configuration_data_item;
+        //memset((void *)&mbms_configuration_data_item, 0, sizeof(M2AP_ENB_MBMS_Configuration_data_Item_t));
+
+        //M2AP_ECGI_t      eCGI;
+                //M2AP_PLMN_Identity_t     pLMN_Identity;
+                //M2AP_EUTRANCellIdentifier_t      eUTRANcellIdentifier
+        //M2AP_MBSFN_SynchronisationArea_ID_t      mbsfnSynchronisationArea;
+        //M2AP_MBMS_Service_Area_ID_List_t         mbmsServiceAreaList;
+
+
+        ASN_SEQUENCE_ADD(&ie->value.choice.ENB_MBMS_Configuration_data_List.list,mbms_configuration_data_list_item_ies);
+
+ }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  
+ LOG_D(M2AP,"m2ap_eNB_data_p->assoc_id %d\n",m2ap_eNB_data_p->assoc_id);
+  /* encode */
+ if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+   LOG_E(M2AP, "Failed to encode M2 setup request\n");
+   return -1;
+ }
+
+
+  LOG_D(M2AP,"pdu.present %d\n",pdu.present);
+ // MSC_LOG_TX_MESSAGE(
+ // MSC_M2AP_eNB,
+ // MSC_M2AP_MCE,
+ // (const char *)buffer,
+ // len,
+ // MSC_AS_TIME_FMT" M2_SETUP_REQUEST initiatingMessage MCEname %s",
+ // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
+ // m2ap_eNB_data_p->ENBname);
+
+
+//  buffer = &bytes[0];
+//  len = 40;
+//
+//  for(int i=0; i < len; i++ )
+//	printf("%02X",buffer[i]);
+//  printf("\n");
+//
+  m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 0);
+
+  return 0;
+}
+
+
+int eNB_handle_M2_SETUP_RESPONSE(instance_t instance,
+				uint32_t               assoc_id,
+				uint32_t               stream,
+				M2AP_M2AP_PDU_t       *pdu)
+{
+
+   LOG_D(M2AP, "eNB_handle_M2_SETUP_RESPONSE\n");
+
+   AssertFatal(pdu->present == M2AP_M2AP_PDU_PR_successfulOutcome,
+	       "pdu->present != M2AP_M2AP_PDU_PR_successfulOutcome\n");
+   AssertFatal(pdu->choice.successfulOutcome.procedureCode  == M2AP_ProcedureCode_id_m2Setup,
+	       "pdu->choice.successfulOutcome.procedureCode != M2AP_ProcedureCode_id_M2Setup\n");
+   AssertFatal(pdu->choice.successfulOutcome.criticality  == M2AP_Criticality_reject,
+	       "pdu->choice.successfulOutcome.criticality != M2AP_Criticality_reject\n");
+   AssertFatal(pdu->choice.successfulOutcome.value.present  == M2AP_SuccessfulOutcome__value_PR_M2SetupResponse,
+	       "pdu->choice.successfulOutcome.value.present != M2AP_SuccessfulOutcome__value_PR_M2SetupResponse\n");
+
+   M2AP_M2SetupResponse_t    *in = &pdu->choice.successfulOutcome.value.choice.M2SetupResponse;
+
+
+   M2AP_M2SetupResponse_Ies_t *ie;
+   //int GlobalMCE_ID = -1;
+   int num_cells_to_activate = 0;
+   //M2AP_Cells_to_be_Activated_List_Item_t *cell;
+   int i,j;
+
+   MessageDef *msg_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_SETUP_RESP);
+   //MessageDef *msg_p2 = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_SETUP_RESP);
+
+   LOG_D(M2AP, "M2AP: M2Setup-Resp: protocolIEs.list.count %d\n",
+         in->protocolIEs.list.count);
+   for (j=0;j < in->protocolIEs.list.count; j++) {
+     ie = in->protocolIEs.list.array[j];
+     switch (ie->id) {
+     case M2AP_ProtocolIE_ID_id_GlobalMCE_ID:
+       AssertFatal(ie->criticality == M2AP_Criticality_reject,
+		   "ie->criticality != M2AP_Criticality_reject\n");
+       AssertFatal(ie->value.present == M2AP_M2SetupResponse_Ies__value_PR_GlobalMCE_ID,
+		   "ie->value.present != M2AP_M2SetupResponse_Ies__value_PR_GlobalMCE_ID\n");
+       LOG_D(M2AP, "M2AP: M2Setup-Resp: GlobalMCE_ID \n");/*,
+             GlobalMCE_ID);*/
+       /*PLMNID_TO_MCC_MNC(&m2ap_pmchconfiguration_item->mbms_Session_List.list.array[k]->tmgi.pLMNidentity,
+				&M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].mcc,
+				&M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].mnc,
+				&M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].mnc_length);*/
+
+       
+       break;
+     case M2AP_ProtocolIE_ID_id_MCEname:
+       AssertFatal(ie->criticality == M2AP_Criticality_ignore,
+		   "ie->criticality != M2AP_Criticality_ignore\n");
+       AssertFatal(ie->value.present == M2AP_M2SetupResponse_Ies__value_PR_MCEname,
+		   "ie->value.present != M2AP_M2SetupResponse_Ies__value_PR_MCEname\n");
+       //M2AP_SETUP_RESP (msg_p).MCE_name = malloc(ie->value.choice.size+1);
+       //memcpy(M2AP_SETUP_RESP (msg_p).gNB_CU_name,ie->value.choice.GNB_CU_Name.buf,ie->value.choice.GNB_CU_Name.size);
+       //M2AP_SETUP_RESP (msg_p).gNB_CU_name[ie->value.choice.GNB_CU_Name.size]='\0';
+       //LOG_D(M2AP, "M2AP: M2Setup-Resp: gNB_CU_name %s\n",
+             //M2AP_SETUP_RESP (msg_p).gNB_CU_name);
+       break;
+     case M2AP_ProtocolIE_ID_id_MCCHrelatedBCCH_ConfigPerMBSFNArea:
+       AssertFatal(ie->criticality == M2AP_Criticality_reject,
+		   "ie->criticality != M2AP_Criticality_reject\n");
+       AssertFatal(ie->value.present == M2AP_M2SetupResponse_Ies__value_PR_MCCHrelatedBCCH_ConfigPerMBSFNArea,
+		   "ie->value.present != M2AP_M2SetupResponse_Ies__value_PR_MCCHrelatedBCCH_ConfigPerMBSFNArea\n");
+       num_cells_to_activate = ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea.list.count;
+       if(ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea.list.count > 0 ){
+        	M2AP_SETUP_RESP(msg_p).num_mcch_config_per_mbsfn = ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea.list.count;
+       }
+       //LOG_D(M2AP, "M2AP: Activating %d cells\n",num_cells_to_activate);
+       for (i=0;i<num_cells_to_activate;i++) {
+	M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_ItemIEs_t * mcch_related_bcch_config_per_mbms_area_ies = (M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_ItemIEs_t*) ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea.list.array[i];
+	AssertFatal(mcch_related_bcch_config_per_mbms_area_ies->id == M2AP_ProtocolIE_ID_id_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item, 
+			" mcch_related_bcch_config_per_mbms_area_ies->id != M2AP_ProtocolIE_ID_id_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item ");
+	M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item_t * config_per_mbsfn_area_item = &mcch_related_bcch_config_per_mbms_area_ies->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea_Item;
+	M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[i].pdcch_length = (uint8_t)config_per_mbsfn_area_item->pdcchLength; 
+	M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[i].offset 	     = (uint8_t)config_per_mbsfn_area_item->offset;
+	M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[i].modification_period = (uint8_t)config_per_mbsfn_area_item->modificationPeriod;
+	M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[i].mcs 	     = (uint8_t)config_per_mbsfn_area_item->modulationAndCodingScheme;
+	M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[i].repetition_period  = (uint8_t)config_per_mbsfn_area_item->repetitionPeriod;
+
+	//LOG_E(M2AP,"mcs %lu\n",config_per_mbsfn_area_item->modulationAndCodingScheme);
+	//LOG_E(M2AP,"pdcch_length %lu\n",config_per_mbsfn_area_item->pdcchLength);
+	//LOG_E(M2AP,"modification_period %lu\n",config_per_mbsfn_area_item->modificationPeriod);
+	//LOG_E(M2AP,"repetition_period %lu\n",config_per_mbsfn_area_item->repetitionPeriod);
+	//LOG_E(M2AP,"offset %lu\n",config_per_mbsfn_area_item->offset);
+	//LOG_E(M2AP,"subframe_allocation_info %lu\n", config_per_mbsfn_area_item->subframeAllocationInfo.size);
+	
+
+	if(config_per_mbsfn_area_item->subframeAllocationInfo.size == 1){
+		M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[i].subframe_allocation_info = config_per_mbsfn_area_item->subframeAllocationInfo.buf[0]>>2;
+		LOG_D(M2AP,"subframe_allocation_info %d\n", config_per_mbsfn_area_item->subframeAllocationInfo.buf[0]);
+	}		
+       }
+       break;
+     }
+   }
+   //AssertFatal(GlobalMCE_ID!=-1,"GlobalMCE_ID was not sent\n");
+   //AssertFatal(num_cells_to_activate>0,"No cells activated\n");
+   //M2AP_SETUP_RESP (msg_p).num_cells_to_activate = num_cells_to_activate;
+
+   //for (int i=0;i<num_cells_to_activate;i++)  
+   //  AssertFatal(M2AP_SETUP_RESP (msg_p).num_SI[i] > 0, "System Information %d is missing",i);
+
+   //MSC_LOG_RX_MESSAGE(
+   // MSC_M2AP_eNB,
+   // MSC_M2AP_CU,
+   // 0,
+   // 0,
+   // MSC_AS_TIME_FMT" eNB_handle_M2_SETUP_RESPONSE successfulOutcome assoc_id %d",
+   // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
+   // assoc_id);
+ 
+   //LOG_D(M2AP, "Sending M2AP_SETUP_RESP ITTI message to ENB_APP with assoc_id (%d->%d)\n",
+   //      assoc_id,ENB_MOeNBLE_ID_TO_INSTANCE(assoc_id));
+   //itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p2);
+   itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p);
+
+   return 0;
+}
+
+// SETUP FAILURE
+int eNB_handle_M2_SETUP_FAILURE(instance_t instance,
+                               uint32_t assoc_id,
+                               uint32_t stream,
+                               M2AP_M2AP_PDU_t *pdu) {
+  LOG_D(M2AP, "eNB_handle_M2_SETUP_FAILURE\n");
+
+  M2AP_M2SetupFailure_t    *in = &pdu->choice.unsuccessfulOutcome.value.choice.M2SetupFailure;
+
+
+   M2AP_M2SetupFailure_Ies_t *ie;
+
+
+  MessageDef *msg_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_SETUP_FAILURE);
+
+   LOG_D(M2AP, "M2AP: M2Setup-Failure: protocolIEs.list.count %d\n",
+         in->protocolIEs.list.count);
+   for (int i=0;i < in->protocolIEs.list.count; i++) {
+     ie = in->protocolIEs.list.array[i];
+     switch (ie->id) {
+     case M2AP_ProtocolIE_ID_id_TimeToWait:
+       AssertFatal(ie->criticality == M2AP_Criticality_ignore,
+		   "ie->criticality != M2AP_Criticality_ignore\n");
+       AssertFatal(ie->value.present == M2AP_M2SetupFailure_Ies__value_PR_TimeToWait,
+		   "ie->value.present != M2AP_M2SetupFailure_Ies__value_PR_TimeToWait\n");
+       LOG_D(M2AP, "M2AP: M2Setup-Failure: TimeToWait \n");/*,
+             GlobalMCE_ID);*/
+       break;
+     }
+   }
+   //AssertFatal(GlobalMCE_ID!=-1,"GlobalMCE_ID was not sent\n");
+   //AssertFatal(num_cells_to_activate>0,"No cells activated\n");
+   //M2AP_SETUP_RESP (msg_p).num_cells_to_activate = num_cells_to_activate;
+
+   //for (int i=0;i<num_cells_to_activate;i++)  
+   //  AssertFatal(M2AP_SETUP_RESP (msg_p).num_SI[i] > 0, "System Information %d is missing",i);
+
+   //MSC_LOG_RX_MESSAGE(
+   // MSC_M2AP_eNB,
+   // MSC_M2AP_CU,
+   // 0,
+   // 0,
+   // MSC_AS_TIME_FMT" eNB_handle_M2_SETUP_RESPONSE successfulOutcome assoc_id %d",
+   // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
+   // assoc_id);
+ 
+   //LOG_D(M2AP, "Sending M2AP_SETUP_RESP ITTI message to ENB_APP with assoc_id (%d->%d)\n",
+   //      assoc_id,ENB_MOeNBLE_ID_TO_INSTANCE(assoc_id));
+
+   itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p);
+  
+  return 0;
+}
+
+/*
+ * eNB Configuration Update
+ */
+int eNB_send_eNB_CONFIGURATION_UPDATE(instance_t instance, m2ap_enb_configuration_update_t * m2ap_enb_configuration_update) 
+{
+
+  AssertFatal(1==0,"Not implemented yet\n");
+
+  M2AP_M2AP_PDU_t          pdu;
+  M2AP_ENBConfigurationUpdate_t    *out;
+  M2AP_ENBConfigurationUpdate_Ies_t *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  int       i = 0;
+  //int       j = 0;
+
+  /* Create */
+  /* 0. pdu Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
+  //pdu.choice.initiatingMessage = (M2AP_InitiatingMessage_t *)calloc(1, sizeof(M2AP_InitiatingMessage_t));
+  pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_eNBConfigurationUpdate;
+  pdu.choice.initiatingMessage.criticality   = M2AP_Criticality_reject;
+  pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_ENBConfigurationUpdate;
+  out = &pdu.choice.initiatingMessage.value.choice.ENBConfigurationUpdate;
+
+  /* mandatory */
+  /* c1. GlobalENB_ID (integer value) */
+  ie = (M2AP_ENBConfigurationUpdate_Ies_t *)calloc(1, sizeof(M2AP_ENBConfigurationUpdate_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_GlobalENB_ID;
+  ie->criticality               = M2AP_Criticality_reject;
+  ie->value.present             = M2AP_ENBConfigurationUpdate_Ies__value_PR_GlobalENB_ID;
+  //ie->value.choice.GlobalENB_ID.eNB_ID = 1;//M2AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);
+  MCC_MNC_TO_PLMNID(0, 0, 3,
+                  &ie->value.choice.GlobalENB_ID.pLMN_Identity);
+  ie->value.choice.GlobalENB_ID.eNB_ID.present = M2AP_ENB_ID_PR_macro_eNB_ID;
+  MACRO_ENB_ID_TO_BIT_STRING(10,
+                           &ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID);
+  M2AP_INFO("%d -> %02x%02x%02x\n", 10,
+          ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0],
+          ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1],
+          ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]);
+
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* optional */
+  /* c3. ENBname */
+  if (0) {
+    ie = (M2AP_ENBConfigurationUpdate_Ies_t *)calloc(1, sizeof(M2AP_ENBConfigurationUpdate_Ies_t));
+    ie->id                        = M2AP_ProtocolIE_ID_id_ENBname;
+    ie->criticality               = M2AP_Criticality_ignore;
+    ie->value.present             = M2AP_ENBConfigurationUpdate_Ies__value_PR_ENBname;
+    //OCTET_STRING_fromBuf(&ie->value.choice.ENBname, m2ap_eNB_data_p->eNB_name,
+                         //strlen(m2ap_eNB_data_p->eNB_name));
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* mandatory */
+  /* c4. serverd cells list */
+  ie = (M2AP_ENBConfigurationUpdate_Ies_t *)calloc(1, sizeof(M2AP_ENBConfigurationUpdate_Ies_t));
+  ie->id                        = M2AP_ProtocolIE_ID_id_ENB_MBMS_Configuration_data_List_ConfigUpdate;
+  ie->criticality               = M2AP_Criticality_reject;
+  ie->value.present             = M2AP_ENBConfigurationUpdate_Ies__value_PR_ENB_MBMS_Configuration_data_List_ConfigUpdate;
+
+  int num_mbms_available = 1;//m2ap_du_data->num_mbms_available;
+  LOG_D(M2AP, "num_mbms_available = %d \n", num_mbms_available);
+
+ for (i=0;
+       i<num_mbms_available;
+       i++) {
+        /* mandatory */
+        /* 4.1 serverd cells item */
+
+        M2AP_ENB_MBMS_Configuration_data_ItemIEs_t *mbms_configuration_data_list_item_ies;
+        mbms_configuration_data_list_item_ies = (M2AP_ENB_MBMS_Configuration_data_ItemIEs_t *)calloc(1, sizeof(M2AP_ENB_MBMS_Configuration_data_ItemIEs_t));
+        mbms_configuration_data_list_item_ies->id = M2AP_ProtocolIE_ID_id_ENB_MBMS_Configuration_data_Item;
+        mbms_configuration_data_list_item_ies->criticality = M2AP_Criticality_reject;
+        mbms_configuration_data_list_item_ies->value.present = M2AP_ENB_MBMS_Configuration_data_ItemIEs__value_PR_ENB_MBMS_Configuration_data_Item;
+
+        M2AP_ENB_MBMS_Configuration_data_Item_t *mbms_configuration_data_item;
+        mbms_configuration_data_item = &mbms_configuration_data_list_item_ies->value.choice.ENB_MBMS_Configuration_data_Item;
+        {
+		/* M2AP_ECGI_t eCGI */
+                MCC_MNC_TO_PLMNID(0, 0, 3,
+                  &mbms_configuration_data_item->eCGI.pLMN_Identity);
+                MACRO_ENB_ID_TO_CELL_IDENTITY(10,0,
+                                   &mbms_configuration_data_item->eCGI.eUTRANcellIdentifier);
+		/* M2AP_MBSFN_SynchronisationArea_ID_t mbsfnSynchronisationArea */ 
+		mbms_configuration_data_item->mbsfnSynchronisationArea=10000; //? long
+		/* M2AP_MBMS_Service_Area_ID_List_t mbmsServiceAreaList */
+                M2AP_MBMS_Service_Area_t * mbms_service_area,*mbms_service_area2;
+                mbms_service_area = (M2AP_MBMS_Service_Area_t*)calloc(1,sizeof(M2AP_MBMS_Service_Area_t));
+                mbms_service_area2 = (M2AP_MBMS_Service_Area_t*)calloc(1,sizeof(M2AP_MBMS_Service_Area_t));
+		//memset(mbms_service_area,0,sizeof(OCTET_STRING_t));
+		OCTET_STRING_fromBuf(mbms_service_area,"01",2);
+                ASN_SEQUENCE_ADD(&mbms_configuration_data_item->mbmsServiceAreaList.list,mbms_service_area);
+		OCTET_STRING_fromBuf(mbms_service_area2,"02",2);
+                ASN_SEQUENCE_ADD(&mbms_configuration_data_item->mbmsServiceAreaList.list,mbms_service_area2);
+
+
+        }
+
+
+        //M2AP_ENB_MBMS_Configuration_data_Item_t mbms_configuration_data_item;
+        //memset((void *)&mbms_configuration_data_item, 0, sizeof(M2AP_ENB_MBMS_Configuration_data_Item_t));
+
+        //M2AP_ECGI_t      eCGI;
+                //M2AP_PLMN_Identity_t     pLMN_Identity;
+                //M2AP_EUTRANCellIdentifier_t      eUTRANcellIdentifier
+        //M2AP_MBSFN_SynchronisationArea_ID_t      mbsfnSynchronisationArea;
+        //M2AP_MBMS_Service_Area_ID_List_t         mbmsServiceAreaList;
+
+
+        ASN_SEQUENCE_ADD(&ie->value.choice.ENB_MBMS_Configuration_data_List_ConfigUpdate.list,mbms_configuration_data_list_item_ies);
+
+ }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  
+ //LOG_D(M2AP,"m2ap_eNB_data_p->assoc_id %d\n",m2ap_eNB_data_p->assoc_id);
+  /* encode */
+ if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+   LOG_E(M2AP, "Failed to encode M2 setup request\n");
+   return -1;
+ }
+
+
+  LOG_D(M2AP,"pdu.present %d\n",pdu.present);
+ // MSC_LOG_TX_MESSAGE(
+ // MSC_M2AP_eNB,
+ // MSC_M2AP_MCE,
+ // (const char *)buffer,
+ // len,
+ // MSC_AS_TIME_FMT" M2_SETUP_REQUEST initiatingMessage MCEname %s",
+ // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
+ // m2ap_eNB_data_p->ENBname);
+
+
+//  buffer = &bytes[0];
+//  len = 40;
+//
+//  for(int i=0; i < len; i++ )
+//	printf("%02X",buffer[i]);
+//  printf("\n");
+//
+  m2ap_eNB_itti_send_sctp_data_req(instance, m2ap_enb_data_g->assoc_id, buffer, len, 0);
+
+   return 0;
+}
+
+int eNB_handle_eNB_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
+                                         uint32_t assoc_id,
+                                         uint32_t stream,
+                                         M2AP_M2AP_PDU_t *pdu)
+{
+
+  AssertFatal(1==0,"Not implemented yet\n");
+  LOG_D(M2AP, "eNB_handle_eNB_CONFIGURATION_UPDATE_FAILURE\n");
+
+  M2AP_ENBConfigurationUpdateFailure_t    *in = &pdu->choice.unsuccessfulOutcome.value.choice.ENBConfigurationUpdateFailure;
+
+
+   //M2AP_ENBConfigurationUpdateFailure_Ies_t *ie;
+
+
+  MessageDef *msg_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_ENB_CONFIGURATION_UPDATE_FAILURE);
+
+   LOG_D(M2AP, "M2AP: ENBConfigurationUpdate-Failure: protocolIEs.list.count %d\n",
+         in->protocolIEs.list.count);
+   //for (int i=0;i < in->protocolIEs.list.count; i++) {
+   //  ie = in->protocolIEs.list.array[i];
+   // // switch (ie->id) {
+   // // case M2AP_ProtocolIE_ID_id_TimeToWait:
+   // //   AssertFatal(ie->criticality == M2AP_Criticality_ignore,
+   // //    	   "ie->criticality != M2AP_Criticality_ignore\n");
+   // //   AssertFatal(ie->value.present == M2AP_M2SetupFailure_Ies__value_PR_TimeToWait,
+   // //    	   "ie->value.present != M2AP_M2SetupFailure_Ies__value_PR_TimeToWait\n");
+   // //   LOG_D(M2AP, "M2AP: M2Setup-Failure: TimeToWait %d\n");/*,
+   // //         GlobalMCE_ID);*/
+   // //   break;
+   // // }
+   //}
+   //AssertFatal(GlobalMCE_ID!=-1,"GlobalMCE_ID was not sent\n");
+   //AssertFatal(num_cells_to_activate>0,"No cells activated\n");
+   //M2AP_SETUP_RESP (msg_p).num_cells_to_activate = num_cells_to_activate;
+
+   //for (int i=0;i<num_cells_to_activate;i++)  
+   //  AssertFatal(M2AP_SETUP_RESP (msg_p).num_SI[i] > 0, "System Information %d is missing",i);
+
+   //MSC_LOG_RX_MESSAGE(
+   // MSC_M2AP_eNB,
+   // MSC_M2AP_CU,
+   // 0,
+   // 0,
+   // MSC_AS_TIME_FMT" eNB_handle_M2_SETUP_RESPONSE successfulOutcome assoc_id %d",
+   // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
+   // assoc_id);
+ 
+   //LOG_D(M2AP, "Sending M2AP_SETUP_RESP ITTI message to ENB_APP with assoc_id (%d->%d)\n",
+   //      assoc_id,ENB_MOeNBLE_ID_TO_INSTANCE(assoc_id));
+
+   itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p);
+
+   return 0;
+}
+
+
+
+int eNB_handle_eNB_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
+                                         uint32_t assoc_id,
+                                         uint32_t stream,
+                                         M2AP_M2AP_PDU_t *pdu)
+{
+  LOG_D(M2AP, "eNB_handle_eNB_CONFIGURATION_UPDATE_ACKNOWLEDGE assoc_id %d\n",assoc_id);
+
+  MessageDef                         *message_p;
+  //M2AP_ENBConfigurationUpdateAcknowledge_t              *container;
+  //M2AP_ENBConfigurationUpdateAcknowledge_Ies_t           *ie;
+  //int i = 0;
+
+  DevAssert(pdu != NULL);
+
+  //container = &pdu->choice.initiatingMessage.value.choice.ENBConfigurationUpdate;
+
+  /* M2 Setup Request == Non UE-related procedure -> stream 0 */
+  if (stream != 0) {
+    LOG_D(M2AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n",
+              assoc_id, stream);
+  }
+
+  message_p  = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_ENB_CONFIGURATION_UPDATE_ACK);
+
+
+  itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p);
+
+
+   return 0;
+}
+
+
+/*
+ * MCE Configuration Update
+ */
+int eNB_handle_MCE_CONFIGURATION_UPDATE(instance_t instance,
+                                          uint32_t assoc_id,
+                                          uint32_t stream,
+                                          M2AP_M2AP_PDU_t *pdu)
+{
+ LOG_D(M2AP, "eNB_handle_MCE_CONFIGURATION_UPDATE assoc_id %d\n",assoc_id);
+
+  MessageDef                         *message_p;
+  //M2AP_MCEConfigurationUpdate_t              *container;
+  //M2AP_MCEConfigurationUpdate_Ies_t           *ie;
+  //int i = 0;
+
+  DevAssert(pdu != NULL);
+
+  //container = &pdu->choice.initiatingMessage.value.choice.MCEConfigurationUpdate;
+
+  /* M2 Setup Request == Non UE-related procedure -> stream 0 */
+  if (stream != 0) {
+    LOG_D(M2AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n",
+              assoc_id, stream);
+  }
+
+  message_p  = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MCE_CONFIGURATION_UPDATE);
+
+
+  itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p);
+
+
+   return 0;
+}
+
+int eNB_send_MCE_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
+                    M2AP_MCEConfigurationUpdateFailure_t *MCEConfigurationUpdateFailure)
+{
+
+  AssertFatal(1==0,"Not implemented yet\n");
+   return 0;
+}
+
+
+int eNB_send_MCE_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
+                    M2AP_MCEConfigurationUpdateAcknowledge_t *MCEConfigurationUpdateAcknowledge)
+{
+  AssertFatal(1==0,"Not implemented yet\n");
+   return 0;
+}
+
+
+/*
+ * Error Indication
+ */
+int eNB_send_ERROR_INDICATION(instance_t instance, m2ap_error_indication_t * m2ap_error_indication)
+{
+  AssertFatal(1==0,"Not implemented yet\n");
+   return 0;
+}
+
+int eNB_handle_ERROR_INDICATION(instance_t instance,
+                               uint32_t assoc_id,
+                               uint32_t stream,
+                               M2AP_M2AP_PDU_t *pdu)
+{
+  AssertFatal(1==0,"Not implemented yet\n");
+   return 0;
+}
+
+
+
+/*
+ * Session Update Request
+ */
+int eNB_handle_MBMS_SESSION_UPDATE_REQUEST(instance_t instance,
+                                                  uint32_t assoc_id,
+                                                  uint32_t stream,
+                                                  M2AP_M2AP_PDU_t *pdu)
+{
+  LOG_D(M2AP, "eNB_handle_MBMS_SESSION_STOP_REQUEST assoc_id %d\n",assoc_id);
+
+  MessageDef                         *message_p;
+  //M2AP_SessionUpdateRequest_t              *container;
+  //M2AP_SessionUpdateRequest_Ies_t           *ie;
+  //int i = 0;
+
+  DevAssert(pdu != NULL);
+
+  //container = &pdu->choice.initiatingMessage.value.choice.SessionUpdateRequest;
+
+  /* M2 Setup Request == Non UE-related procedure -> stream 0 */
+  if (stream != 0) {
+    LOG_D(M2AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n",
+              assoc_id, stream);
+  }
+
+  message_p  = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MBMS_SESSION_UPDATE_REQ);
+
+
+  itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p);
+
+
+
+   return 0;
+}
+
+
+int eNB_send_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance, m2ap_mbms_session_update_resp_t * m2ap_mbms_session_update_resp)
+{
+  AssertFatal(1==0,"Not implemented yet\n");
+   return 0;
+}
+
+
+int eNB_send_MBMS_SESSION_UPDATE_FAILURE(instance_t instance, m2ap_mbms_session_update_failure_t * m2ap_mbms_session_update_failure)
+{
+  AssertFatal(1==0,"Not implemented yet\n");
+   return 0;
+}
+
+/*
+ * Service Counting
+ */
+
+int eNB_handle_MBMS_SERVICE_COUNTING_REQ(instance_t instance,
+                                                  uint32_t assoc_id,
+                                                  uint32_t stream,
+                                                  M2AP_M2AP_PDU_t *pdu)
+{
+  LOG_D(M2AP, "eNB_handle_MBMS_SERVICE_COUNTING_REQUEST assoc_id %d\n",assoc_id);
+
+  MessageDef                         *message_p;
+  //M2AP_MbmsServiceCountingRequest_t              *container;
+  //M2AP_MbmsServiceCountingRequest_Ies_t           *ie;
+  //int i = 0;
+
+  DevAssert(pdu != NULL);
+
+ // container = &pdu->choice.initiatingMessage.value.choice.MbmsServiceCountingRequest;
+
+  /* M2 Setup Request == Non UE-related procedure -> stream 0 */
+  if (stream != 0) {
+    LOG_D(M2AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n",
+              assoc_id, stream);
+  }
+
+  message_p  = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MBMS_SERVICE_COUNTING_REQ);
+
+
+  itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p);
+
+
+
+
+   return 0;
+}
+int eNB_send_MBMS_SERVICE_COUNTING_REPORT(instance_t instance, m2ap_mbms_service_counting_report_t * m2ap_mbms_service_counting_report)
+{
+  AssertFatal(1==0,"Not implemented yet\n");
+   return 0;
+}
+int eNB_send_MBMS_SERVICE_COUNTING_RESP(instance_t instance, m2ap_mbms_service_counting_resp_t * m2ap_mbms_service_counting_resp)
+{
+  AssertFatal(1==0,"Not implemented yet\n");
+   return 0;
+}
+int eNB_send_MBMS_SERVICE_COUNTING_FAILURE(instance_t instance, m2ap_mbms_service_counting_failure_t * m2ap_mbms_service_counting_failure)
+{
+  AssertFatal(1==0,"Not implemented yet\n");
+   return 0;
+}
+
+/*
+ * Overload Notification
+ */
+int eNB_send_MBMS_OVERLOAD_NOTIFICATION(instance_t instance, m2ap_mbms_overload_notification_t * m2ap_mbms_overload_notification)
+{
+  AssertFatal(1==0,"Not implemented yet\n");
+   return 0;
+}
+
+
+
+
diff --git a/openair2/M2AP/m2ap_eNB_interface_management.h b/openair2/M2AP/m2ap_eNB_interface_management.h
new file mode 100644
index 0000000000..09bab1f125
--- /dev/null
+++ b/openair2/M2AP/m2ap_eNB_interface_management.h
@@ -0,0 +1,173 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_eNB_interface_management.h
+ * \brief m2ap interface management for eNB
+ * \author Javier Morgade
+ * \date 2019
+ * \version 0.1
+ * \company Vicomtech
+ * \email: javier.morgade@ieee.org
+ * \note
+ * \warning
+ */
+
+#ifndef M2AP_ENB_INTERFACE_MANAGEMENT_H_
+#define M2AP_ENB_INTERFACE_MANAGEMENT_H_
+
+/*
+ * Session Start 
+ */
+
+int eNB_handle_MBMS_SESSION_START_REQUEST(instance_t instance, 
+					uint32_t assoc_id,
+                                	uint32_t stream,
+                                	M2AP_M2AP_PDU_t *pdu);
+
+int eNB_send_MBMS_SESSION_START_RESPONSE(instance_t instance, m2ap_session_start_resp_t * m2ap_session_start_resp);
+int eNB_send_MBMS_SESSION_START_FAILURE(instance_t instance, m2ap_session_start_failure_t * m2ap_session_start_failure  );
+
+/*
+ * Session Stop
+ */
+
+int eNB_handle_MBMS_SESSION_STOP_REQUEST(instance_t instance, 
+					uint32_t assoc_id,
+                                	uint32_t stream,
+                                	M2AP_M2AP_PDU_t *pdu);
+int eNB_send_MBMS_SESSION_STOP_RESPONSE(instance_t instance, m2ap_session_stop_resp_t * m2ap_session_stop_resp);
+
+
+/*
+ * MBMS Scheduling Information
+ */
+
+int eNB_handle_MBMS_SCHEDULING_INFORMATION(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                M2AP_M2AP_PDU_t *pdu);
+
+int eNB_send_MBMS_SCHEDULING_INFORMATION_RESPONSE(instance_t instance, m2ap_mbms_scheduling_information_resp_t * m2ap_mbms_scheduling_information_resp);
+
+
+/*
+ * Reset
+ */
+int eNB_handle_RESET(instance_t instance,
+                    uint32_t assoc_id,
+                    uint32_t stream,
+                    M2AP_M2AP_PDU_t *pdu);
+int eNB_send_RESET_ACKKNOWLEDGE(instance_t instance, M2AP_ResetAcknowledge_t *ResetAcknowledge);
+int eNB_send_RESET(instance_t instance, M2AP_Reset_t *Reset);
+int eNB_handle_RESET_ACKNOWLEDGE(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                M2AP_M2AP_PDU_t *pdu);
+
+/*
+ * M2AP Setup
+ */
+int eNB_send_M2_SETUP_REQUEST( m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p);
+
+int eNB_handle_M2_SETUP_RESPONSE(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                M2AP_M2AP_PDU_t *pdu);
+
+int eNB_handle_M2_SETUP_FAILURE(instance_t instance,
+                               uint32_t assoc_id,
+                               uint32_t stream,
+                               M2AP_M2AP_PDU_t *pdu);
+
+/*
+ * eNB Configuration Update
+ */ 
+int eNB_send_eNB_CONFIGURATION_UPDATE(instance_t instance, m2ap_enb_configuration_update_t * m2ap_enb_configuration_update);
+
+int eNB_handle_eNB_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
+					 uint32_t assoc_id,
+                                         uint32_t stream,
+                                         M2AP_M2AP_PDU_t *pdu);
+
+int eNB_handle_eNB_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
+				         uint32_t assoc_id,
+                                         uint32_t stream,
+                                         M2AP_M2AP_PDU_t *pdu);
+
+/*
+ * MCE Configuration Update
+ */
+int eNB_handle_MCE_CONFIGURATION_UPDATE(instance_t instance,
+                                          uint32_t assoc_id,
+                                          uint32_t stream,
+                                          M2AP_M2AP_PDU_t *pdu);
+
+int eNB_send_MCE_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
+                    M2AP_MCEConfigurationUpdateFailure_t *MCEConfigurationUpdateFailure);
+
+int eNB_send_MCE_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
+                    M2AP_MCEConfigurationUpdateAcknowledge_t *MCEConfigurationUpdateAcknowledge);
+
+/*
+ * Error Indication
+ */
+int eNB_send_ERROR_INDICATION(instance_t instance, m2ap_error_indication_t * m2ap_error_indication);
+int eNB_handle_ERROR_INDICATION(instance_t instance,
+                               uint32_t assoc_id,
+                               uint32_t stream,
+                               M2AP_M2AP_PDU_t *pdu);
+
+
+/*
+ * Session Update Request
+ */
+int eNB_handle_MBMS_SESSION_UPDATE_REQUEST(instance_t instance,
+                                                  uint32_t assoc_id,
+                                                  uint32_t stream,
+                                                  M2AP_M2AP_PDU_t *pdu);
+
+int eNB_send_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance, m2ap_mbms_session_update_resp_t * m2ap_mbms_session_update_resp); //??
+
+int eNB_send_MBMS_SESSION_UPDATE_FAILURE(instance_t instance, m2ap_mbms_session_update_failure_t * m2ap_mbms_session_update_failure);
+
+/*
+ * Service Counting
+ */ 
+
+int eNB_handle_MBMS_SERVICE_COUNTING_REQ(instance_t instance,
+                                                  uint32_t assoc_id,
+                                                  uint32_t stream,
+                                                  M2AP_M2AP_PDU_t *pdu);
+int eNB_send_MBMS_SERVICE_COUNTING_REPORT(instance_t instance, m2ap_mbms_service_counting_report_t * m2ap_mbms_service_counting_report);
+int eNB_send_MBMS_SERVICE_COUNTING_RESP(instance_t instance, m2ap_mbms_service_counting_resp_t * m2ap_mbms_service_counting_resp);
+int eNB_send_MBMS_SERVICE_COUNTING_FAILURE(instance_t instance, m2ap_mbms_service_counting_failure_t * m2ap_mbms_service_counting_failure);
+
+ 
+/* 
+ * Overload Notification
+ */
+int eNB_send_MBMS_OVERLOAD_NOTIFICATION(instance_t instance, m2ap_mbms_overload_notification_t * m2ap_mbms_overload_notification);
+
+
+#endif /* M2AP_ENB_INTERFACE_MANAGEMENT_H_ */
+
+
+
diff --git a/openair2/M2AP/m2ap_eNB_management_procedures.c b/openair2/M2AP/m2ap_eNB_management_procedures.c
new file mode 100644
index 0000000000..b3ada92fa8
--- /dev/null
+++ b/openair2/M2AP/m2ap_eNB_management_procedures.c
@@ -0,0 +1,257 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_eNB_management_procedures.c
+ * \brief m2ap tasks for eNB
+ * \author Javier Morgade  <javier.morade@ieee.org>
+ * \date 2018
+ * \version 1.0
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "intertask_interface.h"
+
+#include "assertions.h"
+#include "conversions.h"
+
+#include "m2ap_common.h"
+#include "m2ap_eNB_defs.h"
+#include "m2ap_eNB.h"
+
+
+#define M2AP_DEBUG_LIST
+#ifdef M2AP_DEBUG_LIST
+#  define M2AP_eNB_LIST_OUT(x, args...) M2AP_DEBUG("[eNB]%*s"x"\n", 4*indent, "", ##args)
+#else
+#  define M2AP_eNB_LIST_OUT(x, args...)
+#endif
+
+static int                  indent = 0;
+
+
+m2ap_eNB_internal_data_t m2ap_eNB_internal_data;
+
+RB_GENERATE(m2ap_enb_map, m2ap_eNB_data_s, entry, m2ap_eNB_compare_assoc_id);
+
+int m2ap_eNB_compare_assoc_id(
+  struct m2ap_eNB_data_s *p1, struct m2ap_eNB_data_s *p2)
+{
+  if (p1->assoc_id == -1) {
+    if (p1->cnx_id < p2->cnx_id) {
+      return -1;
+    }
+
+    if (p1->cnx_id > p2->cnx_id) {
+      return 1;
+    }
+  } else {
+    if (p1->assoc_id < p2->assoc_id) {
+      return -1;
+    }
+
+    if (p1->assoc_id > p2->assoc_id) {
+      return 1;
+    }
+  }
+
+  /* Matching reference */
+  return 0;
+}
+
+uint16_t m2ap_eNB_fetch_add_global_cnx_id(void)
+{
+  return ++m2ap_eNB_internal_data.global_cnx_id;
+}
+
+void m2ap_eNB_prepare_internal_data(void)
+{
+  memset(&m2ap_eNB_internal_data, 0, sizeof(m2ap_eNB_internal_data));
+  STAILQ_INIT(&m2ap_eNB_internal_data.m2ap_eNB_instances_head);
+}
+
+void m2ap_eNB_insert_new_instance(m2ap_eNB_instance_t *new_instance_p)
+{
+  DevAssert(new_instance_p != NULL);
+
+  STAILQ_INSERT_TAIL(&m2ap_eNB_internal_data.m2ap_eNB_instances_head,
+                     new_instance_p, m2ap_eNB_entries);
+}
+
+void dump_tree_m2(m2ap_eNB_data_t *t)
+{
+  if (t == NULL) return;
+  printf("-----------------------\n");
+  printf("eNB id %d %s\n", t->eNB_id, t->eNB_name);
+  printf("state %d\n", t->state);
+  printf("nextstream %d\n", t->nextstream);
+  printf("in_streams %d out_streams %d\n", t->in_streams, t->out_streams);
+  printf("cnx_id %d assoc_id %d\n", t->cnx_id, t->assoc_id);
+  dump_tree_m2(t->entry.rbe_left);
+  dump_tree_m2(t->entry.rbe_right);
+}
+
+void dump_trees_m2(void)
+{
+m2ap_eNB_instance_t *zz;
+STAILQ_FOREACH(zz, &m2ap_eNB_internal_data.m2ap_eNB_instances_head,
+               m2ap_eNB_entries) {
+printf("here comes the tree (instance %d):\n---------------------------------------------\n", zz->instance);
+dump_tree_m2(zz->m2ap_enb_head.rbh_root);
+printf("---------------------------------------------\n");
+}
+}
+
+struct m2ap_eNB_data_s *m2ap_get_eNB(m2ap_eNB_instance_t *instance_p,
+				     int32_t assoc_id,
+				     uint16_t cnx_id)
+{
+  struct m2ap_eNB_data_s  temp;
+  struct m2ap_eNB_data_s *found;
+
+printf("m2ap_get_eNB at 1 (looking for assoc_id %d cnx_id %d)\n", assoc_id, cnx_id);
+dump_trees_m2();
+
+  memset(&temp, 0, sizeof(struct m2ap_eNB_data_s));
+
+  temp.assoc_id = assoc_id;
+  temp.cnx_id   = cnx_id;
+
+  if (instance_p == NULL) {
+    STAILQ_FOREACH(instance_p, &m2ap_eNB_internal_data.m2ap_eNB_instances_head,
+                   m2ap_eNB_entries) {
+      found = RB_FIND(m2ap_enb_map, &instance_p->m2ap_enb_head, &temp);
+
+      if (found != NULL) {
+        return found;
+      }
+    }
+  } else {
+    return RB_FIND(m2ap_enb_map, &instance_p->m2ap_enb_head, &temp);
+  }
+
+  return NULL;
+}
+
+
+m2ap_eNB_instance_t *m2ap_eNB_get_instance(instance_t instance)
+{
+  m2ap_eNB_instance_t *temp = NULL;
+
+  STAILQ_FOREACH(temp, &m2ap_eNB_internal_data.m2ap_eNB_instances_head,
+                 m2ap_eNB_entries) {
+    if (temp->instance == instance) {
+      /* Matching occurence */
+      return temp;
+    }
+  }
+
+  return NULL;
+}
+
+/// utility functions
+
+void m2ap_dump_eNB (m2ap_eNB_data_t  * eNB_ref);
+
+void
+m2ap_dump_eNB_list (void) {
+   m2ap_eNB_instance_t *inst = NULL;
+   struct m2ap_eNB_data_s *found = NULL;
+   struct m2ap_eNB_data_s temp;
+
+   memset(&temp, 0, sizeof(struct m2ap_eNB_data_s));
+
+  STAILQ_FOREACH (inst, &m2ap_eNB_internal_data.m2ap_eNB_instances_head,  m2ap_eNB_entries) {
+    found = RB_FIND(m2ap_enb_map, &inst->m2ap_enb_head, &temp);
+    m2ap_dump_eNB (found);
+  }
+}
+
+void m2ap_dump_eNB (m2ap_eNB_data_t  * eNB_ref) {
+
+  if (eNB_ref == NULL) {
+    return;
+  }
+
+  M2AP_eNB_LIST_OUT ("");
+  M2AP_eNB_LIST_OUT ("eNB name:          %s", eNB_ref->eNB_name == NULL ? "not present" : eNB_ref->eNB_name);
+  M2AP_eNB_LIST_OUT ("eNB STATE:         %07x", eNB_ref->state);
+  M2AP_eNB_LIST_OUT ("eNB ID:            %07x", eNB_ref->eNB_id);
+  indent++;
+  M2AP_eNB_LIST_OUT ("SCTP cnx id:     %d", eNB_ref->cnx_id);
+  M2AP_eNB_LIST_OUT ("SCTP assoc id:     %d", eNB_ref->assoc_id);
+  M2AP_eNB_LIST_OUT ("SCTP instreams:    %d", eNB_ref->in_streams);
+  M2AP_eNB_LIST_OUT ("SCTP outstreams:   %d", eNB_ref->out_streams);
+  indent--;
+}
+
+m2ap_eNB_data_t  * m2ap_is_eNB_pci_in_list (const uint32_t pci)
+{
+  m2ap_eNB_instance_t    *inst;
+  struct m2ap_eNB_data_s *elm;
+
+  STAILQ_FOREACH(inst, &m2ap_eNB_internal_data.m2ap_eNB_instances_head, m2ap_eNB_entries) {
+    RB_FOREACH(elm, m2ap_enb_map, &inst->m2ap_enb_head) {
+      for (int i = 0; i<elm->num_cc; i++) {
+        if (elm->Nid_cell[i] == pci) {
+          return elm;
+        }
+      }
+    }
+  }
+  return NULL;
+}
+
+m2ap_eNB_data_t  * m2ap_is_eNB_id_in_list (const uint32_t eNB_id)
+{
+  m2ap_eNB_instance_t    *inst;
+  struct m2ap_eNB_data_s *elm;
+
+  STAILQ_FOREACH(inst, &m2ap_eNB_internal_data.m2ap_eNB_instances_head, m2ap_eNB_entries) {
+    RB_FOREACH(elm, m2ap_enb_map, &inst->m2ap_enb_head) {
+      if (elm->eNB_id == eNB_id)
+        return elm;
+    }
+  }
+  return NULL;
+}
+
+m2ap_eNB_data_t  * m2ap_is_eNB_assoc_id_in_list (const uint32_t sctp_assoc_id)
+{
+  m2ap_eNB_instance_t    *inst;
+  struct m2ap_eNB_data_s *found;
+  struct m2ap_eNB_data_s temp;
+
+  temp.assoc_id = sctp_assoc_id;
+  temp.cnx_id = -1;
+
+  STAILQ_FOREACH(inst, &m2ap_eNB_internal_data.m2ap_eNB_instances_head, m2ap_eNB_entries) {
+    found = RB_FIND(m2ap_enb_map, &inst->m2ap_enb_head, &temp);
+    if (found != NULL){
+      if (found->assoc_id == sctp_assoc_id) {
+	return found;
+      }
+    }
+  }
+  return NULL;
+}
diff --git a/openair2/M2AP/m2ap_eNB_management_procedures.h b/openair2/M2AP/m2ap_eNB_management_procedures.h
new file mode 100644
index 0000000000..fbc49d0169
--- /dev/null
+++ b/openair2/M2AP/m2ap_eNB_management_procedures.h
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_eNB_management_procedures.h
+ * \brief m2ap tasks for eNB
+ * \author Javier Morgade <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#ifndef M2AP_ENB_MANAGEMENT_PROCEDURES_H_
+#define M2AP_ENB_MANAGEMENT_PROCEDURES_H
+
+void m2ap_eNB_prepare_internal_data(void);
+
+void dump_trees_m2(void);
+
+void m2ap_eNB_insert_new_instance(m2ap_eNB_instance_t *new_instance_p);
+
+m2ap_eNB_instance_t *m2ap_eNB_get_instance(uint8_t mod_id);
+
+uint16_t m2ap_eNB_fetch_add_global_cnx_id(void);
+
+//void m2ap_eNB_prepare_internal_data(void);
+
+m2ap_eNB_data_t* m2ap_is_eNB_id_in_list(uint32_t eNB_id);
+
+m2ap_eNB_data_t* m2ap_is_eNB_assoc_id_in_list(uint32_t sctp_assoc_id);
+
+m2ap_eNB_data_t* m2ap_is_eNB_pci_in_list (const uint32_t pci);
+
+struct m2ap_eNB_data_s *m2ap_get_eNB(m2ap_eNB_instance_t *instance_p,
+                                     int32_t assoc_id,
+                                     uint16_t cnx_id);
+
+#endif /* M2AP_ENB_MANAGEMENT_PROCEDURES_H_ */
diff --git a/openair2/M2AP/m2ap_encoder.c b/openair2/M2AP/m2ap_encoder.c
new file mode 100644
index 0000000000..8f798ff55c
--- /dev/null
+++ b/openair2/M2AP/m2ap_encoder.c
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_encoder.c
+ * \brief m2ap encoder procedures
+ * \author Javier Morgade <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "assertions.h"
+#include "conversions.h"
+#include "intertask_interface.h"
+#include "m2ap_common.h"
+#include "m2ap_encoder.h"
+
+int m2ap_encode_pdu(M2AP_M2AP_PDU_t *pdu, uint8_t **buffer, uint32_t *len)
+{
+  ssize_t    encoded;
+
+  DevAssert(pdu != NULL);
+  DevAssert(buffer != NULL);
+  DevAssert(len != NULL);
+
+  if (asn1_xer_print) {
+    xer_fprint(stdout, &asn_DEF_M2AP_M2AP_PDU, (void *)pdu);
+  }
+
+  encoded = aper_encode_to_new_buffer(&asn_DEF_M2AP_M2AP_PDU, 0, pdu, (void **)buffer);
+
+  if (encoded < 0) {
+    return -1;
+  }
+
+  *len = encoded;
+
+  ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, pdu);
+  return encoded;
+}
diff --git a/openair2/M2AP/m2ap_encoder.h b/openair2/M2AP/m2ap_encoder.h
new file mode 100644
index 0000000000..cf844f2983
--- /dev/null
+++ b/openair2/M2AP/m2ap_encoder.h
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_encoder.h
+ * \brief m2ap encoder procedures
+ * \author Javier Morgade  <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#ifndef M2AP_ENCODER_H_
+#define M2AP_ENCODER_H_
+
+int m2ap_encode_pdu(M2AP_M2AP_PDU_t *pdu, uint8_t **buffer, uint32_t *len)
+__attribute__ ((warn_unused_result));
+
+#endif /* M2AP_ENCODER_H_ */
diff --git a/openair2/M2AP/m2ap_handler.c b/openair2/M2AP/m2ap_handler.c
new file mode 100644
index 0000000000..1221bcedb5
--- /dev/null
+++ b/openair2/M2AP/m2ap_handler.c
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_eNB_handler.c
+ * \brief m2ap handler procedures for eNB
+ * \author Javier Morgade <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#include <stdint.h>
+
+#include "intertask_interface.h"
+
+#include "asn1_conversions.h"
+
+#include "m2ap_common.h"
+#include "m2ap_eNB_defs.h"
+//#include "m2ap_handler.h"
+#include "m2ap_decoder.h"
+#include "m2ap_ids.h"
+
+//#include "m2ap_eNB_management_procedures.h"
+#include "m2ap_eNB_generate_messages.h"
+
+#include "m2ap_MCE_interface_management.h"
+#include "m2ap_eNB_interface_management.h"
+
+#include "msc.h"
+#include "assertions.h"
+#include "conversions.h"
+
+/* Handlers matrix. Only eNB related procedure present here */
+m2ap_message_decoded_callback m2ap_messages_callback[][3] = {
+  { eNB_handle_MBMS_SESSION_START_REQUEST, MCE_handle_MBMS_SESSION_START_RESPONSE, 0 }, /* MBMSSessionStart  */
+  { eNB_handle_MBMS_SESSION_STOP_REQUEST, MCE_handle_MBMS_SESSION_STOP_RESPONSE, 0 }, /* MBMSSessionStop */
+  { eNB_handle_MBMS_SCHEDULING_INFORMATION, MCE_handle_MBMS_SCHEDULING_INFORMATION_RESPONSE, 0 }, /* MBMSSchedulingInformation */
+  { 0, 0, 0 }, /* Error Indication */
+  { 0, 0, 0 }, /* Reset */
+  { MCE_handle_M2_SETUP_REQUEST,eNB_handle_M2_SETUP_RESPONSE,eNB_handle_M2_SETUP_FAILURE }, /* M2 Setup */
+  { 0, 0, 0 }, /* eNBConfigurationUpdate */
+  { 0, 0, 0 }, /* MCEConfigurationUpdate */
+  { 0, 0, 0 }, /* privateMessage */
+  { 0, 0, 0 }, /* MBMSSessionUpdate */
+  { 0, 0, 0 }, /* MBMSServiceCounting */
+  { 0, 0, 0 }, /* MBMSServiceCountingResultReport */
+  { 0, 0, 0 } /* MBMSOverloadNotification */
+};
+
+static char *m2ap_direction2String(int m2ap_dir) {
+static char *m2ap_direction_String[] = {
+  "", /* Nothing */
+  "Originating message", /* originating message */
+  "Successfull outcome", /* successfull outcome */
+  "UnSuccessfull outcome", /* successfull outcome */
+};
+return(m2ap_direction_String[m2ap_dir]);
+}
+
+
+int m2ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
+                            const uint8_t * const data, const uint32_t data_length)
+{
+  M2AP_M2AP_PDU_t pdu;
+  int ret;
+
+  DevAssert(data != NULL);
+
+  memset(&pdu, 0, sizeof(pdu));
+
+  if (m2ap_decode_pdu(&pdu, data, data_length) < 0) {
+    LOG_E(M2AP, "Failed to decode PDU\n");
+    return -1;
+  }
+
+  /* Checking procedure Code and direction of message */
+  if (pdu.choice.initiatingMessage.procedureCode > sizeof(m2ap_messages_callback) / (3 * sizeof(
+        m2ap_message_decoded_callback))
+      || (pdu.present > M2AP_M2AP_PDU_PR_unsuccessfulOutcome)) {
+    LOG_E(M2AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n",
+               assoc_id, pdu.choice.initiatingMessage.procedureCode, pdu.present);
+    ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu);
+    return -1;
+  }
+
+  /* No handler present.
+   * This can mean not implemented or no procedure for eNB (wrong direction).
+   */
+  if (m2ap_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1] == NULL) {
+    LOG_E(M2AP, "[SCTP %d] No handler for procedureCode %ld in %s\n",
+                assoc_id, pdu.choice.initiatingMessage.procedureCode,
+               m2ap_direction2String(pdu.present - 1));
+    ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu);
+    return -1;
+  }
+  
+  /* Calling the right handler */
+  LOG_I(M2AP, "Calling handler with instance %d\n",instance);
+  ret = (*m2ap_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1])
+        (instance, assoc_id, stream, &pdu);
+  ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu);
+  return ret;
+}
+
+
diff --git a/openair2/M2AP/m2ap_handler.h b/openair2/M2AP/m2ap_handler.h
new file mode 100644
index 0000000000..88fb26bc3e
--- /dev/null
+++ b/openair2/M2AP/m2ap_handler.h
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_handler.h
+ * \brief m2ap handler procedures for eNB
+ * \author Javier Morgade <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#ifndef M2AP_ENB_OLD_HANDLERS_H_
+#define M2AP_ENB_OLD_HANDLERS_H_
+
+#include "m2ap_eNB_defs.h"
+
+void m2ap_handle_m2_setup_message(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown);
+
+int m2ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
+                            const uint8_t * const data, const uint32_t data_length);
+
+int m2ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
+                            const uint8_t * const data, const uint32_t data_length);
+
+
+#endif /* M2AP_ENB_OLD_HANDLERS_H_ */
diff --git a/openair2/M2AP/m2ap_ids.c b/openair2/M2AP/m2ap_ids.c
new file mode 100644
index 0000000000..347ba36d82
--- /dev/null
+++ b/openair2/M2AP/m2ap_ids.c
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+#include "m2ap_ids.h"
+
+#include <string.h>
+
+void m2ap_id_manager_init(m2ap_id_manager *m)
+{
+  int i;
+  memset(m, 0, sizeof(m2ap_id_manager));
+  for (i = 0; i < M2AP_MAX_IDS; i++)
+    m->ids[i].rnti = -1;
+}
+
+int m2ap_allocate_new_id(m2ap_id_manager *m)
+{
+  int i;
+  for (i = 0; i < M2AP_MAX_IDS; i++)
+    if (m->ids[i].rnti == -1) {
+      m->ids[i].rnti = 0;
+      m->ids[i].id_source = -1;
+      m->ids[i].id_target = -1;
+      return i;
+    }
+  return -1;
+}
+
+void m2ap_release_id(m2ap_id_manager *m, int id)
+{
+  m->ids[id].rnti = -1;
+}
+
+int m2ap_find_id(m2ap_id_manager *m, int id_source, int id_target)
+{
+  int i;
+  for (i = 0; i < M2AP_MAX_IDS; i++)
+    if (m->ids[i].rnti != -1 &&
+        m->ids[i].id_source == id_source &&
+        m->ids[i].id_target == id_target)
+      return i;
+  return -1;
+}
+
+int m2ap_find_id_from_id_source(m2ap_id_manager *m, int id_source)
+{
+  int i;
+  for (i = 0; i < M2AP_MAX_IDS; i++)
+    if (m->ids[i].rnti != -1 &&
+        m->ids[i].id_source == id_source)
+      return i;
+  return -1;
+}
+
+int m2ap_find_id_from_rnti(m2ap_id_manager *m, int rnti)
+{
+  int i;
+  for (i = 0; i < M2AP_MAX_IDS; i++)
+    if (m->ids[i].rnti == rnti)
+      return i;
+  return -1;
+}
+
+void m2ap_set_ids(m2ap_id_manager *m, int ue_id, int rnti, int id_source, int id_target)
+{
+  m->ids[ue_id].rnti      = rnti;
+  m->ids[ue_id].id_source = id_source;
+  m->ids[ue_id].id_target = id_target;
+}
+
+/* real type of target is m2ap_eNB_data_t * */
+void m2ap_id_set_target(m2ap_id_manager *m, int ue_id, void *target)
+{
+  m->ids[ue_id].target = target;
+}
+
+void m2ap_id_set_state(m2ap_id_manager *m, int ue_id, m2id_state_t state)
+{
+  m->ids[ue_id].state = state;
+}
+
+void m2ap_set_reloc_prep_timer(m2ap_id_manager *m, int ue_id, uint64_t time)
+{
+  m->ids[ue_id].t_reloc_prep_start = time;
+}
+
+void m2ap_set_reloc_overall_timer(m2ap_id_manager *m, int ue_id, uint64_t time)
+{
+  m->ids[ue_id].tm2_reloc_overall_start = time;
+}
+
+int m2ap_id_get_id_source(m2ap_id_manager *m, int ue_id)
+{
+  return m->ids[ue_id].id_source;
+}
+
+int m2ap_id_get_id_target(m2ap_id_manager *m, int ue_id)
+{
+  return m->ids[ue_id].id_target;
+}
+
+int m2ap_id_get_rnti(m2ap_id_manager *m, int ue_id)
+{
+  return m->ids[ue_id].rnti;
+}
+
+void *m2ap_id_get_target(m2ap_id_manager *m, int ue_id)
+{
+  return m->ids[ue_id].target;
+}
diff --git a/openair2/M2AP/m2ap_ids.h b/openair2/M2AP/m2ap_ids.h
new file mode 100644
index 0000000000..8603d67788
--- /dev/null
+++ b/openair2/M2AP/m2ap_ids.h
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+#ifndef M2AP_IDS_H_
+#define M2AP_IDS_H_
+
+#include <stdint.h>
+
+/* maximum number of simultaneous handovers, do not set too high */
+#define M2AP_MAX_IDS	16
+
+/*
+ * state:
+ * - when starting handover in source, UE is in state M2ID_STATE_SOURCE_PREPARE
+ * - after receiving HO_ack in source, UE is in state M2ID_STATE_SOURCE_OVERALL
+ * - in target, UE is in state X2ID_STATE_TARGET
+ * The state is used to check timers.
+ */
+typedef enum {
+  M2ID_STATE_SOURCE_PREPARE,
+  M2ID_STATE_SOURCE_OVERALL,
+  M2ID_STATE_TARGET
+} m2id_state_t;
+
+typedef struct {
+  int           rnti;             /* -1 when free */
+  int           id_source;
+  int           id_target;
+
+  /* the target eNB. Real type is m2ap_eNB_data_t * */
+  void          *target;
+
+  /* state: needed to check timers */
+  m2id_state_t  state;
+
+  /* timers */
+  uint64_t      t_reloc_prep_start;
+  uint64_t      tm2_reloc_overall_start;
+} m2ap_id;
+
+typedef struct {
+  m2ap_id ids[M2AP_MAX_IDS];
+} m2ap_id_manager;
+
+void m2ap_id_manager_init(m2ap_id_manager *m);
+int m2ap_allocate_new_id(m2ap_id_manager *m);
+void m2ap_release_id(m2ap_id_manager *m, int id);
+int m2ap_find_id(m2ap_id_manager *, int id_source, int id_target);
+int m2ap_find_id_from_id_source(m2ap_id_manager *, int id_source);
+int m2ap_find_id_from_rnti(m2ap_id_manager *, int rnti);
+void m2ap_set_ids(m2ap_id_manager *m, int ue_id, int rnti, int id_source, int id_target);
+void m2ap_id_set_state(m2ap_id_manager *m, int ue_id, m2id_state_t state);
+/* real type of target is m2ap_eNB_data_t * */
+void m2ap_id_set_target(m2ap_id_manager *m, int ue_id, void *target);
+void m2ap_set_reloc_prep_timer(m2ap_id_manager *m, int ue_id, uint64_t time);
+void m2ap_set_reloc_overall_timer(m2ap_id_manager *m, int ue_id, uint64_t time);
+int m2ap_id_get_id_source(m2ap_id_manager *m, int ue_id);
+int m2ap_id_get_id_target(m2ap_id_manager *m, int ue_id);
+int m2ap_id_get_rnti(m2ap_id_manager *m, int ue_id);
+void *m2ap_id_get_target(m2ap_id_manager *m, int ue_id);
+
+#endif /* M2AP_IDS_H_ */
diff --git a/openair2/M2AP/m2ap_itti_messaging.c b/openair2/M2AP/m2ap_itti_messaging.c
new file mode 100644
index 0000000000..b9cfd32901
--- /dev/null
+++ b/openair2/M2AP/m2ap_itti_messaging.c
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_eNB_itti_messaging.c
+ * \brief m2ap tasks for eNB
+ * \author Javier Morgade <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#include "intertask_interface.h"
+
+#include "m2ap_itti_messaging.h"
+
+void m2ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
+                                      uint32_t buffer_length, uint16_t stream)
+{
+  MessageDef      *message_p;
+  sctp_data_req_t *sctp_data_req;
+
+  message_p = itti_alloc_new_message(TASK_M2AP_ENB, SCTP_DATA_REQ);
+
+  sctp_data_req = &message_p->ittiMsg.sctp_data_req;
+
+  sctp_data_req->assoc_id      = assoc_id;
+  sctp_data_req->buffer        = buffer;
+  sctp_data_req->buffer_length = buffer_length;
+  sctp_data_req->stream        = stream;
+
+  //LOG_W(M2AP,"assoc_id %d, stream %d\n",assoc_id,stream);
+
+  itti_send_msg_to_task(TASK_SCTP, instance, message_p);
+}
+
+
+void m2ap_eNB_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id)
+{
+  MessageDef               *message_p = NULL;
+  sctp_close_association_t *sctp_close_association_p = NULL;
+
+  message_p = itti_alloc_new_message(TASK_M2AP_ENB, SCTP_CLOSE_ASSOCIATION);
+  sctp_close_association_p = &message_p->ittiMsg.sctp_close_association;
+  sctp_close_association_p->assoc_id      = assoc_id;
+
+  itti_send_msg_to_task(TASK_SCTP, instance, message_p);
+}
+
+
+void m2ap_MCE_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
+                                      uint32_t buffer_length, uint16_t stream)
+{
+  MessageDef      *message_p;
+  sctp_data_req_t *sctp_data_req;
+
+  message_p = itti_alloc_new_message(TASK_M2AP_MCE, SCTP_DATA_REQ);
+
+  sctp_data_req = &message_p->ittiMsg.sctp_data_req;
+
+  sctp_data_req->assoc_id      = assoc_id;
+  sctp_data_req->buffer        = buffer;
+  sctp_data_req->buffer_length = buffer_length;
+  sctp_data_req->stream        = stream;
+
+  itti_send_msg_to_task(TASK_SCTP, instance, message_p);
+}
+
+
+void m2ap_MCE_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id)
+{
+  MessageDef               *message_p = NULL;
+  sctp_close_association_t *sctp_close_association_p = NULL;
+
+  message_p = itti_alloc_new_message(TASK_M2AP_MCE, SCTP_CLOSE_ASSOCIATION);
+  sctp_close_association_p = &message_p->ittiMsg.sctp_close_association;
+  sctp_close_association_p->assoc_id      = assoc_id;
+
+  itti_send_msg_to_task(TASK_SCTP, instance, message_p);
+}
diff --git a/openair2/M2AP/m2ap_itti_messaging.h b/openair2/M2AP/m2ap_itti_messaging.h
new file mode 100644
index 0000000000..bdc416bca7
--- /dev/null
+++ b/openair2/M2AP/m2ap_itti_messaging.h
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file m2ap_itti_messaging.h
+ * \brief m2ap tasks for eNB
+ * \author Javier Morgade <javier.morgade@ieee.org>
+ * \date 2019
+ * \version 0.1
+ */
+
+#ifndef M2AP_ENB_ITTI_MESSAGING_H_
+#define M2AP_ENB_ITTI_MESSAGING_H_
+
+void m2ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
+                                      uint32_t buffer_length, uint16_t stream);
+
+
+void m2ap_eNB_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id);
+
+
+void m2ap_MCE_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
+                                      uint32_t buffer_length, uint16_t stream);
+
+
+void m2ap_MCE_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id);
+
+
+
+
+#endif /* M2AP_ENB_ITTI_MESSAGING_H_ */
diff --git a/openair2/M2AP/m2ap_timers.c b/openair2/M2AP/m2ap_timers.c
new file mode 100644
index 0000000000..13ec6423ac
--- /dev/null
+++ b/openair2/M2AP/m2ap_timers.c
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+#include "m2ap_timers.h"
+#include "assertions.h"
+#include "PHY/defs_common.h"         /* TODO: try to not include this */
+#include "m2ap_messages_types.h"
+#include "m2ap_eNB_defs.h"
+#include "m2ap_ids.h"
+#include "m2ap_eNB_management_procedures.h"
+#include "m2ap_eNB_generate_messages.h"
+
+void m2ap_timers_init(m2ap_timers_t *t, int t_reloc_prep, int tm2_reloc_overall)
+{
+  t->tti               = 0;
+  t->t_reloc_prep      = t_reloc_prep;
+  t->tm2_reloc_overall = tm2_reloc_overall;
+}
+
+void m2ap_check_timers(instance_t instance)
+{
+  //m2ap_eNB_instance_t          *instance_p;
+  //m2ap_timers_t                *t;
+  //m2ap_id_manager              *m;
+  //int                          i;
+  //m2ap_handover_cancel_cause_t cause;
+  //void                         *target;
+  //MessageDef                   *msg;
+  //int                          m2_ongoing;
+
+  //instance_p = m2ap_eNB_get_instance(instance);
+  //DevAssert(instance_p != NULL);
+
+  //t = &instance_p->timers;
+  //m = &instance_p->id_manager;
+
+  ///* increment subframe count */
+  //t->tti++;
+
+  //m2_ongoing = 0;
+
+  //for (i = 0; i < M2AP_MAX_IDS; i++) {
+  //  if (m->ids[i].rnti == -1) continue;
+  //  m2_ongoing++;
+
+  //  if (m->ids[i].state == M2ID_STATE_SOURCE_PREPARE &&
+  //      t->tti > m->ids[i].t_reloc_prep_start + t->t_reloc_prep) {
+  //    LOG_I(M2AP, "M2 timeout reloc prep\n");
+  //    /* t_reloc_prep timed out */
+  //    cause = M2AP_T_RELOC_PREP_TIMEOUT;
+  //    goto timeout;
+  //  }
+
+  //  if (m->ids[i].state == M2ID_STATE_SOURCE_OVERALL &&
+  //      t->tti > m->ids[i].tm2_reloc_overall_start + t->tm2_reloc_overall) {
+  //    LOG_I(M2AP, "M2 timeout reloc overall\n");
+  //    /* tm2_reloc_overall timed out */
+  //    cause = M2AP_TM2_RELOC_OVERALL_TIMEOUT;
+  //    goto timeout;
+  //  }
+
+  //  /* no timeout -> check next UE */
+  //  continue;
+
+  // timeout:
+  //  /* inform target about timeout */
+  //  target = m2ap_id_get_target(m, i);
+  //  m2ap_eNB_generate_m2_handover_cancel(instance_p, target, i, cause);
+
+  //  /* inform RRC of cancellation */
+  //  msg = itti_alloc_new_message(TASK_M2AP, M2AP_HANDOVER_CANCEL);
+  //  M2AP_HANDOVER_CANCEL(msg).rnti  = m2ap_id_get_rnti(m, i);
+  //  M2AP_HANDOVER_CANCEL(msg).cause = cause;
+  //  itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg);
+
+  //  /* remove UE from M2AP */
+  //  m2ap_release_id(m, i);
+  //}
+
+  //if (m2_ongoing && t->tti % 1000 == 0)
+  //  LOG_I(M2AP, "M2 has %d process ongoing\n", m2_ongoing);
+}
+
+uint64_t m2ap_timer_get_tti(m2ap_timers_t *t)
+{
+  return t->tti;
+}
diff --git a/openair2/M2AP/m2ap_timers.h b/openair2/M2AP/m2ap_timers.h
new file mode 100644
index 0000000000..d2875d92af
--- /dev/null
+++ b/openair2/M2AP/m2ap_timers.h
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+#ifndef M2AP_TIMERS_H_
+#define M2AP_TIMERS_H_
+
+#include <stdint.h>
+#include "platform_types.h"
+
+typedef struct {
+  /* incremented every TTI (every millisecond when in realtime).
+   * Used to check timers.
+   * 64 bits gives us more than 500 million years of (realtime) processing.
+   * It should be enough.
+   */
+  uint64_t tti;
+
+  /* timer values (unit: TTI, ie. millisecond when in realtime) */
+  int      t_reloc_prep;
+  int      tm2_reloc_overall;
+} m2ap_timers_t;
+
+void m2ap_timers_init(m2ap_timers_t *t, int t_reloc_prep, int tm2_reloc_overall);
+void m2ap_check_timers(instance_t instance);
+uint64_t m2ap_timer_get_tti(m2ap_timers_t *t);
+
+#endif /* M2AP_TIMERS_H_ */
diff --git a/openair2/MCE_APP/mce_app.c b/openair2/MCE_APP/mce_app.c
new file mode 100644
index 0000000000..32dfa5cc42
--- /dev/null
+++ b/openair2/MCE_APP/mce_app.c
@@ -0,0 +1,754 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*
+                                mce_app.c
+                             -------------------
+  AUTHOR  : Javier Morgade
+  COMPANY : VICOMTECH Spain
+  EMAIL   : javier.morgade@ieee.org
+*/
+
+#include <string.h>
+#include <stdio.h>
+
+#include "mce_app.h"
+#include "mce_config.h"
+#include "assertions.h"
+#include "common/ran_context.h"
+#include "targets/RT/USER/lte-softmodem.h"
+
+#include "common/utils/LOG/log.h"
+
+# include "intertask_interface.h"
+#   include "s1ap_eNB.h"
+#   include "sctp_eNB_task.h"
+#   include "gtpv1u_eNB_task.h"
+#   include "flexran_agent.h"
+
+#   include "x2ap_eNB.h"
+#   include "x2ap_messages_types.h"
+#   include "m2ap_eNB.h"
+#   include "m2ap_MCE.h"
+#   include "m2ap_messages_types.h"
+#   include "m3ap_MCE.h"
+#   include "m3ap_messages_types.h"
+#   define X2AP_ENB_REGISTER_RETRY_DELAY   10
+
+#include "openair1/PHY/INIT/phy_init.h"
+extern unsigned char NB_MCE_INST;
+
+extern RAN_CONTEXT_t RC;
+
+#   define MCE_REGISTER_RETRY_DELAY 10
+
+#include "targets/RT/USER/lte-softmodem.h"
+
+static m2ap_mbms_scheduling_information_t * m2ap_mbms_scheduling_information_local = NULL;
+static m2ap_setup_resp_t * m2ap_setup_resp_local = NULL;
+static m2ap_setup_req_t * m2ap_setup_req_local = NULL;
+
+
+/*------------------------------------------------------------------------------*/
+
+static uint32_t MCE_app_register(ngran_node_t node_type,uint32_t mce_id_start, uint32_t mce_id_end) {
+  uint32_t         mce_id;
+  MessageDef      *msg_p;
+  uint32_t         register_mce_pending = 0;
+
+  for (mce_id = mce_id_start; (mce_id < mce_id_end) ; mce_id++) {
+    {
+      // M3AP registration
+        /* note:  there is an implicit relationship between the data structure and the message name */
+        msg_p = itti_alloc_new_message (TASK_MCE_APP, M3AP_REGISTER_MCE_REQ);
+        //RCconfig_S1(msg_p, mce_id);
+
+        //if (mce_id == 0) 
+		//RCconfig_gtpu();
+
+        //LOG_I(MCE_APP,"default drx %d\n",((M3AP_REGISTER_MCE_REQ(msg_p)).default_drx));
+
+        LOG_I(ENB_APP,"[MCE %d] MCE_app_register via M3AP for instance %d\n", mce_id, ENB_MODULE_ID_TO_INSTANCE(mce_id));
+        itti_send_msg_to_task (TASK_M3AP, ENB_MODULE_ID_TO_INSTANCE(mce_id), msg_p);
+
+      //if (NODE_IS_DU(node_type)) { // F1AP registration
+      //  // configure F1AP here for F1C
+      //  LOG_I(ENB_APP,"ngran_eNB_DU: Allocating ITTI message for F1AP_SETUP_REQ\n");
+      //  msg_p = itti_alloc_new_message (TASK_ENB_APP, F1AP_SETUP_REQ);
+      //  RCconfig_DU_F1(msg_p, enb_id);
+
+      //  LOG_I(ENB_APP,"[eNB %d] eNB_app_register via F1AP for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id));
+      //  itti_send_msg_to_task (TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
+      //  // configure GTPu here for F1U
+      //}
+      //else { // S1AP registration
+      //  /* note:  there is an implicit relationship between the data structure and the message name */
+      //  msg_p = itti_alloc_new_message (TASK_ENB_APP, S1AP_REGISTER_ENB_REQ);
+      //  RCconfig_S1(msg_p, enb_id);
+
+      //  if (enb_id == 0) RCconfig_gtpu();
+
+      //  LOG_I(ENB_APP,"default drx %d\n",((S1AP_REGISTER_ENB_REQ(msg_p)).default_drx));
+
+      //  LOG_I(ENB_APP,"[eNB %d] eNB_app_register via S1AP for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id));
+      //  itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
+      //}
+
+      register_mce_pending++;
+    }
+  }
+
+  return register_mce_pending;
+}
+
+
+/*------------------------------------------------------------------------------*/
+//static uint32_t MCE_app_register_x2(uint32_t mce_id_start, uint32_t mce_id_end) {
+//  uint32_t         mce_id;
+//  MessageDef      *msg_p;
+//  uint32_t         register_mce_m2_pending = 0;
+//
+//  for (mce_id = mce_id_start; (mce_id < mce_id_end) ; mce_id++) {
+//    {
+//      msg_p = itti_alloc_new_message (TASK_ENB_APP, X2AP_REGISTER_ENB_REQ);
+//      RCconfig_X2(msg_p, mce_id);
+//      itti_send_msg_to_task (TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(mce_id), msg_p);
+//      register_mce_x2_pending++;
+//    }
+//  }
+//
+//  return register_mce_x2_pending;
+//}
+
+/*------------------------------------------------------------------------------*/
+//static uint32_t MCE_app_register_m2(uint32_t mce_id_start, uint32_t mce_id_end) {
+//  uint32_t         mce_id;
+//  MessageDef      *msg_p;
+//  uint32_t         register_mce_m2_pending = 0;
+//
+//  LOG_W(MCE_APP,"Register ...");
+//  for (mce_id = mce_id_start; (mce_id < mce_id_end) ; mce_id++) {
+//    {
+//  //	LOG_W(MCE_APP,"Register commes inside ...\n");
+//      msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_REGISTER_MCE_REQ);
+//      //RCconfig_M2_MCE(msg_p, mce_id);
+//      itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(mce_id), msg_p);
+//  //	LOG_W(MCE_APP,"Register sent ...\n");
+//      register_mce_m2_pending++;
+//    }
+//  }
+//
+//  return register_mce_m2_pending;
+//}
+//
+/*------------------------------------------------------------------------------*/
+static uint32_t MCE_app_register_m3(uint32_t mce_id_start, uint32_t mce_id_end) {
+  uint32_t         mce_id;
+  MessageDef      *msg_p;
+  uint32_t         register_mce_m3_pending = 0;
+
+  LOG_D(MCE_APP,"Register ...\n");
+  for (mce_id = mce_id_start; (mce_id < mce_id_end) ; mce_id++) {
+    {
+  //	LOG_W(MCE_APP,"Register commes inside ...\n");
+      msg_p = itti_alloc_new_message (TASK_MCE_APP, M3AP_REGISTER_MCE_REQ);
+      RCconfig_M3(msg_p, mce_id);
+      itti_send_msg_to_task (TASK_M3AP_MCE, ENB_MODULE_ID_TO_INSTANCE(mce_id), msg_p);
+  	LOG_D(MCE_APP,"Register sent ...\n");
+      register_mce_m3_pending++;
+    }
+  }
+
+  return register_mce_m3_pending;
+}
+
+/***************************  M3AP MCE handle **********************************/
+//static uint32_t MCE_app_handle_m3ap_mbms_session_start_req(instance_t instance){
+//  	//uint32_t         mce_id=0;
+//  //	MessageDef      *msg_p;
+//  //      msg_p = itti_alloc_new_message (TASK_MCE_APP, M3AP_MBMS_SESSION_START_RESP);
+//  //      itti_send_msg_to_task (TASK_M3AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
+//	
+//	
+//	return 0;
+//}
+
+static uint32_t MCE_app_handle_m3ap_mbms_session_stop_req(instance_t instance){
+  	//uint32_t         mce_id=0;
+  	MessageDef      *msg_p;
+        msg_p = itti_alloc_new_message (TASK_MCE_APP, M3AP_MBMS_SESSION_STOP_RESP);
+        itti_send_msg_to_task (TASK_M3AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
+	
+	return 0;
+}
+
+static uint32_t MCE_app_handle_m3ap_mbms_session_update_req(instance_t instance){
+  	//uint32_t         mce_id=0;
+  	MessageDef      *msg_p;
+        msg_p = itti_alloc_new_message (TASK_MCE_APP, M3AP_MBMS_SESSION_UPDATE_RESP);
+        itti_send_msg_to_task (TASK_M3AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
+	
+	return 0;
+}
+//// end M3AP MCE handle **********************************/
+
+
+/***************************  M2AP MCE handle **********************************/
+static uint32_t MCE_app_handle_m2ap_setup_req(instance_t instance){
+	
+  	//uint32_t         mce_id=0;
+  	MessageDef      *msg_p;
+        msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_SETUP_RESP);
+	if(m2ap_setup_resp_local)
+		memcpy(&M2AP_SETUP_RESP(msg_p),m2ap_setup_resp_local,sizeof(m2ap_setup_resp_t));
+	else
+		RCconfig_M2_MCCH(msg_p,0);
+
+	
+        itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
+	
+	return 0;
+}
+
+static uint32_t MCE_app_handle_m2ap_mbms_session_start_resp(instance_t instance){
+	MessageDef      *msg_p;
+  	msg_p = itti_alloc_new_message (TASK_MCE_APP, M3AP_MBMS_SESSION_START_RESP); 
+	itti_send_msg_to_task (TASK_M3AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
+	return 0;
+}
+
+//// end M2AP MCE handle **********************************/
+
+
+/***************************  M2AP MCE send **********************************/
+static uint32_t MCE_app_send_m2ap_mbms_scheduling_information(instance_t instance){
+	
+  	//uint32_t         mce_id=0;
+  	MessageDef      *msg_p;
+        msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_MBMS_SCHEDULING_INFORMATION);
+	if(m2ap_mbms_scheduling_information_local)
+		memcpy(&M2AP_MBMS_SCHEDULING_INFORMATION(msg_p),m2ap_mbms_scheduling_information_local,sizeof(m2ap_mbms_scheduling_information_t));
+	else
+		RCconfig_M2_SCHEDULING(msg_p,0);
+        itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
+	
+	return 0;
+}
+
+static uint32_t MCE_app_send_m2ap_session_start_req(instance_t instance){
+	
+  	//uint32_t         mce_id=0;
+  	MessageDef      *msg_p;
+        msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_MBMS_SESSION_START_REQ);
+        itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
+	
+	return 0;
+}
+//static uint32_t MCE_app_send_m2ap_session_stop_req(instance_t instance){
+//	
+//  	//uint32_t         mce_id=0;
+//  	MessageDef      *msg_p;
+//        msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_MBMS_SESSION_STOP_REQ);
+//        itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
+//	
+//	return 0;
+//}
+//static uint32_t MCE_app_send_m2ap_mce_configuration_update(instance_t instance){
+//	
+//  	//uint32_t         mce_id=0;
+//  	MessageDef      *msg_p;
+//        msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_MCE_CONFIGURATION_UPDATE);
+//        itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
+//	
+//	return 0;
+//}
+//static uint32_t MCE_app_send_m2ap_enb_configuration_update_ack(instance_t instance){
+//	
+//  	//uint32_t         mce_id=0;
+//  	MessageDef      *msg_p;
+//        msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_ENB_CONFIGURATION_UPDATE_ACK);
+//        itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
+//	
+//	return 0;
+//}
+//static uint32_t MCE_app_send_m2ap_enb_configuration_update_failure(instance_t instance){
+//	
+//  	//uint32_t         mce_id=0;
+//  	MessageDef      *msg_p;
+//        msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_ENB_CONFIGURATION_UPDATE_FAILURE);
+//        itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
+//	
+//	return 0;
+//} //// end M2AP MCE send **********************************/
+
+//static uint32_t MCE_app_send_MME_APP(instance_t instance){
+//	
+//  	//uint32_t         mce_id=0;
+//  	MessageDef      *msg_p;
+//        msg_p = itti_alloc_new_message (TASK_MCE_APP, MESSAGE_TEST);
+//        itti_send_msg_to_task (TASK_MME_APP, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
+//	
+//	return 0;
+//}
+
+//static uint32_t MCE_app_send_MME_APP2(instance_t instance){
+//	
+//  	//uint32_t         mce_id=0;
+//  	MessageDef      *msg_p;
+//        msg_p = itti_alloc_new_message (TASK_MCE_APP, MESSAGE_TEST);
+//        itti_send_msg_to_task (TASK_M3AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
+//	
+//	return 0;
+//}
+
+/*------------------------------------------------------------------------------*/
+void *MCE_app_task(void *args_p) {
+  uint32_t                        mce_nb = 1;//RC.nb_inst; 
+  uint32_t                        mce_id_start = 0;
+  uint32_t                        mce_id_end = mce_id_start + mce_nb;
+  uint32_t                        register_mce_pending=0;
+  uint32_t                        registered_mce=0;
+  //long                            mce_register_retry_timer_id;
+  long 				  mce_scheduling_info_timer_id;
+  //uint32_t                        m3_register_mce_pending = 0;
+ // uint32_t                        x2_registered_mce = 0;
+ // long                            x2_mce_register_retry_timer_id;
+ // uint32_t                        m2_register_mce_pending = 0;
+ // uint32_t                        m2_registered_mce = 0;
+ // long                            m2_mce_register_retry_timer_id;
+  MessageDef                     *msg_p           = NULL;
+  instance_t                      instance;
+  int                             result;
+  /* for no gcc warnings */
+  (void)instance;
+  itti_mark_task_ready (TASK_MCE_APP);
+
+  /* Try to register each MCE */
+  // This assumes that node_type of all RRC instances is the same
+  if (EPC_MODE_ENABLED) {
+    register_mce_pending = MCE_app_register(RC.rrc[0]->node_type, mce_id_start, mce_id_end);
+  }
+
+    /* Try to register each MCE with each other */
+ // if (is_x2ap_enabled() && !NODE_IS_DU(RC.rrc[0]->node_type)) {
+ //   x2_register_enb_pending = MCE_app_register_x2 (enb_id_start, enb_id_end);
+ // }
+ // MCE_app_send_MME_APP2(0);
+
+
+ if (is_m2ap_MCE_enabled() /*&& !NODE_IS_DU(RC.rrc[0]->node_type)*/) {
+  RCconfig_MCE();
+
+  if(!m2ap_mbms_scheduling_information_local)
+	m2ap_mbms_scheduling_information_local = (m2ap_mbms_scheduling_information_t*)calloc(1,sizeof(m2ap_mbms_scheduling_information_t));
+  if(m2ap_mbms_scheduling_information_local)
+  	RCconfig_m2_scheduling(m2ap_mbms_scheduling_information_local,0);
+
+  if(!m2ap_setup_resp_local)
+	m2ap_setup_resp_local = (m2ap_setup_resp_t*)calloc(1,sizeof(m2ap_setup_resp_t));
+  if(m2ap_setup_resp_local)
+	RCconfig_m2_mcch(m2ap_setup_resp_local,0);
+ }
+
+ // /* Try to register each MCE with MCE each other */
+ if (is_m3ap_MCE_enabled() /*&& !NODE_IS_DU(RC.rrc[0]->node_type)*/) {
+   	///*m3_register_mce_pending =*/ MCE_app_register_m3 (mce_id_start, mce_id_end);
+   }
+
+  do {
+    // Wait for a message
+    itti_receive_msg (TASK_MCE_APP, &msg_p);
+    instance = ITTI_MSG_INSTANCE (msg_p);
+
+    switch (ITTI_MSG_ID(msg_p)) {
+    case TERMINATE_MESSAGE:
+      LOG_W(MCE_APP, " *** Exiting MCE_APP thread\n");
+      itti_exit_task ();
+      break;
+
+    case MESSAGE_TEST:
+      LOG_I(MCE_APP, "Received %s\n", ITTI_MSG_NAME(msg_p));
+      break;
+
+    case SOFT_RESTART_MESSAGE:
+      //handle_reconfiguration(instance);
+      break;
+
+    case M3AP_REGISTER_MCE_CNF:
+      //AssertFatal(!NODE_IS_DU(RC.rrc[0]->node_type), "Should not have received S1AP_REGISTER_ENB_CNF\n");
+          LOG_I(MCE_APP, "[MCE %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p),
+                M3AP_REGISTER_MCE_CNF(msg_p).nb_mme);
+          DevAssert(register_mce_pending > 0);
+          register_mce_pending--;
+
+          /* Check if at least MCE is registered with one MME */
+          if (M3AP_REGISTER_MCE_CNF(msg_p).nb_mme > 0) {
+            registered_mce++;
+          }
+
+          /* Check if all register MCE requests have been processed */
+          if (register_mce_pending == 0) {
+            if (registered_mce == mce_nb) {
+              /* If all MCE are registered, start L2L1 task */
+             // MessageDef *msg_init_p;
+             // msg_init_p = itti_alloc_new_message (TASK_ENB_APP, INITIALIZE_MESSAGE);
+             // itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p);
+            } else {
+              LOG_W(MCE_APP, " %d MCE not associated with a MME, retrying registration in %d seconds ...\n",
+                    mce_nb - registered_mce,  MCE_REGISTER_RETRY_DELAY);
+
+            //  /* Restart the MCE registration process in MCE_REGISTER_RETRY_DELAY seconds */
+            //  if (timer_setup (MCE_REGISTER_RETRY_DELAY, 0, TASK_MCE_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT,
+            //                   NULL, &mce_register_retry_timer_id) < 0) {
+            //    LOG_E(MCE_APP, " Can not start MCE register retry timer, use \"sleep\" instead!\n");
+            //    sleep(MCE_REGISTER_RETRY_DELAY);
+            //    /* Restart the registration process */
+            //    registered_mce = 0;
+            //    register_mce_pending = MCE_app_register (RC.rrc[0]->node_type,mce_id_start, mce_id_end);
+            //  }
+            }
+          }
+
+      break;
+
+   case M3AP_MBMS_SESSION_START_REQ:
+        LOG_I(MCE_APP, "Received M3AP_MBMS_SESSION_START_REQ message %s\n", ITTI_MSG_NAME (msg_p));
+	//MCE_app_handle_m3ap_mbms_session_start_req(ITTI_MESSAGE_GET_INSTANCE(msg_p));
+	if(m2ap_setup_req_local)
+		if (timer_setup (2, 0, TASK_MCE_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT,
+                               NULL, &mce_scheduling_info_timer_id) < 0) {
+   		}
+
+
+	break;
+
+   case M3AP_MBMS_SESSION_STOP_REQ:
+        LOG_I(MCE_APP, "Received M3AP_MBMS_SESSION_STOP_REQ message %s\n", ITTI_MSG_NAME (msg_p));
+	MCE_app_handle_m3ap_mbms_session_stop_req(ITTI_MESSAGE_GET_INSTANCE(msg_p));
+	break;
+
+   case M3AP_MBMS_SESSION_UPDATE_REQ:
+        LOG_I(MCE_APP, "Received M3AP_MBMS_SESSION_UPDATE_REQ message %s\n", ITTI_MSG_NAME (msg_p));
+	MCE_app_handle_m3ap_mbms_session_update_req(ITTI_MESSAGE_GET_INSTANCE(msg_p));
+	break;
+
+
+
+   case M3AP_SETUP_RESP:
+      LOG_I(MCE_APP, "Received M3AP_SETUP_RESP message %s\n", ITTI_MSG_NAME (msg_p));
+   //   //AssertFatal(NODE_IS_DU(RC.rrc[0]->node_type), "Should not have received F1AP_REGISTER_ENB_CNF in CU/MCE\n");
+
+   //   //LOG_I(MCE_APP, "Received %s: associated ngran_MCE_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p),
+   //         //F1AP_SETUP_RESP(msg_p).gNB_CU_name,F1AP_SETUP_RESP(msg_p).num_cells_to_activate);
+   //   
+   //   //handle_f1ap_setup_resp(&F1AP_SETUP_RESP(msg_p));
+   //   handle_m3ap_setup_resp(&M3AP_SETUP_RESP(msg_p));
+
+   //   DevAssert(register_mce_pending > 0);
+   //   register_mce_pending--;
+
+   //   /* Check if at least MCE is registered with one MME */
+   //   //if (M3AP_SETUP_RESP(msg_p).num_cells_to_activate > 0) {
+   //   //  registered_enb++;
+   //   //}
+
+   //   /* Check if all register MCE requests have been processed */
+   //   if (register_mce_pending == 0) {
+   //     if (registered_mce == mce_nb) {
+   //       /* If all MCE cells are registered, start L2L1 task */
+   //       MessageDef *msg_init_p;
+
+   //       //msg_init_p = itti_alloc_new_message (TASK_MCE_APP, INITIALIZE_MESSAGE);
+   //       //itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p);
+
+   //     } else {
+   //       LOG_W(MCE_APP, " %d MCE not associated with a MME, retrying registration in %d seconds ...\n",
+   //             mce_nb - registered_mce,  MCE_REGISTER_RETRY_DELAY);
+
+   //       /* Restart the MCE registration process in MCE_REGISTER_RETRY_DELAY seconds */
+   //       if (timer_setup (MCE_REGISTER_RETRY_DELAY, 0, TASK_MCE_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT,
+   //                        NULL, &mce_register_retry_timer_id) < 0) {
+   //         LOG_E(ENB_APP, " Can not start MCE register retry timer, use \"sleep\" instead!\n");
+
+   //         sleep(MCE_REGISTER_RETRY_DELAY);
+   //         /* Restart the registration process */
+   //         registered_mce = 0;
+   //         register_mce_pending = MCE_app_register (RC.rrc[0]->node_type,mce_id_start, mce_id_end);//, enb_properties_p);
+   //       }
+   //     }
+   //   }
+
+      break;
+
+    case M3AP_DEREGISTERED_MCE_IND:
+      if (EPC_MODE_ENABLED) {
+  	LOG_W(MCE_APP, "[MCE %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p),
+  	      M3AP_DEREGISTERED_MCE_IND(msg_p).nb_mme);
+  	/* TODO handle recovering of registration */
+      }
+
+      break;
+
+    case TIMER_HAS_EXPIRED:
+	      LOG_I(MCE_APP, " Received %s: timer_id %ld\n", ITTI_MSG_NAME (msg_p), TIMER_HAS_EXPIRED(msg_p).timer_id);
+
+	      if (TIMER_HAS_EXPIRED (msg_p).timer_id == mce_scheduling_info_timer_id/*mce_register_retry_timer_id*/) {
+		/* Restart the registration process */
+		//registered_mce = 0;
+		//register_mce_pending = MCE_app_register (RC.rrc[0]->node_type, mce_id_start, mce_id_end);
+		MCE_app_send_m2ap_mbms_scheduling_information(0);
+	      }
+
+	      //if (TIMER_HAS_EXPIRED (msg_p).timer_id == x2_mce_register_retry_timer_id) {
+	      //  /* Restart the registration process */
+	      //  x2_registered_mce = 0;
+	      //  x2_register_mce_pending = MCE_app_register_x2 (mce_id_start, mce_id_end);
+	      //}
+
+      break;
+
+ //   case X2AP_DEREGISTERED_ENB_IND:
+ //     LOG_W(ENB_APP, "[MCE %d] Received %s: associated MCE %d\n", instance, ITTI_MSG_NAME (msg_p),
+ //           X2AP_DEREGISTERED_ENB_IND(msg_p).nb_x2);
+ //     /* TODO handle recovering of registration */
+ //     break;
+
+ //   case X2AP_REGISTER_ENB_CNF:
+ //     LOG_I(ENB_APP, "[MCE %d] Received %s: associated MCE %d\n", instance, ITTI_MSG_NAME (msg_p),
+ //           X2AP_REGISTER_ENB_CNF(msg_p).nb_x2);
+ //     DevAssert(x2_register_enb_pending > 0);
+ //     x2_register_enb_pending--;
+
+ //     /* Check if at least MCE is registered with one target MCE */
+ //     if (X2AP_REGISTER_ENB_CNF(msg_p).nb_x2 > 0) {
+ //       x2_registered_enb++;
+ //     }
+
+ //     /* Check if all register MCE requests have been processed */
+ //     if (x2_register_enb_pending == 0) {
+ //       if (x2_registered_enb == enb_nb) {
+ //         /* If all MCE are registered, start RRC HO task */
+ //         } else {
+ //         uint32_t x2_not_associated = enb_nb - x2_registered_enb;
+ //         LOG_W(ENB_APP, " %d MCE %s not associated with the target\n",
+ //               x2_not_associated, x2_not_associated > 1 ? "are" : "is");
+
+ //         // timer to retry
+ //         /* Restart the MCE registration process in ENB_REGISTER_RETRY_DELAY seconds */
+ //         if (timer_setup (X2AP_ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP,
+ //       		   INSTANCE_DEFAULT, TIMER_ONE_SHOT, NULL,
+ //       		   &x2_enb_register_retry_timer_id) < 0) {
+ //           LOG_E(ENB_APP, " Can not start MCE X2AP register: retry timer, use \"sleep\" instead!\n");
+ //           sleep(X2AP_ENB_REGISTER_RETRY_DELAY);
+ //           /* Restart the registration process */
+ //           x2_registered_enb = 0;
+ //           x2_register_enb_pending = MCE_app_register_x2 (enb_id_start, enb_id_end);
+ //         }
+ //       }
+ //     }
+
+ //     break;
+
+ //   case M2AP_DEREGISTERED_ENB_IND:
+ //     LOG_W(ENB_APP, "[MCE %d] Received %s: associated MCE %d\n", instance, ITTI_MSG_NAME (msg_p),
+ //           M2AP_DEREGISTERED_ENB_IND(msg_p).nb_m2);
+ //     /* TODO handle recovering of registration */
+ //     break;
+
+ //   case M2AP_REGISTER_ENB_CNF:
+ //     LOG_I(ENB_APP, "[MCE %d] Received %s: associated MCE %d\n", instance, ITTI_MSG_NAME (msg_p),
+ //           M2AP_REGISTER_ENB_CNF(msg_p).nb_m2);
+ //     DevAssert(m2_register_enb_pending > 0);
+ //     m2_register_enb_pending--;
+
+ //     /* Check if at least MCE is registered with one target MCE */
+ //     if (M2AP_REGISTER_ENB_CNF(msg_p).nb_m2 > 0) {
+ //       m2_registered_enb++;
+ //     }
+
+ //     /* Check if all register MCE requests have been processed */
+ //     if (m2_register_enb_pending == 0) {
+ //       if (m2_registered_enb == enb_nb) {
+ //         /* If all MCE are registered, start RRC HO task */
+ //         } else {
+ //         uint32_t m2_not_associated = enb_nb - m2_registered_enb;
+ //         LOG_W(ENB_APP, " %d MCE %s not associated with the target\n",
+ //               m2_not_associated, m2_not_associated > 1 ? "are" : "is");
+
+ //         // timer to retry
+ //         /* Restart the MCE registration process in ENB_REGISTER_RETRY_DELAY seconds */
+ //         //if (timer_setup (X2AP_ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP,
+ //         //      	   INSTANCE_DEFAULT, TIMER_ONE_SHOT, NULL,
+ //         //      	   &x2_enb_register_retry_timer_id) < 0) {
+ //         //  LOG_E(ENB_APP, " Can not start MCE X2AP register: retry timer, use \"sleep\" instead!\n");
+ //         //  sleep(X2AP_ENB_REGISTER_RETRY_DELAY);
+ //         //  /* Restart the registration process */
+ //         //  x2_registered_enb = 0;
+ //         //  x2_register_enb_pending = MCE_app_register_x2 (enb_id_start, enb_id_end);
+ //         //}
+ //       }
+ //     }
+
+ //     break;
+   case M2AP_RESET:
+      LOG_I(MCE_APP, "Received M2AP_RESET message %s\n", ITTI_MSG_NAME (msg_p));
+	break;
+
+   case M2AP_SETUP_REQ:
+      LOG_I(MCE_APP, "Received M2AP_SETUP_REQ message %s\n", ITTI_MSG_NAME (msg_p));
+	if(!m2ap_setup_req_local)
+		m2ap_setup_req_local = (m2ap_setup_req_t*)calloc(1,sizeof(m2ap_setup_req_t));
+	if(m2ap_setup_req_local)
+		memcpy(m2ap_setup_req_local,&M2AP_SETUP_REQ(msg_p),sizeof(m2ap_setup_req_t));
+	MCE_app_handle_m2ap_setup_req(ITTI_MESSAGE_GET_INSTANCE(msg_p));
+	//MCE_app_send_m2ap_mbms_scheduling_information(0);
+	//if (timer_setup (2, 0, TASK_MCE_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT,
+        //                       NULL, &mce_scheduling_info_timer_id) < 0) {
+   	//}
+
+
+   	/*m3_register_mce_pending =*/ MCE_app_register_m3 (mce_id_start, mce_id_end);
+
+	//MCE_app_send_m2ap_session_start_req(0);
+	break;
+
+   case M2AP_MBMS_SESSION_START_RESP:
+      LOG_I(MCE_APP, "Received M2AP_MBMS_SESSION_START_RESP message %s\n", ITTI_MSG_NAME (msg_p));
+	//MCE_app_send_m2ap_session_stop_req(0);
+	MCE_app_handle_m2ap_mbms_session_start_resp(0);
+	break;
+
+   case M2AP_MBMS_SESSION_STOP_RESP:
+      LOG_I(MCE_APP, "Received M2AP_MBMS_SESSION_STOP_RESP message %s\n", ITTI_MSG_NAME (msg_p));
+	//MCE_app_send_m2ap_session_start_req(0);
+	//MCE_app_handle_m2ap_mbms_session_start_resp(0);
+	//MCE_app_send_MME_APP(0);
+	break;
+
+   case M2AP_MBMS_SCHEDULING_INFORMATION_RESP:
+      LOG_I(MCE_APP, "Received M2AP_MBMS_SCHEDULING_INFORMATION_RESP message %s\n", ITTI_MSG_NAME (msg_p));
+	MCE_app_send_m2ap_session_start_req(0);
+	break;
+
+   case M2AP_ENB_CONFIGURATION_UPDATE:
+      LOG_I(MCE_APP, "Received M2AP_ENB_CONFIGURATION_UPDATE message %s\n", ITTI_MSG_NAME (msg_p));
+	break;
+	
+   case M2AP_ERROR_INDICATION:
+      LOG_I(MCE_APP, "Received M2AP_ERROR_INDICATION message %s\n", ITTI_MSG_NAME (msg_p));
+	break;
+
+   case M2AP_MBMS_SESSION_UPDATE_RESP:
+      LOG_I(MCE_APP, "Received M2AP_MBMS_SESSION_UPDATE_RESP message %s\n", ITTI_MSG_NAME (msg_p));
+	break;
+
+   case M2AP_MBMS_SESSION_UPDATE_FAILURE:
+      LOG_I(MCE_APP, "Received M2AP_MBMS_SESSION_UPDATE_FAILURE message %s\n", ITTI_MSG_NAME (msg_p));
+	break;
+
+   case M2AP_MBMS_SERVICE_COUNTING_REPORT:
+      LOG_I(MCE_APP, "Received M2AP_MBMS_SESSION_UPDATE_REPORT message %s\n", ITTI_MSG_NAME (msg_p));
+	break;
+
+   case M2AP_MBMS_OVERLOAD_NOTIFICATION:
+      LOG_I(MCE_APP, "Received M2AP_MBMS_OVERLOAD_NOTIFICATION message %s\n", ITTI_MSG_NAME (msg_p));
+	break;
+
+   case M2AP_MBMS_SERVICE_COUNTING_RESP:
+      LOG_I(MCE_APP, "Received M2AP_MBMS_SESSION_UPDATE_RESP message %s\n", ITTI_MSG_NAME (msg_p));
+	break;
+
+   case M2AP_MBMS_SERVICE_COUNTING_FAILURE:
+      LOG_I(MCE_APP, "Received M2AP_MBMS_SESSION_UPDATE_FAILURE message %s\n", ITTI_MSG_NAME (msg_p));
+	break;
+
+   case M2AP_MCE_CONFIGURATION_UPDATE_ACK:
+      LOG_I(MCE_APP, "Received M2AP_MCE_CONFIGURATION_UPDATE_ACK message %s\n", ITTI_MSG_NAME (msg_p));
+	break;
+   case M2AP_MCE_CONFIGURATION_UPDATE_FAILURE:
+      LOG_I(MCE_APP, "Received M2AP_MCE_CONFIGURATION_UPDATE_FAILURE message %s\n", ITTI_MSG_NAME (msg_p));
+	break;
+
+    default:
+      LOG_E(MCE_APP, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p));
+      break;
+    }
+
+    result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
+    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
+  } while (1);
+
+  return NULL;
+}
+
+//void handle_reconfiguration(module_id_t mod_id) {
+//  struct timespec start, end;
+//  clock_gettime(CLOCK_MONOTONIC, &start);
+//  flexran_agent_info_t *flexran = RC.flexran[mod_id];
+//  LOG_I(ENB_APP, "lte-softmodem soft-restart requested\n");
+//
+//  if (ENB_WAIT == flexran->node_ctrl_state) {
+//    /* this is already waiting, just release */
+//    pthread_mutex_lock(&flexran->mutex_node_ctrl);
+//    flexran->node_ctrl_state = ENB_NORMAL_OPERATION;
+//    pthread_mutex_unlock(&flexran->mutex_node_ctrl);
+//    pthread_cond_signal(&flexran->cond_node_ctrl);
+//    return;
+//  }
+//
+//  if (stop_L1L2(mod_id) < 0) {
+//    LOG_E(ENB_APP, "can not stop lte-softmodem, aborting restart\n");
+//    return;
+//  }
+//
+//  /* node_ctrl_state should have value ENB_MAKE_WAIT only if this method is not
+//   * executed by the FlexRAN thread */
+//  if (ENB_MAKE_WAIT == flexran->node_ctrl_state) {
+//    LOG_I(ENB_APP, " * MCE %d: Waiting for FlexRAN RTController command *\n", mod_id);
+//    pthread_mutex_lock(&flexran->mutex_node_ctrl);
+//    flexran->node_ctrl_state = ENB_WAIT;
+//
+//    while (ENB_NORMAL_OPERATION != flexran->node_ctrl_state)
+//      pthread_cond_wait(&flexran->cond_node_ctrl, &flexran->mutex_node_ctrl);
+//
+//    pthread_mutex_unlock(&flexran->mutex_node_ctrl);
+//  }
+//
+//  if (restart_L1L2(mod_id) < 0) {
+//    LOG_E(ENB_APP, "can not restart, killing lte-softmodem\n");
+//    exit_fun("can not restart L1L2, killing lte-softmodem");
+//    return;
+//  }
+//
+//  clock_gettime(CLOCK_MONOTONIC, &end);
+//  end.tv_sec -= start.tv_sec;
+//
+//  if (end.tv_nsec >= start.tv_nsec) {
+//    end.tv_nsec -= start.tv_nsec;
+//  } else {
+//    end.tv_sec -= 1;
+//    end.tv_nsec = end.tv_nsec - start.tv_nsec + 1000000000;
+//  }
+//
+//  LOG_I(ENB_APP, "lte-softmodem restart succeeded in %ld.%ld s\n", end.tv_sec, end.tv_nsec / 1000000);
+//}
+
+
diff --git a/openair2/MCE_APP/mce_app.h b/openair2/MCE_APP/mce_app.h
new file mode 100644
index 0000000000..59146b9d0d
--- /dev/null
+++ b/openair2/MCE_APP/mce_app.h
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*
+                                mce_app.h
+                             -------------------
+  AUTHOR  : Javier Morgade
+  COMPANY : VICOMTECH Spain
+  EMAIL   : javier.morgade@ieee.org
+*/
+
+#ifndef MCE_APP_H_
+#define MCE_APP_H_
+
+#include <stdint.h>
+#include "platform_types.h"
+
+
+void *MCE_app_task(void *args_p);
+
+//void handle_reconfiguration(module_id_t mod_id);
+
+#endif /* ENB_APP_H_ */
diff --git a/openair2/MCE_APP/mce_config.c b/openair2/MCE_APP/mce_config.c
new file mode 100644
index 0000000000..975f524ebd
--- /dev/null
+++ b/openair2/MCE_APP/mce_config.c
@@ -0,0 +1,512 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*
+  mce_config.c
+  -------------------
+  AUTHOR  : Javier Morgade
+  COMPANY : Vicomtech, Spain
+  EMAIL   : javier.morgade@ieee.org
+*/
+
+#include <string.h>
+#include <inttypes.h>
+
+#include "common/utils/LOG/log.h"
+#include "assertions.h"
+#include "enb_config.h"
+#include "UTIL/OTG/otg.h"
+#include "UTIL/OTG/otg_externs.h"
+#include "intertask_interface.h"
+#include "s1ap_eNB.h"
+#include "sctp_eNB_task.h"
+#include "common/ran_context.h"
+#include "sctp_default_values.h"
+#include "LTE_SystemInformationBlockType2.h"
+#include "LAYER2/MAC/mac_extern.h"
+#include "LAYER2/MAC/mac_proto.h"
+#include "PHY/phy_extern.h"
+#include "PHY/INIT/phy_init.h"
+#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h"
+#include "nfapi_vnf.h"
+#include "nfapi_pnf.h"
+
+#include "L1_paramdef.h"
+#include "MACRLC_paramdef.h"
+#include "common/config/config_userapi.h"
+#include "RRC_config_tools.h"
+#include "enb_paramdef.h"
+#include "proto_agent.h"
+
+#include "m3ap_MCE.h"
+
+
+
+int RCconfig_MCE(void ) {
+  //int               num_enbs                      = 0;
+  //char             *enb_interface_name_for_S1U    = NULL;
+  char               *mce_interface_name_for_m2_enb = NULL;
+  char               *mce_interface_name_for_m3_mme = NULL;
+  //char             *enb_ipv4_address_for_S1U      = NULL;
+  char               *mce_ipv4_address_for_m2c      = NULL;
+  char               *mce_ipv4_address_for_m3c      = NULL;
+  //uint32_t          enb_port_for_S1U              = 0;
+  uint32_t            mce_port_for_m2c              = 0;
+  uint32_t            mce_port_for_m3c              = 0;
+  char             *address                       = NULL;
+  char             *cidr                          = NULL;
+  //char gtpupath[MAX_OPTNAME_SIZE*2 + 8];
+  char mcepath[MAX_OPTNAME_SIZE*2 + 8];
+  //paramdef_t ENBSParams[] = ENBSPARAMS_DESC;
+  //paramdef_t GTPUParams[]  = GTPUPARAMS_DESC;
+
+  paramdef_t   MCEParams[] = MCE_NETPARAMS_DESC;
+
+  ///* get number of active eNodeBs */
+  //config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL);
+  //num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt;
+  //AssertFatal (num_enbs >0,
+  //             "Failed to parse config file no active eNodeBs in %s \n", ENB_CONFIG_STRING_ACTIVE_ENBS);
+  //sprintf(gtpupath,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,0,ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
+  sprintf(mcepath,"%s.[%i].%s","MCEs",0,MCE_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
+  //config_get( GTPUParams,sizeof(GTPUParams)/sizeof(paramdef_t),gtpupath);
+  config_get(MCEParams,sizeof(MCEParams)/sizeof(paramdef_t),mcepath);
+  //cidr = enb_ipv4_address_for_S1U;
+  cidr = mce_ipv4_address_for_m2c;
+  address = strtok(cidr, "/");
+
+  //LOG_W(MCE_APP,"cidr %s\n",cidr);
+  //LOG_W(MCE_APP,"address %s\n",address);
+  //LOG_W(MCE_APP,"mce_interface_name_for_m2_enb %s\n",mce_interface_name_for_m2_enb);
+  //LOG_W(MCE_APP,"mce_ipv4_address_for_m2c %s\n",mce_ipv4_address_for_m2c);
+  //LOG_W(MCE_APP,"mce_ipv4_address_for_m2c %s\n",*(MCEParams[1/*MCE_IPV4_ADDRESS_FOR_M2C_IDX*/].strptr));
+  //LOG_W(MCE_APP,"mce_port_for_m2c %d\n",mce_port_for_m2c);
+  //LOG_W(MCE_APP,"mce_interface_name_for_m3_mme %s\n",mce_interface_name_for_m3_mme);
+  //LOG_W(MCE_APP,"mce_ipv4_address_for_m3c %s\n",mce_ipv4_address_for_m3c);
+  //LOG_W(MCE_APP,"mce_port_for_m3c %d\n",mce_port_for_m3c);
+
+//   strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4_address,*(X2ParamList.paramarray[l][ENB_X2_IPV4_ADDRESS_IDX].strptr));
+
+
+  if (address) {
+    MessageDef *message; 
+    AssertFatal((message = itti_alloc_new_message(TASK_MCE_APP, M2AP_MCE_SCTP_REQ))!=NULL,"");
+    //IPV4_STR_ADDR_TO_INT_NWBO ( address, M2AP_MCE_SCTP_REQ(message).mce_m2_ip_address, "BAD IP ADDRESS FORMAT FOR MCE M2_C !\n" );
+    M2AP_MCE_SCTP_REQ (message).mce_m2_ip_address.ipv6 = 0;
+    M2AP_MCE_SCTP_REQ (message).mce_m2_ip_address.ipv4 = 1;
+    strcpy( M2AP_MCE_SCTP_REQ (message).mce_m2_ip_address.ipv4_address, address);
+    //LOG_I(MCE_APP,"Configuring M2_C address : %s -> %x\n",address,M2AP_MCE_SCTP_REQ(message).mce_m2_ip_address);
+    M2AP_MCE_SCTP_REQ(message).mce_port_for_M2C = mce_port_for_m2c;
+    itti_send_msg_to_task (TASK_M2AP_MCE, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id) 
+  } else
+    LOG_E(MCE_APP,"invalid address for M2AP\n");
+  
+  return 0;
+}
+
+
+int RCconfig_M3(MessageDef *msg_p, uint32_t i) {
+  int l;
+  //int               num_enbs                      = 0;
+  //char             *enb_interface_name_for_S1U    = NULL;
+  char               *mce_interface_name_for_m2_enb = NULL;
+  char               *mce_interface_name_for_m3_mme = NULL;
+  //char             *enb_ipv4_address_for_S1U      = NULL;
+  char               *mce_ipv4_address_for_m2c      = NULL;
+  char               *mce_ipv4_address_for_m3c      = NULL;
+  //uint32_t          enb_port_for_S1U              = 0;
+  uint32_t            mce_port_for_m2c              = 0;
+  uint32_t            mce_port_for_m3c              = 0;
+  char             *address                       = NULL;
+  char             *cidr                          = NULL;
+
+
+  char mcepath[MAX_OPTNAME_SIZE*2 + 8];
+  paramdef_t   MCEParams[] = MCE_NETPARAMS_DESC;
+  paramdef_t M3Params[]  = M3PARAMS_DESC;
+  paramdef_t MCCHParams[]  = MCCH_PARAMS_DESC;
+
+  sprintf(mcepath,"%s.[%i].%s","MCEs",0,MCE_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
+  config_get(MCEParams,sizeof(MCEParams)/sizeof(paramdef_t),mcepath);
+
+  paramlist_def_t M3ParamList = {MCE_CONFIG_STRING_TARGET_MME_M3_IP_ADDRESS,NULL,0};
+  paramlist_def_t MCCHParamList = {MCE_CONFIG_STRING_MCCH_CONFIG_PER_MBSFN_AREA,NULL,0};
+
+  char aprefix[MAX_OPTNAME_SIZE*80 + 8];
+  sprintf(aprefix,"%s.[%i]","MCEs",0);
+  /* Some default/random parameters */
+  M3AP_REGISTER_MCE_REQ (msg_p).MCE_id = i;
+  //M3AP_REGISTER_MCE_REQ (msg_p).MME_name = "kk";
+  sprintf(aprefix,"%s.[%i]","MCEs",0);
+  config_getlist( &M3ParamList,M3Params,sizeof(M3Params)/sizeof(paramdef_t),aprefix);
+  //printf("M3ParamList.numelt %d\n",M3ParamList.numelt);
+  M3AP_REGISTER_MCE_REQ (msg_p).nb_m3 = 0;
+  for (l = 0; l < M3ParamList.numelt; l++) {
+	M3AP_REGISTER_MCE_REQ (msg_p).nb_m3 += 1;
+	M3AP_REGISTER_MCE_REQ (msg_p).MCE_name         = strdup(*(M3ParamList.paramarray[l][MCE_MCE_NAME_IDX].strptr));
+
+        strcpy(M3AP_REGISTER_MCE_REQ (msg_p).target_mme_m3_ip_address[l].ipv4_address,*(M3ParamList.paramarray[l][MCE2_M3_IPV4_ADDRESS_IDX].strptr));
+        strcpy(M3AP_REGISTER_MCE_REQ (msg_p).target_mme_m3_ip_address[l].ipv6_address,*(M3ParamList.paramarray[l][MCE2_M3_IPV6_ADDRESS_IDX].strptr));
+
+        if (strcmp(*(M3ParamList.paramarray[l][MCE2_M3_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) {
+		M3AP_REGISTER_MCE_REQ (msg_p).target_mme_m3_ip_address[l].ipv4 = 1;
+		M3AP_REGISTER_MCE_REQ (msg_p).target_mme_m3_ip_address[l].ipv6 = 0;
+	} else if (strcmp(*(M3ParamList.paramarray[l][MCE2_M3_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) {
+		M3AP_REGISTER_MCE_REQ (msg_p).target_mme_m3_ip_address[l].ipv4 = 0;
+		M3AP_REGISTER_MCE_REQ (msg_p).target_mme_m3_ip_address[l].ipv6 = 1;
+	} else if (strcmp(*(M3ParamList.paramarray[l][MCE2_M3_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) {
+		M3AP_REGISTER_MCE_REQ (msg_p).target_mme_m3_ip_address[l].ipv4 = 1;
+		M3AP_REGISTER_MCE_REQ (msg_p).target_mme_m3_ip_address[l].ipv6 = 1;
+        }
+	M3AP_REGISTER_MCE_REQ (msg_p).sctp_out_streams = 2;
+	M3AP_REGISTER_MCE_REQ (msg_p).sctp_in_streams  = 2;
+  }
+
+  sprintf(aprefix,"%s.[%i].%s","MCEs",0,MCE_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
+  config_get( MCEParams,sizeof(MCEParams)/sizeof(paramdef_t),aprefix);
+  M3AP_REGISTER_MCE_REQ (msg_p).mme_port_for_M3C = (uint32_t)*(MCEParams[MCE2_PORT_FOR_M3C_IDX].uptr);
+
+  if ((MCEParams[MCE2_IPV4_ADDR_FOR_M3C_IDX].strptr == NULL) || (M3AP_REGISTER_MCE_REQ (msg_p).mme_port_for_M3C == 0)) {
+      LOG_E(RRC,"Add eNB IPv4 address and/or port for M3C in the CONF file!\n");
+      exit(1);
+  }
+
+  cidr = *(MCEParams[MCE2_IPV4_ADDR_FOR_M3C_IDX].strptr);
+  address = strtok(cidr, "/");
+  M3AP_REGISTER_MCE_REQ (msg_p).mme_m3_ip_address.ipv6 = 0;
+  M3AP_REGISTER_MCE_REQ (msg_p).mme_m3_ip_address.ipv4 = 1;
+  strcpy(M3AP_REGISTER_MCE_REQ (msg_p).mme_m3_ip_address.ipv4_address, address);
+
+  sprintf(aprefix,"%s.[%i]","MCEs",0);
+  config_getlist( &MCCHParamList,MCCHParams,sizeof(MCCHParams)/sizeof(paramdef_t),aprefix);
+  //printf("MCCHParamList.numelt %d\n",MCCHParamList.numelt);
+  for (l = 0; l < MCCHParamList.numelt; l++) {
+        //M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].mbsfn_area = *(MCCHParamList.paramarray[l][MCCH_MBSFN_AREA_IDX].uptr);
+        //M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].pdcch_length = *(MCCHParamList.paramarray[l][MCCH_PDCCH_LENGTH_IDX].uptr);
+        //M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].repetition_period = *(MCCHParamList.paramarray[l][MCCH_REPETITION_PERIOD_IDX].uptr);
+        //M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].offset = *(MCCHParamList.paramarray[l][MCCH_OFFSET_IDX].uptr);
+        //M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].modification_period = *(MCCHParamList.paramarray[l][MCCH_MODIFICATION_PERIOD_IDX].uptr);
+        //M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].subframe_allocation_info = *(MCCHParamList.paramarray[l][MCCH_SF_ALLOCATION_INFO_IDX].uptr);
+        //M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].mcs = strdup(*(MCCHParamList.paramarray[l][MCCH_MCS_IDX].strptr));
+  }
+
+
+  
+
+
+    return 0;
+}
+int RCconfig_m2_mcch(m2ap_setup_resp_t * m2ap_setup_resp, uint32_t i) {
+  int l;
+
+  char mcepath[MAX_OPTNAME_SIZE*2 + 8];
+  paramdef_t MCCHParams[]  = MCCH_PARAMS_DESC;
+  paramdef_t   MCEParams[] = MCE_PARAMS_DESC;
+  paramdef_t PLNMParams[]  = MCE_PLMN_PARAMS_DESC;
+  paramlist_def_t MCCHParamList = {MCE_CONFIG_STRING_MCCH_CONFIG_PER_MBSFN_AREA,NULL,0};
+  char aprefix[MAX_OPTNAME_SIZE*80 + 8];
+  sprintf(mcepath,"%s.[%i]","MCEs",0);
+  config_get(MCEParams,sizeof(MCEParams)/sizeof(paramdef_t),mcepath);
+  m2ap_setup_resp->MCE_id = *(MCEParams[MCE_MCE_ID_IDX].uptr);
+  m2ap_setup_resp->MCE_name = strdup(*(MCEParams[MCE_MCE_NAME_IDX].strptr));;
+  sprintf(mcepath,"%s.[%i].%s","MCEs",0,MCE_CONFIG_STRING_PLMN);
+  config_get(PLNMParams,sizeof(PLNMParams)/sizeof(paramdef_t),mcepath);
+  m2ap_setup_resp->mcc = *(PLNMParams[MCE_CONFIG_STRING_MCC_IDX].uptr);
+  m2ap_setup_resp->mnc = *(PLNMParams[MCE_CONFIG_STRING_MNC_IDX].uptr);
+  m2ap_setup_resp->mnc_digit_length = *(PLNMParams[MCE_CONFIG_STRING_MNC_LENGTH_IDX].uptr);
+  //LOG_E(MCE_APP,"PLNM %d\n",*(PLNMParams[MCE_CONFIG_STRING_MCC_IDX].uptr));
+  //LOG_E(MCE_APP,"PLNM %d\n",*(PLNMParams[MCE_CONFIG_STRING_MNC_LENGTH_IDX].uptr));
+
+
+  sprintf(aprefix,"%s.[%i]","MCEs",0);
+  config_getlist( &MCCHParamList,MCCHParams,sizeof(MCCHParams)/sizeof(paramdef_t),aprefix);
+  //printf("MCCHParamList.numelt %d\n",MCCHParamList.numelt);
+  AssertFatal(MCCHParamList.numelt <= 8, "File wrong parsed\n");
+  for (l = 0; l < MCCHParamList.numelt; l++) {
+        m2ap_setup_resp->mcch_config_per_mbsfn[l].mbsfn_area = *(MCCHParamList.paramarray[l][MCCH_MBSFN_AREA_IDX].uptr);
+        m2ap_setup_resp->mcch_config_per_mbsfn[l].pdcch_length = *(MCCHParamList.paramarray[l][MCCH_PDCCH_LENGTH_IDX].uptr);
+        m2ap_setup_resp->mcch_config_per_mbsfn[l].repetition_period = *(MCCHParamList.paramarray[l][MCCH_REPETITION_PERIOD_IDX].uptr);
+        m2ap_setup_resp->mcch_config_per_mbsfn[l].offset = *(MCCHParamList.paramarray[l][MCCH_OFFSET_IDX].uptr);
+        m2ap_setup_resp->mcch_config_per_mbsfn[l].modification_period = *(MCCHParamList.paramarray[l][MCCH_MODIFICATION_PERIOD_IDX].uptr);
+        m2ap_setup_resp->mcch_config_per_mbsfn[l].subframe_allocation_info = *(MCCHParamList.paramarray[l][MCCH_SF_ALLOCATION_INFO_IDX].uptr);
+        m2ap_setup_resp->mcch_config_per_mbsfn[l].mcs = *(MCCHParamList.paramarray[l][MCCH_MCS_IDX].uptr);
+  }
+  m2ap_setup_resp->num_mcch_config_per_mbsfn = MCCHParamList.numelt;
+	return 0;
+}
+int RCconfig_M2_MCCH(MessageDef *msg_p, uint32_t i) {
+  int l;
+
+  char mcepath[MAX_OPTNAME_SIZE*2 + 8];
+  paramdef_t MCCHParams[]  = MCCH_PARAMS_DESC;
+  paramdef_t   MCEParams[] = MCE_PARAMS_DESC;
+  paramdef_t PLNMParams[]  = MCE_PLMN_PARAMS_DESC;
+  paramlist_def_t MCCHParamList = {MCE_CONFIG_STRING_MCCH_CONFIG_PER_MBSFN_AREA,NULL,0};
+  char aprefix[MAX_OPTNAME_SIZE*80 + 8];
+  sprintf(mcepath,"%s.[%i]","MCEs",0);
+  config_get(MCEParams,sizeof(MCEParams)/sizeof(paramdef_t),mcepath);
+  M2AP_SETUP_RESP (msg_p).MCE_id = *(MCEParams[MCE_MCE_ID_IDX].uptr);
+  M2AP_SETUP_RESP (msg_p).MCE_name = strdup(*(MCEParams[MCE_MCE_NAME_IDX].strptr));;
+  sprintf(mcepath,"%s.[%i].%s","MCEs",0,MCE_CONFIG_STRING_PLMN);
+  config_get(PLNMParams,sizeof(PLNMParams)/sizeof(paramdef_t),mcepath);
+  M2AP_SETUP_RESP (msg_p).mcc = *(PLNMParams[MCE_CONFIG_STRING_MCC_IDX].uptr);
+  M2AP_SETUP_RESP (msg_p).mnc = *(PLNMParams[MCE_CONFIG_STRING_MNC_IDX].uptr);
+  M2AP_SETUP_RESP (msg_p).mnc_digit_length = *(PLNMParams[MCE_CONFIG_STRING_MNC_LENGTH_IDX].uptr);
+  //LOG_E(MCE_APP,"PLNM %d\n",*(PLNMParams[MCE_CONFIG_STRING_MCC_IDX].uptr));
+  //LOG_E(MCE_APP,"PLNM %d\n",*(PLNMParams[MCE_CONFIG_STRING_MNC_LENGTH_IDX].uptr));
+
+
+  sprintf(aprefix,"%s.[%i]","MCEs",0);
+  config_getlist( &MCCHParamList,MCCHParams,sizeof(MCCHParams)/sizeof(paramdef_t),aprefix);
+  //printf("MCCHParamList.numelt %d\n",MCCHParamList.numelt);
+  AssertFatal(MCCHParamList.numelt <= 8, "File wrong parsed\n");
+  for (l = 0; l < MCCHParamList.numelt; l++) {
+        M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].mbsfn_area = *(MCCHParamList.paramarray[l][MCCH_MBSFN_AREA_IDX].uptr);
+        M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].pdcch_length = *(MCCHParamList.paramarray[l][MCCH_PDCCH_LENGTH_IDX].uptr);
+        M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].repetition_period = *(MCCHParamList.paramarray[l][MCCH_REPETITION_PERIOD_IDX].uptr);
+        M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].offset = *(MCCHParamList.paramarray[l][MCCH_OFFSET_IDX].uptr);
+        M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].modification_period = *(MCCHParamList.paramarray[l][MCCH_MODIFICATION_PERIOD_IDX].uptr);
+        M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].subframe_allocation_info = *(MCCHParamList.paramarray[l][MCCH_SF_ALLOCATION_INFO_IDX].uptr);
+        M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].mcs = *(MCCHParamList.paramarray[l][MCCH_MCS_IDX].uptr);
+  }
+  M2AP_SETUP_RESP(msg_p).num_mcch_config_per_mbsfn = MCCHParamList.numelt;
+
+
+	return 0;
+}
+int RCconfig_m2_scheduling(  m2ap_mbms_scheduling_information_t * m2ap_mbms_scheduling_information, uint32_t i) {
+  int l,j,k/*,m*/;
+  char mcepath[MAX_OPTNAME_SIZE*2 + 8];
+  paramdef_t MBMS_SCHE_Params[]  = MCE_MBMS_SCHEDULING_INFO_PARAMS_DESC;
+  sprintf(mcepath,"%s.[%i].%s","MCEs",0,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO);
+  //LOG_E(MCE_APP,"%s\n",mcepath);
+  config_get(MBMS_SCHE_Params,sizeof(MBMS_SCHE_Params)/sizeof(paramdef_t),mcepath);
+  //LOG_E(MCE_APP,"%s %d\n",mcepath, *(MBMS_SCHE_Params[MCE_CONFIG_STRING_MCCH_UPDATE_TIME_IDX].uptr));
+  m2ap_mbms_scheduling_information->mcch_update_time=*(MBMS_SCHE_Params[MCE_CONFIG_STRING_MCCH_UPDATE_TIME_IDX].uptr);
+
+  paramdef_t MBMS_CONFIGURATION_Params[] = MCE_MBMS_AREA_CONFIGURATION_LIST_PARAMS_DESC;
+  paramlist_def_t MBMS_AREA_CONFIGURATION_ParamList = {MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,NULL,0};
+  sprintf(mcepath,"%s.[%i].%s","MCEs",0,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO);
+  config_getlist(&MBMS_AREA_CONFIGURATION_ParamList,MBMS_CONFIGURATION_Params,sizeof(MBMS_CONFIGURATION_Params)/sizeof(paramdef_t),mcepath);
+  AssertFatal(MBMS_AREA_CONFIGURATION_ParamList.numelt <= 8, "File wrong parsed\n");
+  //LOG_E(MCE_APP,"%s\n",mcepath);
+  //LOG_E(MCE_APP,"MBMS_AREA_CONFIGURATION_ParamList.numelt %d\n",MBMS_AREA_CONFIGURATION_ParamList.numelt);
+
+  m2ap_mbms_scheduling_information->num_mbms_area_config_list = MBMS_AREA_CONFIGURATION_ParamList.numelt;
+  for (l = 0; l < MBMS_AREA_CONFIGURATION_ParamList.numelt; l++) {
+	m2ap_mbms_scheduling_information->mbms_area_config_list[l].common_sf_allocation_period = *(MBMS_AREA_CONFIGURATION_ParamList.paramarray[l][MCE_CONFIG_STRING_COMMON_SF_ALLOCATION_PERIOD_IDX].uptr);
+	m2ap_mbms_scheduling_information->mbms_area_config_list[l].mbms_area_id=*(MBMS_AREA_CONFIGURATION_ParamList.paramarray[l][MCE_CONFIG_STRING_MBMS_AREA_ID_IDX].uptr);
+  	char mcepath2[MAX_OPTNAME_SIZE*2 + 8];
+  	paramdef_t PMCH_Params[]  = MCE_MBMS_PMCH_CONFIGURATION_LIST_PARAMS_DESC;
+  	paramlist_def_t PMCH_ParamList = {MCE_CONFIG_STRING_PMCH_CONFIGURATION_LIST,NULL,0};
+  	sprintf(mcepath2,"%s.[%i].%s.%s.[%i]","MCEs",i,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO,MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,l);
+	//LOG_E(MCE_APP,"%s\n",mcepath2);
+  	config_getlist(&PMCH_ParamList,PMCH_Params,sizeof(PMCH_Params)/sizeof(paramdef_t),mcepath2);
+  	AssertFatal(PMCH_ParamList.numelt <= 8, "File wrong parsed\n");
+	m2ap_mbms_scheduling_information->mbms_area_config_list[l].num_pmch_config_list=PMCH_ParamList.numelt;
+	for(j = 0; j < PMCH_ParamList.numelt; j++){
+	m2ap_mbms_scheduling_information->mbms_area_config_list[l].pmch_config_list[j].allocated_sf_end =	*(PMCH_ParamList.paramarray[j][MCE_CONFIG_STRING_ALLOCATED_SF_END_IDX].uptr);
+		m2ap_mbms_scheduling_information->mbms_area_config_list[l].pmch_config_list[j].data_mcs = *(PMCH_ParamList.paramarray[j][MCE_CONFIG_STRING_DATA_MCS_IDX].uptr);
+	m2ap_mbms_scheduling_information->mbms_area_config_list[l].pmch_config_list[j].mch_scheduling_period= *(PMCH_ParamList.paramarray[j][MCE_CONFIG_STRING_MCH_SCHEDULING_PERIOD_IDX].uptr);
+  		char mcepath3[MAX_OPTNAME_SIZE*2 + 8];
+		paramdef_t MBMS_SESSION_LIST_Params[] = MCE_MBMS_MBMS_SESSION_LIST_DESC;
+		paramlist_def_t MBMS_SESSION_LIST_ParamList = {MCE_CONFIG_STRING_MBMS_SESSION_LIST,NULL,0};
+  		sprintf(mcepath3,"%s.[%i].%s.%s.[%i].%s.[%i]","MCEs",i,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO,MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,l,MCE_CONFIG_STRING_PMCH_CONFIGURATION_LIST,j);
+  		config_getlist(&MBMS_SESSION_LIST_ParamList,MBMS_SESSION_LIST_Params,sizeof(MBMS_SESSION_LIST_Params)/sizeof(paramdef_t),mcepath3);
+		//LOG_E(MCE_APP,"%s ---- %d\n",mcepath3, MBMS_SESSION_LIST_ParamList.numelt);
+  		AssertFatal(MBMS_SESSION_LIST_ParamList.numelt <= 8, "File wrong parsed\n");
+		m2ap_mbms_scheduling_information->mbms_area_config_list[l].pmch_config_list[j].num_mbms_session_list = MBMS_SESSION_LIST_ParamList.numelt;
+		for(k = 0; k < MBMS_SESSION_LIST_ParamList.numelt; k++ ){
+
+  			//char mcepath4[MAX_OPTNAME_SIZE*8 + 8];
+			//paramdef_t MBMS_SESSION_LIST_PER_PMCH_Params[] = MCE_MBMS_MBMS_SESSION_LIST_PER_PMCH_PARAMS_DESC;
+			//paramlist_def_t MBMS_SESSION_LIST_PER_PMCH_ParamList = {MCE_CONFIG_STRING_MBMS_SESSION_LIST_PER_PMCH,NULL,0};
+	        	//sprintf(mcepath4,"%s.[%i].%s.%s.[%i].%s.[%i].%s.[%i]","MCEs",i,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO,MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,l,MCE_CONFIG_STRING_PMCH_CONFIGURATION_LIST,j,MCE_CONFIG_STRING_MBMS_SESSION_LIST,k);
+			//LOG_E(MCE_APP,"%s\n",mcepath4);
+			//config_getlist(&MBMS_SESSION_LIST_PER_PMCH_ParamList,MBMS_SESSION_LIST_PER_PMCH_Params,sizeof(MBMS_SESSION_LIST_PER_PMCH_Params)/sizeof(paramdef_t),mcepath4);
+			//m2ap_mbms_scheduling_information->mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].num_mbms_session_per_pmch = MBMS_SESSION_LIST_PER_PMCH_ParamList.numelt;
+			//for(m = 0; m < MBMS_SESSION_LIST_PER_PMCH_ParamList.numelt; m++){
+
+			m2ap_mbms_scheduling_information->mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].service_id = 	
+			*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_MBMS_SERVICE_ID_IDX].uptr);
+			uint32_t lcid =*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_MBMS_LCID_IDX].uptr);
+			m2ap_mbms_scheduling_information->mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].lcid =lcid;	
+			//uint32_t service_id2=*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_MBMS_LCID_IDX].uptr);
+			//m2ap_mbms_scheduling_information->mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].service_id2 =service_id2;
+			//LOG_E(MCE_APP,"lcid %ld\n",*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_MBMS_LCID_IDX].uptr));
+			//LOG_E(MCE_APP,"service_id %d\n",*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_MBMS_SERVICE_ID_IDX].uptr));
+
+			char mcepath5[MAX_OPTNAME_SIZE*8 + 8];
+			paramdef_t PLNMParams[]  = MCE_PLMN_PARAMS_DESC;
+			sprintf(mcepath5,"%s.[%i].%s.%s.[%i].%s.[%i].%s.[%i].%s","MCEs",i,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO,MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,l,MCE_CONFIG_STRING_PMCH_CONFIGURATION_LIST,j,MCE_CONFIG_STRING_MBMS_SESSION_LIST,k,MCE_CONFIG_STRING_PLMN);
+			config_get(PLNMParams,sizeof(PLNMParams)/sizeof(paramdef_t),mcepath5);
+			//LOG_E(MCE_APP,"PLNM %d\n",*(PLNMParams[MCE_CONFIG_STRING_MNC_LENGTH_IDX].uptr));
+			m2ap_mbms_scheduling_information->mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].mcc = 	*(PLNMParams[MCE_CONFIG_STRING_MCC_IDX].uptr);
+			m2ap_mbms_scheduling_information->mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].mnc = 	*(PLNMParams[MCE_CONFIG_STRING_MNC_IDX].uptr);
+			m2ap_mbms_scheduling_information->mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].mnc_length = 	*(PLNMParams[MCE_CONFIG_STRING_MNC_LENGTH_IDX].uptr);
+			
+			//}
+			//LOG_E(MCE_APP,"MBMS_SESSION_LIST_PER_PMCH_ParamList.numelt %d\n",MBMS_SESSION_LIST_PER_PMCH_ParamList.numelt);
+			//AssertFatal(MBMS_SESSION_LIST_PER_PMCH_ParamList.numelt <= 8, "File wrong parsed\n");
+
+			//printf("%d\n",*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_PLNM_IDENTITY_IDX].uptr));
+			//printf("%d\n",*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_SERVICE_ID_IDX].uptr));
+			//printf("%d\n",*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_LCID_IDX].uptr));
+			//*((MBMS_SESSION_LIST_ParamList[k][].uptr);
+			//*((MBMS_SESSION_LIST_ParamList[k][].uptr);
+			//*((MBMS_SESSION_LIST_ParamList[k][].uptr);
+			//*((MBMS_SESSION_LIST_ParamList[k][].uptr);
+			//*((MBMS_SESSION_LIST_ParamList[k][].uptr);
+		}
+	}
+	paramdef_t MBSFN_SF_Params[]  = MCE_MBMS_MBMS_SF_CONFIGURATION_LIST_PARAMS_DESC;
+  	paramlist_def_t MBSFN_SF_ParamList = {MCE_CONFIG_STRING_MBMS_SF_CONFIGURATION_LIST,NULL,0};
+  	sprintf(mcepath2,"%s.[%i].%s.%s.[%i]","MCEs",i,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO,MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,l);
+	//LOG_E(MCE_APP,"%s\n",mcepath2);
+  	config_getlist(&MBSFN_SF_ParamList,MBSFN_SF_Params,sizeof(MBSFN_SF_Params)/sizeof(paramdef_t),mcepath2);
+  	AssertFatal(MBSFN_SF_ParamList.numelt <= 8, "File wrong parsed\n");
+
+	m2ap_mbms_scheduling_information->mbms_area_config_list[l].num_mbms_sf_config_list=MBSFN_SF_ParamList.numelt;
+	for(j = 0; j < MBSFN_SF_ParamList.numelt; j++){
+		m2ap_mbms_scheduling_information->mbms_area_config_list[l].mbms_sf_config_list[j].radioframe_allocation_period=*(MBSFN_SF_ParamList.paramarray[j][MCE_CONFIG_STRING_RADIOFRAME_ALLOCATION_PERIOD_IDX].uptr);
+		m2ap_mbms_scheduling_information->mbms_area_config_list[l].mbms_sf_config_list[j].radioframe_allocation_offset = *(MBSFN_SF_ParamList.paramarray[j][MCE_CONFIG_STRING_RADIOFRAME_ALLOOCATION_OFFSET_IDX].uptr);
+		if(strcmp(*(MBSFN_SF_ParamList.paramarray[j][MCE_CONFIG_STRING_NUM_FRAME_IDX].strptr),"oneFrame")==0){
+			m2ap_mbms_scheduling_information->mbms_area_config_list[l].mbms_sf_config_list[j].is_four_sf = 0;
+		}else{
+			m2ap_mbms_scheduling_information->mbms_area_config_list[l].mbms_sf_config_list[j].is_four_sf = 1;
+		}
+		m2ap_mbms_scheduling_information->mbms_area_config_list[l].mbms_sf_config_list[j].subframe_allocation = *(MBSFN_SF_ParamList.paramarray[j][MCE_CONFIG_STRING_SUBFRAME_ALLOCATION_IDX].uptr);
+	}
+
+
+  }
+	return 0;
+}
+int RCconfig_M2_SCHEDULING(MessageDef *msg_p, uint32_t i) {
+  int l,j,k/*,m*/;
+  char mcepath[MAX_OPTNAME_SIZE*2 + 8];
+  paramdef_t MBMS_SCHE_Params[]  = MCE_MBMS_SCHEDULING_INFO_PARAMS_DESC;
+  sprintf(mcepath,"%s.[%i].%s","MCEs",0,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO);
+  //LOG_E(MCE_APP,"%s\n",mcepath);
+  config_get(MBMS_SCHE_Params,sizeof(MBMS_SCHE_Params)/sizeof(paramdef_t),mcepath);
+  //LOG_E(MCE_APP,"%s %d\n",mcepath, *(MBMS_SCHE_Params[MCE_CONFIG_STRING_MCCH_UPDATE_TIME_IDX].uptr));
+  M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mcch_update_time=*(MBMS_SCHE_Params[MCE_CONFIG_STRING_MCCH_UPDATE_TIME_IDX].uptr);
+
+  paramdef_t MBMS_CONFIGURATION_Params[] = MCE_MBMS_AREA_CONFIGURATION_LIST_PARAMS_DESC;
+  paramlist_def_t MBMS_AREA_CONFIGURATION_ParamList = {MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,NULL,0};
+  sprintf(mcepath,"%s.[%i].%s","MCEs",0,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO);
+  config_getlist(&MBMS_AREA_CONFIGURATION_ParamList,MBMS_CONFIGURATION_Params,sizeof(MBMS_CONFIGURATION_Params)/sizeof(paramdef_t),mcepath);
+  AssertFatal(MBMS_AREA_CONFIGURATION_ParamList.numelt <= 8, "File wrong parsed\n");
+  //LOG_E(MCE_APP,"%s\n",mcepath);
+  //LOG_E(MCE_APP,"MBMS_AREA_CONFIGURATION_ParamList.numelt %d\n",MBMS_AREA_CONFIGURATION_ParamList.numelt);
+
+  M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).num_mbms_area_config_list = MBMS_AREA_CONFIGURATION_ParamList.numelt;
+  for (l = 0; l < MBMS_AREA_CONFIGURATION_ParamList.numelt; l++) {
+	M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].common_sf_allocation_period = *(MBMS_AREA_CONFIGURATION_ParamList.paramarray[l][MCE_CONFIG_STRING_COMMON_SF_ALLOCATION_PERIOD_IDX].uptr);
+	M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].mbms_area_id=*(MBMS_AREA_CONFIGURATION_ParamList.paramarray[l][MCE_CONFIG_STRING_MBMS_AREA_ID_IDX].uptr);
+  	char mcepath2[MAX_OPTNAME_SIZE*2 + 8];
+  	paramdef_t PMCH_Params[]  = MCE_MBMS_PMCH_CONFIGURATION_LIST_PARAMS_DESC;
+  	paramlist_def_t PMCH_ParamList = {MCE_CONFIG_STRING_PMCH_CONFIGURATION_LIST,NULL,0};
+  	sprintf(mcepath2,"%s.[%i].%s.%s.[%i]","MCEs",i,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO,MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,l);
+	//LOG_E(MCE_APP,"%s\n",mcepath2);
+  	config_getlist(&PMCH_ParamList,PMCH_Params,sizeof(PMCH_Params)/sizeof(paramdef_t),mcepath2);
+  	AssertFatal(PMCH_ParamList.numelt <= 8, "File wrong parsed\n");
+	M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].num_pmch_config_list=PMCH_ParamList.numelt;
+	for(j = 0; j < PMCH_ParamList.numelt; j++){
+	M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].pmch_config_list[j].allocated_sf_end =	*(PMCH_ParamList.paramarray[j][MCE_CONFIG_STRING_ALLOCATED_SF_END_IDX].uptr);
+		M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].pmch_config_list[j].data_mcs = *(PMCH_ParamList.paramarray[j][MCE_CONFIG_STRING_DATA_MCS_IDX].uptr);
+	M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].pmch_config_list[j].mch_scheduling_period= *(PMCH_ParamList.paramarray[j][MCE_CONFIG_STRING_MCH_SCHEDULING_PERIOD_IDX].uptr);
+  		char mcepath3[MAX_OPTNAME_SIZE*2 + 8];
+		paramdef_t MBMS_SESSION_LIST_Params[] = MCE_MBMS_MBMS_SESSION_LIST_DESC;
+		paramlist_def_t MBMS_SESSION_LIST_ParamList = {MCE_CONFIG_STRING_MBMS_SESSION_LIST,NULL,0};
+  		sprintf(mcepath3,"%s.[%i].%s.%s.[%i].%s.[%i]","MCEs",i,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO,MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,l,MCE_CONFIG_STRING_PMCH_CONFIGURATION_LIST,j);
+  		config_getlist(&MBMS_SESSION_LIST_ParamList,MBMS_SESSION_LIST_Params,sizeof(MBMS_SESSION_LIST_Params)/sizeof(paramdef_t),mcepath3);
+		//LOG_E(MCE_APP,"%s ---- %d\n",mcepath3, MBMS_SESSION_LIST_ParamList.numelt);
+  		AssertFatal(MBMS_SESSION_LIST_ParamList.numelt <= 8, "File wrong parsed\n");
+		M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].pmch_config_list[j].num_mbms_session_list = MBMS_SESSION_LIST_ParamList.numelt;
+		for(k = 0; k < MBMS_SESSION_LIST_ParamList.numelt; k++ ){
+
+  			//char mcepath4[MAX_OPTNAME_SIZE*8 + 8];
+			//paramdef_t MBMS_SESSION_LIST_PER_PMCH_Params[] = MCE_MBMS_MBMS_SESSION_LIST_PER_PMCH_PARAMS_DESC;
+			//paramlist_def_t MBMS_SESSION_LIST_PER_PMCH_ParamList = {MCE_CONFIG_STRING_MBMS_SESSION_LIST_PER_PMCH,NULL,0};
+	        	//sprintf(mcepath4,"%s.[%i].%s.%s.[%i].%s.[%i].%s.[%i]","MCEs",i,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO,MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,l,MCE_CONFIG_STRING_PMCH_CONFIGURATION_LIST,j,MCE_CONFIG_STRING_MBMS_SESSION_LIST,k);
+			//LOG_E(MCE_APP,"%s\n",mcepath4);
+			//config_getlist(&MBMS_SESSION_LIST_PER_PMCH_ParamList,MBMS_SESSION_LIST_PER_PMCH_Params,sizeof(MBMS_SESSION_LIST_PER_PMCH_Params)/sizeof(paramdef_t),mcepath4);
+			//M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].num_mbms_session_per_pmch = MBMS_SESSION_LIST_PER_PMCH_ParamList.numelt;
+			//for(m = 0; m < MBMS_SESSION_LIST_PER_PMCH_ParamList.numelt; m++){
+
+			M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].service_id = 	
+			*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_MBMS_SERVICE_ID_IDX].uptr);
+			uint32_t lcid =*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_MBMS_LCID_IDX].uptr);
+			M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].lcid =lcid;	
+			//uint32_t service_id2=*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_MBMS_LCID_IDX].uptr);
+			//M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].service_id2 =service_id2;
+			//LOG_E(MCE_APP,"lcid %ld\n",*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_MBMS_LCID_IDX].uptr));
+			//LOG_E(MCE_APP,"service_id %d\n",*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_MBMS_SERVICE_ID_IDX].uptr));
+
+			char mcepath5[MAX_OPTNAME_SIZE*8 + 8];
+			paramdef_t PLNMParams[]  = MCE_PLMN_PARAMS_DESC;
+			sprintf(mcepath5,"%s.[%i].%s.%s.[%i].%s.[%i].%s.[%i].%s","MCEs",i,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO,MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,l,MCE_CONFIG_STRING_PMCH_CONFIGURATION_LIST,j,MCE_CONFIG_STRING_MBMS_SESSION_LIST,k,MCE_CONFIG_STRING_PLMN);
+			config_get(PLNMParams,sizeof(PLNMParams)/sizeof(paramdef_t),mcepath5);
+			//LOG_E(MCE_APP,"PLNM %d\n",*(PLNMParams[MCE_CONFIG_STRING_MNC_LENGTH_IDX].uptr));
+			M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].mcc = 	*(PLNMParams[MCE_CONFIG_STRING_MCC_IDX].uptr);
+			M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].mnc = 	*(PLNMParams[MCE_CONFIG_STRING_MNC_IDX].uptr);
+			M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].mnc_length = 	*(PLNMParams[MCE_CONFIG_STRING_MNC_LENGTH_IDX].uptr);
+			
+			//}
+			//LOG_E(MCE_APP,"MBMS_SESSION_LIST_PER_PMCH_ParamList.numelt %d\n",MBMS_SESSION_LIST_PER_PMCH_ParamList.numelt);
+			//AssertFatal(MBMS_SESSION_LIST_PER_PMCH_ParamList.numelt <= 8, "File wrong parsed\n");
+
+			//printf("%d\n",*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_PLNM_IDENTITY_IDX].uptr));
+			//printf("%d\n",*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_SERVICE_ID_IDX].uptr));
+			//printf("%d\n",*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_LCID_IDX].uptr));
+			//*((MBMS_SESSION_LIST_ParamList[k][].uptr);
+			//*((MBMS_SESSION_LIST_ParamList[k][].uptr);
+			//*((MBMS_SESSION_LIST_ParamList[k][].uptr);
+			//*((MBMS_SESSION_LIST_ParamList[k][].uptr);
+			//*((MBMS_SESSION_LIST_ParamList[k][].uptr);
+		}
+	}
+	paramdef_t MBSFN_SF_Params[]  = MCE_MBMS_MBMS_SF_CONFIGURATION_LIST_PARAMS_DESC;
+  	paramlist_def_t MBSFN_SF_ParamList = {MCE_CONFIG_STRING_MBMS_SF_CONFIGURATION_LIST,NULL,0};
+  	sprintf(mcepath2,"%s.[%i].%s.%s.[%i]","MCEs",i,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO,MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,l);
+	//LOG_E(MCE_APP,"%s\n",mcepath2);
+  	config_getlist(&MBSFN_SF_ParamList,MBSFN_SF_Params,sizeof(MBSFN_SF_Params)/sizeof(paramdef_t),mcepath2);
+  	AssertFatal(MBSFN_SF_ParamList.numelt <= 8, "File wrong parsed\n");
+
+	M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].num_mbms_sf_config_list=MBSFN_SF_ParamList.numelt;
+	for(j = 0; j < MBSFN_SF_ParamList.numelt; j++){
+		M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].mbms_sf_config_list[j].radioframe_allocation_period=*(MBSFN_SF_ParamList.paramarray[j][MCE_CONFIG_STRING_RADIOFRAME_ALLOCATION_PERIOD_IDX].uptr);
+		M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].mbms_sf_config_list[j].radioframe_allocation_offset = *(MBSFN_SF_ParamList.paramarray[j][MCE_CONFIG_STRING_RADIOFRAME_ALLOOCATION_OFFSET_IDX].uptr);
+		if(strcmp(*(MBSFN_SF_ParamList.paramarray[j][MCE_CONFIG_STRING_NUM_FRAME_IDX].strptr),"oneFrame")==0){
+			M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].mbms_sf_config_list[j].is_four_sf = 0;
+		}else{
+			M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].mbms_sf_config_list[j].is_four_sf = 1;
+		}
+		M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].mbms_sf_config_list[j].subframe_allocation = *(MBSFN_SF_ParamList.paramarray[j][MCE_CONFIG_STRING_SUBFRAME_ALLOCATION_IDX].uptr);
+	}
+
+
+  }
+
+  return 0;
+}
+
diff --git a/openair2/MCE_APP/mce_config.h b/openair2/MCE_APP/mce_config.h
new file mode 100644
index 0000000000..f339401540
--- /dev/null
+++ b/openair2/MCE_APP/mce_config.h
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*
+                                mce_config.h
+                             -------------------
+  AUTHOR  : Javier Morgade
+  COMPANY : VICOMTECH, Spain
+  EMAIL   : javier.morgade@ieee.org
+*/
+
+#ifndef MCE_CONFIG_H_
+#define MCE_CONFIG_H_
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <libconfig.h>
+
+#include "commonDef.h"
+#include "platform_types.h"
+#include "platform_constants.h"
+#include "PHY/impl_defs_lte.h"
+#include "PHY/defs_eNB.h"
+#include "s1ap_messages_types.h"
+#include "f1ap_messages_types.h"
+#include "LTE_SystemInformationBlockType2.h"
+#include "rrc_messages_types.h"
+#include "RRC/LTE/rrc_defs.h"
+#include <intertask_interface.h>
+#include "enb_paramdef.h"
+
+#define IPV4_STR_ADDR_TO_INT_NWBO(AdDr_StR,NwBo,MeSsAgE ) do {\
+            struct in_addr inp;\
+            if ( inet_aton(AdDr_StR, &inp ) < 0 ) {\
+                AssertFatal (0, MeSsAgE);\
+            } else {\
+                NwBo = inp.s_addr;\
+            }\
+        } while (0);
+
+
+void read_config_and_init(void);
+
+int RCconfig_MCE(void);
+int RCconfig_M3(MessageDef *msg_p, uint32_t i);
+int RCconfig_M2_MCCH(MessageDef *msg_p, uint32_t i);
+int RCconfig_m2_mcch(m2ap_setup_resp_t * m2ap_setup_resp, uint32_t i);
+int RCconfig_M2_SCHEDULING(MessageDef *msg_p, uint32_t i);
+int RCconfig_m2_scheduling(m2ap_mbms_scheduling_information_t *m2ap_mbms_scheduling_information, uint32_t i);
+
+
+#endif /* MCE_CONFIG_H_ */
+/** @} */
-- 
2.26.2