diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index 21aca820c280ddd7f9a1ce93f8769cdda280a720..d85faf4c2cec17fcfa24d16f17acd562b7aa37ec 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -130,6 +130,54 @@ int et_strip_extension(char *in_filename) } //------------------------------------------------------------------------------ // return number of splitted items +void et_get_shift_arg( char * line_argument, shift_packet_t * const shift) +{ + int len = strlen(line_argument); + int i = 0; + int j = 0; + int num_milli = 0; + char my_num[64]; + int negative = 0; + + + while ((line_argument[i] != ':') && (i < len)) { + my_num[i] = line_argument[i]; + i += 1; + } + my_num[i++] = '\0'; + shift->frame_number = atoi(my_num); + AssertFatal(i<len, "Shift argument %s bad format", line_argument); + + if (line_argument[i] == '-') { + negative = 1; + i += 1; + } else if (line_argument[i] == '+') { + i += 1; + } + AssertFatal(i<len, "Shift argument %s bad format", line_argument); + while ((line_argument[i] != '.') && (i < len)) { + my_num[j++] = line_argument[i++]; + } + my_num[j] = '\0'; + j = 0; + i += 1; + shift->shift_seconds = atoi(my_num); + // may omit .mmm, accept .m or .mm or .mmm or ... + while ((i < len) && (num_milli++ < 3)){ + my_num[j++] = line_argument[i++]; + } + while (num_milli++ < 6){ + my_num[j++] = '0'; + } + my_num[j] = '\0'; + shift->shift_microseconds = atoi(my_num); + if (negative == 1) { + shift->shift_seconds = - shift->shift_seconds; + shift->shift_microseconds = - shift->shift_microseconds; + } +} +//------------------------------------------------------------------------------ +// return number of splitted items int split_path( char * pathP, char *** resP) { char * saveptr1; @@ -764,9 +812,168 @@ void *et_eNB_app_task(void *args_p) } //------------------------------------------------------------------------------ -int et_play_scenario(et_scenario_t* const scenario) +int et_play_scenario(et_scenario_t* const scenario, const struct shift_packet_s *shifts) { - et_event_t event; + et_event_t event; + struct shift_packet_s *shift = shifts; + et_packet_t *packet = NULL; + et_packet_t *next_packet = NULL; + struct timeval shift_all_packets = { .tv_sec = 0, .tv_usec = 0 }; + struct timeval relative_last_sent_packet = { .tv_sec = 0, .tv_usec = 0 }; + struct timeval relative_last_received_packet = { .tv_sec = 0, .tv_usec = 0 }; + struct timeval initial_time = { .tv_sec = 0, .tv_usec = 0 }; + char first_packet = 1; + char first_sent_packet = 1; + char first_received_packet = 1; + + // first apply timing shifts if requested + while (shift) { + packet = scenario->list_packet; + while (packet) { + fprintf(stdout, "*shift: %p\n", shift); + fprintf(stdout, "\tframe_number: %p\n", shift->frame_number); + fprintf(stdout, "\tshift_seconds: %ld\n", shift->shift_seconds); + fprintf(stdout, "\tshift_microseconds: %ld\n", shift->shift_microseconds); + fprintf(stdout, "\tsingle: %d\n\n", shift->single); + fprintf(stdout, "\tshift_all_packets_seconds: %ld\n", shift_all_packets.tv_sec); + fprintf(stdout, "\tshift_all_packets_microseconds: %ld\n", shift_all_packets.tv_usec); + + 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); + 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); + 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); + fprintf(stdout, "\tpacket num %u, original frame number %u time_relative_to_first_packet=%d.%d\n", + packet->packet_number, + packet->original_frame_number, + packet->time_relative_to_first_packet.tv_sec, + packet->time_relative_to_first_packet.tv_usec); + fprintf(stdout, "\tpacket num %u, original frame number %u time_relative_to_last_received_packet=%d.%d\n", + packet->packet_number, + packet->original_frame_number, + packet->time_relative_to_last_received_packet.tv_sec, + packet->time_relative_to_last_received_packet.tv_usec); + fprintf(stdout, "\tpacket num %u, original frame number %u time_relative_to_last_sent_packet=%d.%d\n", + packet->packet_number, + packet->original_frame_number, + packet->time_relative_to_last_sent_packet.tv_sec, + packet->time_relative_to_last_sent_packet.tv_usec); + + if ((shift->single) && (shift->frame_number == packet->original_frame_number)) { + struct timeval t_offset = { .tv_sec = shift->shift_seconds, .tv_usec = shift->shift_microseconds }; + et_packet_shift_timing(packet, &t_offset); + next_packet = packet->next; + if (next_packet) { + t_offset.tv_sec = -t_offset.tv_sec; + t_offset.tv_usec = -t_offset.tv_usec; + + if (packet->action == ET_PACKET_ACTION_S1C_SEND) { + timeval_add(&next_packet->time_relative_to_last_sent_packet, &next_packet->time_relative_to_last_sent_packet, &t_offset); + } else if (packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { + timeval_add(&next_packet->time_relative_to_last_received_packet, &next_packet->time_relative_to_last_received_packet, &t_offset); + } + } + } + if ((0 == shift->single) && (shift->frame_number == packet->original_frame_number)) { + shift_all_packets.tv_sec = shift->shift_seconds; + shift_all_packets.tv_usec = shift->shift_microseconds; + timeval_add(&packet->time_relative_to_first_packet, &packet->time_relative_to_first_packet, &shift_all_packets); + fprintf(stdout, "\tpacket num %u, now original frame number %u time_relative_to_first_packet=%d.%d\n", + packet->packet_number, + packet->original_frame_number, + packet->time_relative_to_first_packet.tv_sec, + packet->time_relative_to_first_packet.tv_usec); + 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); + } else if ((0 == shift->single) && (shift->frame_number < packet->original_frame_number)) { + timeval_add(&packet->time_relative_to_first_packet, &packet->time_relative_to_first_packet, &shift_all_packets); + fprintf(stdout, "\tpacket num %u, now original frame number %u time_relative_to_first_packet=%d.%d\n", + packet->packet_number, + packet->original_frame_number, + packet->time_relative_to_first_packet.tv_sec, + packet->time_relative_to_first_packet.tv_usec); + 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); + } + packet = packet->next; + } + shift = shift->next; + } + // now recompute time_relative_to_last_received_packet, time_relative_to_last_sent_packet + if (shifts) { + packet = scenario->list_packet; + while (packet) { + 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); + } + } + packet = packet->next; + } + } et_display_scenario(scenario); // create SCTP ITTI task: same as eNB code @@ -804,16 +1011,16 @@ static void et_usage ( fprintf (stdout, "Please report any bug to: %s\n",PACKAGE_BUGREPORT); fprintf (stdout, "Usage: %s [options]\n\n", argv[0]); fprintf (stdout, "\n"); - //fprintf (stdout, "Client options:\n"); - //fprintf (stdout, "\t-S | --server <server network @> File name (with no path) of a test scenario that has to be replayed (TODO in future?)\n"); - //fprintf (stdout, "Server options:\n"); - fprintf (stdout, "\t-d | --test-dir <dir> Directory where a set of files related to a particular test are located\n"); - fprintf (stdout, "\t-c | --enb-conf-file <file> Provide an eNB config file, valid for the testbed\n"); - fprintf (stdout, "\t-s | --scenario <file> File name (with no path) of a test scenario that has to be replayed ()\n"); + fprintf (stdout, "\t-d | --test-dir <dir> Directory where a set of files related to a particular test are located\n"); + fprintf (stdout, "\t-c | --enb-conf-file <file> Provide an eNB config file, valid for the testbed\n"); + fprintf (stdout, "\t-f | --shift-packet <frame:[+|-]seconds[.usec]> Shift the timing of a packet'\n"); + fprintf (stdout, "\t-F | --shift-packets <frame:[+|-]seconds[.usec]> Shift the timing of packets starting at frame 'frame' included\n"); + fprintf (stdout, "\t-m | --max-speed Play scenario as fast as possible without respecting frame timings\n"); + fprintf (stdout, "\t-s | --scenario <file> File name (with no path) of a test scenario that has to be replayed ()\n"); fprintf (stdout, "\n"); fprintf (stdout, "Other options:\n"); - fprintf (stdout, "\t-h | --help Print this help and return\n"); - fprintf (stdout, "\t-v | --version Print informations about the version of this executable\n"); + fprintf (stdout, "\t-h | --help Print this help and return\n"); + fprintf (stdout, "\t-v | --version Print informations about the version of this executable\n"); fprintf (stdout, "\n"); } @@ -824,11 +1031,13 @@ et_config_parse_opt_line ( char *argv[], char **et_dir_name, char **scenario_file_name, - char **enb_config_file_name) + char **enb_config_file_name, + shift_packet_t **shifts) //------------------------------------------------------------------------------ { - int option; - int rv = 0; + int option = 0; + int rv = 0; + shift_packet_t *shift = NULL; enum long_option_e { LONG_OPTION_START = 0x100, /* Start after regular single char options */ @@ -836,6 +1045,8 @@ et_config_parse_opt_line ( LONG_OPTION_SCENARIO_FILE, LONG_OPTION_MAX_SPEED, LONG_OPTION_TEST_DIR, + LONG_OPTION_SHIFT_PACKET, + LONG_OPTION_SHIFT_PACKETS, LONG_OPTION_HELP, LONG_OPTION_VERSION }; @@ -845,6 +1056,8 @@ et_config_parse_opt_line ( {"scenario ", required_argument, 0, LONG_OPTION_SCENARIO_FILE}, {"max-speed ", no_argument, 0, LONG_OPTION_MAX_SPEED}, {"test-dir", required_argument, 0, LONG_OPTION_TEST_DIR}, + {"shift-packet", required_argument, 0, LONG_OPTION_SHIFT_PACKET}, + {"shift-packets", required_argument, 0, LONG_OPTION_SHIFT_PACKETS}, {"help", no_argument, 0, LONG_OPTION_HELP}, {"version", no_argument, 0, LONG_OPTION_VERSION}, {NULL, 0, NULL, 0} @@ -853,7 +1066,7 @@ et_config_parse_opt_line ( /* * Parsing command line */ - while ((option = getopt_long (argc, argv, "vhmc:s:d:", long_options, NULL)) != -1) { + while ((option = getopt_long (argc, argv, "vhmc:s:d:f:F", long_options, NULL)) != -1) { switch (option) { case LONG_OPTION_ENB_CONF_FILE: case 'c': @@ -885,6 +1098,37 @@ et_config_parse_opt_line ( } break; + case LONG_OPTION_SHIFT_PACKET: + case 'f': + if (optarg) { + if (NULL == *shifts) { + shift = calloc(1, sizeof (*shift)); + *shifts = shift; + } else { + shift->next = calloc(1, sizeof (*shift)); + shift = shift->next; + } + shift->single = 1; + et_get_shift_arg(optarg, shift); + printf("Arg Shift packet %s\n", optarg); + } + break; + + case LONG_OPTION_SHIFT_PACKETS: + case 'F': + if (optarg) { + if (NULL == *shifts) { + shift = calloc(1, sizeof (*shift)); + *shifts = shift; + } else { + shift->next = calloc(1, sizeof (*shift)); + shift = shift->next; + } + et_get_shift_arg(optarg, shift); + printf("Arg Shift packets %s\n", optarg); + } + break; + case LONG_OPTION_MAX_SPEED: case 'm': g_max_speed = 1; @@ -938,6 +1182,7 @@ int main( int argc, char **argv ) char *et_dir_name = NULL; char *scenario_file_name = NULL; char *enb_config_file_name = NULL; + struct shift_packet_s *shifts = NULL; int ret = 0; et_scenario_t *scenario = NULL; char play_scenario_filename[NAME_MAX]; @@ -957,11 +1202,11 @@ int main( int argc, char **argv ) asn1_xer_print = 1; //parameters - actions = et_config_parse_opt_line (argc, argv, &et_dir_name, &scenario_file_name, &enb_config_file_name); //Command-line options + actions = et_config_parse_opt_line (argc, argv, &et_dir_name, &scenario_file_name, &enb_config_file_name, &shifts); //Command-line options if (actions & PLAY_SCENARIO) { if (et_generate_xml_scenario(et_dir_name, scenario_file_name,enb_config_file_name, play_scenario_filename) == 0) { if (NULL != (scenario = et_generate_scenario(play_scenario_filename))) { - ret = et_play_scenario(scenario); + ret = et_play_scenario(scenario, shifts); } else { fprintf(stderr, "ERROR: Could not generate scenario from tsml file\n"); ret = -1; diff --git a/openair3/TEST/EPC_TEST/play_scenario.h b/openair3/TEST/EPC_TEST/play_scenario.h index 0391ac5c472382a4a3ca6f1884a4011b2bd13b91..ca569e514180318ae7f4305b78ed12c3e46c46a0 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.h +++ b/openair3/TEST/EPC_TEST/play_scenario.h @@ -89,6 +89,15 @@ #define ENB_CONFIG_STRING_ENB_PORT_FOR_S1U "ENB_PORT_FOR_S1U" +typedef struct shift_packet_s { + unsigned int frame_number; + int shift_seconds; + int shift_microseconds; + int single; // only this packet + struct shift_packet_s *next; +} shift_packet_t; + + typedef struct mme_ip_address_s { unsigned ipv4:1; unsigned ipv6:1; @@ -445,6 +454,10 @@ int et_generate_xml_scenario( const char const * enb_config_filename, char const * tsml_out_scenario_filename); //------------------------- +void timeval_add (struct timeval * const result, const struct timeval * const a, const struct timeval * const b); +int timeval_subtract (struct timeval * const result, struct timeval * const a, struct timeval * const b); +void et_scenario_wait_rx_packet(et_packet_t * const packet); +void et_scenario_schedule_tx_packet(et_packet_t * const packet); et_fsm_state_t et_scenario_fsm_notify_event_state_running(et_event_t event); et_fsm_state_t et_scenario_fsm_notify_event_state_waiting_tx(et_event_t event); et_fsm_state_t et_scenario_fsm_notify_event_state_waiting_rx(et_event_t event); @@ -458,7 +471,7 @@ void et_parse_sctp_init_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sct void et_parse_sctp_init_ack_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_initackhdr_t * const sctp_hdr); void et_parse_sctp(xmlDocPtr doc, const xmlNode const *sctp_node, et_sctp_hdr_t * const sctp_hdr); et_packet_t* et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node); -et_scenario_t* et_generate_scenario(const char * const et_scenario_filename ); +et_scenario_t* et_generate_scenario(const char * const et_scenario_filename); //------------------------- asn_comp_rval_t * et_s1ap_ies_is_matching(const S1AP_PDU_PR present, s1ap_message * const m1, s1ap_message * const m2, const uint32_t constraints); void update_xpath_node_mme_ue_s1ap_id(et_s1ap_t * const s1ap, xmlNode *node, const S1ap_MME_UE_S1AP_ID_t new_id); @@ -471,6 +484,7 @@ asn_comp_rval_t * et_sctp_is_matching(et_sctp_hdr_t * const sctp1, et_sctp_hdr_t void et_print_hex_octets(const unsigned char * const byte_stream, const unsigned long int num); int et_is_file_exists ( const char const * file_nameP, const char const *file_roleP); int et_strip_extension( char *in_filename); +void et_get_shift_arg( char * line_argument, shift_packet_t * const shift); 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); @@ -486,6 +500,6 @@ void et_enb_config_init(const char const * lib_config_file_name_pP); const Enb_properties_array_t *et_enb_config_get(void); 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); +int et_play_scenario(et_scenario_t* const scenario, const struct shift_packet_s *shifts); #endif /* PLAY_SCENARIO_H_ */ diff --git a/openair3/TEST/EPC_TEST/play_scenario_fsm.c b/openair3/TEST/EPC_TEST/play_scenario_fsm.c index a8f7e7331f1ba8a1d14f6db122623b688c967b19..dece907deee706a52055c0feac304a9ef33abfcb 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_fsm.c +++ b/openair3/TEST/EPC_TEST/play_scenario_fsm.c @@ -54,36 +54,35 @@ pthread_mutex_t g_fsm_lock = PTHREAD_MUTEX_INITIALIZER; et_fsm_state_t g_fsm_state = ET_FSM_STATE_NULL; uint32_t g_constraints = ET_BIT_MASK_MATCH_SCTP_STREAM | ET_BIT_MASK_MATCH_SCTP_SSN; //------------------------------------------------------------------------------ -int timeval_subtract (struct timeval * const result, struct timeval * const a, struct timeval * const b) +// it is assumed that if a time is negative tv_sec and tv_usec are both negative +void timeval_add (struct timeval * const result, const struct timeval * const a, const struct timeval * const b) { - struct timeval b2; - int nsec = 0; - b2.tv_sec = b->tv_sec; - b2.tv_usec = b->tv_usec; - - - /* Perform the carry for the later subtraction by updating y. */ - if (a->tv_usec < b2.tv_usec) { - nsec = (b2.tv_usec - a->tv_usec) / 1000000 + 1; - b2.tv_usec -= 1000000 * nsec; - b2.tv_sec += nsec; + AssertFatal(((a->tv_sec <= 0) && (a->tv_usec <= 0)) || ((a->tv_sec >= 0) && (a->tv_usec >= 0)), " Bad time format arg a\n"); + AssertFatal(((b->tv_sec <= 0) && (b->tv_usec <= 0)) || ((b->tv_sec >= 0) && (b->tv_usec >= 0)), " Bad time format arg b\n"); + // may happen overflows but were are not dealing with very large timings + long long int r = a->tv_usec + b->tv_usec + (a->tv_sec + b->tv_sec) * 1000000; + result->tv_sec = r / (long long int)1000000; + result->tv_usec = r % (long long int)1000000; + if ((result != a) && (result != b)) { + LOG_D(ENB_APP, "timeval_add(%ld.%06d, %ld.%06d)=%ld.%06d\n", a->tv_sec, a->tv_usec, b->tv_sec, b->tv_usec, result->tv_sec, result->tv_usec); } - if (a->tv_usec - b2.tv_usec > 1000000) { - nsec = (a->tv_usec - b2.tv_usec) / 1000000; - b2.tv_usec += 1000000 * nsec; - b2.tv_sec -= nsec; - } - - /* Compute the time remaining to wait. - tv_usec is certainly positive. */ - result->tv_sec = a->tv_sec - b2.tv_sec; - result->tv_usec = a->tv_usec - b2.tv_usec; - - LOG_D(ENB_APP, "timeval_subtract(%ld.%06d, %ld.%06d)=%ld.%06d\n", a->tv_sec, a->tv_usec, b->tv_sec, b->tv_usec, result->tv_sec, result->tv_usec); - - return a->tv_sec < b2.tv_sec; } +//------------------------------------------------------------------------------ +// it is assumed that if a time is negative tv_sec and tv_usec are both negative +int timeval_subtract (struct timeval * const result, struct timeval * const a, struct timeval * const b) +{ + AssertFatal(((a->tv_sec <= 0) && (a->tv_usec <= 0)) || ((a->tv_sec >= 0) && (a->tv_usec >= 0)), " Bad time format arg a\n"); + AssertFatal(((b->tv_sec <= 0) && (b->tv_usec <= 0)) || ((b->tv_sec >= 0) && (b->tv_usec >= 0)), " Bad time format arg b\n"); + // may happen overflows but were are not dealing with very large timings + long long int r = a->tv_usec - b->tv_usec + (a->tv_sec - b->tv_sec) * 1000000; + result->tv_sec = r / (long long int)1000000; + result->tv_usec = r % (long long int)1000000; + if ((result != a) && (result != b)) { + LOG_D(ENB_APP, "timeval_subtract(%ld.%06d, %ld.%06d)=%ld.%06d\n", a->tv_sec, a->tv_usec, b->tv_sec, b->tv_usec, result->tv_sec, result->tv_usec); + } + return result->tv_sec < 0; +} //------------------------------------------------------------------------------ void et_scenario_wait_rx_packet(et_packet_t * const packet) @@ -137,10 +136,9 @@ void et_scenario_schedule_tx_packet(et_packet_t * const packet) } if ((0 < we_are_too_early) && (0 == g_max_speed)){ // set timer - if (offset.tv_sec < 0) offset.tv_sec = -offset.tv_sec; - if (offset.tv_usec < 0) { - offset.tv_usec = offset.tv_usec + 1000000; - offset.tv_sec -= 1; + if (offset.tv_sec < 0) { + offset.tv_sec = -offset.tv_sec; + offset.tv_usec = -offset.tv_usec; } LOG_D(ENB_APP, "Send packet num %u original frame number %u in %ld.%06d sec\n", diff --git a/openair3/TEST/EPC_TEST/play_scenario_parse.c b/openair3/TEST/EPC_TEST/play_scenario_parse.c index 4004dd507499e9ed3884010c45c481f2b9765cbc..11dac34f0a451f48c71e11638945c10d282e3d36 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_parse.c +++ b/openair3/TEST/EPC_TEST/play_scenario_parse.c @@ -62,7 +62,7 @@ extern Enb_properties_array_t g_enb_properties; //------------------------------------------------------------------------------ void et_parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, et_s1ap_t * const s1ap) { - xmlNode *cur_node = NULL; + xmlNodePtr cur_node = NULL; xmlChar *xml_char = NULL; xmlChar *xml_char2 = NULL; unsigned int size = 0; @@ -329,9 +329,38 @@ void et_parse_sctp(xmlDocPtr doc, const xmlNode const *sctp_node, et_sctp_hdr_t } } //------------------------------------------------------------------------------ -et_packet_t* et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node) { +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 *packet = NULL; +//------------------------------------------------------------------------------ +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; @@ -343,6 +372,7 @@ et_packet_t* et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node) { static char first_received_packet = 1; static unsigned int packet_number = 1; + if (NULL != node) { packet = calloc(1, sizeof(*packet)); @@ -441,15 +471,15 @@ et_packet_t* et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node) { } //------------------------------------------------------------------------------ et_scenario_t* et_generate_scenario( - const char * const tsml_out_scenario_filename ) + 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; + 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) { diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c index 6a39397f19acde6b321cfacccba483a7c07c97e5..285b883ded865e9a2181bb576506670109bab65b 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c @@ -68,7 +68,6 @@ int et_s1ap_eNB_compare_assoc_id( if (p1->cnx_id < p2->cnx_id) { return -1; } - if (p1->cnx_id > p2->cnx_id) { return 1; } @@ -76,7 +75,6 @@ int et_s1ap_eNB_compare_assoc_id( if (p1->assoc_id < p2->assoc_id) { return -1; } - if (p1->assoc_id > p2->assoc_id) { return 1; } diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c index 31d784b2bdc4c62fb536782350aed65cb8f17280..32b571f823d47f6fd65939feec813f8b451a6115 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c @@ -586,7 +586,6 @@ int et_s1ap_update_mme_ue_s1ap_id(et_packet_t * const packet, const S1ap_MME_UE_ { - xmlNode *cur_node = NULL; xmlChar xpath_expression[ET_XPATH_EXPRESSION_MAX_LENGTH]; int ret = 0; xmlDocPtr doc = NULL;