/******************************************************************************* OpenAirInterface Copyright(c) 1999 - 2014 Eurecom OpenAirInterface is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenAirInterface is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenAirInterface.The full GNU General Public License is included in this distribution in the file called "COPYING". If not, see <http://www.gnu.org/licenses/>. Contact Information OpenAirInterface Admin: openair_admin@eurecom.fr OpenAirInterface Tech : openair_tech@eurecom.fr OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE *******************************************************************************/ /* play_scenario_parse.c ------------------- AUTHOR : Lionel GAUTHIER COMPANY : EURECOM EMAIL : Lionel.Gauthier@eurecom.fr */ #include <libxml/xmlmemory.h> #include <libxml/debugXML.h> #include <libxml/xmlIO.h> #include <libxml/DOCBparser.h> #include <libxml/xinclude.h> #include <libxml/catalog.h> #include <libxml/xmlreader.h> #include <libxslt/xslt.h> #include <libxslt/xsltInternals.h> #include <libxslt/transform.h> #include <libxslt/xsltutils.h> #include <sys/time.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include "intertask_interface.h" #include "platform_types.h" #include "assertions.h" #include "play_scenario.h" //------------------------------------------------------------------------------ #define ENB_CONFIG_MAX_XSLT_PARAMS 32 //------------------------------------------------------------------------------ extern Enb_properties_array_t g_enb_properties; //------------------------------------------------------------------------------ void et_parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, et_s1ap_t * const s1ap) { xmlNodePtr cur_node = NULL; xmlChar *xml_char = NULL; xmlChar *xml_char2 = NULL; unsigned int size = 0; int rc = 0; unsigned int go_deeper_in_tree = 1; if ((NULL != s1ap_node) && (NULL != s1ap)) { // see http://www.xmlsoft.org/html/libxml-tree.html#xmlCopyNode cur_node = xmlCopyNode(s1ap_node, 1); AssertFatal(NULL != cur_node, "xmlCopyNode Failed"); s1ap->doc = xmlNewDoc(BAD_CAST "1.0"); xmlDocSetRootElement(s1ap->doc, cur_node); for (cur_node = (xmlNode *)s1ap_node; cur_node; cur_node = cur_node->next) { go_deeper_in_tree = 1; if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"field"))) { // do not get hidden fields xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"hide"); if (NULL != xml_char) { if ((!xmlStrcmp(xml_char, (const xmlChar *)"yes"))) { go_deeper_in_tree = 0; } xmlFree(xml_char); } if (0 < go_deeper_in_tree) { // first get size xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"size"); if (NULL != xml_char) { size = strtoul((const char *)xml_char, NULL, 0); xmlFree(xml_char); // second: try to get value (always hex) xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value"); if (NULL != xml_char) { xml_char2 = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"name"); fprintf(stdout, "s1ap %p field %s size %d value %s\n",s1ap, xml_char2, size, xml_char); xmlFree(xml_char2); // if success to get value, do not parse children //AssertFatal ((xmlStrlen(xml_char) == size), "ERROR %s() mismatch in size %d and strlen %d\n", __FUNCTION__, size, xmlStrlen(xml_char)); //if (xmlStrlen(xml_char) == size) { AssertFatal ((s1ap->binary_stream_pos+xmlStrlen(xml_char)/2) <= s1ap->binary_stream_allocated_size, "ERROR %s() in buffer size: binary_stream_pos %d xmlStrlen(xml_char)/2=%d\n", __FUNCTION__, s1ap->binary_stream_pos, xmlStrlen(xml_char)/2); rc = et_hex2data( &s1ap->binary_stream[s1ap->binary_stream_pos], xml_char, xmlStrlen(xml_char)); s1ap->binary_stream_pos += xmlStrlen(xml_char)/2; et_display_node(cur_node, 0); AssertFatal (rc >= 0, "ERROR %s() in converting hex string %s len %d size %d rc %d\n", __FUNCTION__, xml_char, xmlStrlen(xml_char), size, rc); go_deeper_in_tree = 0; //} xmlFree(xml_char); } } } } if (0 < go_deeper_in_tree) { et_parse_s1ap(doc, cur_node->children, s1ap); } } } } //------------------------------------------------------------------------------ void et_parse_sctp_data_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_datahdr_t * const sctp_hdr) { xmlNode *cur_node = NULL; xmlChar *xml_char = NULL; xmlChar *xml_char2 = NULL; if ((NULL != sctp_node) && (NULL != sctp_hdr)) { xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name"); if (NULL != xml_char) { if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.data_payload_proto_id"))) { xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); if (NULL != xml_char2) { sctp_hdr->ppid = strtoul((const char *)xml_char2, NULL, 0); xmlFree(xml_char2); } } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.data_sid"))) { xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); if (NULL != xml_char2) { sctp_hdr->stream = strtoul((const char *)xml_char2, NULL, 16); xmlFree(xml_char2); } } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.data_tsn"))) { xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); if (NULL != xml_char2) { sctp_hdr->tsn = strtoul((const char *)xml_char2, NULL, 0); xmlFree(xml_char2); } } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.data_ssn"))) { xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); if (NULL != xml_char2) { sctp_hdr->ssn = strtoul((const char *)xml_char2, NULL, 0); xmlFree(xml_char2); } } xmlFree(xml_char); } for (cur_node = sctp_node->children; cur_node; cur_node = cur_node->next) { et_parse_sctp_data_chunk(doc, cur_node, sctp_hdr); } } } //------------------------------------------------------------------------------ void et_parse_sctp_init_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_inithdr_t * const sctp_hdr) { xmlNode *cur_node = NULL; xmlChar *xml_char = NULL; xmlChar *xml_char2 = NULL; if ((NULL != sctp_node) && (NULL != sctp_hdr)) { xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name"); if (NULL != xml_char) { if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_nr_out_streams"))) { xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); if (NULL != xml_char2) { sctp_hdr->num_outbound_streams = strtoul((const char *)xml_char2, NULL, 0); xmlFree(xml_char2); } } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_nr_in_streams"))) { xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); if (NULL != xml_char2) { sctp_hdr->num_inbound_streams = strtoul((const char *)xml_char2, NULL, 0); xmlFree(xml_char2); } } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_credit"))) { xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); if (NULL != xml_char2) { sctp_hdr->a_rwnd = strtoul((const char *)xml_char2, NULL, 0); xmlFree(xml_char2); } } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_initial_tsn"))) { xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); if (NULL != xml_char2) { sctp_hdr->initial_tsn = strtoul((const char *)xml_char2, NULL, 0); xmlFree(xml_char2); } } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_initiate_tag"))) { xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); if (NULL != xml_char2) { sctp_hdr->init_tag = strtoul((const char *)xml_char2, NULL, 16); xmlFree(xml_char2); } } xmlFree(xml_char); } for (cur_node = sctp_node->children; cur_node; cur_node = cur_node->next) { et_parse_sctp_init_chunk(doc, cur_node, sctp_hdr); } } } //------------------------------------------------------------------------------ void et_parse_sctp_init_ack_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_initackhdr_t * const sctp_hdr) { xmlNode *cur_node = NULL; xmlChar *xml_char = NULL; xmlChar *xml_char2 = NULL; if ((NULL != sctp_node) && (NULL != sctp_hdr)) { xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name"); if (NULL != xml_char) { if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_nr_out_streams"))) { xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); if (NULL != xml_char2) { sctp_hdr->num_outbound_streams = strtoul((const char *)xml_char2, NULL, 0); xmlFree(xml_char2); } } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_nr_in_streams"))) { xml_char2 = xmlGetProp((xmlNode *)(xmlNode *)sctp_node, (const xmlChar *)"value"); if (NULL != xml_char2) { sctp_hdr->num_inbound_streams = strtoul((const char *)xml_char2, NULL, 0); xmlFree(xml_char2); } } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_credit"))) { xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); if (NULL != xml_char2) { sctp_hdr->a_rwnd = strtoul((const char *)xml_char2, NULL, 0); xmlFree(xml_char2); } } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_initial_tsn"))) { xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); if (NULL != xml_char2) { sctp_hdr->initial_tsn = strtoul((const char *)xml_char2, NULL, 0); xmlFree(xml_char2); } } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_initiate_tag"))) { xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); if (NULL != xml_char2) { sctp_hdr->init_tag = strtoul((const char *)xml_char2, NULL, 16); xmlFree(xml_char2); } } xmlFree(xml_char); } for (cur_node = sctp_node->children; cur_node; cur_node = cur_node->next) { et_parse_sctp_init_ack_chunk(doc, cur_node, sctp_hdr); } } } //------------------------------------------------------------------------------ void et_parse_sctp(xmlDocPtr doc, const xmlNode const *sctp_node, et_sctp_hdr_t * const sctp_hdr) { xmlNode *cur_node = NULL; xmlChar *xml_char = NULL; xmlChar *xml_char2 = NULL; if ((NULL != sctp_node) && (NULL != sctp_hdr)) { if ((!xmlStrcmp(sctp_node->name, (const xmlChar *)"proto"))) { xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name"); if (NULL != xml_char) { if ((!xmlStrcmp(xml_char, (const xmlChar *)"s1ap"))) { xmlFree(xml_char); xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"size"); if (NULL != xml_char2) { sctp_hdr->u.data_hdr.payload.binary_stream_allocated_size = strtoul((const char *)xml_char2, NULL, 0); sctp_hdr->u.data_hdr.payload.binary_stream = calloc(1, sctp_hdr->u.data_hdr.payload.binary_stream_allocated_size); xmlFree(xml_char2); } et_parse_s1ap(doc, sctp_node, &sctp_hdr->u.data_hdr.payload); et_decode_s1ap(&sctp_hdr->u.data_hdr.payload); return; } xmlFree(xml_char); } } //if ((cur_node->type == XML_ATTRIBUTE_NODE) || (cur_node->type == XML_ELEMENT_NODE)) { xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name"); if (NULL != xml_char) { if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.srcport"))) { xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); if (NULL != xml_char2) { sctp_hdr->src_port = strtoul((const char *)xml_char2, NULL, 16); xmlFree(xml_char2); } } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.dstport"))) { xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); if (NULL != xml_char2) { sctp_hdr->dst_port = strtoul((const char *)xml_char2, NULL, 16); xmlFree(xml_char2); } } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.chunk_type"))) { xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); if (NULL != xml_char2) { sctp_hdr->chunk_type = strtoul((const char *)xml_char2, NULL, 0); xmlFree(xml_char2); switch (sctp_hdr->chunk_type) { case SCTP_CID_DATA: et_parse_sctp_data_chunk(doc, sctp_node->parent, &sctp_hdr->u.data_hdr); break; case SCTP_CID_INIT: et_parse_sctp_init_chunk(doc, sctp_node->parent, &sctp_hdr->u.init_hdr); break; case SCTP_CID_INIT_ACK: et_parse_sctp_init_ack_chunk(doc, sctp_node->parent, &sctp_hdr->u.init_ack_hdr); break; default: ; } } } } for (cur_node = sctp_node->children; cur_node; cur_node = cur_node->next) { et_parse_sctp(doc, cur_node, sctp_hdr); } } } //------------------------------------------------------------------------------ void et_packet_shift_timing(et_packet_t * const packet, const struct timeval * const shift) { timeval_add(&packet->time_relative_to_first_packet, &packet->time_relative_to_first_packet, shift); AssertFatal((packet->time_relative_to_first_packet.tv_sec >= 0) && (packet->time_relative_to_first_packet.tv_usec >= 0), "Bad timing result time_relative_to_first_packet=%d.%d packet num %u, original frame number %u", packet->time_relative_to_first_packet.tv_sec, packet->time_relative_to_first_packet.tv_usec, packet->packet_number, packet->original_frame_number); timeval_add(&packet->time_relative_to_last_received_packet, &packet->time_relative_to_last_received_packet, shift); AssertFatal((packet->time_relative_to_last_received_packet.tv_sec >= 0) && (packet->time_relative_to_last_received_packet.tv_usec >= 0), "Bad timing result time_relative_to_last_received_packet=%d.%d packet num %u, original frame number %u", packet->time_relative_to_last_received_packet.tv_sec, packet->time_relative_to_last_received_packet.tv_usec, packet->packet_number, packet->original_frame_number); timeval_add(&packet->time_relative_to_last_sent_packet, &packet->time_relative_to_last_sent_packet, shift); AssertFatal((packet->time_relative_to_last_sent_packet.tv_sec >= 0) && (packet->time_relative_to_last_sent_packet.tv_usec >= 0), "Bad timing result time_relative_to_last_sent_packet=%d.%d packet num %u, original frame number %u", packet->time_relative_to_last_sent_packet.tv_sec, packet->time_relative_to_last_sent_packet.tv_usec, packet->packet_number, packet->original_frame_number); } //------------------------------------------------------------------------------ et_packet_t* et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node) { et_packet_t *packet = NULL; xmlNode *cur_node = NULL; xmlChar *xml_char = NULL; float afloat = (float)0.0; static struct timeval initial_time = { .tv_sec = 0, .tv_usec = 0 }; static struct timeval relative_last_sent_packet = { .tv_sec = 0, .tv_usec = 0 }; static struct timeval relative_last_received_packet = { .tv_sec = 0, .tv_usec = 0 }; static char first_packet = 1; static char first_sent_packet = 1; static char first_received_packet = 1; static unsigned int packet_number = 1; if (NULL != node) { packet = calloc(1, sizeof(*packet)); xml_char = xmlGetProp(node, (const xmlChar *)"action"); packet->action = et_action_str2et_action_t(xml_char); packet->status = ET_PACKET_STATUS_NONE; xmlFree(xml_char); packet->packet_number = packet_number++; for (cur_node = node->children; cur_node; cur_node = cur_node->next) { //if (cur_node->type == XML_ELEMENT_NODE) { if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"frame.time_relative"))) { xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value"); afloat = atof((const char*)xml_char); xmlFree(xml_char); packet->time_relative_to_first_packet.tv_sec = (int)afloat; packet->time_relative_to_first_packet.tv_usec = (int)((afloat - packet->time_relative_to_first_packet.tv_sec)*1000000.0); if (first_packet > 0) { initial_time = packet->time_relative_to_first_packet; packet->time_relative_to_first_packet.tv_sec = 0; packet->time_relative_to_first_packet.tv_usec = 0; first_packet = 0; } else { timersub(&packet->time_relative_to_first_packet, &initial_time, &packet->time_relative_to_first_packet); } if (packet->action == ET_PACKET_ACTION_S1C_SEND) { if (first_sent_packet > 0) { relative_last_sent_packet = packet->time_relative_to_first_packet; packet->time_relative_to_last_sent_packet.tv_sec = 0; packet->time_relative_to_last_sent_packet.tv_usec = 0; first_sent_packet = 0; } else { timersub(&packet->time_relative_to_first_packet, &relative_last_sent_packet, &packet->time_relative_to_last_sent_packet); relative_last_sent_packet = packet->time_relative_to_first_packet; } if (first_received_packet > 0) { packet->time_relative_to_last_received_packet.tv_sec = 0; packet->time_relative_to_last_received_packet.tv_usec = 0; } else { timersub(&packet->time_relative_to_first_packet, &relative_last_received_packet, &packet->time_relative_to_last_received_packet); } } else if (packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { if (first_received_packet > 0) { relative_last_received_packet.tv_sec = packet->time_relative_to_first_packet.tv_sec; relative_last_received_packet.tv_usec = packet->time_relative_to_first_packet.tv_usec; packet->time_relative_to_last_received_packet.tv_sec = 0; packet->time_relative_to_last_received_packet.tv_usec = 0; first_received_packet = 0; } else { timersub(&packet->time_relative_to_first_packet, &relative_last_received_packet, &packet->time_relative_to_last_received_packet); relative_last_received_packet = packet->time_relative_to_first_packet; } if (first_sent_packet > 0) { packet->time_relative_to_last_sent_packet.tv_sec = 0; packet->time_relative_to_last_sent_packet.tv_usec = 0; } else { timersub(&packet->time_relative_to_first_packet, &relative_last_sent_packet, &packet->time_relative_to_last_sent_packet); } } } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"frame.number"))) { xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value"); packet->original_frame_number = strtoul((const char *)xml_char, NULL, 0); xmlFree(xml_char); } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"ip.src"))) { xml_char = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1); et_ip_str2et_ip(xml_char, &packet->ip_hdr.src); xmlFree(xml_char); } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"ip.dst"))) { xml_char = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1); et_ip_str2et_ip(xml_char, &packet->ip_hdr.dst); xmlFree(xml_char); } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"proto"))) { xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"name"); if (NULL != xml_char) { if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp"))) { et_parse_sctp(doc, cur_node, &packet->sctp_hdr); } xmlFree(xml_char); } } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"eNB.instance"))) { xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value"); packet->enb_instance = strtoul((const char *)xml_char, NULL, 0); xmlFree(xml_char); } //} } } return packet; } //------------------------------------------------------------------------------ et_scenario_t* et_generate_scenario( const char * const tsml_out_scenario_filename) { xmlDocPtr doc = NULL; xmlNodePtr root = NULL; xmlNodePtr node = NULL; xmlChar *xml_char = NULL; et_scenario_t *scenario = NULL; et_packet_t *packet = NULL; et_packet_t **next_packet = NULL; doc = xmlParseFile(tsml_out_scenario_filename); if (NULL == doc) { AssertFatal (0, "Could not parse scenario xml file %s!\n", tsml_out_scenario_filename); } else { fprintf(stdout, "Test scenario file to play: %s\n", tsml_out_scenario_filename); //xmlDebugDumpDocument(NULL, doc); } // 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 = et_parse_xml_packet(doc, node); if (NULL != packet) { *next_packet = packet; next_packet = &packet->next; } else { fprintf(stdout, "WARNING omitted packet:\n"); et_display_node(node, 0); } } } } } else { fprintf(stderr, "Empty xml document\n"); } xmlFreeDoc(doc); xmlCleanupParser(); return scenario; } //------------------------------------------------------------------------------ int et_generate_xml_scenario( const char const * xml_in_dir_name, const char const * xml_in_scenario_filename, const char const * enb_config_filename, char const * tsml_out_scenario_filename) //------------------------------------------------------------------------------ { //int fd_pdml_in; xsltStylesheetPtr cur = NULL; xmlDocPtr doc, res; FILE *play_scenario_file = NULL; const char *params[2*ENB_CONFIG_MAX_XSLT_PARAMS]; int nb_params = 0; int i,j; char astring[1024]; struct in_addr addr; int ret = 0; memset(astring, 0, sizeof(astring)); if (getcwd(astring, sizeof(astring)) != NULL) { fprintf(stdout, "working in %s directory\n", astring); } else { perror("getcwd() ERROR"); exit(1); } xmlSubstituteEntitiesDefault(1); xmlLoadExtDtdDefaultValue = 1; cur = xsltParseStylesheetFile((const xmlChar *)"/usr/share/oai/xsl/play_scenario.xsl"); if (NULL == cur) { AssertFatal (0, "Could not parse stylesheet file /usr/share/oai/xsl/play_scenario.xsl!\n"); } else { fprintf(stdout, "XSLT style sheet: /usr/share/oai/xsl/play_scenario.xsl\n"); } doc = xmlParseFile(xml_in_scenario_filename); if (NULL == doc) { AssertFatal (0, "Could not parse scenario xml file %s!\n", xml_in_scenario_filename); } else { fprintf(stdout, "Test scenario file: %s\n", xml_in_scenario_filename); } for (i = 0; i < g_enb_properties.number; i++) { // eNB S1-C IPv4 address sprintf(astring, "enb%d_s1c", i); params[nb_params++] = strdup(astring); addr.s_addr = g_enb_properties.properties[i]->enb_ipv4_address_for_S1_MME; sprintf(astring, "\"%s\"", inet_ntoa(addr)); params[nb_params++] = strdup(astring); // MME S1-C IPv4 address for (j = 0; j < g_enb_properties.properties[i]->nb_mme; j++) { sprintf(astring, "mme%d_s1c_%d", i, j); params[nb_params++] = strdup(astring); AssertFatal (g_enb_properties.properties[i]->mme_ip_address[j].ipv4_address, "Only support MME IPv4 address\n"); sprintf(astring, "\"%s\"", g_enb_properties.properties[i]->mme_ip_address[j].ipv4_address); params[nb_params++] = strdup(astring); } } params[nb_params] = NULL; res = xsltApplyStylesheet(cur, doc, params); if (NULL != res) { sprintf((char *)tsml_out_scenario_filename,"%s",xml_in_scenario_filename); if (et_strip_extension((char *)tsml_out_scenario_filename) > 0) { strcat((char *)tsml_out_scenario_filename, ".tsml"); play_scenario_file = fopen( tsml_out_scenario_filename, "w+"); if (NULL != play_scenario_file) { xsltSaveResultToFile(play_scenario_file, res, cur); fclose(play_scenario_file); fprintf(stdout, "Wrote test scenario to %s\n", tsml_out_scenario_filename); } else { fprintf(stderr, "ERROR in fopen(%s)\n", tsml_out_scenario_filename); ret = -1; } } else { fprintf(stderr, "ERROR in strip_extension()\n"); ret = -1; } } else { fprintf(stderr, "ERROR in xsltApplyStylesheet()\n"); ret = -1; } xsltFreeStylesheet(cur); xmlFreeDoc(doc); xmlFreeDoc(res); xsltCleanupGlobals(); xmlCleanupParser(); return ret; }