From 717cd8a102d002fba32f57ba04c7421347e06c36 Mon Sep 17 00:00:00 2001
From: gauthier <lionel.gauthier@eurecom.fr>
Date: Tue, 24 Nov 2015 16:51:15 +0100
Subject: [PATCH] Starting debug, remainig TODO report new mme_ue_id

---
 openair2/COMMON/s1ap_messages_types.h        |   2 +-
 openair3/SCTP/sctp_eNB_task.c                |   9 ++
 openair3/TEST/EPC_TEST/play_scenario.c       |  97 +++++++++----
 openair3/TEST/EPC_TEST/play_scenario.h       |   8 +-
 openair3/TEST/EPC_TEST/play_scenario.xsl     | 144 +++++++++----------
 openair3/TEST/EPC_TEST/play_scenario_fsm.c   |  68 ++++-----
 openair3/TEST/EPC_TEST/play_scenario_parse.c |   2 -
 openair3/TEST/EPC_TEST/play_scenario_s1ap.c  |  86 +++++++++--
 8 files changed, 266 insertions(+), 150 deletions(-)

diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h
index c39725b737..f2c6a2a3a2 100644
--- a/openair2/COMMON/s1ap_messages_types.h
+++ b/openair2/COMMON/s1ap_messages_types.h
@@ -112,7 +112,7 @@ typedef struct net_ip_address_s {
   unsigned ipv4:1;
   unsigned ipv6:1;
   char ipv4_address[16];
-  char ipv6_address[40];
+  char ipv6_address[46];
 } net_ip_address_t;
 
 typedef uint64_t bitrate_t;
diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c
index c1e7d989e9..357803ac4f 100644
--- a/openair3/SCTP/sctp_eNB_task.c
+++ b/openair3/SCTP/sctp_eNB_task.c
@@ -100,6 +100,7 @@ static STAILQ_HEAD(sctp_cnx_list_head, sctp_cnx_list_elm_s) sctp_cnx_list;
 static uint16_t sctp_nb_cnx = 0;
 
 
+//------------------------------------------------------------------------------
 struct sctp_cnx_list_elm_s *sctp_get_cnx(int32_t assoc_id, int sd)
 {
   struct sctp_cnx_list_elm_s *elm;
@@ -119,6 +120,7 @@ struct sctp_cnx_list_elm_s *sctp_get_cnx(int32_t assoc_id, int sd)
   return NULL;
 }
 
+//------------------------------------------------------------------------------
 void
 sctp_handle_new_association_req(
   const instance_t instance,
@@ -388,6 +390,7 @@ sctp_handle_new_association_req(
              sd, sctp_nb_cnx, assoc_id);
 }
 
+  //------------------------------------------------------------------------------
 void sctp_send_data(
   instance_t       instance,
   task_id_t        task_id,
@@ -430,6 +433,7 @@ void sctp_send_data(
              sctp_cnx->assoc_id);
 }
 
+//------------------------------------------------------------------------------
 static int sctp_close_association(
   const instance_t instance,
   const task_id_t  requestor,
@@ -456,6 +460,7 @@ static int sctp_close_association(
   return 0;
 }
 
+//------------------------------------------------------------------------------
 static int sctp_create_new_listener(
   const instance_t instance,
   const task_id_t  requestor,
@@ -580,6 +585,7 @@ err:
   return -1;
 }
 
+//------------------------------------------------------------------------------
 static inline
 void
 sctp_eNB_accept_associations(
@@ -646,6 +652,7 @@ sctp_eNB_accept_associations(
   }
 }
 
+//------------------------------------------------------------------------------
 static inline
 void
 sctp_eNB_read_from_socket(
@@ -770,6 +777,7 @@ sctp_eNB_read_from_socket(
   }
 }
 
+//------------------------------------------------------------------------------
 void
 sctp_eNB_flush_sockets(
   struct epoll_event *events, int nb_events)
@@ -799,6 +807,7 @@ sctp_eNB_flush_sockets(
 }
 
 
+//------------------------------------------------------------------------------
 void *sctp_eNB_task(void *arg)
 {
   int                 nb_events;
diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c
index f29393f0e7..f8f334dd9c 100644
--- a/openair3/TEST/EPC_TEST/play_scenario.c
+++ b/openair3/TEST/EPC_TEST/play_scenario.c
@@ -51,6 +51,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <pthread.h>
 
 
 #include "intertask_interface_init.h"
@@ -60,6 +61,7 @@
 #include "intertask_interface.h"
 #include "play_scenario.h"
 #include "sctp_eNB_task.h"
+#include "sctp_default_values.h"
 #include "log.h"
 //------------------------------------------------------------------------------
 #define PLAY_SCENARIO              1
@@ -73,6 +75,7 @@ extern et_scenario_t  *g_scenario;
 extern int             xmlLoadExtDtdDefaultValue;
 extern int             asn_debug;
 extern int             asn1_xer_print;
+extern pthread_mutex_t g_fsm_lock;
 
 //------------------------------------------------------------------------------
 // MEMO:
@@ -170,7 +173,7 @@ void et_free_scenario(et_scenario_t* scenario)
       packet = next_packet->next;
     }
     et_free_pointer(scenario);
-    pthread_mutex_destroy(&scenario->fsm_lock);
+    pthread_mutex_destroy(&g_fsm_lock);
   }
 }
 
@@ -276,7 +279,7 @@ const char * const et_chunk_type_cid2str(const sctp_cid_t chunk_type)
     case  SCTP_CID_ASCONF:            return "ASCONF"; break;
     case  SCTP_CID_ASCONF_ACK:        return "ASCONF_ACK"; break;
     default:
-      AssertFatal (0, "ERROR %s(): Unknown chunk_type %d!\n", __FUNCTION__, chunk_type);
+      AssertFatal (0, "ERROR: Unknown chunk_type %d!\n", chunk_type);
   }
 }
 //------------------------------------------------------------------------------
@@ -284,24 +287,50 @@ et_packet_action_t et_action_str2et_action_t(const xmlChar * const action)
 {
   if ((!xmlStrcmp(action, (const xmlChar *)"SEND")))              { return ET_PACKET_ACTION_S1C_SEND;}
   if ((!xmlStrcmp(action, (const xmlChar *)"RECEIVE")))              { return ET_PACKET_ACTION_S1C_RECEIVE;}
-  AssertFatal (0, "ERROR: %s cannot convert: %s\n", __FUNCTION__, action);
+  AssertFatal (0, "ERROR: cannot convert: %s\n", action);
   //if (NULL == action) {return ACTION_S1C_NULL;}
 }
 //------------------------------------------------------------------------------
 void et_ip_str2et_ip(const xmlChar  * const ip_str, et_ip_t * const ip)
 {
-  AssertFatal (NULL != ip_str, "ERROR %s() Cannot convert null string to ip address!\n", __FUNCTION__);
-  AssertFatal (NULL != ip,     "ERROR %s() out parameter pointer is NULL!\n", __FUNCTION__);
+  AssertFatal (NULL != ip_str, "ERROR Cannot convert null string to ip address!\n");
+  AssertFatal (NULL != ip,     "ERROR out parameter pointer is NULL!\n");
   // store this IP address in sa:
   if (inet_pton(AF_INET, (const char*)ip_str, (void*)&(ip->address.ipv4)) > 0) {
     ip->address_family = AF_INET;
+    strncpy((char *)ip->str, (const char *)ip_str, INET_ADDRSTRLEN+1);
   } else if (inet_pton(AF_INET6, (const char*)ip_str, (void*)&(ip->address.ipv6)) > 0) {
     ip->address_family = AF_INET6;
+    strncpy((char *)ip->str, (const char *)ip_str, INET6_ADDRSTRLEN+1);
   } else {
     ip->address_family = AF_UNSPEC;
     AssertFatal (0, "ERROR %s() Could not parse ip address %s!\n", __FUNCTION__, ip_str);
   }
 }
+//------------------------------------------------------------------------------
+int et_compare_et_ip_to_net_ip_address(const et_ip_t * const ip, const net_ip_address_t * const net_ip)
+{
+  AssertFatal (NULL != ip,     "ERROR ip parameter\n");
+  AssertFatal (NULL != net_ip, "ERROR net_ip parameter\n");
+  switch (ip->address_family) {
+    case AF_INET:
+      if (net_ip->ipv4) {
+        S1AP_DEBUG("%s(%s,%s)=%d\n",__FUNCTION__,ip->str, net_ip->ipv4_address, strcmp(ip->str, net_ip->ipv4_address));
+        return strcmp(ip->str, net_ip->ipv4_address);
+      }
+      return -1;
+      break;
+    case AF_INET6:
+      if (net_ip->ipv6) {
+        return strcmp(ip->str, net_ip->ipv6_address);
+      }
+      return -1;
+      break;
+    default:
+      return -1;
+  }
+}
+
 #ifdef LIBCONFIG_LONG
 #define libconfig_int long
 #else
@@ -317,6 +346,7 @@ void et_enb_config_init(const  char const * lib_config_file_name_pP)
   config_setting_t *setting_mme_addresses         = NULL;
   config_setting_t *setting_mme_address           = NULL;
   config_setting_t *setting_enb                   = NULL;
+  libconfig_int     my_int;
   int               num_enb_properties            = 0;
   int               enb_properties_index          = 0;
   int               num_enbs                      = 0;
@@ -479,6 +509,20 @@ void et_enb_config_init(const  char const * lib_config_file_name_pP)
               g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv6 = 1;
             }
           }
+          // SCTP SETTING
+          g_enb_properties.properties[enb_properties_index]->sctp_out_streams = SCTP_OUT_STREAMS;
+          g_enb_properties.properties[enb_properties_index]->sctp_in_streams  = SCTP_IN_STREAMS;
+          subsetting = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_SCTP_CONFIG);
+
+          if (subsetting != NULL) {
+            if ( (config_setting_lookup_int( subsetting, ENB_CONFIG_STRING_SCTP_INSTREAMS, &my_int) )) {
+              g_enb_properties.properties[enb_properties_index]->sctp_in_streams = (uint16_t)my_int;
+            }
+
+            if ( (config_setting_lookup_int( subsetting, ENB_CONFIG_STRING_SCTP_OUTSTREAMS, &my_int) )) {
+              g_enb_properties.properties[enb_properties_index]->sctp_out_streams = (uint16_t)my_int;
+            }
+          }
 
 
           // NETWORK_INTERFACES
@@ -536,19 +580,19 @@ const Enb_properties_array_t *et_enb_config_get(void)
   return &g_enb_properties;
 }
 /*------------------------------------------------------------------------------*/
-uint32_t et_eNB_app_register(const Enb_properties_array_t *enb_properties)
+void et_eNB_app_register(const Enb_properties_array_t *enb_properties)
 {
-  uint32_t         enb_id;
-  uint32_t         mme_id;
-  MessageDef      *msg_p;
-  char            *str                  = NULL;
-  struct in_addr   addr;
+  uint32_t         enb_id = 0;
+  uint32_t         mme_id = 0;
+  MessageDef      *msg_p  = NULL;
+  char            *str    = NULL;
+  struct in_addr   addr   = {.s_addr = 0};
 
 
   g_scenario->register_enb_pending = 0;
   for (enb_id = 0; (enb_id < enb_properties->number) ; enb_id++) {
     {
-      s1ap_register_enb_req_t *s1ap_register_eNB;
+      s1ap_register_enb_req_t *s1ap_register_eNB = NULL;
 
       /* 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);
@@ -589,13 +633,10 @@ uint32_t et_eNB_app_register(const Enb_properties_array_t *enb_properties)
       str = inet_ntoa(addr);
       strcpy(s1ap_register_eNB->enb_ip_address.ipv4_address, str);
 
-      itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
-
       g_scenario->register_enb_pending++;
+      itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
     }
   }
-
-  return g_scenario->register_enb_pending;
 }
 /*------------------------------------------------------------------------------*/
 void *et_eNB_app_task(void *args_p)
@@ -603,12 +644,11 @@ void *et_eNB_app_task(void *args_p)
   et_scenario_t                  *scenario = (et_scenario_t*)args_p;
   MessageDef                     *msg_p           = NULL;
   const char                     *msg_name        = NULL;
-  instance_t                      instance;
-  int                             result;
+  instance_t                      instance        = 0;
+  int                             result          = 0;
 
   itti_mark_task_ready (TASK_ENB_APP);
 
-
   do {
     // Wait for a message
     itti_receive_msg (TASK_ENB_APP, &msg_p);
@@ -625,18 +665,20 @@ void *et_eNB_app_task(void *args_p)
       LOG_I(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, msg_name,
             S1AP_REGISTER_ENB_CNF(msg_p).nb_mme);
 
-      DevAssert(g_scenario->register_enb_pending > 0);
-      g_scenario->register_enb_pending--;
+      DevAssert(scenario->register_enb_pending > 0);
+      scenario->register_enb_pending--;
 
       /* Check if at least eNB is registered with one MME */
       if (S1AP_REGISTER_ENB_CNF(msg_p).nb_mme > 0) {
-        g_scenario->registered_enb++;
+        scenario->registered_enb++;
       }
 
       /* Check if all register eNB requests have been processed */
       if (scenario->register_enb_pending == 0) {
+        timer_remove(scenario->enb_register_retry_timer_id);
         if (scenario->registered_enb == scenario->enb_properties->number) {
           /* If all eNB are registered, start scenario */
+          LOG_D(ENB_APP, " All eNB are now associated with a MME\n");
           et_event_t event;
           event.code = ET_EVENT_S1C_CONNECTED;
           et_scenario_fsm_notify_event(event);
@@ -654,7 +696,7 @@ void *et_eNB_app_task(void *args_p)
             sleep(ET_ENB_REGISTER_RETRY_DELAY);
             /* Restart the registration process */
             scenario->registered_enb = 0;
-            scenario->register_enb_pending = et_eNB_app_register (scenario->enb_properties);
+            et_eNB_app_register (scenario->enb_properties);
           }
         }
       }
@@ -674,7 +716,7 @@ void *et_eNB_app_task(void *args_p)
       if (TIMER_HAS_EXPIRED (msg_p).timer_id == scenario->enb_register_retry_timer_id) {
         /* Restart the registration process */
         scenario->registered_enb = 0;
-        scenario->register_enb_pending = et_eNB_app_register (scenario->enb_properties);
+        et_eNB_app_register (scenario->enb_properties);
       }
       break;
 
@@ -870,10 +912,13 @@ int main( int argc, char **argv )
 
   // logging
   logInit();
+  set_glog(LOG_TRACE, LOG_MED);
+
   itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL);
 
+  set_comp_log(ENB_APP, LOG_TRACE, LOG_MED, 1);
   set_comp_log(S1AP, LOG_TRACE, LOG_MED, 1);
-  set_comp_log(SCTP, LOG_TRACE, LOG_MED, 1);
+  set_comp_log(SCTP, LOG_TRACE, LOG_FULL, 1);
   asn_debug      = 0;
   asn1_xer_print = 1;
 
@@ -895,6 +940,6 @@ int main( int argc, char **argv )
     et_free_pointer(scenario_file_name);
     et_free_pointer(enb_config_file_name);
   }
-
+  itti_wait_tasks_end();
   return ret;
 }
diff --git a/openair3/TEST/EPC_TEST/play_scenario.h b/openair3/TEST/EPC_TEST/play_scenario.h
index 3a52c6a0b8..060c77b8ee 100644
--- a/openair3/TEST/EPC_TEST/play_scenario.h
+++ b/openair3/TEST/EPC_TEST/play_scenario.h
@@ -39,7 +39,6 @@
 #define PLAY_SCENARIO_H_
 #  include <time.h>
 #  include <stdint.h>
-#  include <pthread.h>
 #  include <libxml/tree.h>
 #  include <netinet/in.h>
 
@@ -274,6 +273,7 @@ typedef struct et_ip_s {
     struct in6_addr  ipv6;
     in_addr_t        ipv4;
   }address;
+  char str[INET6_ADDRSTRLEN+1];
 }et_ip_t;
 
 typedef struct et_ip_hdr_s {
@@ -323,8 +323,6 @@ typedef struct et_scenario_s {
   uint32_t                registered_enb;
   long                    enb_register_retry_timer_id;
 
-  pthread_mutex_t         fsm_lock;
-  et_fsm_state_t          fsm_state;
 
   hash_table_t           *hash_mme2association_id;
   hash_table_t           *hash_old_ue_mme_id2ue_mme_id;
@@ -391,6 +389,7 @@ int et_s1ap_decode_pdu(S1AP_PDU_t * const pdu, s1ap_message * const message, con
 void et_decode_s1ap(et_s1ap_t * const s1ap);
 //-------------------------
 int et_s1ap_eNB_compare_assoc_id( struct s1ap_eNB_mme_data_s *p1, struct s1ap_eNB_mme_data_s *p2);
+uint32_t et_s1ap_generate_eNB_id(void);
 uint16_t et_s1ap_eNB_fetch_add_global_cnx_id(void);
 void et_s1ap_eNB_prepare_internal_data(void);
 void et_s1ap_eNB_insert_new_instance(s1ap_eNB_instance_t *new_instance_p);
@@ -436,6 +435,7 @@ int  et_split_path     ( char * pathP, char *** resP);
 void et_display_node   ( xmlNodePtr node, unsigned int indent);
 void et_display_tree   ( xmlNodePtr node, unsigned int indent);
 char * et_ip2ip_str(const et_ip_t * const ip);
+int et_compare_et_ip_to_net_ip_address(const et_ip_t * const ip, const net_ip_address_t * const net_ip);
 int et_hex2data(unsigned char * const data, const unsigned char * const hexstring, const unsigned int len);
 sctp_cid_t et_chunk_type_str2cid(const xmlChar * const chunk_type_str);
 const char * const et_chunk_type_cid2str(const sctp_cid_t chunk_type);
@@ -443,7 +443,7 @@ et_packet_action_t et_action_str2et_action_t(const xmlChar * const action);
 void et_ip_str2et_ip(const xmlChar  * const ip_str, et_ip_t * const ip);
 void et_enb_config_init(const  char const * lib_config_file_name_pP);
 const Enb_properties_array_t *et_enb_config_get(void);
-uint32_t et_eNB_app_register(const Enb_properties_array_t *enb_properties);
+void et_eNB_app_register(const Enb_properties_array_t *enb_properties);
 void *et_eNB_app_task(void *args_p);
 int et_play_scenario(et_scenario_t* const scenario);
 
diff --git a/openair3/TEST/EPC_TEST/play_scenario.xsl b/openair3/TEST/EPC_TEST/play_scenario.xsl
index 6b1c36cc3d..0ce22c08df 100644
--- a/openair3/TEST/EPC_TEST/play_scenario.xsl
+++ b/openair3/TEST/EPC_TEST/play_scenario.xsl
@@ -9,57 +9,57 @@
   />
 
   <!-- Ugly but no time to find a better way in XSLT 1.0 (map/list)-->
-  <xsl:param name="enb_s1c0"   select="'0.0.0.0'"/>
-  <xsl:param name="enb_s1c1"   select="'0.0.0.0'"/>
-  <xsl:param name="enb_s1c2"   select="'0.0.0.0'"/>
-  <xsl:param name="enb_s1c3"   select="'0.0.0.0'"/>
-  <xsl:param name="enb_s1c4"   select="'0.0.0.0'"/>
-  <xsl:param name="enb_s1c5"   select="'0.0.0.0'"/>
-  <xsl:param name="enb_s1c6"   select="'0.0.0.0'"/>
-  <xsl:param name="enb_s1c7"   select="'0.0.0.0'"/>
-  <xsl:param name="mme_s1c0_0" select="'0.0.0.0'"/>
-  <xsl:param name="mme_s1c0_1" select="'0.0.0.0'"/>
-  <xsl:param name="mme_s1c0_2" select="'0.0.0.0'"/>
-  <xsl:param name="mme_s1c0_3" select="'0.0.0.0'"/>
-  <xsl:param name="mme_s1c1_0" select="'0.0.0.0'"/>
-  <xsl:param name="mme_s1c1_1" select="'0.0.0.0'"/>
-  <xsl:param name="mme_s1c1_2" select="'0.0.0.0'"/>
-  <xsl:param name="mme_s1c1_3" select="'0.0.0.0'"/>
-  <xsl:param name="mme_s1c2_0" select="'0.0.0.0'"/>
-  <xsl:param name="mme_s1c2_1" select="'0.0.0.0'"/>
-  <xsl:param name="mme_s1c2_2" select="'0.0.0.0'"/>
-  <xsl:param name="mme_s1c2_3" select="'0.0.0.0'"/>
-  <xsl:param name="mme_s1c3_0" select="'0.0.0.0'"/>
-  <xsl:param name="mme_s1c3_1" select="'0.0.0.0'"/>
-  <xsl:param name="mme_s1c3_2" select="'0.0.0.0'"/>
-  <xsl:param name="mme_s1c3_3" select="'0.0.0.0'"/>
+  <xsl:param name="enb0_s1c"   select="'0.0.0.0'"/>
+  <xsl:param name="enb1_s1c"   select="'0.0.0.0'"/>
+  <xsl:param name="enb2_s1c"   select="'0.0.0.0'"/>
+  <xsl:param name="enb3_s1c"   select="'0.0.0.0'"/>
+  <xsl:param name="enb4_s1c"   select="'0.0.0.0'"/>
+  <xsl:param name="enb5_s1c"   select="'0.0.0.0'"/>
+  <xsl:param name="enb6_s1c"   select="'0.0.0.0'"/>
+  <xsl:param name="enb7_s1c"   select="'0.0.0.0'"/>
+  <xsl:param name="mme0_s1c_0" select="'0.0.0.0'"/>
+  <xsl:param name="mme0_s1c_1" select="'0.0.0.0'"/>
+  <xsl:param name="mme0_s1c_2" select="'0.0.0.0'"/>
+  <xsl:param name="mme0_s1c_3" select="'0.0.0.0'"/>
+  <xsl:param name="mme1_s1c_0" select="'0.0.0.0'"/>
+  <xsl:param name="mme1_s1c_1" select="'0.0.0.0'"/>
+  <xsl:param name="mme1_s1c_2" select="'0.0.0.0'"/>
+  <xsl:param name="mme1_s1c_3" select="'0.0.0.0'"/>
+  <xsl:param name="mme2_s1c_0" select="'0.0.0.0'"/>
+  <xsl:param name="mme2_s1c_1" select="'0.0.0.0'"/>
+  <xsl:param name="mme2_s1c_2" select="'0.0.0.0'"/>
+  <xsl:param name="mme2_s1c_3" select="'0.0.0.0'"/>
+  <xsl:param name="mme3_s1c_0" select="'0.0.0.0'"/>
+  <xsl:param name="mme3_s1c_1" select="'0.0.0.0'"/>
+  <xsl:param name="mme3_s1c_2" select="'0.0.0.0'"/>
+  <xsl:param name="mme3_s1c_3" select="'0.0.0.0'"/>
 
   <xsl:template match="ip.src[parent::packet]/@value">
     <xsl:choose>
-      <xsl:when test=".='enb_s1c0'"><xsl:value-of select="$enb_s1c0"/></xsl:when>
-      <xsl:when test=".='enb_s1c1'"><xsl:value-of select="$enb_s1c1"/></xsl:when>
-      <xsl:when test=".='enb_s1c2'"><xsl:value-of select="$enb_s1c2"/></xsl:when>
-      <xsl:when test=".='enb_s1c3'"><xsl:value-of select="$enb_s1c3"/></xsl:when>
-      <xsl:when test=".='enb_s1c4'"><xsl:value-of select="$enb_s1c4"/></xsl:when>
-      <xsl:when test=".='enb_s1c5'"><xsl:value-of select="$enb_s1c5"/></xsl:when>
-      <xsl:when test=".='enb_s1c6'"><xsl:value-of select="$enb_s1c6"/></xsl:when>
-      <xsl:when test=".='enb_s1c7'"><xsl:value-of select="$enb_s1c7"/></xsl:when>
-      <xsl:when test=".='mme_s1c0_0'"><xsl:value-of select="$mme_s1c0_0"/></xsl:when>
-      <xsl:when test=".='mme_s1c0_1'"><xsl:value-of select="$mme_s1c0_1"/></xsl:when>
-      <xsl:when test=".='mme_s1c0_2'"><xsl:value-of select="$mme_s1c0_2"/></xsl:when>
-      <xsl:when test=".='mme_s1c0_3'"><xsl:value-of select="$mme_s1c0_3"/></xsl:when>
-      <xsl:when test=".='mme_s1c1_0'"><xsl:value-of select="$mme_s1c1_0"/></xsl:when>
-      <xsl:when test=".='mme_s1c1_1'"><xsl:value-of select="$mme_s1c1_1"/></xsl:when>
-      <xsl:when test=".='mme_s1c1_2'"><xsl:value-of select="$mme_s1c1_2"/></xsl:when>
-      <xsl:when test=".='mme_s1c1_3'"><xsl:value-of select="$mme_s1c1_3"/></xsl:when>
-      <xsl:when test=".='mme_s1c2_0'"><xsl:value-of select="$mme_s1c2_0"/></xsl:when>
-      <xsl:when test=".='mme_s1c2_1'"><xsl:value-of select="$mme_s1c2_1"/></xsl:when>
-      <xsl:when test=".='mme_s1c2_2'"><xsl:value-of select="$mme_s1c2_2"/></xsl:when>
-      <xsl:when test=".='mme_s1c2_3'"><xsl:value-of select="$mme_s1c2_3"/></xsl:when>
-      <xsl:when test=".='mme_s1c3_0'"><xsl:value-of select="$mme_s1c3_0"/></xsl:when>
-      <xsl:when test=".='mme_s1c3_1'"><xsl:value-of select="$mme_s1c3_1"/></xsl:when>
-      <xsl:when test=".='mme_s1c3_2'"><xsl:value-of select="$mme_s1c3_2"/></xsl:when>
-      <xsl:when test=".='mme_s1c3_3'"><xsl:value-of select="$mme_s1c3_3"/></xsl:when>
+      <xsl:when test=".='enb0_s1c'"><xsl:value-of select="$enb0_s1c"/></xsl:when>
+      <xsl:when test=".='enb1_s1c'"><xsl:value-of select="$enb1_s1c"/></xsl:when>
+      <xsl:when test=".='enb2_s1c'"><xsl:value-of select="$enb2_s1c"/></xsl:when>
+      <xsl:when test=".='enb3_s1c'"><xsl:value-of select="$enb3_s1c"/></xsl:when>
+      <xsl:when test=".='enb4_s1c'"><xsl:value-of select="$enb4_s1c"/></xsl:when>
+      <xsl:when test=".='enb5_s1c'"><xsl:value-of select="$enb5_s1c"/></xsl:when>
+      <xsl:when test=".='enb6_s1c'"><xsl:value-of select="$enb6_s1c"/></xsl:when>
+      <xsl:when test=".='enb7_s1c'"><xsl:value-of select="$enb7_s1c"/></xsl:when>
+      <xsl:when test=".='mme0_s1c_0'"><xsl:value-of select="$mme0_s1c_0"/></xsl:when>
+      <xsl:when test=".='mme0_s1c_1'"><xsl:value-of select="$mme0_s1c_1"/></xsl:when>
+      <xsl:when test=".='mme0_s1c_2'"><xsl:value-of select="$mme0_s1c_2"/></xsl:when>
+      <xsl:when test=".='mme0_s1c_3'"><xsl:value-of select="$mme0_s1c_3"/></xsl:when>
+      <xsl:when test=".='mme1_s1c_0'"><xsl:value-of select="$mme1_s1c_0"/></xsl:when>
+      <xsl:when test=".='mme1_s1c_1'"><xsl:value-of select="$mme1_s1c_1"/></xsl:when>
+      <xsl:when test=".='mme1_s1c_2'"><xsl:value-of select="$mme1_s1c_2"/></xsl:when>
+      <xsl:when test=".='mme1_s1c_3'"><xsl:value-of select="$mme1_s1c_3"/></xsl:when>
+      <xsl:when test=".='mme2_s1c_0'"><xsl:value-of select="$mme2_s1c_0"/></xsl:when>
+      <xsl:when test=".='mme2_s1c_1'"><xsl:value-of select="$mme2_s1c_1"/></xsl:when>
+      <xsl:when test=".='mme2_s1c_2'"><xsl:value-of select="$mme2_s1c_2"/></xsl:when>
+      <xsl:when test=".='mme2_s1c_3'"><xsl:value-of select="$mme2_s1c_3"/></xsl:when>
+      <xsl:when test=".='mme3_s1c_0'"><xsl:value-of select="$mme3_s1c_0"/></xsl:when>
+      <xsl:when test=".='mme3_s1c_1'"><xsl:value-of select="$mme3_s1c_1"/></xsl:when>
+      <xsl:when test=".='mme3_s1c_2'"><xsl:value-of select="$mme3_s1c_2"/></xsl:when>
+      <xsl:when test=".='mme3_s1c_3'"><xsl:value-of select="$mme3_s1c_3"/></xsl:when>
       <xsl:otherwise>
         <xsl:message terminate="yes">ERROR: Cannot resolv IP <xsl:value-of select="."/> !
         </xsl:message>
@@ -69,30 +69,30 @@
   
   <xsl:template match="ip.dst[parent::packet]/@value">
     <xsl:choose>
-      <xsl:when test=".='enb_s1c0'"><xsl:value-of select="$enb_s1c0"/></xsl:when>
-      <xsl:when test=".='enb_s1c1'"><xsl:value-of select="$enb_s1c1"/></xsl:when>
-      <xsl:when test=".='enb_s1c2'"><xsl:value-of select="$enb_s1c2"/></xsl:when>
-      <xsl:when test=".='enb_s1c3'"><xsl:value-of select="$enb_s1c3"/></xsl:when>
-      <xsl:when test=".='enb_s1c4'"><xsl:value-of select="$enb_s1c4"/></xsl:when>
-      <xsl:when test=".='enb_s1c5'"><xsl:value-of select="$enb_s1c5"/></xsl:when>
-      <xsl:when test=".='enb_s1c6'"><xsl:value-of select="$enb_s1c6"/></xsl:when>
-      <xsl:when test=".='enb_s1c7'"><xsl:value-of select="$enb_s1c7"/></xsl:when>
-      <xsl:when test=".='mme_s1c0_0'"><xsl:value-of select="$mme_s1c0_0"/></xsl:when>
-      <xsl:when test=".='mme_s1c0_1'"><xsl:value-of select="$mme_s1c0_1"/></xsl:when>
-      <xsl:when test=".='mme_s1c0_2'"><xsl:value-of select="$mme_s1c0_2"/></xsl:when>
-      <xsl:when test=".='mme_s1c0_3'"><xsl:value-of select="$mme_s1c0_3"/></xsl:when>
-      <xsl:when test=".='mme_s1c1_0'"><xsl:value-of select="$mme_s1c1_0"/></xsl:when>
-      <xsl:when test=".='mme_s1c1_1'"><xsl:value-of select="$mme_s1c1_1"/></xsl:when>
-      <xsl:when test=".='mme_s1c1_2'"><xsl:value-of select="$mme_s1c1_2"/></xsl:when>
-      <xsl:when test=".='mme_s1c1_3'"><xsl:value-of select="$mme_s1c1_3"/></xsl:when>
-      <xsl:when test=".='mme_s1c2_0'"><xsl:value-of select="$mme_s1c2_0"/></xsl:when>
-      <xsl:when test=".='mme_s1c2_1'"><xsl:value-of select="$mme_s1c2_1"/></xsl:when>
-      <xsl:when test=".='mme_s1c2_2'"><xsl:value-of select="$mme_s1c2_2"/></xsl:when>
-      <xsl:when test=".='mme_s1c2_3'"><xsl:value-of select="$mme_s1c2_3"/></xsl:when>
-      <xsl:when test=".='mme_s1c3_0'"><xsl:value-of select="$mme_s1c3_0"/></xsl:when>
-      <xsl:when test=".='mme_s1c3_1'"><xsl:value-of select="$mme_s1c3_1"/></xsl:when>
-      <xsl:when test=".='mme_s1c3_2'"><xsl:value-of select="$mme_s1c3_2"/></xsl:when>
-      <xsl:when test=".='mme_s1c3_3'"><xsl:value-of select="$mme_s1c3_3"/></xsl:when>
+      <xsl:when test=".='enb0_s1c'"><xsl:value-of select="$enb0_s1c"/></xsl:when>
+      <xsl:when test=".='enb1_s1c'"><xsl:value-of select="$enb1_s1c"/></xsl:when>
+      <xsl:when test=".='enb2_s1c'"><xsl:value-of select="$enb2_s1c"/></xsl:when>
+      <xsl:when test=".='enb3_s1c'"><xsl:value-of select="$enb3_s1c"/></xsl:when>
+      <xsl:when test=".='enb4_s1c'"><xsl:value-of select="$enb4_s1c"/></xsl:when>
+      <xsl:when test=".='enb5_s1c'"><xsl:value-of select="$enb5_s1c"/></xsl:when>
+      <xsl:when test=".='enb6_s1c'"><xsl:value-of select="$enb6_s1c"/></xsl:when>
+      <xsl:when test=".='enb7_s1c'"><xsl:value-of select="$enb7_s1c"/></xsl:when>
+      <xsl:when test=".='mme0_s1c_0'"><xsl:value-of select="$mme0_s1c_0"/></xsl:when>
+      <xsl:when test=".='mme0_s1c_1'"><xsl:value-of select="$mme0_s1c_1"/></xsl:when>
+      <xsl:when test=".='mme0_s1c_2'"><xsl:value-of select="$mme0_s1c_2"/></xsl:when>
+      <xsl:when test=".='mme0_s1c_3'"><xsl:value-of select="$mme0_s1c_3"/></xsl:when>
+      <xsl:when test=".='mme1_s1c_0'"><xsl:value-of select="$mme1_s1c_0"/></xsl:when>
+      <xsl:when test=".='mme1_s1c_1'"><xsl:value-of select="$mme1_s1c_1"/></xsl:when>
+      <xsl:when test=".='mme1_s1c_2'"><xsl:value-of select="$mme1_s1c_2"/></xsl:when>
+      <xsl:when test=".='mme1_s1c_3'"><xsl:value-of select="$mme1_s1c_3"/></xsl:when>
+      <xsl:when test=".='mme2_s1c_0'"><xsl:value-of select="$mme2_s1c_0"/></xsl:when>
+      <xsl:when test=".='mme2_s1c_1'"><xsl:value-of select="$mme2_s1c_1"/></xsl:when>
+      <xsl:when test=".='mme2_s1c_2'"><xsl:value-of select="$mme2_s1c_2"/></xsl:when>
+      <xsl:when test=".='mme2_s1c_3'"><xsl:value-of select="$mme2_s1c_3"/></xsl:when>
+      <xsl:when test=".='mme3_s1c_0'"><xsl:value-of select="$mme3_s1c_0"/></xsl:when>
+      <xsl:when test=".='mme3_s1c_1'"><xsl:value-of select="$mme3_s1c_1"/></xsl:when>
+      <xsl:when test=".='mme3_s1c_2'"><xsl:value-of select="$mme3_s1c_2"/></xsl:when>
+      <xsl:when test=".='mme3_s1c_3'"><xsl:value-of select="$mme3_s1c_3"/></xsl:when>
       <xsl:otherwise>
         <xsl:message terminate="yes">ERROR: Cannot resolv IP <xsl:value-of select="."/> !
         </xsl:message>
diff --git a/openair3/TEST/EPC_TEST/play_scenario_fsm.c b/openair3/TEST/EPC_TEST/play_scenario_fsm.c
index 8e59a98258..18dba384b0 100644
--- a/openair3/TEST/EPC_TEST/play_scenario_fsm.c
+++ b/openair3/TEST/EPC_TEST/play_scenario_fsm.c
@@ -36,6 +36,7 @@
  */
 #include <stdio.h>
 #include <sys/time.h>
+#include <pthread.h>
 
 #include "intertask_interface.h"
 #include "platform_types.h"
@@ -46,7 +47,9 @@
 #include "timer.h"
 
 //------------------------------------------------------------------------------
-et_scenario_t  *g_scenario  = NULL;
+et_scenario_t    *g_scenario  = NULL;
+pthread_mutex_t   g_fsm_lock  = PTHREAD_MUTEX_INITIALIZER;
+et_fsm_state_t    g_fsm_state = ET_FSM_STATE_NULL;
 //------------------------------------------------------------------------------
 int timeval_subtract (struct timeval * const result, struct timeval * const a, struct timeval * const b)
 {
@@ -83,7 +86,7 @@ void et_scenario_wait_rx_packet(et_packet_t * const packet)
                    NULL, &packet->timer_id) < 0) {
     AssertFatal(0, " Can not start waiting RX event timer\n");
   }
-  g_scenario->fsm_state = ET_FSM_STATE_WAITING_EVENT;
+  g_fsm_state = ET_FSM_STATE_WAITING_EVENT;
   packet->status = ET_PACKET_STATUS_SCHEDULED_FOR_RECEIVING;
 }
 //------------------------------------------------------------------------------
@@ -102,7 +105,8 @@ void et_scenario_schedule_tx_packet(et_packet_t * const packet)
   s1ap_eNB_instance = et_s1ap_eNB_get_instance(packet->enb_instance);
   AssertFatal(NULL != s1ap_eNB_instance, "Cannot get s1ap_eNB_instance_t for eNB instance %d", packet->enb_instance);
 
-  g_scenario->fsm_state = ET_FSM_STATE_WAITING_EVENT;
+  LOG_D(ENB_APP, "%s\n", __FUNCTION__);
+  g_fsm_state = ET_FSM_STATE_WAITING_EVENT;
 
   switch (packet->sctp_hdr.chunk_type) {
     case SCTP_CID_DATA:
@@ -124,7 +128,7 @@ void et_scenario_schedule_tx_packet(et_packet_t * const packet)
                          NULL, &packet->timer_id) < 0) {
           AssertFatal(0, " Can not start TX event timer\n");
         }
-        // Done g_scenario->fsm_state = ET_FSM_STATE_WAITING_TX_EVENT;
+        // Done g_fsm_state = ET_FSM_STATE_WAITING_TX_EVENT;
       } else {
         // send immediately
         et_s1ap_eNB_itti_send_sctp_data_req(
@@ -134,7 +138,7 @@ void et_scenario_schedule_tx_packet(et_packet_t * const packet)
             packet->sctp_hdr.u.data_hdr.payload.binary_stream_allocated_size,
             packet->sctp_hdr.u.data_hdr.stream);
         packet->status = ET_PACKET_STATUS_SENT;
-        g_scenario->fsm_state = ET_FSM_STATE_RUNNING;
+        g_fsm_state = ET_FSM_STATE_RUNNING;
       }
       break;
     case SCTP_CID_INIT:
@@ -162,7 +166,7 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_running(et_event_t event)
     default:
       AssertFatal(0, "Case event %d not handled in ET_FSM_STATE_RUNNING", event.code);
   }
-  pthread_mutex_unlock(&g_scenario->fsm_lock);
+  pthread_mutex_unlock(&g_fsm_lock);
   return 0;
 }
 
@@ -188,14 +192,14 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_waiting(et_event_t event)
           event.u.tx_timed_packet->sctp_hdr.u.data_hdr.payload.binary_stream_allocated_size,
           event.u.tx_timed_packet->sctp_hdr.u.data_hdr.stream);
       event.u.tx_timed_packet->status = ET_PACKET_STATUS_SENT;
-      g_scenario->fsm_state = ET_FSM_STATE_RUNNING;
+      g_fsm_state = ET_FSM_STATE_RUNNING;
       break;
 
 
     default:
       AssertFatal(0, "Case event %d not handled in ET_FSM_STATE_WAITING", event.code);
   }
-  pthread_mutex_unlock(&g_scenario->fsm_lock);
+  pthread_mutex_unlock(&g_fsm_lock);
   return 0;
 }
 
@@ -215,8 +219,8 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_connecting_s1c(et_event_t even
             // no init in this scenario, may be sub-scenario
             if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_SEND) {
               et_scenario_schedule_tx_packet(g_scenario->next_packet);
-              pthread_mutex_unlock(&g_scenario->fsm_lock);
-              return g_scenario->fsm_state;
+              pthread_mutex_unlock(&g_fsm_lock);
+              return g_fsm_state;
             } else if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_RECEIVE) {
               if (g_scenario->next_packet->status == ET_PACKET_STATUS_RECEIVED) {
                 g_scenario->last_rx_packet = g_scenario->next_packet;
@@ -226,8 +230,8 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_connecting_s1c(et_event_t even
 
               } else if (g_scenario->next_packet->status == ET_PACKET_STATUS_NONE) {
                 et_scenario_wait_rx_packet(g_scenario->next_packet);
-                pthread_mutex_unlock(&g_scenario->fsm_lock);
-                return g_scenario->fsm_state;
+                pthread_mutex_unlock(&g_fsm_lock);
+                return g_fsm_state;
               } else {
                 AssertFatal(0, "Invalid packet status %d", g_scenario->next_packet->status);
               }
@@ -263,15 +267,15 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_connecting_s1c(et_event_t even
         }
       }
       fprintf(stderr, "No Packet found in this scenario: %s\n", g_scenario->name);
-      g_scenario->fsm_state = ET_FSM_STATE_NULL;
-      pthread_mutex_unlock(&g_scenario->fsm_lock);
-      return g_scenario->fsm_state;
+      g_fsm_state = ET_FSM_STATE_NULL;
+      pthread_mutex_unlock(&g_fsm_lock);
+      return g_fsm_state;
       break;
 
     default:
       AssertFatal(0, "Case event %d not handled in ET_FSM_STATE_CONNECTING_S1C", event.code);
   }
-  pthread_mutex_unlock(&g_scenario->fsm_lock);
+  pthread_mutex_unlock(&g_fsm_lock);
   return 0;
 }
 //------------------------------------------------------------------------------
@@ -289,8 +293,8 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_null(et_event_t event)
             // no init in this scenario, may be sub-scenario
             if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_SEND) {
               et_scenario_schedule_tx_packet(g_scenario->next_packet);
-              pthread_mutex_unlock(&g_scenario->fsm_lock);
-              return g_scenario->fsm_state;
+              pthread_mutex_unlock(&g_fsm_lock);
+              return g_fsm_state;
             } else if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_RECEIVE) {
               if (g_scenario->next_packet->status == ET_PACKET_STATUS_RECEIVED) {
                 g_scenario->last_rx_packet = g_scenario->next_packet;
@@ -300,8 +304,8 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_null(et_event_t event)
 
               } else if (g_scenario->next_packet->status == ET_PACKET_STATUS_NONE) {
                 et_scenario_wait_rx_packet(g_scenario->next_packet);
-                pthread_mutex_unlock(&g_scenario->fsm_lock);
-                return g_scenario->fsm_state;
+                pthread_mutex_unlock(&g_fsm_lock);
+                return g_fsm_state;
               } else {
                 AssertFatal(0, "Invalid packet status %d", g_scenario->next_packet->status);
               }
@@ -317,10 +321,10 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_null(et_event_t event)
             g_scenario->hash_mme2association_id      = hashtable_create (256,NULL,NULL);
             // Try to register each eNB
             g_scenario->registered_enb       = 0;
-            g_scenario->fsm_state            = ET_FSM_STATE_CONNECTING_S1C;
-            g_scenario->register_enb_pending = et_eNB_app_register (g_scenario->enb_properties);
-            pthread_mutex_unlock(&g_scenario->fsm_lock);
-            return g_scenario->fsm_state;
+            g_fsm_state            = ET_FSM_STATE_CONNECTING_S1C;
+            et_eNB_app_register (g_scenario->enb_properties);
+            pthread_mutex_unlock(&g_fsm_lock);
+            return g_fsm_state;
             break;
 
           case SCTP_CID_HEARTBEAT:
@@ -348,9 +352,9 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_null(et_event_t event)
         }
       }
       fprintf(stderr, "No Useful packet found in this scenario: %s\n", g_scenario->name);
-      g_scenario->fsm_state = ET_FSM_STATE_NULL;
-      pthread_mutex_unlock(&g_scenario->fsm_lock);
-      return g_scenario->fsm_state;
+      g_fsm_state = ET_FSM_STATE_NULL;
+      pthread_mutex_unlock(&g_fsm_lock);
+      return g_fsm_state;
       break;
 
     default:
@@ -364,15 +368,15 @@ et_fsm_state_t et_scenario_fsm_notify_event(et_event_t event)
 {
   AssertFatal((event.code >= ET_EVENT_START) && (event.code < ET_EVENT_END), "Unknown et_event_t.code %d", event.code);
 
-  pthread_mutex_lock(&g_scenario->fsm_lock);
-  switch (g_scenario->fsm_state){
+  pthread_mutex_lock(&g_fsm_lock);
+  switch (g_fsm_state){
     case ET_FSM_STATE_NULL: return et_scenario_fsm_notify_event_state_null(event); break;
     case ET_FSM_STATE_CONNECTING_S1C: return et_scenario_fsm_notify_event_state_connecting_s1c(event); break;
     case ET_FSM_STATE_WAITING_EVENT: return et_scenario_fsm_notify_event_state_waiting(event); break;
     case ET_FSM_STATE_RUNNING: return et_scenario_fsm_notify_event_state_running(event); break;
     default:
-      AssertFatal(0, "Case fsm_state %d not handled", g_scenario->fsm_state);
+      AssertFatal(0, "Case fsm_state %d not handled", g_fsm_state);
   }
-  pthread_mutex_unlock(&g_scenario->fsm_lock);
-  return g_scenario->fsm_state;
+  pthread_mutex_unlock(&g_fsm_lock);
+  return g_fsm_state;
 }
diff --git a/openair3/TEST/EPC_TEST/play_scenario_parse.c b/openair3/TEST/EPC_TEST/play_scenario_parse.c
index f6d8aa73ac..13c4746a5e 100644
--- a/openair3/TEST/EPC_TEST/play_scenario_parse.c
+++ b/openair3/TEST/EPC_TEST/play_scenario_parse.c
@@ -447,8 +447,6 @@ et_scenario_t* et_generate_scenario(
       printf("scenario name: %s\n", xml_char);
       scenario            = calloc(1, sizeof(*scenario));
       scenario->name      = xml_char; // nodup nofree
-      scenario->fsm_state = ET_FSM_STATE_NULL;
-      pthread_mutex_init(&scenario->fsm_lock, NULL);
 
       next_packet = &scenario->list_packet;
       for (node = root->children; node != NULL; node = node->next) {
diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c
index 7dd80904ae..d11d032b43 100644
--- a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c
+++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c
@@ -308,28 +308,82 @@ void et_s1ap_update_assoc_id_of_packets(const int32_t assoc_id,
                                         s1ap_eNB_mme_data_t        * const mme_desc_p)
 {
   et_packet_t     *packet = NULL;
-  struct in6_addr  s1c_mme_ipv6 = IN6ADDR_ANY_INIT;
-  in_addr_t        s1c_mme_ipv4 = INADDR_ANY;
-  struct in6_addr  s1c_enb_ipv6 = IN6ADDR_ANY_INIT;
-  in_addr_t        s1c_enb_ipv4 = INADDR_ANY;
+  int              ret;
+  unsigned int     old_enb_port = 0;
+  unsigned int     old_mme_port = 0;
 
-  packet = g_scenario->next_packet;
+  S1AP_DEBUG("%s for SCTP association (%u)\n",__FUNCTION__,assoc_id);
+
+  packet = g_scenario->list_packet;
   while (NULL != packet) {
     switch (packet->sctp_hdr.chunk_type) {
 
       case SCTP_CID_DATA :
-        if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_SEND) {
-          // TODO compare addresses and ports
-          if (packet->ip_hdr.dst)
-            packet->sctp_hdr.dst_port == 0;
-          packet->sctp_hdr.src_port == 0;
-
-        } else if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_RECEIVE) {
+        if (ET_PACKET_STATUS_NONE == packet->status) {
+          if (0 < old_mme_port) {
+            if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_SEND) {
+              ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.dst, &mme_desc_p->mme_net_ip_address);
+              if (0 == ret) {
+                ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.src, &s1ap_eNB_instance->s1c_net_ip_address);
+                if (0 == ret) {
+                  // same IP src, same IP dst
+                  if ((packet->sctp_hdr.dst_port == old_mme_port) && (packet->sctp_hdr.src_port == old_enb_port)) {
+                    packet->sctp_hdr.u.data_hdr.assoc_id = assoc_id;
+                    S1AP_DEBUG("tPacket:\tnum %u  | original frame number %u \n", packet->packet_number, packet->original_frame_number);
+                    S1AP_DEBUG("\tUpdated assoc id: %u\n", assoc_id);
+                  }
+                }
+              }
+            } else if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_RECEIVE) {
+              ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.src, &mme_desc_p->mme_net_ip_address);
+              if (0 == ret) {
+                ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.dst, &s1ap_eNB_instance->s1c_net_ip_address);
+                if (0 == ret) {
+                  // same IP src, same IP dst
+                  if ((packet->sctp_hdr.src_port == old_mme_port) && (packet->sctp_hdr.dst_port == old_enb_port)) {
+                    packet->sctp_hdr.u.data_hdr.assoc_id = assoc_id;
+                    S1AP_DEBUG("tPacket:\tnum %u  | original frame number %u \n", packet->packet_number, packet->original_frame_number);
+                    S1AP_DEBUG("\tUpdated assoc id: %u\n", assoc_id);
+                  }
+                }
+              }
+            }
+          }
         }
         break;
 
+        // Strong assumption
+        // in replayed scenario, the order of SCTP INIT packets is supposed to be the same as in the catched scenario
       case SCTP_CID_INIT:
+        ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.dst, &mme_desc_p->mme_net_ip_address);
+        if (0 == ret) {
+          ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.src, &s1ap_eNB_instance->s1c_net_ip_address);
+          if (0 == ret) {
+            if (0 == old_enb_port) {
+              if (ET_PACKET_STATUS_NONE == packet->status) {
+                packet->status = ET_PACKET_STATUS_SENT;
+                old_enb_port = packet->sctp_hdr.src_port;
+              }
+            }
+          }
+        }
+        break;
+
       case SCTP_CID_INIT_ACK:
+        ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.dst, &mme_desc_p->mme_net_ip_address);
+        if (0 == ret) {
+          ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.src, &s1ap_eNB_instance->s1c_net_ip_address);
+          if (0 == ret) {
+            if (old_enb_port == packet->sctp_hdr.dst_port) {
+              if (ET_PACKET_STATUS_NONE == packet->status) {
+                packet->status = ET_PACKET_STATUS_RECEIVED;
+                old_mme_port = packet->sctp_hdr.dst_port;
+              }
+            }
+          }
+        }
+        break;
+
       case SCTP_CID_HEARTBEAT:
       case SCTP_CID_HEARTBEAT_ACK:
       case SCTP_CID_COOKIE_ECHO:
@@ -384,12 +438,14 @@ void et_s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p, int sctp_s
     if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb > 0) {
       /* Decrease pending messages number */
       mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb --;
+      mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb++;
     }
 
     et_s1ap_update_assoc_id_of_packets(mme_desc_p->assoc_id,
         mme_desc_p->s1ap_eNB_instance,
         mme_desc_p);
 
+
     /* If there are no more pending messages, inform eNB app */
     if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb == 0) {
       MessageDef                 *message_p;
@@ -484,6 +540,10 @@ void et_s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_asso
     return;
   }
 
+  S1AP_DEBUG("Received successful 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);
   /* Update parameters */
   s1ap_mme_data_p->assoc_id    = sctp_new_association_resp->assoc_id;
   s1ap_mme_data_p->in_streams  = sctp_new_association_resp->in_streams;
@@ -557,7 +617,7 @@ void *et_s1ap_eNB_task(void *arg)
       if (TIMER_HAS_EXPIRED (received_msg).timer_id == g_scenario->enb_register_retry_timer_id) {
         /* Restart the registration process */
         g_scenario->registered_enb = 0;
-        g_scenario->register_enb_pending = et_eNB_app_register (g_scenario->enb_properties);
+        et_eNB_app_register (g_scenario->enb_properties);
       }
       break;
 
-- 
2.26.2