diff --git a/ui/cli/tap-rtp.c b/ui/cli/tap-rtp.c index ee7596e0af..6c0a598760 100644 --- a/ui/cli/tap-rtp.c +++ b/ui/cli/tap-rtp.c @@ -84,15 +84,15 @@ rtp_streams_stat_draw(void *arg _U_) strinfo = (rtp_stream_info_t*)(list->data); /* payload type */ - if (strinfo->pt > 95) { - if (strinfo->info_payload_type_str != NULL) { - payload_type = g_strdup(strinfo->info_payload_type_str); + if (strinfo->payload_type > 95) { + if (strinfo->payload_type_name != NULL) { + payload_type = g_strdup(strinfo->payload_type_name); }else{ - payload_type = g_strdup_printf("Unknown(%u)", strinfo->pt); + payload_type = g_strdup_printf("Unknown(%u)", strinfo->payload_type); } }else{ - payload_type = g_strdup(val_to_str_ext(strinfo->pt, &rtp_payload_type_vals_ext, + payload_type = g_strdup(val_to_str_ext(strinfo->payload_type, &rtp_payload_type_vals_ext, "Unknown (%u)")); } @@ -113,7 +113,7 @@ rtp_streams_stat_draw(void *arg _U_) strinfo->dest_port, strinfo->ssrc, payload_type, - strinfo->npackets, + strinfo->packet_count, lost, perc, strinfo->rtp_stats.max_delta, strinfo->rtp_stats.max_jitter, diff --git a/ui/gtk/rtp_player.c b/ui/gtk/rtp_player.c index 13867a2b9e..4dad06dd1a 100644 --- a/ui/gtk/rtp_player.c +++ b/ui/gtk/rtp_player.c @@ -66,7 +66,9 @@ #include -#include "../globals.h" +#include "globals.h" + +#include "ui/rtp_stream.h" #include "ui/simple_dialog.h" #include "ui/voip_calls.h" @@ -153,28 +155,10 @@ static PortAudioStream *pa_stream; static PaStream *pa_stream; #endif /* PORTAUDIO_API_1 */ -/* defines a RTP stream */ -typedef struct _rtp_stream_info { - address src_addr; - guint16 src_port; - address dest_addr; - guint16 dest_port; - guint32 ssrc; - guint32 first_frame_number; /* first RTP frame for the stream */ - double start_time; /* RTP stream start time in ms */ - nstime_t start_time_abs; - gboolean play; - guint16 call_num; - GList* rtp_packets_list; /* List of RTP packets in the stream */ - guint32 num_packets; -} rtp_stream_info_t; - - /* defines the RTP streams to be played in an audio channel */ typedef struct _rtp_channel_info { - double start_time; /* RTP stream start time in ms */ nstime_t start_time_abs; - double end_time; /* RTP stream end time in ms */ + nstime_t stop_time_abs; GArray *samples; /* the array with decoded audio */ guint16 call_num; gboolean selected; @@ -268,20 +252,20 @@ static void rtp_stream_value_destroy(gpointer rsi_arg) { rtp_stream_info_t *rsi = (rtp_stream_info_t *)rsi_arg; - GList* rtp_packets_list; + GList* rtp_packet_list; rtp_packet_t *rp; - rtp_packets_list = g_list_first(rsi->rtp_packets_list); - while (rtp_packets_list) + rtp_packet_list = g_list_first(rsi->rtp_packet_list); + while (rtp_packet_list) { - rp = (rtp_packet_t *)rtp_packets_list->data; + rp = (rtp_packet_t *)rtp_packet_list->data; g_free(rp->info); g_free(rp->payload_data); g_free(rp); rp = NULL; - rtp_packets_list = g_list_next(rtp_packets_list); + rtp_packet_list = g_list_next(rtp_packet_list); } g_free((void *)(rsi->src_addr.data)); g_free((void *)(rsi->dest_addr.data)); @@ -378,19 +362,14 @@ add_rtp_packet(const struct _rtp_info *rtp_info, packet_info *pinfo) /* if it is not in the hash table, create a new stream */ if (stream_info==NULL) { - stream_info = g_new(rtp_stream_info_t,1); + stream_info = g_new0(rtp_stream_info_t, 1); COPY_ADDRESS(&(stream_info->src_addr), &(pinfo->src)); stream_info->src_port = pinfo->srcport; COPY_ADDRESS(&(stream_info->dest_addr), &(pinfo->dst)); stream_info->dest_port = pinfo->destport; stream_info->ssrc = rtp_info->info_sync_src; - stream_info->rtp_packets_list = NULL; - stream_info->first_frame_number = pinfo->fd->num; - stream_info->start_time = nstime_to_msec(&pinfo->rel_ts); - stream_info->start_time_abs = pinfo->fd->abs_ts; - stream_info->call_num = 0; - stream_info->play = FALSE; - stream_info->num_packets = 0; + stream_info->start_fd = pinfo->fd; + stream_info->start_rel_time = pinfo->rel_ts; g_hash_table_insert(rtp_streams_hash, g_strdup(key_str->str), stream_info); @@ -399,14 +378,14 @@ add_rtp_packet(const struct _rtp_info *rtp_info, packet_info *pinfo) } /* increment the number of packets in this stream, this is used for the progress bar and statistics */ - stream_info->num_packets++; + stream_info->packet_count++; /* Add the RTP packet to the list */ - new_rtp_packet = g_new(rtp_packet_t,1); + new_rtp_packet = g_new0(rtp_packet_t, 1); new_rtp_packet->info = (struct _rtp_info *)g_malloc(sizeof(struct _rtp_info)); memcpy(new_rtp_packet->info, rtp_info, sizeof(struct _rtp_info)); - new_rtp_packet->arrive_offset = nstime_to_msec(&pinfo->rel_ts) - stream_info->start_time; + new_rtp_packet->arrive_offset = nstime_to_msec(&pinfo->rel_ts) - nstime_to_msec(&stream_info->start_rel_time); /* copy the RTP payload to the rtp_packet to be decoded later */ if (rtp_info->info_all_data_present && (rtp_info->info_payload_len != 0)) { new_rtp_packet->payload_data = (guint8 *)g_malloc(rtp_info->info_payload_len); @@ -415,7 +394,7 @@ add_rtp_packet(const struct _rtp_info *rtp_info, packet_info *pinfo) new_rtp_packet->payload_data = NULL; } - stream_info->rtp_packets_list = g_list_append(stream_info->rtp_packets_list, new_rtp_packet); + stream_info->rtp_packet_list = g_list_append(stream_info->rtp_packet_list, new_rtp_packet); g_string_free(key_str, TRUE); } @@ -435,14 +414,14 @@ mark_rtp_stream_to_play(gchar *key _U_ , rtp_stream_info_t *rsi, gpointer ptr _U /* Reset the "to be play" value because the user can close and reopen the RTP Player window * and the streams are not reset in that case */ - rsi->play = FALSE; + rsi->decode = FALSE; /* and associate the RTP stream with a call using the first RTP packet in the stream */ graph_list = g_queue_peek_nth_link(voip_calls->graph_analysis->items, 0); while (graph_list) { graph_item = (seq_analysis_item_t *)graph_list->data; - if (rsi->first_frame_number == graph_item->fd->num) { + if (rsi->start_fd->num == graph_item->fd->num) { rsi->call_num = graph_item->conv_num; /* if it is in the graph list, then check if the voip_call is selected */ voip_calls_list = g_queue_peek_nth_link(voip_calls->callsinfos, 0); @@ -450,8 +429,8 @@ mark_rtp_stream_to_play(gchar *key _U_ , rtp_stream_info_t *rsi, gpointer ptr _U { tmp_voip_call = (voip_calls_info_t *)voip_calls_list->data; if ( (tmp_voip_call->call_num == rsi->call_num) && (tmp_voip_call->selected == TRUE) ) { - rsi->play = TRUE; - total_packets += rsi->num_packets; + rsi->decode = TRUE; + total_packets += rsi->packet_count; break; } voip_calls_list = g_list_next(voip_calls_list); @@ -467,10 +446,10 @@ mark_rtp_stream_to_play(gchar *key _U_ , rtp_stream_info_t *rsi, gpointer ptr _U * RTP player from the "RTP Analysis" window */ static void -mark_all_rtp_stream_to_play(gchar *key _U_ , rtp_stream_info_t *rsi, gpointer ptr _U_) +mark_all_rtp_stream_to_decode(gchar *key _U_ , rtp_stream_info_t *rsi, gpointer ptr _U_) { - rsi->play = TRUE; - total_packets += rsi->num_packets; + rsi->decode = TRUE; + total_packets += rsi->packet_count; } /****************************************************************************/ @@ -551,7 +530,7 @@ decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr) GString *key_str = NULL; rtp_channel_info_t *rci; gboolean first = TRUE; - GList* rtp_packets_list; + GList* rtp_packet_list; rtp_packet_t *rp; int i; @@ -577,6 +556,7 @@ decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr) SAMPLE *out_buff = NULL; sample_t silence; sample_t sample; + nstime_t sample_delta; guint8 status; guint32 start_timestamp; GHashTable *decoders_hash = NULL; @@ -590,7 +570,7 @@ decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr) silence.status = S_NORMAL; /* skip it if we are not going to play it */ - if (rsi->play == FALSE) { + if (rsi->decode == FALSE) { return; } @@ -611,44 +591,25 @@ decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr) } /* lookup for this stream in the channel hash table */ - rci = (rtp_channel_info_t *)g_hash_table_lookup( rtp_channels_hash, key_str->str); + rci = (rtp_channel_info_t *)g_hash_table_lookup( rtp_channels_hash, key_str->str); /* ..if it is not in the hash, create an entry */ if (rci == NULL) { - rci = g_new(rtp_channel_info_t,1); + rci = g_new0(rtp_channel_info_t, 1); rci->call_num = rsi->call_num; - rci->start_time = rsi->start_time; - rci->start_time_abs = rsi->start_time_abs; - rci->end_time = rsi->start_time; - rci->selected = FALSE; - rci->frame_index = 0; - rci->drop_by_jitter_buff = 0; - rci->out_of_seq = 0; - rci->wrong_timestamp = 0; - rci->max_frame_index = 0; + rci->start_time_abs = rsi->start_fd->abs_ts; + rci->stop_time_abs = rsi->start_fd->abs_ts; rci->samples = g_array_new (FALSE, FALSE, sizeof(sample_t)); - rci->check_bt = NULL; - rci->separator = NULL; - rci->draw_area = NULL; -#if GTK_CHECK_VERSION(2,22,0) - rci->surface = NULL; -#else - rci->pixmap = NULL; -#endif - rci->h_scrollbar_adjustment = NULL; - rci->cursor_pixbuf = NULL; - rci->cursor_prev = 0; - rci->cursor_catch = FALSE; rci->first_stream = rsi; - rci->num_packets = rsi->num_packets; + rci->num_packets = rsi->packet_count; g_hash_table_insert(rtp_channels_hash, g_strdup(key_str->str), rci); } else { /* Add silence between the two streams if needed */ - silence_frames = (gint32)( ((rsi->start_time - rci->end_time)/1000)*sample_rate ); + silence_frames = (gint32)((nstime_to_msec(&rsi->start_fd->abs_ts) - nstime_to_msec(&rci->stop_time_abs)) * sample_rate); for (i = 0; i< silence_frames; i++) { g_array_append_val(rci->samples, silence); } - rci->num_packets += rsi->num_packets; + rci->num_packets += rsi->packet_count; } /* decode the RTP stream */ @@ -677,8 +638,8 @@ decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr) status = S_NORMAL; - rtp_packets_list = g_list_first(rsi->rtp_packets_list); - while (rtp_packets_list) + rtp_packet_list = g_list_first(rsi->rtp_packet_list); + while (rtp_packet_list) { if (progbar_count >= progbar_nextstep) { @@ -692,7 +653,7 @@ decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr) } - rp = (rtp_packet_t *)rtp_packets_list->data; + rp = (rtp_packet_t *)rtp_packet_list->data; if (first == TRUE) { /* defined start_timestmp to avoid overflow in timestamp. TODO: handle the timestamp correctly */ /* XXX: if timestamps (RTP) are missing/ignored try use packet arrive time only (see also "rtp_time") */ @@ -820,11 +781,13 @@ decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr) g_free(out_buff); out_buff = NULL; } - rtp_packets_list = g_list_next (rtp_packets_list); + rtp_packet_list = g_list_next (rtp_packet_list); progbar_count++; } rci->max_frame_index = rci->samples->len; - rci->end_time = rci->start_time + ((double)rci->samples->len/sample_rate)*1000; + sample_delta.secs = rci->samples->len / sample_rate; + sample_delta.nsecs = (rci->samples->len % sample_rate) * 1000000000; + nstime_sum(&rci->stop_time_abs, &rci->start_time_abs, &sample_delta); g_string_free(key_str, TRUE); g_hash_table_destroy(decoders_hash); @@ -1115,22 +1078,26 @@ init_rtp_channels_vals(void) /* if the two channels are to be played, then we need to sync both based on the start/end time of each one */ } else { - rpci->max_frame_index = (guint32)(sample_rate/1000) * (guint32)(MAX(rpci->rci[0]->end_time, rpci->rci[1]->end_time) - - (guint32)MIN(rpci->rci[0]->start_time, rpci->rci[1]->start_time)); + double start_time_0 = nstime_to_msec(&rpci->rci[0]->start_time_abs); + double start_time_1 = nstime_to_msec(&rpci->rci[1]->start_time_abs); + double stop_time_0 = nstime_to_msec(&rpci->rci[0]->stop_time_abs); + double stop_time_1 = nstime_to_msec(&rpci->rci[1]->stop_time_abs); + rpci->max_frame_index = (guint32)(sample_rate/1000) * (guint32)(MAX(stop_time_0, stop_time_1) - + (guint32)MIN(start_time_0, start_time_1)); - if (rpci->rci[0]->start_time < rpci->rci[1]->start_time) { + if (nstime_cmp(&rpci->rci[0]->start_time_abs, &rpci->rci[1]->start_time_abs) < 0) { rpci->start_index[0] = 0; - rpci->start_index[1] = (guint32)(sample_rate/1000) * (guint32)(rpci->rci[1]->start_time - rpci->rci[0]->start_time); + rpci->start_index[1] = (guint32)(sample_rate/1000) * (guint32)(start_time_1 - start_time_0); } else { rpci->start_index[1] = 0; - rpci->start_index[0] = (guint32)(sample_rate/1000) * (guint32)(rpci->rci[0]->start_time - rpci->rci[1]->start_time); + rpci->start_index[0] = (guint32)(sample_rate/1000) * (guint32)(start_time_0 - start_time_1); } - if (rpci->rci[0]->end_time < rpci->rci[1]->end_time) { - rpci->end_index[0] = rpci->max_frame_index - ((guint32)(sample_rate/1000) * (guint32)(rpci->rci[1]->end_time - rpci->rci[0]->end_time)); + if (nstime_cmp(&rpci->rci[0]->stop_time_abs, &rpci->rci[1]->stop_time_abs) < 0) { + rpci->end_index[0] = rpci->max_frame_index - ((guint32)(sample_rate/1000) * (guint32)(stop_time_1 - stop_time_0)); rpci->end_index[1] = rpci->max_frame_index; } else { - rpci->end_index[1] = rpci->max_frame_index - ((guint32)(sample_rate/1000) * (guint32)(rpci->rci[0]->end_time - rpci->rci[1]->end_time)); + rpci->end_index[1] = rpci->max_frame_index - ((guint32)(sample_rate/1000) * (guint32)(stop_time_0 - stop_time_1)); rpci->end_index[0] = rpci->max_frame_index; } } @@ -1301,7 +1268,7 @@ static void channel_draw(rtp_channel_info_t* rci) pango_layout_set_font_description(small_layout, pango_font_description_from_string("Helvetica,Sans,Bold 7")); /* calculated the pixel offset to display integer seconds */ - offset = ((double)rci->start_time/1000 - floor((double)rci->start_time/1000))*sample_rate/MULT; + offset = (nstime_to_sec(&rci->start_time_abs) - floor(nstime_to_sec(&rci->start_time_abs)))*sample_rate/MULT; cr = cairo_create (rci->surface); cairo_set_line_width (cr, 1.0); @@ -1408,7 +1375,7 @@ static void channel_draw(rtp_channel_info_t* rci) timestamp = localtime(&seconds); g_snprintf(label_string, MAX_TIME_LABEL, "%02d:%02d:%02d", timestamp->tm_hour, timestamp->tm_min, timestamp->tm_sec); } else { - g_snprintf(label_string, MAX_TIME_LABEL, "%.0f s", floor(rci->start_time/1000) + i*MULT/sample_rate); + g_snprintf(label_string, MAX_TIME_LABEL, "%.0f s", floor(nstime_to_sec(&rci->start_time_abs)) + i*MULT/sample_rate); } pango_layout_set_text(small_layout, label_string, -1); @@ -1652,18 +1619,18 @@ configure_event_channels(GtkWidget *widget, GdkEventConfigure *event _U_, gpoint }; #endif - static GdkRGBA col[MAX_NUM_COL_CONV+1] = { - /* Red, Green, Blue Alpha */ - {0.0039, 0.0039, 1.0000, 1.0}, - {0.5664, 0.6289, 0.5664, 1.0}, - {1.0000, 0.6289, 0.4805, 1.0}, - {1.0000, 0.7148, 0.7578, 1.0}, - {0.9805, 0.9805, 0.8242, 1.0}, - {1.0000, 1.0000, 0.2031, 1.0}, - {0.4023, 0.8046, 0.6680, 1.0}, - {0.8789, 1.0000, 1.0000, 1.0}, - {0.6914, 0.7695, 0.8710, 1.0}, - {0.8281, 0.8281, 0.8281, 1.0}, + static GdkRGBA col[MAX_NUM_COL_CONV+1] = { + /* Red, Green, Blue Alpha */ + {0.0039, 0.0039, 1.0000, 1.0}, + {0.5664, 0.6289, 0.5664, 1.0}, + {1.0000, 0.6289, 0.4805, 1.0}, + {1.0000, 0.7148, 0.7578, 1.0}, + {0.9805, 0.9805, 0.8242, 1.0}, + {1.0000, 1.0000, 0.2031, 1.0}, + {0.4023, 0.8046, 0.6680, 1.0}, + {0.8789, 1.0000, 1.0000, 1.0}, + {0.6914, 0.7695, 0.8710, 1.0}, + {0.8281, 0.8281, 0.8281, 1.0}, }; #if GTK_CHECK_VERSION(2,22,0) @@ -2215,7 +2182,7 @@ decode_streams(void) if (voip_calls) g_hash_table_foreach( rtp_streams_hash, (GHFunc)mark_rtp_stream_to_play, NULL); else - g_hash_table_foreach( rtp_streams_hash, (GHFunc)mark_all_rtp_stream_to_play, NULL); + g_hash_table_foreach( rtp_streams_hash, (GHFunc)mark_all_rtp_stream_to_decode, NULL); } /* Decode the RTP streams and add them to the RTP channels to be played */ @@ -2388,7 +2355,7 @@ rtp_player_dlg_create(void) gtk_widget_set_size_request(main_scrolled_window, CHANNEL_WIDTH, 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (main_scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_box_pack_start(GTK_BOX(main_vb), main_scrolled_window, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(main_vb), main_scrolled_window, TRUE, TRUE, 0); channels_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE); gtk_container_set_border_width (GTK_CONTAINER (channels_vb), 2); diff --git a/ui/gtk/rtp_stream_dlg.c b/ui/gtk/rtp_stream_dlg.c index 41c43cc841..002eff471b 100644 --- a/ui/gtk/rtp_stream_dlg.c +++ b/ui/gtk/rtp_stream_dlg.c @@ -400,10 +400,10 @@ rtpstream_on_filter(GtkButton *button _U_, gpointer user_data _U_) filter_string_fwd = g_strdup_printf( "(ip%s.src==%s && udp.srcport==%u && ip%s.dst==%s && udp.dstport==%u && rtp.ssrc==0x%X)", ip_version, - ep_address_to_str(&(selected_stream_fwd->src_addr)), + address_to_str(wmem_packet_scope(), &(selected_stream_fwd->src_addr)), selected_stream_fwd->src_port, ip_version, - ep_address_to_str(&(selected_stream_fwd->dest_addr)), + address_to_str(wmem_packet_scope(), &(selected_stream_fwd->dest_addr)), selected_stream_fwd->dest_port, selected_stream_fwd->ssrc); @@ -420,10 +420,10 @@ rtpstream_on_filter(GtkButton *button _U_, gpointer user_data _U_) filter_string_rev = g_strdup_printf( "(ip%s.src==%s && udp.srcport==%u && ip%s.dst==%s && udp.dstport==%u && rtp.ssrc==0x%X)", ip_version, - ep_address_to_str(&(selected_stream_rev->src_addr)), + address_to_str(wmem_packet_scope(), &(selected_stream_rev->src_addr)), selected_stream_rev->src_port, ip_version, - ep_address_to_str(&(selected_stream_rev->dest_addr)), + address_to_str(wmem_packet_scope(), &(selected_stream_rev->dest_addr)), selected_stream_rev->dest_port, selected_stream_rev->ssrc); @@ -691,10 +691,10 @@ add_to_list_store(rtp_stream_info_t* strinfo) data[2] = g_strdup(ep_address_to_display(&(strinfo->dest_addr))); data[3] = NULL; data[4] = g_strdup_printf("0x%X", strinfo->ssrc); - if (strinfo->info_payload_type_str != NULL) { - data[5] = g_strdup(strinfo->info_payload_type_str); + if (strinfo->payload_type_name != NULL) { + data[5] = g_strdup(strinfo->payload_type_name); } else { - data[5] = g_strdup(val_to_str_ext(strinfo->pt, &rtp_payload_type_short_vals_ext, + data[5] = g_strdup(val_to_str_ext(strinfo->payload_type, &rtp_payload_type_short_vals_ext, "Unknown (%u)")); } data[6] = NULL; @@ -731,7 +731,7 @@ add_to_list_store(rtp_stream_info_t* strinfo) RTP_COL_DST_PORT, strinfo->dest_port, RTP_COL_SSRC, data[4], RTP_COL_PAYLOAD, data[5], - RTP_COL_PACKETS, strinfo->npackets, + RTP_COL_PACKETS, strinfo->packet_count, RTP_COL_LOST, data[7], RTP_COL_MAX_DELTA, strinfo->rtp_stats.max_delta, RTP_COL_MAX_JITTER, strinfo->rtp_stats.max_jitter, diff --git a/ui/rtp_stream.h b/ui/rtp_stream.h index 3c002899d6..c173c1a2a0 100644 --- a/ui/rtp_stream.h +++ b/ui/rtp_stream.h @@ -35,7 +35,7 @@ /****************************************************************************/ /* type for storing rtp frame information */ typedef struct st_rtp_sample_header { - guint32 rec_time; /**< milliseconds since start of recording */ + double rec_time; /**< milliseconds since start of recording */ guint16 frame_length; /**< number of bytes in *frame */ } rtp_sample_header_t; @@ -55,22 +55,28 @@ typedef struct _rtp_stream_info { address dest_addr; guint32 dest_port; guint32 ssrc; - guint8 pt; - const gchar *info_payload_type_str; - guint32 npackets; - guint32 first_frame_num; /**< frame number of first frame */ + guint8 payload_type; /**< Numeric payload type */ + gchar *payload_type_name; /**< Payload type name */ + gboolean is_srtp; + + guint32 packet_count; + gboolean end_stream; /**< Used to track streams across payload types */ + int rtp_event; + + guint16 call_num; /**< Used to match call_num in voip_calls_info_t */ guint32 setup_frame_number; /**< frame number of setup message */ - /* start of recording (GMT) of this stream */ - guint32 start_sec; /**< seconds */ - guint32 start_usec; /**< microseconds */ - gboolean tag_vlan_error; - guint32 start_rel_sec; /**< start stream rel seconds */ - guint32 start_rel_usec; /**< start stream rel microseconds */ - guint32 stop_rel_sec; /**< stop stream rel seconds */ - guint32 stop_rel_usec; /**< stop stream rel microseconds */ - gboolean tag_diffserv_error; + /* Start and stop packets needed for .num and .abs_ts */ + frame_data *start_fd; + frame_data *stop_fd; + nstime_t start_rel_time; /**< relative start time from pinfo */ + nstime_t stop_rel_time; /**< relative stop time from pinfo */ guint16 vlan_id; + gboolean tag_vlan_error; + gboolean tag_diffserv_error; + + gboolean decode; /**< Decode this stream */ + GList *rtp_packet_list; /**< List of RTP rtp_packet_t */ tap_rtp_stat_t rtp_stats; /**< here goes the RTP statistics info */ gboolean problem; /**< if the streams had wrong sequence numbers or wrong timerstamps */ diff --git a/ui/tap-rtp-common.c b/ui/tap-rtp-common.c index b998a4fc95..3ed3186537 100644 --- a/ui/tap-rtp-common.c +++ b/ui/tap-rtp-common.c @@ -134,8 +134,8 @@ void rtp_write_header(rtp_stream_info_t *strinfo, FILE *file) ep_address_to_display(&(strinfo->dest_addr)), strinfo->dest_port); - start_sec = g_htonl(strinfo->start_sec); - start_usec = g_htonl(strinfo->start_usec); + start_sec = g_htonl(strinfo->start_fd->abs_ts.secs); + start_usec = g_htonl(strinfo->start_fd->abs_ts.nsecs / 1000000); /* rtpdump only accepts guint32 as source, will be fake for IPv6 */ memset(&source, 0, sizeof source); sourcelen = strinfo->src_addr.len; @@ -186,95 +186,67 @@ int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, con { rtpstream_tapinfo_t *tapinfo = (rtpstream_tapinfo_t *)arg; const struct _rtp_info *rtpinfo = (const struct _rtp_info *)arg2; - rtp_stream_info_t tmp_strinfo; - rtp_stream_info_t *strinfo = NULL; + rtp_stream_info_t new_stream_info; + rtp_stream_info_t *stream_info = NULL; GList* list; rtp_sample_t sample; struct _rtp_conversation_info *p_conv_data = NULL; /* gather infos on the stream this packet is part of */ - COPY_ADDRESS(&(tmp_strinfo.src_addr), &(pinfo->src)); - tmp_strinfo.src_port = pinfo->srcport; - COPY_ADDRESS(&(tmp_strinfo.dest_addr), &(pinfo->dst)); - tmp_strinfo.dest_port = pinfo->destport; - tmp_strinfo.ssrc = rtpinfo->info_sync_src; - tmp_strinfo.pt = rtpinfo->info_payload_type; - tmp_strinfo.info_payload_type_str = rtpinfo->info_payload_type_str; + memset(&new_stream_info, 0, sizeof(rtp_stream_info_t)); + COPY_ADDRESS(&(new_stream_info.src_addr), &(pinfo->src)); + new_stream_info.src_port = pinfo->srcport; + COPY_ADDRESS(&(new_stream_info.dest_addr), &(pinfo->dst)); + new_stream_info.dest_port = pinfo->destport; + new_stream_info.ssrc = rtpinfo->info_sync_src; + new_stream_info.payload_type = rtpinfo->info_payload_type; + new_stream_info.payload_type_name = g_strdup(rtpinfo->info_payload_type_str); if (tapinfo->mode == TAP_ANALYSE) { /* check whether we already have a stream with these parameters in the list */ list = g_list_first(tapinfo->strinfo_list); while (list) { - if (rtp_stream_info_cmp(&tmp_strinfo, (rtp_stream_info_t*)(list->data))==0) + if (rtp_stream_info_cmp(&new_stream_info, (rtp_stream_info_t*)(list->data))==0) { - strinfo = (rtp_stream_info_t*)(list->data); /*found!*/ + stream_info = (rtp_stream_info_t*)(list->data); /*found!*/ break; } list = g_list_next(list); } /* not in the list? then create a new entry */ - if (!strinfo) { - tmp_strinfo.npackets = 0; - tmp_strinfo.first_frame_num = pinfo->fd->num; - tmp_strinfo.start_sec = (guint32) pinfo->fd->abs_ts.secs; - tmp_strinfo.start_usec = pinfo->fd->abs_ts.nsecs/1000; - tmp_strinfo.start_rel_sec = (guint32) pinfo->rel_ts.secs; - tmp_strinfo.start_rel_usec = pinfo->rel_ts.nsecs/1000; - tmp_strinfo.tag_vlan_error = 0; - tmp_strinfo.tag_diffserv_error = 0; - tmp_strinfo.vlan_id = 0; - tmp_strinfo.problem = FALSE; + if (!stream_info) { + new_stream_info.start_fd = pinfo->fd; + new_stream_info.start_rel_time = pinfo->rel_ts; /* reset RTP stats */ - tmp_strinfo.rtp_stats.first_packet = TRUE; - tmp_strinfo.rtp_stats.max_delta = 0; - tmp_strinfo.rtp_stats.max_jitter = 0; - tmp_strinfo.rtp_stats.mean_jitter = 0; - tmp_strinfo.rtp_stats.delta = 0; - tmp_strinfo.rtp_stats.diff = 0; - tmp_strinfo.rtp_stats.jitter = 0; - tmp_strinfo.rtp_stats.bandwidth = 0; - tmp_strinfo.rtp_stats.total_bytes = 0; - tmp_strinfo.rtp_stats.bw_start_index = 0; - tmp_strinfo.rtp_stats.bw_index = 0; - tmp_strinfo.rtp_stats.timestamp = 0; - tmp_strinfo.rtp_stats.max_nr = 0; - tmp_strinfo.rtp_stats.total_nr = 0; - tmp_strinfo.rtp_stats.sequence = 0; - tmp_strinfo.rtp_stats.start_seq_nr = 0; - tmp_strinfo.rtp_stats.stop_seq_nr = 0; - tmp_strinfo.rtp_stats.cycles = 0; - tmp_strinfo.rtp_stats.under = FALSE; - tmp_strinfo.rtp_stats.start_time = 0; - tmp_strinfo.rtp_stats.time = 0; - tmp_strinfo.rtp_stats.reg_pt = PT_UNDEFINED; + new_stream_info.rtp_stats.first_packet = TRUE; + new_stream_info.rtp_stats.reg_pt = PT_UNDEFINED; /* Get the Setup frame number who set this RTP stream */ p_conv_data = (struct _rtp_conversation_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_get_id_by_filter_name("rtp"), 0); if (p_conv_data) - tmp_strinfo.setup_frame_number = p_conv_data->frame_number; + new_stream_info.setup_frame_number = p_conv_data->frame_number; else - tmp_strinfo.setup_frame_number = 0xFFFFFFFF; + new_stream_info.setup_frame_number = 0xFFFFFFFF; - strinfo = g_new(rtp_stream_info_t,1); - *strinfo = tmp_strinfo; /* memberwise copy of struct */ - tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo); + stream_info = g_new(rtp_stream_info_t,1); + *stream_info = new_stream_info; /* memberwise copy of struct */ + tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, stream_info); } /* get RTP stats for the packet */ - rtp_packet_analyse(&(strinfo->rtp_stats), pinfo, rtpinfo); - if (strinfo->rtp_stats.flags & STAT_FLAG_WRONG_TIMESTAMP - || strinfo->rtp_stats.flags & STAT_FLAG_WRONG_SEQ) - strinfo->problem = TRUE; + rtp_packet_analyse(&(stream_info->rtp_stats), pinfo, rtpinfo); + if (stream_info->rtp_stats.flags & STAT_FLAG_WRONG_TIMESTAMP + || stream_info->rtp_stats.flags & STAT_FLAG_WRONG_SEQ) + stream_info->problem = TRUE; /* increment the packets counter for this stream */ - ++(strinfo->npackets); - strinfo->stop_rel_sec = (guint32) pinfo->rel_ts.secs; - strinfo->stop_rel_usec = pinfo->rel_ts.nsecs/1000; + ++(stream_info->packet_count); + stream_info->stop_rel_time = pinfo->rel_ts; /* increment the packets counter of all streams */ ++(tapinfo->npackets); @@ -282,12 +254,11 @@ int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, con return 1; /* refresh output */ } else if (tapinfo->mode == TAP_SAVE) { - if (rtp_stream_info_cmp(&tmp_strinfo, tapinfo->filter_stream_fwd)==0) { + if (rtp_stream_info_cmp(&new_stream_info, tapinfo->filter_stream_fwd)==0) { /* XXX - what if rtpinfo->info_all_data_present is FALSE, so that we don't *have* all the data? */ - sample.header.rec_time = - (pinfo->fd->abs_ts.nsecs/1000 + 1000000 - tapinfo->filter_stream_fwd->start_usec)/1000 - + (guint32) (pinfo->fd->abs_ts.secs - tapinfo->filter_stream_fwd->start_sec - 1)*1000; + sample.header.rec_time = nstime_to_msec(&pinfo->fd->abs_ts) - + nstime_to_msec(&tapinfo->filter_stream_fwd->start_fd->abs_ts); sample.header.frame_length = rtpinfo->info_data_len; sample.frame = rtpinfo->info_data; rtp_write_sample(&sample, tapinfo->save_file); @@ -587,7 +558,7 @@ int rtp_packet_analyse(tap_rtp_stat_t *statinfo, if(rtpinfo->info_payload_rate !=0){ clock_rate = rtpinfo->info_payload_rate; }else{ - clock_rate = get_dyn_pt_clock_rate(rtpinfo-> info_payload_type_str); + clock_rate = get_dyn_pt_clock_rate(rtpinfo->info_payload_type_str); } } }else{ diff --git a/ui/voip_calls.c b/ui/voip_calls.c index 5e42156025..3b61c09912 100644 --- a/ui/voip_calls.c +++ b/ui/voip_calls.c @@ -62,6 +62,7 @@ #include "epan/rtp_pt.h" #include "ui/alert_box.h" +#include "ui/rtp_stream.h" #include "ui/simple_dialog.h" #include "ui/tap-sequence-analysis.h" #include "ui/ui_util.h" @@ -152,28 +153,6 @@ typedef struct _h245_labels { graph_str labels[H245_MAX]; } h245_labels_t; -/* defines a RTP stream */ -typedef struct _voip_rtp_stream_info { - address src_addr; - guint16 src_port; - address dest_addr; - guint16 dest_port; - guint32 ssrc; - guint32 pt; - gchar *pt_str; - gboolean is_srtp; - guint32 npackets; - gboolean end_stream; - - guint32 setup_frame_number; /* frame number of setup message */ - /* The frame_data struct holds the frame number and timing information needed. */ - frame_data *start_fd; - nstime_t start_rel_ts; - frame_data *stop_fd; - nstime_t stop_rel_ts; - gint32 rtp_event; -} voip_rtp_stream_info_t; - static void actrace_calls_init_tap(voip_calls_tapinfo_t *tap_id_base); static void h225_calls_init_tap(voip_calls_tapinfo_t *tap_id_base); static void h245dg_calls_init_tap(voip_calls_tapinfo_t *tap_id_base); @@ -273,7 +252,7 @@ void voip_calls_reset_all_taps(voip_calls_tapinfo_t *tapinfo) { voip_calls_info_t *callsinfo; - voip_rtp_stream_info_t *strinfo; + rtp_stream_info_t *strinfo; GList *list = NULL; /* free the data items first */ @@ -310,8 +289,8 @@ voip_calls_reset_all_taps(voip_calls_tapinfo_t *tapinfo) list = g_list_first(tapinfo->rtp_stream_list); while(list) { - strinfo = (voip_rtp_stream_info_t *)list->data; - g_free(strinfo->pt_str); + strinfo = (rtp_stream_info_t *)list->data; + g_free(strinfo->payload_type_name); list = g_list_next(list); } g_list_free(tapinfo->rtp_stream_list); @@ -595,8 +574,8 @@ static gboolean rtp_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, void const *rtp_info_ptr) { voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_); - voip_rtp_stream_info_t *tmp_listinfo; - voip_rtp_stream_info_t *strinfo = NULL; + rtp_stream_info_t *tmp_listinfo; + rtp_stream_info_t *strinfo = NULL; GList *list; struct _rtp_conversation_info *p_conv_data = NULL; @@ -615,15 +594,15 @@ rtp_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, void c list = g_list_first(tapinfo->rtp_stream_list); while (list) { - tmp_listinfo=(voip_rtp_stream_info_t *)list->data; + tmp_listinfo=(rtp_stream_info_t *)list->data; if ( (tmp_listinfo->setup_frame_number == rtp_info->info_setup_frame_num) && (tmp_listinfo->ssrc == rtp_info->info_sync_src) && (tmp_listinfo->end_stream == FALSE)) { /* if the payload type has changed, we mark the stream as finished to create a new one this is to show multiple payload changes in the Graph for example for DTMF RFC2833 */ - if ( tmp_listinfo->pt != rtp_info->info_payload_type ) { + if ( tmp_listinfo->payload_type != rtp_info->info_payload_type ) { tmp_listinfo->end_stream = TRUE; } else { - strinfo = (voip_rtp_stream_info_t*)(list->data); + strinfo = (rtp_stream_info_t*)(list->data); break; } } @@ -637,40 +616,39 @@ rtp_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, void c /* not in the list? then create a new entry */ if (strinfo==NULL) { - strinfo = (voip_rtp_stream_info_t *)g_malloc(sizeof(voip_rtp_stream_info_t)); + strinfo = (rtp_stream_info_t *)g_malloc(sizeof(rtp_stream_info_t)); COPY_ADDRESS(&(strinfo->src_addr), &(pinfo->src)); strinfo->src_port = pinfo->srcport; COPY_ADDRESS(&(strinfo->dest_addr), &(pinfo->dst)); strinfo->dest_port = pinfo->destport; strinfo->ssrc = rtp_info->info_sync_src; strinfo->end_stream = FALSE; - strinfo->pt = rtp_info->info_payload_type; - strinfo->pt_str = NULL; + strinfo->payload_type = rtp_info->info_payload_type; + strinfo->payload_type_name = NULL; strinfo->is_srtp = rtp_info->info_is_srtp; /* if it is dynamic payload, let use the conv data to see if it is defined */ - if ( (strinfo->pt >= PT_UNDF_96) && (strinfo->pt <= PT_UNDF_127) ) { + if ( (strinfo->payload_type >= PT_UNDF_96) && (strinfo->payload_type <= PT_UNDF_127) ) { /* Use existing packet info if available */ p_conv_data = (struct _rtp_conversation_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_get_id_by_filter_name("rtp"), 0); if (p_conv_data && p_conv_data->rtp_dyn_payload) { - const gchar *encoding_name = rtp_dyn_payload_get_name(p_conv_data->rtp_dyn_payload, strinfo->pt); + const gchar *encoding_name = rtp_dyn_payload_get_name(p_conv_data->rtp_dyn_payload, strinfo->payload_type); if (encoding_name) { - strinfo->pt_str = g_strdup(encoding_name); + strinfo->payload_type_name = g_strdup(encoding_name); } } } - if (!strinfo->pt_str) strinfo->pt_str = g_strdup(val_to_str_ext(strinfo->pt, &rtp_payload_type_short_vals_ext, "%u")); - strinfo->npackets = 0; + if (!strinfo->payload_type_name) strinfo->payload_type_name = g_strdup(val_to_str_ext(strinfo->payload_type, &rtp_payload_type_short_vals_ext, "%u")); + strinfo->packet_count = 0; strinfo->start_fd = pinfo->fd; - strinfo->start_rel_ts = pinfo->rel_ts; + strinfo->start_rel_time = pinfo->rel_ts; strinfo->setup_frame_number = rtp_info->info_setup_frame_num; strinfo->rtp_event = -1; tapinfo->rtp_stream_list = g_list_prepend(tapinfo->rtp_stream_list, strinfo); } /* Add the info to the existing RTP stream */ - strinfo->npackets++; + strinfo->packet_count++; strinfo->stop_fd = pinfo->fd; - strinfo->stop_rel_ts = pinfo->rel_ts; /* process RTP Event */ if (tapinfo->rtp_evt_frame_num == pinfo->fd->num) { @@ -692,7 +670,7 @@ rtp_draw(void *tap_offset_ptr) { voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_); GList *rtp_streams_list; - voip_rtp_stream_info_t *rtp_listinfo; + rtp_stream_info_t *rtp_listinfo; /* GList *voip_calls_graph_list; */ seq_analysis_item_t *gai = NULL; seq_analysis_item_t *new_gai; @@ -704,7 +682,7 @@ rtp_draw(void *tap_offset_ptr) rtp_streams_list = g_list_first(tapinfo->rtp_stream_list); while (rtp_streams_list) { - rtp_listinfo = (voip_rtp_stream_info_t *)rtp_streams_list->data; + rtp_listinfo = (rtp_stream_info_t *)rtp_streams_list->data; /* using the setup frame number of the RTP stream, we get the call number that it belongs to*/ /* voip_calls_graph_list = g_list_first(tapinfo->graph_analysis->list); */ @@ -712,15 +690,16 @@ rtp_draw(void *tap_offset_ptr) gai = (seq_analysis_item_t *)g_hash_table_lookup(tapinfo->graph_analysis->ht, &rtp_listinfo->setup_frame_number); } if(gai != NULL) { + const char *comment_fmt = "%s, %u packets. Duration: %u.%03us SSRC: 0x%X"; /* Found the setup frame*/ conv_num = gai->conv_num; /* if RTP was already in the Graph, just update the comment information */ gai = (seq_analysis_item_t *)g_hash_table_lookup(tapinfo->graph_analysis->ht, &rtp_listinfo->start_fd->num); if (gai != NULL) { - duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_rel_ts) - nstime_to_msec(&rtp_listinfo->start_rel_ts)); + duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_rel_time) - nstime_to_msec(&rtp_listinfo->start_rel_time)); g_free(gai->comment); - gai->comment = g_strdup_printf("%s Num packets:%u Duration:%u.%03us SSRC:0x%X", - (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->npackets, + gai->comment = g_strdup_printf(comment_fmt, + (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->packet_count, duration/1000,(duration%1000), rtp_listinfo->ssrc); } else { new_gai = (seq_analysis_item_t *)g_malloc(sizeof(seq_analysis_item_t)); @@ -729,14 +708,14 @@ rtp_draw(void *tap_offset_ptr) COPY_ADDRESS(&(new_gai->dst_addr),&(rtp_listinfo->dest_addr)); new_gai->port_src = rtp_listinfo->src_port; new_gai->port_dst = rtp_listinfo->dest_port; - duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_rel_ts) - nstime_to_msec(&rtp_listinfo->start_rel_ts)); + duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_rel_time) - nstime_to_msec(&rtp_listinfo->start_rel_time)); new_gai->frame_label = g_strdup_printf("%s (%s) %s", (rtp_listinfo->is_srtp)?"SRTP":"RTP", - rtp_listinfo->pt_str, + rtp_listinfo->payload_type_name, (rtp_listinfo->rtp_event == -1)? "":val_to_str_ext_const(rtp_listinfo->rtp_event, &rtp_event_type_values_ext, "Unknown RTP Event")); - new_gai->comment = g_strdup_printf("%s Num packets:%u Duration:%u.%03us SSRC:0x%X", - (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->npackets, + new_gai->comment = g_strdup_printf(comment_fmt, + (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->packet_count, duration/1000,(duration%1000), rtp_listinfo->ssrc); new_gai->conv_num = conv_num; set_fd_time(tapinfo->session, new_gai->fd, time_str); @@ -760,7 +739,7 @@ rtp_packet_draw(void *tap_offset_ptr) { voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_); GList *rtp_streams_list; - voip_rtp_stream_info_t *rtp_listinfo; + rtp_stream_info_t *rtp_listinfo; GList *voip_calls_graph_list; guint item; seq_analysis_item_t *gai; @@ -813,7 +792,7 @@ rtp_packet_draw(void *tap_offset_ptr) duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_fd->rel_ts) - nstime_to_msec(&rtp_listinfo->start_fd->rel_ts)); new_gai->frame_label = g_strdup_printf("%s (%s) %s", (rtp_listinfo->is_srtp)?"SRTP":"RTP", - rtp_listinfo->pt_str, + rtp_listinfo->payload_type_str, (rtp_listinfo->rtp_event == -1)? "":val_to_str_ext_const(rtp_listinfo->rtp_event, &rtp_event_type_values_ext, "Unknown RTP Event")); new_gai->comment = g_strdup_printf("%s Num packets:%u Duration:%u.%03us SSRC:0x%X", @@ -2895,7 +2874,7 @@ h248_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, } add_to_graph(tapinfo, pinfo, edt, cmd->str ? cmd->str : "unknown Msg", - ep_strdup_printf("TrxId = %u, CtxId = %.8x",cmd->trx->id,cmd->ctx->id), + wmem_strdup_printf(wmem_packet_scope(), "TrxId = %u, CtxId = %.8x",cmd->trx->id,cmd->ctx->id), callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1); ++(tapinfo->npackets); diff --git a/ui/voip_calls.h b/ui/voip_calls.h index fc6cdb5904..91308e6ab5 100644 --- a/ui/voip_calls.h +++ b/ui/voip_calls.h @@ -199,7 +199,7 @@ typedef struct _voip_calls_tapinfo { seq_analysis_info_t* graph_analysis; epan_t *session; /**< epan session */ int nrtp_streams; /**< number of rtp streams */ - GList* rtp_stream_list; /**< list with the rtp streams */ + GList* rtp_stream_list; /**< list of rtp_stream_info_t */ guint32 rtp_evt_frame_num; guint8 rtp_evt; gboolean rtp_evt_end;