from lars ruoff a few extra columns for rtp analysis
authorsahlberg <sahlberg@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 16 Feb 2005 09:24:52 +0000 (09:24 +0000)
committersahlberg <sahlberg@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 16 Feb 2005 09:24:52 +0000 (09:24 +0000)
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@13410 f5534014-38df-0310-8fa8-9805f1628bb7

gtk/rtp_analysis.c
gtk/rtp_analysis.h
gtk/rtp_stream.c
gtk/rtp_stream.h
gtk/rtp_stream_dlg.c

index d8c9231f900b9c7b7538750b30b3dbb846f02a05..f6ad1016b23c3b47f126f88b92bc30fd228699b9 100644 (file)
@@ -181,8 +181,6 @@ typedef struct _dialog_data_t {
 } dialog_data_t;
 
 #define OK_TEXT "[ Ok ]"
-#define PT_UNDEFINED -1
-
 
 typedef struct _key_value {
   guint32  key;
@@ -253,54 +251,6 @@ GtkRcStyle *rc_style;
 GdkColormap *colormap;
 #endif
 
-/****************************************************************************/
-/* structure that holds the information about the forward and reversed direction */
-typedef struct _bw_history_item {
-        double time;
-        guint32 bytes;
-} bw_history_item;
-#define BUFF_BW 300 
-typedef struct _tap_rtp_stat_t {
-       gboolean first_packet;     /* do not use in code that is called after rtp_packet_analyse */
-                                  /* use (flags & STAT_FLAG_FIRST) instead */
-       /* all of the following fields will be initialized after
-        rtp_packet_analyse has been called */
-       guint32 flags;             /* see STAT_FLAG-defines below */
-       guint16 seq_num;
-       guint32 timestamp;
-       guint32 delta_timestamp;
-       double bandwidth;
-       bw_history_item bw_history[BUFF_BW];
-       guint16 bw_start_index;
-       guint16 bw_index;
-       guint32 total_bytes;
-       double delta;
-       double jitter;
-       double diff;
-       double time;
-       double start_time;
-       double max_delta;
-       guint32 max_nr;
-       guint16 start_seq_nr;
-       guint16 stop_seq_nr;
-       guint32 total_nr;
-       guint32 sequence;
-       gboolean under;
-       gint cycles;
-       guint16 pt;
-       int reg_pt;
-} tap_rtp_stat_t;
-
-/* status flags for the flags parameter in tap_rtp_stat_t */
-#define STAT_FLAG_FIRST       0x01
-#define STAT_FLAG_MARKER      0x02
-#define STAT_FLAG_WRONG_SEQ   0x04
-#define STAT_FLAG_PT_CHANGE   0x08
-#define STAT_FLAG_PT_CN       0x10
-#define STAT_FLAG_FOLLOW_PT_CN  0x20
-#define STAT_FLAG_REG_PT_CHANGE  0x40
-#define STAT_FLAG_WRONG_TIMESTAMP  0x80
-
 typedef struct _tap_rtp_save_info_t {
        FILE *fp;
        guint32 count;
@@ -388,6 +338,10 @@ rtp_reset(void *user_data_arg)
        user_data->reversed.statinfo.first_packet = TRUE;
        user_data->forward.statinfo.max_delta = 0;
        user_data->reversed.statinfo.max_delta = 0;
+       user_data->forward.statinfo.max_jitter = 0;
+       user_data->reversed.statinfo.max_jitter = 0;
+       user_data->forward.statinfo.mean_jitter = 0;
+       user_data->reversed.statinfo.mean_jitter = 0;
        user_data->forward.statinfo.delta = 0;
        user_data->reversed.statinfo.delta = 0;
         user_data->forward.statinfo.diff = 0;
@@ -530,12 +484,10 @@ static void add_to_clist(GtkCList *clist, guint32 number, guint16 seq_num,
                          double delta, double jitter, double bandwidth, gchar *status, gboolean marker,
                          gchar *timeStr, guint32 pkt_len, GdkColor *color);
 
-static int rtp_packet_analyse(tap_rtp_stat_t *statinfo,
-                              packet_info *pinfo,
-                              const struct _rtp_info *rtpinfo);
 static int rtp_packet_add_info(GtkCList *clist,
        tap_rtp_stat_t *statinfo, packet_info *pinfo,
        const struct _rtp_info *rtpinfo);
+
 static int rtp_packet_save_payload(tap_rtp_save_info_t *saveinfo, 
                                    tap_rtp_stat_t *statinfo,
                                    packet_info *pinfo,
@@ -593,7 +545,7 @@ static int rtp_packet(void *user_data_arg, packet_info *pinfo, epan_dissect_t *e
 
 
 /****************************************************************************/
-static int rtp_packet_analyse(tap_rtp_stat_t *statinfo,
+int rtp_packet_analyse(tap_rtp_stat_t *statinfo,
                               packet_info *pinfo,
                               const struct _rtp_info *rtpinfo)
 {
@@ -674,6 +626,11 @@ static int rtp_packet_analyse(tap_rtp_stat_t *statinfo,
                        statinfo->max_delta = statinfo->delta;
                        statinfo->max_nr = pinfo->fd->num;
                }
+               /* maximum and mean jitter calculation */
+               if (statinfo->jitter > statinfo->max_jitter) {
+                       statinfo->max_jitter = statinfo->jitter;
+               }
+               statinfo->mean_jitter = (statinfo->mean_jitter*statinfo->total_nr + current_diff) / (statinfo->total_nr+1);
        }
        /* regular payload change? (CN ignored) */
        if (!(statinfo->flags & STAT_FLAG_FIRST)
index 1dda687c79f0be89619b97dbd136648f11475ea6..dc88c8dc49160236a4a5879024fc323d7df102ae 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <glib.h>
 #include <epan/address.h>
+#include <epan/packet_info.h>
 
 /** @file
  *  ??? 
@@ -53,5 +54,67 @@ void rtp_analysis(
                guint32 ssrc_rev
                );
 
+/****************************************************************************/
+/* structure that holds the information about the forward and reversed direction */
+typedef struct _bw_history_item {
+        double time;
+        guint32 bytes;
+} bw_history_item;
+
+#define BUFF_BW 300 
+
+typedef struct _tap_rtp_stat_t {
+       gboolean first_packet;     /* do not use in code that is called after rtp_packet_analyse */
+                                  /* use (flags & STAT_FLAG_FIRST) instead */
+       /* all of the following fields will be initialized after
+        rtp_packet_analyse has been called */
+       guint32 flags;             /* see STAT_FLAG-defines below */
+       guint16 seq_num;
+       guint32 timestamp;
+       guint32 delta_timestamp;
+       double bandwidth;
+       bw_history_item bw_history[BUFF_BW];
+       guint16 bw_start_index;
+       guint16 bw_index;
+       guint32 total_bytes;
+       double delta;
+       double jitter;
+       double diff;
+       double time;
+       double start_time;
+       double max_delta;
+       double max_jitter;
+       double mean_jitter;
+       guint32 max_nr;
+       guint16 start_seq_nr;
+       guint16 stop_seq_nr;
+       guint32 total_nr;
+       guint32 sequence;
+       gboolean under;
+       gint cycles;
+       guint16 pt;
+       int reg_pt;
+} tap_rtp_stat_t;
+
+#define PT_UNDEFINED -1
+
+/* status flags for the flags parameter in tap_rtp_stat_t */
+#define STAT_FLAG_FIRST       0x01
+#define STAT_FLAG_MARKER      0x02
+#define STAT_FLAG_WRONG_SEQ   0x04
+#define STAT_FLAG_PT_CHANGE   0x08
+#define STAT_FLAG_PT_CN       0x10
+#define STAT_FLAG_FOLLOW_PT_CN  0x20
+#define STAT_FLAG_REG_PT_CHANGE  0x40
+#define STAT_FLAG_WRONG_TIMESTAMP  0x80
+
+/* forward */
+struct _rtp_info;
+
+/* function for analysing an RTP packet. Called from rtp_analysis and rtp_streams */
+extern int rtp_packet_analyse(tap_rtp_stat_t *statinfo,
+        packet_info *pinfo,
+        const struct _rtp_info *rtpinfo);
+
 
 #endif /*RTP_ANALYSIS_H_INCLUDED*/
index 7861870d9d93156e0800e30f52787dcc502aa100..5c496362096f771fc9d51e48cfd51aaf7d7c8acc 100644 (file)
@@ -245,9 +245,33 @@ static int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _
                        tmp_strinfo.tag_vlan_error = 0;
                        tmp_strinfo.tag_diffserv_error = 0;
                        tmp_strinfo.vlan_id = 0;
-                       
-            /* Get the Setup frame number who set this RTP stream */
+                       tmp_strinfo.problem = FALSE;
+
+                       /* 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;
 
+            /* Get the Setup frame number who set this RTP stream */
             p_conv_data = p_get_proto_data(pinfo->fd, proto_get_id_by_filter_name("rtp"));
             if (p_conv_data)
                                tmp_strinfo.setup_frame_number = p_conv_data->frame_number;
@@ -259,6 +283,13 @@ static int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _
                        tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
                }
 
+               /* 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;
+
+
                /* increment the packets counter for this stream */
                ++(strinfo->npackets);
                strinfo->stop_rel_sec = pinfo->fd->rel_secs;
index 78c904435bdb75de881dccf92faecc517d0e37f3..6128fe8ab279f929297668ee070453c88c864c7b 100644 (file)
@@ -28,6 +28,7 @@
 #ifndef RTP_STREAM_H_INCLUDED
 #define RTP_STREAM_H_INCLUDED
 
+#include "rtp_analysis.h"
 #include <glib.h>
 #include <stdio.h>
 #include <epan/address.h>
@@ -77,6 +78,8 @@ typedef struct _rtp_stream_info {
        gboolean tag_diffserv_error;
        guint16 vlan_id;
 
+       tap_rtp_stat_t rtp_stats;  /* here goes the RTP statistics info */
+       gboolean problem; /* if the streams had wrong sequence numbers or wrong timerstamps */
 } rtp_stream_info_t;
 
 
index f585a68c21afe05b461cf4c47ce757be5e3675f4..2bdded0dcaa6737d5fe7e62e48e68b8897b8f7fb 100644 (file)
@@ -72,14 +72,19 @@ static GList *last_list = NULL;
 
 static guint32 streams_nb = 0;     /* number of displayed streams */
 
+#define NUM_COLS 12
+
 /****************************************************************************/
 /* append a line to clist */
 static void add_to_clist(rtp_stream_info_t* strinfo)
 {
        gchar label_text[256];
        gint added_row;
-       gchar *data[8];
-       gchar field[8][30];
+       gchar *data[NUM_COLS];
+       gchar field[NUM_COLS][30];
+       guint32 expected;
+       gint32 lost;
+       double perc;
 
        data[0]=&field[0][0];
        data[1]=&field[1][0];
@@ -89,6 +94,10 @@ static void add_to_clist(rtp_stream_info_t* strinfo)
        data[5]=&field[5][0];
        data[6]=&field[6][0];
        data[7]=&field[7][0];
+       data[8]=&field[8][0];
+       data[9]=&field[9][0];
+       data[10]=&field[10][0];
+       data[11]=&field[11][0];
 
        g_snprintf(field[0], 20, "%s", address_to_str_w_none(&(strinfo->src_addr)));
        g_snprintf(field[1], 20, "%u", strinfo->src_port);
@@ -98,8 +107,23 @@ static void add_to_clist(rtp_stream_info_t* strinfo)
        g_snprintf(field[5], 30, "%s", val_to_str(strinfo->pt, rtp_payload_type_vals,
                "Unknown (%u)"));
        g_snprintf(field[6], 20, "%u", strinfo->npackets);
-       /* XXX: Comment field is not used for the moment */
-/*     g_snprintf(field[7], 20, "%s", "");*/
+
+       expected = (strinfo->rtp_stats.stop_seq_nr + strinfo->rtp_stats.cycles*65536)
+               - strinfo->rtp_stats.start_seq_nr + 1;
+       lost = expected - strinfo->rtp_stats.total_nr;
+       if (expected){
+               perc = (double)(lost*100)/(double)expected;
+       } else {
+               perc = 0;
+       }
+       g_snprintf(field[7], 20, "%d (%.1f%%)", lost, perc);
+       g_snprintf(field[8], 20, "%.2f", strinfo->rtp_stats.max_delta*1000);
+       g_snprintf(field[9], 20, "%.2f", strinfo->rtp_stats.max_jitter*1000);
+       g_snprintf(field[10], 20, "%.2f", strinfo->rtp_stats.mean_jitter*1000);
+       if (strinfo->problem)
+               g_snprintf(field[11], 20, "X");
+       else
+               g_snprintf(field[11], 20, "");
 
        added_row = gtk_clist_append(GTK_CLIST(clist), data);
 
@@ -491,8 +515,6 @@ rtpstream_on_select_row(GtkCList *clist,
 
 
 /****************************************************************************/
-#define NUM_COLS 7
-
 typedef struct column_arrows {
        GtkWidget *table;
        GtkWidget *ascend_pm;
@@ -551,12 +573,16 @@ rtpstream_sort_column(GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2)
        case 0:
        case 2:
        case 5:
-       case 7:
+       case 11:
                return strcmp (text1, text2);
        case 1:
        case 3:
        case 4:
        case 6:
+       case 7:
+       case 8:
+       case 9:
+       case 10:
                i1=atoi(text1);
                i2=atoi(text2);
                return i1-i2;
@@ -586,7 +612,7 @@ static void rtpstream_dlg_create (void)
        GtkWidget *bt_close;
     GtkTooltips *tooltips = gtk_tooltips_new();
 
-       gchar *titles[8] =  {"Src IP addr", "Src port",  "Dest IP addr", "Dest port", "SSRC", "Payload", "Packets", "Comment"};
+       gchar *titles[NUM_COLS] =  {"Src IP addr", "Src port",  "Dest IP addr", "Dest port", "SSRC", "Payload", "Packets", "Lost", "Max Delta (ms)", "Max Jitter (ms)", "Mean Jitter (ms)", "Pb?"};
        column_arrows *col_arrows;
        GtkWidget *column_lb;
        int i;
@@ -607,14 +633,18 @@ static void rtpstream_dlg_create (void)
        clist = gtk_clist_new (NUM_COLS);
        gtk_container_add (GTK_CONTAINER (scrolledwindow), clist);
 
-       gtk_clist_set_column_width (GTK_CLIST (clist), 0, 100);
-       gtk_clist_set_column_width (GTK_CLIST (clist), 1, 50);
-       gtk_clist_set_column_width (GTK_CLIST (clist), 2, 100);
-       gtk_clist_set_column_width (GTK_CLIST (clist), 3, 50);
-       gtk_clist_set_column_width (GTK_CLIST (clist), 4, 80);
-       gtk_clist_set_column_width (GTK_CLIST (clist), 5, 118);
-       gtk_clist_set_column_width (GTK_CLIST (clist), 6, 40);
-/*     gtk_clist_set_column_width (GTK_CLIST (clist), 7, 51);*/
+       gtk_clist_set_column_width (GTK_CLIST (clist), 0, 88);
+       gtk_clist_set_column_width (GTK_CLIST (clist), 1, 44);
+       gtk_clist_set_column_width (GTK_CLIST (clist), 2, 88);
+       gtk_clist_set_column_width (GTK_CLIST (clist), 3, 44);
+       gtk_clist_set_column_width (GTK_CLIST (clist), 4, 64);
+       gtk_clist_set_column_width (GTK_CLIST (clist), 5, 96);
+       gtk_clist_set_column_width (GTK_CLIST (clist), 6, 50);
+       gtk_clist_set_column_width (GTK_CLIST (clist), 7, 50);
+       gtk_clist_set_column_width (GTK_CLIST (clist), 8, 80);
+       gtk_clist_set_column_width (GTK_CLIST (clist), 9, 80);
+       gtk_clist_set_column_width (GTK_CLIST (clist), 10, 80);
+       gtk_clist_set_column_width (GTK_CLIST (clist), 11, 40);
 
        gtk_clist_set_column_justification(GTK_CLIST(clist), 0, GTK_JUSTIFY_CENTER);
        gtk_clist_set_column_justification(GTK_CLIST(clist), 1, GTK_JUSTIFY_CENTER);
@@ -623,7 +653,11 @@ static void rtpstream_dlg_create (void)
        gtk_clist_set_column_justification(GTK_CLIST(clist), 4, GTK_JUSTIFY_CENTER);
        gtk_clist_set_column_justification(GTK_CLIST(clist), 5, GTK_JUSTIFY_LEFT);
        gtk_clist_set_column_justification(GTK_CLIST(clist), 6, GTK_JUSTIFY_RIGHT);
-/*     gtk_clist_set_column_justification(GTK_CLIST(clist), 7, GTK_JUSTIFY_CENTER);*/
+       gtk_clist_set_column_justification(GTK_CLIST(clist), 7, GTK_JUSTIFY_RIGHT);
+       gtk_clist_set_column_justification(GTK_CLIST(clist), 8, GTK_JUSTIFY_RIGHT);
+       gtk_clist_set_column_justification(GTK_CLIST(clist), 9, GTK_JUSTIFY_RIGHT);
+       gtk_clist_set_column_justification(GTK_CLIST(clist), 10, GTK_JUSTIFY_RIGHT);
+       gtk_clist_set_column_justification(GTK_CLIST(clist), 11, GTK_JUSTIFY_LEFT);
 
        gtk_clist_column_titles_show (GTK_CLIST (clist));