diff --git a/openair3/TEST/EPC_TEST/generic_scenario.xsl b/openair3/TEST/EPC_TEST/generic_scenario.xsl
index e55bfffd69038e567dba9ad1b90c541cdb955084..b1cadbcdfa21a8c42a88705a7d786c6eea2d335b 100644
--- a/openair3/TEST/EPC_TEST/generic_scenario.xsl
+++ b/openair3/TEST/EPC_TEST/generic_scenario.xsl
@@ -146,7 +146,7 @@
         <xsl:when test="$sctp_chunk_type_str='DATA'">
           <xsl:for-each select="./proto[@name='s1ap']">
             <xsl:variable name="s1ap_pos_offset" select="./@pos"/>
-            <payload name="{$sctp_chunk_type_str}" action="{$action}">
+            <packet name="{$sctp_chunk_type_str}" action="{$action}">
               <frame.time_relative        value="{$time_relative}"/>
                
               <!-- TODO: pos_offset(substract it from all pos_offsets in s1ap, may depend on which test scenario protocol target S1AP/NAS or NAS only...)-->
@@ -160,14 +160,14 @@
               <sctp.data_payload_proto_id value="{$sctp_data_payload_proto_id}"/>
               <sctp.chunk_type_str        value="{$sctp_chunk_type_str}"/>
               <xsl:copy-of select="node()"/>
-            </payload>
+            </packet>
           </xsl:for-each>
         </xsl:when>
         <xsl:when test="$sctp_chunk_type_str='INIT'">
           <xsl:variable name="sctp_init_nr_out_streams"  select="./field/field[@name='sctp.init_nr_out_streams']/@show"/>
           <xsl:variable name="sctp_init_nr_in_streams"   select="./field/field[@name='sctp.init_nr_in_streams']/@show"/>
           <xsl:variable name="sctp_init_initial_tsn"     select="./field/field[@name='sctp.init_initial_tsn']/@show"/>
-          <payload name="{$sctp_chunk_type_str}" action="{$action}">
+          <packet name="{$sctp_chunk_type_str}" action="{$action}">
             <frame.time_relative        value="{$time_relative}"/>
             <!-- TODO: pos_offset(substract it from all pos_offsets in s1ap, may depend on which test scenario protocol target S1AP/NAS or NAS only...)-->
             <pos_offset                 value="{$sctp_pos_offset}"/>
@@ -181,13 +181,13 @@
             <sctp.init_initial_tsn      value="{$sctp_init_initial_tsn}"/>
             <sctp.chunk_type_str        value="{$sctp_chunk_type_str}"/>
             <!--xsl:copy-of select="node()"/-->
-          </payload>
+          </packet>
         </xsl:when>
         <xsl:when test="$sctp_chunk_type_str='INIT_ACK'">
           <xsl:variable name="sctp_initack_nr_out_streams"  select="./field/field[@name='sctp.initack_nr_out_streams']/@show"/>
           <xsl:variable name="sctp_initack_nr_in_streams"   select="./field/field[@name='sctp.initack_nr_in_streams']/@show"/>
           <xsl:variable name="sctp_initack_initial_tsn"     select="./field/field[@name='sctp.initack_initial_tsn']/@show"/>
-          <payload name="{$sctp_chunk_type_str}" action="{$action}">
+          <packet name="{$sctp_chunk_type_str}" action="{$action}">
             <frame.time_relative        value="{$time_relative}"/>
             <!-- TODO: pos_offset(substract it from all pos_offsets in s1ap, may depend on which test scenario protocol target S1AP/NAS or NAS only...)-->
             <pos_offset                 value="{$sctp_pos_offset}"/>
@@ -201,13 +201,13 @@
             <sctp.initack_initial_tsn   value="{$sctp_initack_initial_tsn}"/>
             <sctp.chunk_type_str        value="{$sctp_chunk_type_str}"/>
             <!--xsl:copy-of select="node()"/-->
-          </payload>
+          </packet>
         </xsl:when>
         <!--xsl:when test="$sctp_chunk_type_str='SACK'">       </xsl:when-->
         <!--xsl:when test="$sctp_chunk_type_str='HEARTBEAT'"></xsl:when-->
         <!--xsl:when test="$sctp_chunk_type_str='HEARTBEAT_ACK'"></xsl:when-->
         <xsl:when test="$sctp_chunk_type_str='ABORT'">
-          <payload name="{$sctp_chunk_type_str}" action="{$action}">
+          <packet name="{$sctp_chunk_type_str}" action="{$action}">
             <frame.time_relative        value="{$time_relative}"/>
             <!-- TODO: pos_offset(substract it from all pos_offsets in s1ap, may depend on which test scenario protocol target S1AP/NAS or NAS only...)-->
             <pos_offset                 value="{$sctp_pos_offset}"/>
@@ -218,10 +218,10 @@
             <sctp.dstport               value="{$sctp_dstport}"/>
             <sctp.chunk_type_str        value="{$sctp_chunk_type_str}"/>
             <xsl:copy-of select="node()"/>
-          </payload>
+          </packet>
         </xsl:when>
         <xsl:when test="$sctp_chunk_type_str='SHUTDOWN'">
-          <payload name="{$sctp_chunk_type_str}" action="{$action}">
+          <packet name="{$sctp_chunk_type_str}" action="{$action}">
             <frame.time_relative        value="{$time_relative}"/>
             <!-- TODO: pos_offset(substract it from all pos_offsets in s1ap, may depend on which test scenario protocol target S1AP/NAS or NAS only...)-->
             <pos_offset                 value="{$sctp_pos_offset}"/>
@@ -232,11 +232,11 @@
             <sctp.dstport               value="{$sctp_dstport}"/>
             <sctp.chunk_type_str        value="{$sctp_chunk_type_str}"/>
             <xsl:copy-of select="node()"/>
-          </payload>
+          </packet>
         </xsl:when>
         <!--xsl:when test="$sctp_chunk_type_str='SHUTDOWN_ACK'"></xsl:when-->
         <xsl:when test="$sctp_chunk_type_str='ERROR'">
-          <payload name="{$sctp_chunk_type_str}" action="{$action}">
+          <packet name="{$sctp_chunk_type_str}" action="{$action}">
             <frame.time_relative        value="{$time_relative}"/>
             <!-- TODO: pos_offset(substract it from all pos_offsets in s1ap, may depend on which test scenario protocol target S1AP/NAS or NAS only...)-->
             <pos_offset                 value="{$sctp_pos_offset}"/>
@@ -247,7 +247,7 @@
             <sctp.dstport               value="{$sctp_dstport}"/>
             <sctp.chunk_type_str        value="{$sctp_chunk_type_str}"/>
             <xsl:copy-of select="node()"/>
-          </payload>
+          </packet>
         </xsl:when>
         <!--xsl:when test="$sctp_chunk_type_str='COOKIE_ECHO'">            </xsl:when-->
         <!--xsl:when test="$sctp_chunk_type_str='COOKIE_ACK'">            </xsl:when-->
diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c
index b8252854e408f56126c979b40014208a3d9d950d..e73a41a68372a207f0da37bfd8b5782ec3c40e48 100644
--- a/openair3/TEST/EPC_TEST/play_scenario.c
+++ b/openair3/TEST/EPC_TEST/play_scenario.c
@@ -49,7 +49,6 @@
 #include <unistd.h>
 #include <libxml/xmlmemory.h>
 #include <libxml/debugXML.h>
-#include <libxml/HTMLtree.h>
 #include <libxml/xmlIO.h>
 #include <libxml/DOCBparser.h>
 #include <libxml/xinclude.h>
@@ -138,16 +137,132 @@ int split_path( char * pathP, char *** resP)
   }
   return n_spaces;
 }
-
 //------------------------------------------------------------------------------
-void play_scenario(
+void display_node(xmlNodePtr node) {
+  if (node->type == XML_ELEMENT_NODE) {
+    xmlChar *path = xmlGetNodePath(node);
+    if (node->children != NULL && node->children->type == XML_TEXT_NODE) {
+      xmlChar *content = xmlNodeGetContent(node);
+      printf("%s -> %s\n", path, content);
+      xmlFree(content);
+    } else {
+      printf("%s\n", path);
+    }
+    xmlFree(path);
+  }
+}
+//------------------------------------------------------------------------------
+void free_scenario(test_scenario_t* scenario)
+{
+  //TODO
+}
+//------------------------------------------------------------------------------
+sctp_cid_t chunk_type_str2cid(xmlChar *chunk_type_str)
+{
+  if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"DATA")))              { return SCTP_CID_DATA;}
+  if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"INIT")))              { return SCTP_CID_INIT;}
+  if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"INIT_ACK")))          { return SCTP_CID_INIT_ACK;}
+  if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"SACK")))              { return SCTP_CID_SACK;}
+  if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"HEARTBEAT")))         { return SCTP_CID_HEARTBEAT;}
+  if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"HEARTBEAT_ACK")))     { return SCTP_CID_HEARTBEAT_ACK;}
+  if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"ABORT")))             { return SCTP_CID_ABORT;}
+  if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"SHUTDOWN")))          { return SCTP_CID_SHUTDOWN;}
+  if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"SHUTDOWN_ACK")))      { return SCTP_CID_SHUTDOWN_ACK;}
+  if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"ERROR")))             { return SCTP_CID_ERROR;}
+  if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"COOKIE_ECHO")))       { return SCTP_CID_COOKIE_ECHO;}
+  if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"COOKIE_ACK")))        { return SCTP_CID_COOKIE_ACK;}
+  if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"ECN_ECNE")))          { return SCTP_CID_ECN_ECNE;}
+  if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"ECN_CWR")))           { return SCTP_CID_ECN_CWR;}
+  if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"SHUTDOWN_COMPLETE"))) { return SCTP_CID_SHUTDOWN_COMPLETE;}
+  if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"AUTH")))              { return SCTP_CID_AUTH;}
+  if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"FWD_TSN")))           { return SCTP_CID_FWD_TSN;}
+  if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"ASCONF")))            { return SCTP_CID_ASCONF;}
+  if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"ASCONF_ACK")))        { return SCTP_CID_ASCONF_ACK;}
+  fprintf(stderr, "ERROR: Could not convert: %s\n", chunk_type_str);
+  exit(-1);
+}
+//------------------------------------------------------------------------------
+test_packet_t* parse_xml_packet(xmlNodePtr node) {
+
+  test_packet_t *packet   = NULL;
+  xmlNode       *cur_node = NULL;
+  xmlChar       *xml_char = NULL;
+
+  if (NULL != node) {
+    packet = calloc(1, sizeof(*packet));
+
+    for (cur_node = node->children; cur_node; cur_node = cur_node->next) {
+      if (cur_node->type == XML_ELEMENT_NODE) {
+        printf("node type: Element, name: %s\n", cur_node->name);
+        if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"frame.time_relative"))) {
+        } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"ip.src"))) {
+        } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"ip.dst"))) {
+        } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"sctp.chunk_type_str"))) {
+          xml_char = xmlGetProp(cur_node, (const xmlChar *)"value");
+          packet->sctp_hdr.chunk_type = chunk_type_str2cid(xml_char);
+          fprintf(stdout, "chunk_type_str2cid: %s\n", xml_char);
+        }
+      }
+    }
+  }
+  return packet;
+}
+//------------------------------------------------------------------------------
+int play_scenario(test_scenario_t* scenario) {
+  //TODO
+  return 0;
+}
+//------------------------------------------------------------------------------
+test_scenario_t* generate_scenario(
     const char const * play_scenario_filename )
 {
+  xmlDocPtr         doc      = NULL;
+  xmlNodePtr        root     = NULL;
+  xmlNodePtr        node     = NULL;
+  xmlChar          *xml_char = NULL;
+  test_scenario_t  *scenario = NULL;
+  test_packet_t    *packet   = NULL;
+  test_packet_t   **next_packet   = NULL;
+
+  doc = xmlParseFile(play_scenario_filename);
+  if (NULL == doc) {
+    AssertFatal (0, "Could not parse scenario xml file %s!\n", play_scenario_filename);
+  } else {
+    fprintf(stdout, "Test scenario file to play: %s\n", play_scenario_filename);
+  }
 
+  // Get root
+  root = xmlDocGetRootElement(doc);
+  if (NULL != root) {
+    if ((!xmlStrcmp(root->name, (const xmlChar *)"scenario"))) {
+      xml_char = xmlGetProp(root, (const xmlChar *)"name");
+      printf("scenario name: %s\n", xml_char);
+      scenario = calloc(1, sizeof(*scenario));
+      scenario->name = xml_char; // nodup nofree
+      next_packet = &scenario->list_packet;
+      for (node = root->children; node != NULL; node = node->next) {
+        if ((!xmlStrcmp(node->name, (const xmlChar *)"packet"))) {
+          packet = parse_xml_packet(node);
+          if (NULL != packet) {
+            *next_packet = packet;
+            next_packet = &packet->next;
+          } else {
+            fprintf(stdout, "WARNING omitted packet:\n");
+            display_node(node);
+          }
+        }
+      }
+    }
+  } else {
+    fprintf(stderr, "Empty xml document\n");
+  }
+  xmlFreeDoc(doc);
+  xmlCleanupParser();
+  return scenario;
 }
 
 //------------------------------------------------------------------------------
-int generate_play_scenario(
+int generate_xml_scenario(
     const char const * test_dir_name,
     const char const * test_scenario_filename,
     const char const * enb_config_filename,
@@ -180,7 +295,7 @@ int generate_play_scenario(
 
   xmlSubstituteEntitiesDefault(1);
   xmlLoadExtDtdDefaultValue = 1;
-  cur = xsltParseStylesheetFile(astring);
+  cur = xsltParseStylesheetFile((const xmlChar *)astring);
   if (NULL == cur) {
     AssertFatal (0, "Could not parse stylesheet file %s (check OPENAIR_DIR env variable)!\n", astring);
   } else {
@@ -215,7 +330,6 @@ int generate_play_scenario(
   params[nb_params] = NULL;
   res = xsltApplyStylesheet(cur, doc, params);
   if (NULL != res) {
-    // since pdml filename is not relative (no path), just filename in current directory we can safely remove
     sprintf(play_scenario_filename,"%s",test_scenario_filename);
     if (strip_extension(play_scenario_filename) > 0) {
       strcat(play_scenario_filename, ".tsml");
@@ -237,8 +351,8 @@ int generate_play_scenario(
     ret = -1;
   }
   xsltFreeStylesheet(cur);
-  xmlFreeDoc(res);
   xmlFreeDoc(doc);
+  xmlFreeDoc(res);
 
   xsltCleanupGlobals();
   xmlCleanupParser();
@@ -378,11 +492,13 @@ config_parse_opt_line (
 int main( int argc, char **argv )
 //------------------------------------------------------------------------------
 {
-  int     actions              = 0;
-  char   *test_dir_name        = NULL;
-  char   *scenario_file_name   = NULL;
-  char   *enb_config_file_name = NULL;
-  char    play_scenario_filename[NAME_MAX];
+  int              actions              = 0;
+  char            *test_dir_name        = NULL;
+  char            *scenario_file_name   = NULL;
+  char            *enb_config_file_name = NULL;
+  char             play_scenario_filename[NAME_MAX];
+  int              ret                  = 0;
+  test_scenario_t *scenario             = NULL;
 
   memset(play_scenario_filename, 0, sizeof(play_scenario_filename));
   g_openair_dir = getenv("OPENAIR_DIR");
@@ -393,13 +509,21 @@ int main( int argc, char **argv )
 
   actions = config_parse_opt_line (argc, argv, &test_dir_name, &scenario_file_name, &enb_config_file_name); //Command-line options
   if  (actions & PLAY_SCENARIO) {
-    if (generate_play_scenario(test_dir_name, scenario_file_name,enb_config_file_name, play_scenario_filename) == 0) {
-      play_scenario(play_scenario_filename);
+    if (generate_xml_scenario(test_dir_name, scenario_file_name,enb_config_file_name, play_scenario_filename) == 0) {
+      if (NULL != (scenario = generate_scenario(play_scenario_filename))) {
+        ret = play_scenario(scenario);
+      } else {
+        fprintf(stderr, "Error: Could not generate scenario from tsml file\n");
+        ret = -1;
+      }
+    } else {
+      fprintf(stderr, "Error: Could not generate tsml scenario from xml file\n");
+      ret = -1;
     }
     free_pointer(test_dir_name);
     free_pointer(scenario_file_name);
     free_pointer(enb_config_file_name);
   }
 
-  return 0;
+  return ret;
 }
diff --git a/openair3/TEST/EPC_TEST/play_scenario.h b/openair3/TEST/EPC_TEST/play_scenario.h
index c6e1087a04d60da25e8dcb66eda22804cb82fe83..4916950783d3f3effb853ab0a2bc956cd2dcdece 100644
--- a/openair3/TEST/EPC_TEST/play_scenario.h
+++ b/openair3/TEST/EPC_TEST/play_scenario.h
@@ -37,12 +37,100 @@
 
 #ifndef GENERATE_SCENARIO_H_
 #define GENERATE_SCENARIO_H_
+# include <time.h>
+# include <stdint.h>
+#include <libxml/tree.h>
 
 /** @defgroup _enb_app ENB APP 
  * @ingroup _oai2
  * @{
  */
 
+typedef enum {
+  ACTION_S1C_START = 0,
+  ACTION_S1C_NULL  = ACTION_S1C_START,
+  ACTION_S1C_SEND,
+  ACTION_S1C_RECEIVE,
+  ACTION_S1C_END
+} test_action_t;
+
+// from kernel source file 3.19/include/linux/sctp.h
+typedef enum {
+  SCTP_CID_DATA                   = 0,
+  SCTP_CID_INIT                   = 1,
+  SCTP_CID_INIT_ACK               = 2,
+  SCTP_CID_SACK                   = 3,
+  SCTP_CID_HEARTBEAT              = 4,
+  SCTP_CID_HEARTBEAT_ACK          = 5,
+  SCTP_CID_ABORT                  = 6,
+  SCTP_CID_SHUTDOWN               = 7,
+  SCTP_CID_SHUTDOWN_ACK           = 8,
+  SCTP_CID_ERROR                  = 9,
+  SCTP_CID_COOKIE_ECHO            = 10,
+  SCTP_CID_COOKIE_ACK             = 11,
+  SCTP_CID_ECN_ECNE               = 12,
+  SCTP_CID_ECN_CWR                = 13,
+  SCTP_CID_SHUTDOWN_COMPLETE      = 14,
+
+  /* AUTH Extension Section 4.1 */
+  SCTP_CID_AUTH                   = 0x0F,
+
+  /* PR-SCTP Sec 3.2 */
+  SCTP_CID_FWD_TSN                = 0xC0,
+
+  /* Use hex, as defined in ADDIP sec. 3.1 */
+  SCTP_CID_ASCONF                 = 0xC1,
+  SCTP_CID_ASCONF_ACK             = 0x80,
+} sctp_cid_t; /* enum */
+
+// from kernel source file 3.19/include/linux/sctp.h, Big Endians
+typedef struct sctp_datahdr_s {
+  uint32_t tsn;
+  uint16_t stream;
+  uint16_t ssn;
+  uint32_t ppid;
+  uint8_t  payload[0];
+} sctp_datahdr_t;
+
+// from kernel source file 3.19/include/linux/sctp.h, Big Endians
+typedef struct sctp_inithdr {
+  uint32_t init_tag;
+  uint32_t a_rwnd;
+  uint16_t num_outbound_streams;
+  uint16_t num_inbound_streams;
+  uint32_t initial_tsn;
+  uint8_t  params[0];
+}  sctp_inithdr_t;
+
+typedef sctp_inithdr_t sctp_initackhdr_t;
+
+typedef struct test_sctp_hdr_s {
+  unsigned int src_port;
+  unsigned int dst_port;
+  sctp_cid_t   chunk_type;
+  union {
+    sctp_datahdr_t    data_hdr;
+    sctp_inithdr_t    init_hdr;
+    sctp_initackhdr_t init_ack_hdr;
+  } u;
+} test_sctp_hdr_t;
+
+typedef struct test_packet_s {
+  test_action_t   action;
+  struct timeval  time_relative_to_first_packet;
+  struct timeval  time_relative_to_last_packet;
+  test_sctp_hdr_t sctp_hdr;
+  uint16_t        s1ap_byte_stream_count;
+  uint8_t        *s1ap_byte_stream;
+  xmlNodePtr     *s1ap_node;
+
+  struct test_packet_s *next;
+}test_packet_t;
+
+typedef struct test_scenario_s {
+  xmlChar        *name;
+  test_packet_t  *list_packet;
+}test_scenario_t;
 
 inline void free_pointer(void *p) {if (NULL != p) {free(p); p=NULL;}};
 #endif /* ENB_CONFIG_H_ */
diff --git a/openair3/TEST/EPC_TEST/play_scenario.xsl b/openair3/TEST/EPC_TEST/play_scenario.xsl
index 1a89128005cee64062714823ab88c3486f9f523f..6b1c36cc3d98bcd8001cc8a7d16ccc9e72ba6dd0 100644
--- a/openair3/TEST/EPC_TEST/play_scenario.xsl
+++ b/openair3/TEST/EPC_TEST/play_scenario.xsl
@@ -34,7 +34,7 @@
   <xsl:param name="mme_s1c3_2" select="'0.0.0.0'"/>
   <xsl:param name="mme_s1c3_3" select="'0.0.0.0'"/>
 
-  <xsl:template match="ip.src[parent::payload]/@value">
+  <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>
@@ -67,7 +67,7 @@
     </xsl:choose> 
   </xsl:template>
   
-  <xsl:template match="ip.dst[parent::payload]/@value">
+  <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>