aboutsummaryrefslogtreecommitdiffstats
path: root/gtk
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2003-09-06 08:30:26 +0000
committerGuy Harris <guy@alum.mit.edu>2003-09-06 08:30:26 +0000
commitd66f162b7158cbd661f0d5e1c774196d52a93576 (patch)
treef2977aa3031c5313a3b05dc1663794ff017a5f93 /gtk
parent029c86ab1cebe98f3e1231938f17bbac97b2b27f (diff)
From Brian K. Teravskis: add an option to save the data in CSV form.
svn path=/trunk/; revision=8405
Diffstat (limited to 'gtk')
-rw-r--r--gtk/tap_rtp.c253
1 files changed, 242 insertions, 11 deletions
diff --git a/gtk/tap_rtp.c b/gtk/tap_rtp.c
index b0ddfeb44d..9bb7506dcb 100644
--- a/gtk/tap_rtp.c
+++ b/gtk/tap_rtp.c
@@ -1,7 +1,7 @@
/*
* tap_rtp.c
*
- * $Id: tap_rtp.c,v 1.14 2003/09/03 23:32:40 guy Exp $
+ * $Id: tap_rtp.c,v 1.15 2003/09/06 08:30:26 guy Exp $
*
* RTP analysing addition for ethereal
*
@@ -123,6 +123,7 @@
static GtkWidget *rtp_w = NULL;
static GtkWidget *save_voice_as_w = NULL;
+static GtkWidget *save_csv_as_w = NULL;
static GtkWidget *main_vb;
static GtkWidget *clist;
static GtkWidget *clist_r;
@@ -285,10 +286,10 @@ static void draw_stat(void *prs)
/* append a line to clist */
/* XXX is there a nicer way to make these assignements? */
static void add_to_clist(gboolean forward, guint32 number, guint16 seq_num,
- double delay, double jitter, gboolean status, gboolean marker)
+ double delay, double jitter, gboolean status, gboolean marker, gchar *timeStr, guint32 pkt_len)
{
- gchar *data[6];
- gchar field[6][30];
+ gchar *data[8];
+ gchar field[8][30];
data[0]=&field[0][0];
data[1]=&field[1][0];
@@ -296,6 +297,8 @@ static void add_to_clist(gboolean forward, guint32 number, guint16 seq_num,
data[3]=&field[3][0];
data[4]=&field[4][0];
data[5]=&field[5][0];
+ data[6]=&field[6][0];
+ data[7]=&field[7][0];
g_snprintf(field[0], 20, "%u", number);
g_snprintf(field[1], 20, "%u", seq_num);
@@ -303,6 +306,8 @@ static void add_to_clist(gboolean forward, guint32 number, guint16 seq_num,
g_snprintf(field[3], 20, "%f", jitter);
g_snprintf(field[4], 20, "%s", marker? "SET" : "");
g_snprintf(field[5], 29, "%s", status? "OK" : "NOK - Wrong sequence nr.");
+ g_snprintf(field[6], 32, "%s", timeStr);
+ g_snprintf(field[7], 20, "%u", pkt_len);
gtk_clist_append(GTK_CLIST(forward? clist : clist_r), data);
@@ -405,7 +410,24 @@ int do_calculation(gboolean direc, packet_type pkt_type, void *ptrs, void *vpri,
double current_jitter;
guint8 *data;
gint16 tmp;
+ guint16 msecs;
+ gchar timeStr[32];
+ struct tm *tm_tmp;
+ time_t then;
+
+ then = pinfo->fd->abs_secs;
+ msecs = (guint16)(pinfo->fd->abs_usecs/1000);
+
+ tm_tmp = localtime(&then);
+ snprintf(timeStr,32,"%02d/%02d/%04d %02d:%02d:%02d.%03d",
+ tm_tmp->tm_mon + 1,
+ tm_tmp->tm_mday,
+ tm_tmp->tm_year + 1900,
+ tm_tmp->tm_hour,
+ tm_tmp->tm_min,
+ tm_tmp->tm_sec,
+ msecs);
/* store the current time and calculate the current jitter */
current_time = (double)pinfo->fd->rel_secs + (double) pinfo->fd->rel_usecs/1000000;
current_jitter = ptr->jitter + ( fabs (current_time - (ptr->time) -
@@ -419,7 +441,8 @@ int do_calculation(gboolean direc, packet_type pkt_type, void *ptrs, void *vpri,
ptr->start_seq_nr = pri->info_seq_num;
ptr->start_time = current_time;
add_to_clist(direc, pinfo->fd->num, pri->info_seq_num, 0,
- pri->info_marker_set? TRUE: FALSE, TRUE, FALSE);
+ pri->info_marker_set? TRUE: FALSE, TRUE, FALSE,
+ timeStr, pinfo->fd->pkt_len);
if (ptr->fp == NULL) {
ptr->saved = FALSE;
ptr->error_type = TAP_RTP_FILE_OPEN_ERROR;
@@ -431,7 +454,7 @@ int do_calculation(gboolean direc, packet_type pkt_type, void *ptrs, void *vpri,
else if (pkt_type == MARK_SET) {
ptr->delta_timestamp = pri->info_timestamp - ptr->timestamp;
add_to_clist(direc, pinfo->fd->num, pri->info_seq_num, current_time - (ptr->time),
- current_jitter, ptr->seq_num+1 == pri->info_seq_num? TRUE: FALSE, TRUE);
+ current_jitter, ptr->seq_num+1 == pri->info_seq_num? TRUE: FALSE, TRUE, timeStr, pinfo->fd->pkt_len);
}
/* if neither then it is a "normal" packet pkt_type == NORMAL_PACKET */
else {
@@ -440,7 +463,7 @@ int do_calculation(gboolean direc, packet_type pkt_type, void *ptrs, void *vpri,
ptr->max_nr = pinfo->fd->num;
}
add_to_clist(direc, pinfo->fd->num, pri->info_seq_num, current_time -(ptr->time),
- current_jitter , ptr->seq_num+1 == pri->info_seq_num?TRUE:FALSE, FALSE);
+ current_jitter , ptr->seq_num+1 == pri->info_seq_num?TRUE:FALSE, FALSE, timeStr, pinfo->fd->pkt_len);
}
/* When calculating expected rtp packets the seq number can wrap around
@@ -677,6 +700,199 @@ static void refresh_cb(GtkWidget *w _U_, void *pri)
draw_stat(rs);
}
+/* when we want to save the information */
+static void save_csv_as_ok_cb(GtkWidget *ok_bt, gpointer fs)
+{
+ gchar *g_dest;
+ GtkWidget *rev, *forw, *both;
+ info_stat *rs;
+
+ FILE *fp;
+ char *columnText;
+ int i,j;
+
+ g_dest = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION (fs)));
+
+ /* Perhaps the user specified a directory instead of a file.
+ Check whether they did. */
+ if (test_for_directory(g_dest) == EISDIR) {
+ /* It's a directory - set the file selection box to display it. */
+ set_last_open_dir(g_dest);
+ g_free(g_dest);
+ gtk_file_selection_set_filename(GTK_FILE_SELECTION(fs), last_open_dir);
+ return;
+ }
+
+ rev = (GtkWidget *)OBJECT_GET_DATA(ok_bt, "reversed_rb");
+ forw = (GtkWidget *)OBJECT_GET_DATA(ok_bt, "forward_rb");
+ both = (GtkWidget *)OBJECT_GET_DATA(ok_bt, "both_rb");
+ rs = (info_stat *)OBJECT_GET_DATA(ok_bt, "info_stat");
+
+ if (GTK_TOGGLE_BUTTON(forw)->active || GTK_TOGGLE_BUTTON(both)->active) {
+ fp = fopen(g_dest, "w");
+
+ if (GTK_TOGGLE_BUTTON(both)->active) {
+ fprintf(fp, "Forward\n");
+ }
+
+ for(j = 0; j < GTK_CLIST(clist)->columns; j++) {
+ if (j == 0) {
+ fprintf(fp,"%s",GTK_CLIST(clist)->column[j].title);
+ } else {
+ fprintf(fp,",%s",GTK_CLIST(clist)->column[j].title);
+ }
+ }
+ fprintf(fp,"\n");
+ for (i = 0; i < GTK_CLIST(clist)->rows; i++) {
+ for(j = 0; j < GTK_CLIST(clist)->columns; j++) {
+ gtk_clist_get_text(GTK_CLIST(clist),i,j,&columnText);
+ if (j == 0) {
+ fprintf(fp,"%s",columnText);
+ } else {
+ fprintf(fp,",%s",columnText);
+ }
+ }
+ fprintf(fp,"\n");
+ }
+
+ fclose(fp);
+ }
+
+ if (GTK_TOGGLE_BUTTON(rev)->active || GTK_TOGGLE_BUTTON(both)->active) {
+
+ if (GTK_TOGGLE_BUTTON(both)->active) {
+ fp = fopen(g_dest, "a");
+ fprintf(fp, "\nReverse\n");
+ } else {
+ fp = fopen(g_dest, "w");
+ }
+ for(j = 0; j < GTK_CLIST(clist_r)->columns; j++) {
+ if (j == 0) {
+ fprintf(fp,"%s",GTK_CLIST(clist_r)->column[j].title);
+ } else {
+ fprintf(fp,",%s",GTK_CLIST(clist_r)->column[j].title);
+ }
+ }
+ fprintf(fp,"\n");
+ for (i = 0; i < GTK_CLIST(clist_r)->rows; i++) {
+ for(j = 0; j < GTK_CLIST(clist_r)->columns; j++) {
+ gtk_clist_get_text(GTK_CLIST(clist_r),i,j,&columnText);
+ if (j == 0) {
+ fprintf(fp,"%s",columnText);
+ } else {
+ fprintf(fp,",%s",columnText);
+ }
+ }
+ fprintf(fp,"\n");
+ }
+ fclose(fp);
+ }
+ /* XXX I get GTK warning (sometimes?)!!! */
+ gtk_widget_destroy(GTK_WIDGET(save_csv_as_w));
+}
+
+static void save_csv_as_destroy_cb(GtkWidget *win _U_, gpointer user_data _U_)
+{
+ save_csv_as_w = NULL;
+}
+
+/* when the user wants to save the csv information in a file */
+static void save_csv_as_cb(GtkWidget *w _U_, gpointer data)
+{
+ info_stat *rs=(info_stat *)data;
+
+ GtkWidget *vertb;
+ GtkWidget *table1;
+ GtkWidget *label_format;
+ GtkWidget *channels_label;
+ GSList *channels_group = NULL;
+ GtkWidget *forward_rb;
+ GtkWidget *reversed_rb;
+ GtkWidget *both_rb;
+ GtkWidget *ok_bt;
+
+ if (save_csv_as_w != NULL) {
+ /* There's already a Save CSV info dialog box; reactivate it. */
+ reactivate_window(save_csv_as_w);
+ return;
+ }
+
+ save_csv_as_w = gtk_file_selection_new("Ethereal: Save Data As CSV");
+ gtk_signal_connect(GTK_OBJECT(save_csv_as_w), "destroy",
+ GTK_SIGNAL_FUNC(save_csv_as_destroy_cb), NULL);
+
+ /* Container for each row of widgets */
+ vertb = gtk_vbox_new(FALSE, 0);
+ gtk_container_border_width(GTK_CONTAINER(vertb), 5);
+ gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(save_csv_as_w)->action_area),
+ vertb, FALSE, FALSE, 0);
+ gtk_widget_show (vertb);
+
+ table1 = gtk_table_new (2, 4, FALSE);
+ gtk_widget_show (table1);
+ gtk_box_pack_start (GTK_BOX (vertb), table1, FALSE, FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (table1), 10);
+ gtk_table_set_row_spacings (GTK_TABLE (table1), 20);
+
+ label_format = gtk_label_new ("Format: Comma Separated Values");
+ gtk_widget_show (label_format);
+ gtk_table_attach (GTK_TABLE (table1), label_format, 0, 3, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+
+ channels_label = gtk_label_new ("Channels:");
+ gtk_widget_show (channels_label);
+ gtk_table_attach (GTK_TABLE (table1), channels_label, 0, 1, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (channels_label), 0, 0.5);
+
+ forward_rb = gtk_radio_button_new_with_label (channels_group, "forward ");
+ channels_group = gtk_radio_button_group (GTK_RADIO_BUTTON (forward_rb));
+ gtk_widget_show (forward_rb);
+ gtk_table_attach (GTK_TABLE (table1), forward_rb, 1, 2, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ reversed_rb = gtk_radio_button_new_with_label (channels_group, "reversed");
+ channels_group = gtk_radio_button_group (GTK_RADIO_BUTTON (reversed_rb));
+ gtk_widget_show (reversed_rb);
+ gtk_table_attach (GTK_TABLE (table1), reversed_rb, 2, 3, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ both_rb = gtk_radio_button_new_with_label (channels_group, "both");
+ channels_group = gtk_radio_button_group (GTK_RADIO_BUTTON (both_rb));
+ gtk_widget_show (both_rb);
+ gtk_table_attach (GTK_TABLE (table1), both_rb, 3, 4, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(both_rb), TRUE);
+
+ ok_bt = GTK_FILE_SELECTION(save_csv_as_w)->ok_button;
+ OBJECT_SET_DATA(ok_bt, "forward_rb", forward_rb);
+ OBJECT_SET_DATA(ok_bt, "reversed_rb", reversed_rb);
+ OBJECT_SET_DATA(ok_bt, "both_rb", both_rb);
+ OBJECT_SET_DATA(ok_bt, "info_stat", rs);
+
+ /* Connect the cancel_button to destroy the widget */
+ SIGNAL_CONNECT_OBJECT(GTK_FILE_SELECTION(save_csv_as_w)->cancel_button,
+ "clicked", (GtkSignalFunc)gtk_widget_destroy,
+ save_csv_as_w);
+
+ /* Catch the "key_press_event" signal in the window, so that we can catch
+ the ESC key being pressed and act as if the "Cancel" button had
+ been selected. */
+ dlg_set_cancel(save_csv_as_w, GTK_FILE_SELECTION(save_csv_as_w)->cancel_button);
+
+ gtk_signal_connect(GTK_OBJECT(ok_bt), "clicked",
+ GTK_SIGNAL_FUNC(save_csv_as_ok_cb), save_csv_as_w);
+
+ gtk_widget_show(save_csv_as_w);
+}
+
static void save_voice_as_destroy_cb(GtkWidget *win _U_, gpointer user_data _U_)
{
/* Note that we no longer have a Save voice info dialog box. */
@@ -952,9 +1168,9 @@ static void add_rtp_notebook(void *pri)
GtkWidget *notebook, *page, *page_r, *label, *label1, *label2, *label3;
GtkWidget *scrolled_window, *scrolled_window_r/*, *frame, *text, *label4, *page_help*/;
- GtkWidget *box4, *voice_bt, *refresh_bt, *close_bn;
+ GtkWidget *box4, *voice_bt, *refresh_bt, *close_bn, *csv_bt;
- gchar *titles[6] = {"Packet nr.", "Sequence", "Delay (s)", "Jitter (s)", "Marker", "Status"};
+ gchar *titles[8] = {"Packet nr.", "Sequence", "Delay (s)", "Jitter (s)", "Marker", "Status", "Date", "Length"};
gchar label_forward[150];
gchar label_reverse[150];
@@ -995,7 +1211,7 @@ static void add_rtp_notebook(void *pri)
gtk_box_pack_end(GTK_BOX(page), max, FALSE, FALSE, 5);
/* clist for the information */
- clist = gtk_clist_new_with_titles(6, titles);
+ clist = gtk_clist_new_with_titles(8, titles);
gtk_widget_show(clist);
gtk_container_add(GTK_CONTAINER(scrolled_window), clist);
gtk_box_pack_start(GTK_BOX(page), scrolled_window, TRUE, TRUE, 0);
@@ -1004,6 +1220,10 @@ static void add_rtp_notebook(void *pri)
label = gtk_label_new(" Forward Direction ");
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page, label);
+ /* Hide date and length column */
+ gtk_clist_set_column_visibility(GTK_CLIST(clist), 6, FALSE);
+ gtk_clist_set_column_visibility(GTK_CLIST(clist), 7, FALSE);
+
/* column width and justification */
gtk_clist_set_column_width(GTK_CLIST(clist), 0, 80);
gtk_clist_set_column_width(GTK_CLIST(clist), 1, 80);
@@ -1028,13 +1248,18 @@ static void add_rtp_notebook(void *pri)
gtk_box_pack_start(GTK_BOX(page_r), label3, FALSE, FALSE, 0);
max_r = gtk_label_new("\n\n");
gtk_box_pack_end(GTK_BOX(page_r), max_r, FALSE, FALSE, 5);
- clist_r = gtk_clist_new_with_titles(6, titles);
+ clist_r = gtk_clist_new_with_titles(8, titles);
gtk_widget_show(clist_r);
gtk_container_add(GTK_CONTAINER(scrolled_window_r), clist_r);
gtk_box_pack_start(GTK_BOX(page_r), scrolled_window_r, TRUE, TRUE, 0);
label2 = gtk_label_new(" Reversed Direction ");
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page_r, label2);
+ /* Hide date and length column */
+ gtk_clist_set_column_visibility(GTK_CLIST(clist_r), 6, FALSE);
+ gtk_clist_set_column_visibility(GTK_CLIST(clist_r), 7, FALSE);
+
+ /* column width and justification */
gtk_clist_set_column_width(GTK_CLIST(clist_r), 0, 80);
gtk_clist_set_column_width(GTK_CLIST(clist_r), 1, 80);
gtk_clist_set_column_width(GTK_CLIST(clist_r), 2, 80);
@@ -1080,6 +1305,12 @@ static void add_rtp_notebook(void *pri)
gtk_signal_connect(GTK_OBJECT(refresh_bt), "clicked",
GTK_SIGNAL_FUNC(refresh_cb), rs);
+ csv_bt = gtk_button_new_with_label("Save As CSV...");
+ gtk_container_add(GTK_CONTAINER(box4), csv_bt);
+ gtk_widget_show(csv_bt);
+ gtk_signal_connect(GTK_OBJECT(csv_bt), "clicked",
+ GTK_SIGNAL_FUNC(save_csv_as_cb), rs);
+
close_bn = gtk_button_new_with_label("Close");
gtk_container_add(GTK_CONTAINER(box4), close_bn);
gtk_widget_show(close_bn);