/******************************************************************************* 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_display.c ------------------- AUTHOR : Lionel GAUTHIER COMPANY : EURECOM EMAIL : Lionel.Gauthier@eurecom.fr */ #include <string.h> #include <stdio.h> #include "intertask_interface.h" #include "platform_types.h" #include "assertions.h" #include "s1ap_ies_defs.h" #include "s1ap_eNB_decoder.h" #include "play_scenario.h" //----------------------------------------------------------------------------- void et_print_hex_octets(const unsigned char * const byte_stream, const unsigned long int num) { unsigned long octet_index = 0; if (byte_stream == NULL) { return; } fprintf(stdout, "+-----+-------------------------------------------------+\n"); fprintf(stdout, "| | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n"); fprintf(stdout, "+-----+-------------------------------------------------+\n"); for (octet_index = 0; octet_index < num; octet_index++) { if ((octet_index % 16) == 0) { if (octet_index != 0) { fprintf(stdout, " |\n"); } fprintf(stdout, " %04ld |", octet_index); } /* * Print every single octet in hexadecimal form */ fprintf(stdout, " %02x", byte_stream[octet_index]); /* * Align newline and pipes according to the octets in groups of 2 */ } /* * Append enough spaces and put final pipe */ unsigned char index; for (index = octet_index; index < 16; ++index) { fprintf(stdout, " "); } fprintf(stdout, " |\n"); } //------------------------------------------------------------------------------ void et_display_node(xmlNodePtr node, unsigned int indent) { int i = 0; if (node->type == XML_ELEMENT_NODE) { xmlChar *path = xmlGetNodePath(node); for (i=0; i<indent; i++) { printf(" "); } 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 et_display_tree(xmlNodePtr node, unsigned int indent) { xmlNode *cur_node = NULL; for (cur_node = node; cur_node; cur_node = cur_node->next) { if (cur_node->type == XML_ELEMENT_NODE) { et_display_node(cur_node, indent); } et_display_tree(cur_node->children, indent++); } } //------------------------------------------------------------------------------ void et_display_packet_s1ap_data(const et_s1ap_t * const s1ap) { char *message_string = NULL; if (s1ap) { message_string = calloc(20000, sizeof(char)); AssertFatal (NULL != message_string, "ERROR malloc()failed!\n"); s1ap_string_total_size = 0; switch(s1ap->pdu.present) { case S1AP_PDU_PR_initiatingMessage: switch(s1ap->pdu.choice.initiatingMessage.procedureCode) { case S1ap_ProcedureCode_id_downlinkNASTransport: s1ap_xer_print_s1ap_downlinknastransport(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; case S1ap_ProcedureCode_id_InitialContextSetup: s1ap_xer_print_s1ap_initialcontextsetuprequest(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; case S1ap_ProcedureCode_id_UEContextRelease: s1ap_xer_print_s1ap_uecontextreleasecommand(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; case S1ap_ProcedureCode_id_Paging: s1ap_xer_print_s1ap_paging(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; case S1ap_ProcedureCode_id_uplinkNASTransport: s1ap_xer_print_s1ap_uplinknastransport(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; case S1ap_ProcedureCode_id_S1Setup: s1ap_xer_print_s1ap_s1setuprequest(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; case S1ap_ProcedureCode_id_initialUEMessage: s1ap_xer_print_s1ap_initialuemessage(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; case S1ap_ProcedureCode_id_UEContextReleaseRequest: s1ap_xer_print_s1ap_uecontextreleaserequest(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; case S1ap_ProcedureCode_id_UECapabilityInfoIndication:s1ap_xer_print_s1ap_uecapabilityinfoindication(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; case S1ap_ProcedureCode_id_NASNonDeliveryIndication: s1ap_xer_print_s1ap_nasnondeliveryindication_(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; default: AssertFatal( 0 , "Unknown procedure ID (%d) for initiating message\n", (int)s1ap->pdu.choice.initiatingMessage.procedureCode); } break; case S1AP_PDU_PR_successfulOutcome: switch(s1ap->pdu.choice.successfulOutcome.procedureCode) { case S1ap_ProcedureCode_id_S1Setup: s1ap_xer_print_s1ap_s1setupresponse(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; case S1ap_ProcedureCode_id_InitialContextSetup: s1ap_xer_print_s1ap_initialcontextsetupresponse(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; case S1ap_ProcedureCode_id_UEContextRelease: s1ap_xer_print_s1ap_uecontextreleasecomplete(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; default: AssertFatal(0, "Unknown procedure ID (%d) for successfull outcome message\n", (int)s1ap->pdu.choice.successfulOutcome.procedureCode); } break; case S1AP_PDU_PR_unsuccessfulOutcome: switch(s1ap->pdu.choice.unsuccessfulOutcome.procedureCode) { case S1ap_ProcedureCode_id_S1Setup: s1ap_xer_print_s1ap_s1setupfailure(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; case S1ap_ProcedureCode_id_InitialContextSetup: s1ap_xer_print_s1ap_initialcontextsetupfailure(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; default: et_free_pointer(message_string); AssertFatal(0,"Unknown procedure ID (%d) for unsuccessfull outcome message\n", (int)s1ap->pdu.choice.unsuccessfulOutcome.procedureCode); break; } break; default: AssertFatal(0, "Unknown presence (%d) or not implemented\n", (int)s1ap->pdu.present); break; } fprintf(stdout, "\t\tSCTP.data XML dump:\n%s\n", message_string); et_free_pointer(message_string); } } //------------------------------------------------------------------------------ void et_display_packet_sctp_init(const sctp_inithdr_t * const sctp) { if (sctp) { fprintf(stdout, "\t\tSCTP.init.init_tag : %u\n", sctp->init_tag); fprintf(stdout, "\t\tSCTP.init.a_rwnd : %u\n", sctp->a_rwnd); fprintf(stdout, "\t\tSCTP.init.num_inbound_streams : %u\n", sctp->num_inbound_streams); fprintf(stdout, "\t\tSCTP.init.num_outbound_streams : %u\n", sctp->num_outbound_streams); fprintf(stdout, "\t\tSCTP.init.initial_tsn : %u\n", sctp->initial_tsn); } } //------------------------------------------------------------------------------ void et_display_packet_sctp_initack(const sctp_initackhdr_t * const sctp) { if (sctp) { fprintf(stdout, "\t\tSCTP.initack.init_tag : %u\n", sctp->init_tag); fprintf(stdout, "\t\tSCTP.initack.a_rwnd : %u\n", sctp->a_rwnd); fprintf(stdout, "\t\tSCTP.initack.num_inbound_streams : %u\n", sctp->num_inbound_streams); fprintf(stdout, "\t\tSCTP.initack.num_outbound_streams : %u\n", sctp->num_outbound_streams); fprintf(stdout, "\t\tSCTP.initack.initial_tsn : %u\n", sctp->initial_tsn); } } //------------------------------------------------------------------------------ void et_display_packet_sctp_data(const sctp_datahdr_t * const sctp) { if (sctp) { fprintf(stdout, "\t\tSCTP.data.tsn : %u\n", sctp->tsn); fprintf(stdout, "\t\tSCTP.data.stream : %u\n", sctp->stream); fprintf(stdout, "\t\tSCTP.data.ssn : %u\n", sctp->ssn); fprintf(stdout, "\t\tSCTP.data.ppid : %u\n", sctp->ppid); if (sctp->ppid == 18) { et_display_packet_s1ap_data(&sctp->payload); } fprintf(stdout, "\t\tSCTP.data.binary_stream_allocated_size : %u\n", sctp->payload.binary_stream_allocated_size); if (NULL != sctp->payload.binary_stream) { fprintf(stdout, "\t\tSCTP.data.binary_stream :\n"); et_print_hex_octets(sctp->payload.binary_stream, sctp->payload.binary_stream_allocated_size); } else { fprintf(stdout, "\t\tSCTP.data.binary_stream : NULL\n"); } } } //------------------------------------------------------------------------------ void et_display_packet_sctp(const et_sctp_hdr_t * const sctp) { if (sctp) { fprintf(stdout, "\t\tSCTP.src_port : %u\n", sctp->src_port); fprintf(stdout, "\t\tSCTP.dst_port : %u\n", sctp->dst_port); fprintf(stdout, "\t\tSCTP.chunk_type : %s\n", et_chunk_type_cid2str(sctp->chunk_type)); switch (sctp->chunk_type) { case SCTP_CID_DATA: et_display_packet_sctp_data(&sctp->u.data_hdr); break; case SCTP_CID_INIT: et_display_packet_sctp_initack(&sctp->u.init_hdr); break; case SCTP_CID_INIT_ACK: et_display_packet_sctp_initack(&sctp->u.init_ack_hdr); break; default: ; } } } //------------------------------------------------------------------------------ void et_display_packet_ip(const et_ip_hdr_t * const ip) { if (ip) { fprintf(stdout, "\t\tSource address : %s\n", et_ip2ip_str(&ip->src)); fprintf(stdout, "\t\tDestination address : %s\n", et_ip2ip_str(&ip->dst)); } } //------------------------------------------------------------------------------ void et_display_packet(const et_packet_t * const packet) { if (packet) { fprintf(stdout, "-------------------------------------------------------------------------------\n"); fprintf(stdout, "\tPacket:\tnum %u | original frame number %u \n", packet->packet_number, packet->original_frame_number); fprintf(stdout, "\tPacket:\ttime relative to 1st packet %ld.%06lu\n", packet->time_relative_to_first_packet.tv_sec, packet->time_relative_to_first_packet.tv_usec); fprintf(stdout, "\tPacket:\ttime relative to last tx packet %ld.%06lu\n", packet->time_relative_to_last_sent_packet.tv_sec, packet->time_relative_to_last_sent_packet.tv_usec); fprintf(stdout, "\tPacket:\ttime relative to last_received packet %ld.%06lu\n", packet->time_relative_to_last_received_packet.tv_sec, packet->time_relative_to_last_received_packet.tv_usec); switch(packet->action) { case ET_PACKET_ACTION_S1C_SEND: fprintf(stdout, "\tPacket:\tAction SEND\n"); break; case ET_PACKET_ACTION_S1C_RECEIVE: fprintf(stdout, "\tPacket:\tAction RECEIVE\n"); break; default: fprintf(stdout, "\tPacket:\tAction UNKNOWN\n"); } switch(packet->status) { case ET_PACKET_STATUS_NONE: fprintf(stdout, "\tPacket:\tStatus NONE\n"); break; case ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT: fprintf(stdout, "\tPacket:\tStatus NOT_TAKEN_IN_ACCOUNT\n"); break; case ET_PACKET_STATUS_SCHEDULED_FOR_SENDING: fprintf(stdout, "\tPacket:\tStatus SCHEDULED_FOR_SENDING\n"); break; case ET_PACKET_STATUS_SENT: fprintf(stdout, "\tPacket:\tStatus SENT\n"); break; case ET_PACKET_STATUS_SCHEDULED_FOR_RECEIVING: fprintf(stdout, "\tPacket:\tStatus SCHEDULED_FOR_RECEIVING\n"); break; case ET_PACKET_STATUS_RECEIVED: fprintf(stdout, "\tPacket:\tStatus RECEIVED\n"); break; default: fprintf(stdout, "\tPacket:\tStatus UNKNOWN\n"); } et_display_packet_ip(&packet->ip_hdr); et_display_packet_sctp(&packet->sctp_hdr); } } //------------------------------------------------------------------------------ void et_display_scenario(const et_scenario_t * const scenario) { et_packet_t *packet = NULL; if (scenario) { fprintf(stdout, "Scenario: %s\n", (scenario->name != NULL) ? (char*)scenario->name:"UNKNOWN NAME"); packet = scenario->list_packet; while (packet) { et_display_packet(packet); packet = packet->next; } } }