ed3ff11d57c0fe01e2dd949fb5f01f6d5a71e108
[metze/wireshark/wip.git] / ui / gtk / mtp3_summary.c
1 /* mtp3_summary.c
2  * Routines for MTP3 Statictics summary window
3  *
4  * Copyright 2004, Michael Lum <mlum [AT] telostech.com>
5  * In association with Telos Technology Inc.
6  *
7  * Modified from gsm_map_summary.c
8  *
9  * $Id$
10  *
11  * Wireshark - Network traffic analyzer
12  * By Gerald Combs <gerald@wireshark.org>
13  * Copyright 1998 Gerald Combs
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28  */
29
30 #include "config.h"
31
32 #include <string.h>
33
34 #include <gtk/gtk.h>
35
36 #include "epan/packet_info.h"
37 #include "epan/epan.h"
38 #include "epan/value_string.h"
39 #include <epan/tap.h>
40 #include <epan/dissectors/packet-mtp3.h>
41
42 #include "../stat_menu.h"
43 #include "../globals.h"
44 #include "../file.h"
45 #include "../summary.h"
46
47 #include "ui/gtk/gui_stat_menu.h"
48 #include "ui/gtk/dlg_utils.h"
49 #include "ui/gtk/gui_utils.h"
50 #include "ui/gtk/mtp3_stat.h"
51
52 #define SUM_STR_MAX 1024
53
54
55 typedef struct _my_columns_t {
56     guint32           value;
57     const gchar      *strptr;
58     GtkJustification  just;
59 } my_columns_t;
60
61 enum
62 {
63    SI_COLUMN,
64    NUM_MSUS_COLUMN,
65    NUM_MSUS_SEC_COLUMN,
66    NUM_BYTES_COLUMN,
67    NUM_BYTES_MSU_COLUMN,
68    NUM_BYTES_SEC_COLUMN,
69    N_COLUMN /* The number of columns */
70 };
71
72 /* Create list */
73 static GtkWidget *
74 create_list(void)
75 {
76
77     GtkListStore      *list_store;
78     GtkWidget         *list;
79     GtkTreeViewColumn *column;
80     GtkCellRenderer   *renderer;
81     GtkTreeSortable   *sortable;
82     GtkTreeView       *list_view;
83     GtkTreeSelection  *selection;
84
85     /* Create the store */
86     list_store = gtk_list_store_new(N_COLUMN,   /* Total number of columns XXX*/
87                                G_TYPE_STRING,   /* SI               */
88                                G_TYPE_INT,      /* Num MSUs         */
89                                G_TYPE_STRING,   /* MSUs/sec         */
90                                G_TYPE_INT,      /* Num Bytes        */
91                                G_TYPE_STRING,   /* Bytes/MSU        */
92                                G_TYPE_STRING);  /* Bytes/sec        */
93
94     /* Create a view */
95     list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
96
97     list_view = GTK_TREE_VIEW(list);
98     sortable = GTK_TREE_SORTABLE(list_store);
99
100     /* Speed up the list display */
101     gtk_tree_view_set_fixed_height_mode(list_view, TRUE);
102
103     /* Setup the sortable columns */
104     gtk_tree_sortable_set_sort_column_id(sortable, SI_COLUMN, GTK_SORT_ASCENDING);
105     gtk_tree_view_set_headers_clickable(list_view, FALSE);
106
107     /* The view now holds a reference.  We can get rid of our own reference */
108     g_object_unref (G_OBJECT (list_store));
109
110     /*
111      * Create the first column packet, associating the "text" attribute of the
112      * cell_renderer to the first column of the model
113      */
114     /* 1:st column */
115     renderer = gtk_cell_renderer_text_new ();
116     column = gtk_tree_view_column_new_with_attributes ("SI", renderer,
117                 "text", SI_COLUMN,
118                 NULL);
119
120     gtk_tree_view_column_set_sort_column_id(column, SI_COLUMN);
121     gtk_tree_view_column_set_resizable(column, TRUE);
122     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
123     gtk_tree_view_column_set_min_width(column, 110);
124
125     /* Add the column to the view. */
126     gtk_tree_view_append_column (list_view, column);
127
128     /* 2:nd column... */
129     renderer = gtk_cell_renderer_text_new ();
130     column = gtk_tree_view_column_new_with_attributes ("Num MSUs", renderer,
131                 "text", NUM_MSUS_COLUMN,
132                 NULL);
133     gtk_tree_view_column_set_sort_column_id(column, NUM_MSUS_COLUMN);
134     gtk_tree_view_column_set_resizable(column, TRUE);
135     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
136     gtk_tree_view_column_set_min_width(column, 100);
137     gtk_tree_view_append_column (list_view, column);
138
139     /* 3:d column... */
140     renderer = gtk_cell_renderer_text_new ();
141     column = gtk_tree_view_column_new_with_attributes ("MSUs/sec", renderer,
142                 "text", NUM_MSUS_SEC_COLUMN,
143                 NULL);
144     gtk_tree_view_column_set_sort_column_id(column, NUM_MSUS_SEC_COLUMN);
145     gtk_tree_view_column_set_resizable(column, TRUE);
146     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
147     gtk_tree_view_column_set_min_width(column, 100);
148     gtk_tree_view_append_column (list_view, column);
149
150     /* 4:d column... */
151     renderer = gtk_cell_renderer_text_new ();
152     column = gtk_tree_view_column_new_with_attributes ("Num Bytes", renderer,
153                 "text", NUM_BYTES_COLUMN,
154                 NULL);
155     gtk_tree_view_column_set_sort_column_id(column, NUM_BYTES_COLUMN);
156     gtk_tree_view_column_set_resizable(column, TRUE);
157     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
158     gtk_tree_view_column_set_min_width(column, 100);
159     gtk_tree_view_append_column (list_view, column);
160
161     /* 5:th column... */
162     renderer = gtk_cell_renderer_text_new ();
163     column = gtk_tree_view_column_new_with_attributes ("Bytes/MSU", renderer,
164                 "text", NUM_BYTES_MSU_COLUMN,
165                 NULL);
166
167
168     gtk_tree_view_column_set_sort_column_id(column, NUM_BYTES_MSU_COLUMN);
169     gtk_tree_view_column_set_resizable(column, TRUE);
170     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
171     gtk_tree_view_column_set_min_width(column, 100);
172     gtk_tree_view_append_column (list_view, column);
173
174     /* 6:th column... */
175     renderer = gtk_cell_renderer_text_new ();
176     column = gtk_tree_view_column_new_with_attributes ("Bytes/sec", renderer,
177                 "text", NUM_BYTES_SEC_COLUMN,
178                 NULL);
179
180     gtk_tree_view_column_set_sort_column_id(column, NUM_BYTES_SEC_COLUMN);
181     gtk_tree_view_column_set_resizable(column, TRUE);
182     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
183     gtk_tree_view_column_set_min_width(column, 100);
184     gtk_tree_view_append_column (list_view, column);
185
186     /* Now enable the sorting of each column */
187     gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(list_view), TRUE);
188     gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(list_view), TRUE);
189
190     /* Setup the selection handler */
191     selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list));
192     gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
193
194     return list;
195
196 }
197
198 static void
199 add_string_to_box(gchar *str, GtkWidget *box)
200 {
201     GtkWidget *lb;
202     lb = gtk_label_new(str);
203     gtk_misc_set_alignment(GTK_MISC(lb), 0.0f, 0.5f);
204     gtk_box_pack_start(GTK_BOX(box), lb,FALSE,FALSE, 0);
205     gtk_widget_show(lb);
206 }
207
208
209
210 static void
211 mtp3_sum_draw(
212     GtkWidget *table,
213     double     seconds,
214     int       *tot_num_msus_p,
215     double    *tot_num_bytes_p)
216 {
217     char         *entries[N_COLUMN];
218     int           i, j;
219     int           num_msus;
220     int           num_bytes;
221     GtkListStore *list_store;
222     GtkTreeIter   iter;
223
224     *tot_num_msus_p = 0;
225     *tot_num_bytes_p = 0;
226
227     list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (table))); /* Get store */
228
229     for (i=0; i < MTP3_NUM_SI_CODE; i++)
230     {
231         j = 0;
232         num_msus = 0;
233         num_bytes = 0;
234
235         while (j < mtp3_num_used)
236         {
237             num_msus += mtp3_stat[j].si_code[i].num_msus;
238             num_bytes += mtp3_stat[j].si_code[i].size;
239
240             j++;
241         }
242
243         *tot_num_msus_p += num_msus;
244         *tot_num_bytes_p += num_bytes;
245
246         entries[2] = (seconds) ? g_strdup_printf("%.2f", (double)num_msus/seconds) : g_strdup("N/A");
247         entries[4] = (num_msus) ? g_strdup_printf("%.2f", (double)num_bytes/num_msus) : g_strdup("N/A");
248         entries[5] = (seconds) ? g_strdup_printf("%.2f", (double)num_bytes/seconds) : g_strdup("N/A");
249
250         gtk_list_store_insert_with_values( list_store , &iter, G_MAXINT,
251                                            SI_COLUMN, mtp3_service_indicator_code_short_vals[i].strptr,
252                                            NUM_MSUS_COLUMN, num_msus,
253                                            NUM_MSUS_SEC_COLUMN, entries[2],
254                                            NUM_BYTES_COLUMN, num_bytes,
255                                            NUM_BYTES_MSU_COLUMN, entries[4],
256                                            NUM_BYTES_SEC_COLUMN, entries[5],
257                                            -1);
258
259         g_free(entries[2]);
260         g_free(entries[4]);
261         g_free(entries[5]);
262     }
263 }
264
265
266 void
267 mtp3_sum_gtk_sum_cb(GtkAction *action _U_, gpointer user_data _U_)
268 {
269     summary_tally  summary;
270     GtkWidget     *sum_open_w;
271     GtkWidget     *main_vb, *file_fr, *data_fr, *file_box;
272     GtkWidget     *data_box, *bbox, *close_bt;
273     GtkWidget     *tot_fr, *tot_box;
274     GtkWidget     *table, *table_fr;
275
276     gchar          string_buff[SUM_STR_MAX];
277     const char    *file_type;
278     double         seconds;
279     int            tot_num_msus;
280     double         tot_num_bytes;
281
282     if (cfile.state == FILE_CLOSED) {
283         return;
284     }
285
286     /* initialize the tally */
287     summary_fill_in(&cfile, &summary);
288
289     /* initial computations */
290     seconds = summary.stop_time - summary.start_time;
291
292     sum_open_w = dlg_window_new("MTP3 Statistics: Summary");  /* transient_for top_level */
293     gtk_window_set_destroy_with_parent (GTK_WINDOW(sum_open_w), TRUE);
294
295     /* Container for each row of widgets */
296     main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
297     gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5);
298     gtk_container_add(GTK_CONTAINER(sum_open_w), main_vb);
299     gtk_widget_show(main_vb);
300
301     /* File frame */
302     file_fr = gtk_frame_new("File");
303     gtk_box_pack_start(GTK_BOX(main_vb), file_fr, TRUE, TRUE, 0);
304     gtk_widget_show(file_fr);
305
306     file_box = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
307     gtk_container_add(GTK_CONTAINER(file_fr), file_box);
308     gtk_widget_show(file_box);
309
310     /* filename */
311     g_snprintf(string_buff, SUM_STR_MAX, "Name: %s", ((summary.filename) ? summary.filename : "None"));
312     add_string_to_box(string_buff, file_box);
313
314     /* length */
315     g_snprintf(string_buff, SUM_STR_MAX, "Length: %" G_GINT64_MODIFIER "d", summary.file_length);
316     add_string_to_box(string_buff, file_box);
317
318     /* format */
319     file_type = wtap_file_type_string(summary.file_type);
320     g_snprintf(string_buff, SUM_STR_MAX, "Format: %s", (file_type ? file_type : "N/A"));
321     add_string_to_box(string_buff, file_box);
322
323     if (summary.has_snap) {
324         /* snapshot length */
325         g_snprintf(string_buff, SUM_STR_MAX, "Snapshot length: %u", summary.snap);
326         add_string_to_box(string_buff, file_box);
327     }
328
329     /* Data frame */
330     data_fr = gtk_frame_new("Data");
331     gtk_box_pack_start(GTK_BOX(main_vb), data_fr, TRUE, TRUE, 0);
332     gtk_widget_show(data_fr);
333
334     data_box = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
335     gtk_container_add(GTK_CONTAINER(data_fr), data_box);
336     gtk_widget_show(data_box);
337
338     /*
339      * We must have no un-time-stamped packets (i.e., the number of
340      * time-stamped packets must be the same as the number of packets),
341      * and at least two time-stamped packets, in order for the elapsed
342      * time to be valid.
343      */
344     if (summary.packet_count_ts == summary.packet_count &&
345         summary.packet_count_ts >= 2) {
346         /* seconds */
347         g_snprintf(string_buff, SUM_STR_MAX, "Elapsed time: %.3f seconds", summary.elapsed_time);
348         add_string_to_box(string_buff, data_box);
349
350         g_snprintf(string_buff, SUM_STR_MAX, "Between first and last packet: %.3f seconds", seconds);
351         add_string_to_box(string_buff, data_box);
352     }
353
354     /* Packet count */
355     g_snprintf(string_buff, SUM_STR_MAX, "Packet count: %i", summary.packet_count);
356     add_string_to_box(string_buff, data_box);
357
358     /* MTP3 SPECIFIC */
359     table_fr = gtk_frame_new("Service Indicator (SI) Totals");
360     gtk_box_pack_start(GTK_BOX(main_vb), table_fr, TRUE, TRUE, 0);
361     gtk_widget_show(table_fr);
362
363     table = create_list();
364
365     gtk_container_add(GTK_CONTAINER(table_fr), table);
366     gtk_widget_show(table);
367
368
369     mtp3_sum_draw(table, seconds, &tot_num_msus, &tot_num_bytes);
370
371     /* Totals frame */
372     tot_fr = gtk_frame_new("Totals");
373     gtk_box_pack_start(GTK_BOX(main_vb), tot_fr, TRUE, TRUE, 0);
374     gtk_widget_show(tot_fr);
375
376     tot_box = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
377     gtk_container_add(GTK_CONTAINER(tot_fr), tot_box);
378     gtk_widget_show(tot_box);
379
380     g_snprintf(string_buff, SUM_STR_MAX, "Total MSUs: %u", tot_num_msus);
381     add_string_to_box(string_buff, tot_box);
382
383     /*
384      * We must have no un-time-stamped packets (i.e., the number of
385      * time-stamped packets must be the same as the number of packets),
386      * and at least two time-stamped packets, in order for the elapsed
387      * time to be valid.
388      */
389     if (summary.packet_count_ts == summary.packet_count &&
390         summary.packet_count_ts >= 2) {
391         if (seconds) {
392             g_snprintf(string_buff, SUM_STR_MAX, "MSUs/second: %.2f", tot_num_msus/seconds);
393         }
394         else {
395             g_snprintf(string_buff, SUM_STR_MAX, "MSUs/second: N/A");
396         }
397         add_string_to_box(string_buff, tot_box);
398     }
399
400     g_snprintf(string_buff, SUM_STR_MAX, "Total Bytes: %.0f", tot_num_bytes);
401     add_string_to_box(string_buff, tot_box);
402
403     if (tot_num_msus) {
404         g_snprintf(string_buff, SUM_STR_MAX, "Average Bytes/MSU: %.2f", tot_num_bytes/tot_num_msus);
405     }
406     else {
407         g_snprintf(string_buff, SUM_STR_MAX, "Average Bytes/MSU: N/A");
408     }
409     add_string_to_box(string_buff, tot_box);
410
411     /*
412      * We must have no un-time-stamped packets (i.e., the number of
413      * time-stamped packets must be the same as the number of packets),
414      * and at least two time-stamped packets, in order for the elapsed
415      * time to be valid.
416      */
417     if (summary.packet_count_ts == summary.packet_count &&
418         summary.packet_count_ts >= 2) {
419         if (seconds) {
420             g_snprintf(string_buff, SUM_STR_MAX, "Bytes/second: %.2f", tot_num_bytes/seconds);
421         }
422         else {
423             g_snprintf(string_buff, SUM_STR_MAX, "Bytes/second: N/A");
424         }
425         add_string_to_box(string_buff, tot_box);
426     }
427
428     /* Button row. */
429     bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
430     gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 0);
431     gtk_widget_show(bbox);
432
433     close_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
434     window_set_cancel_button(sum_open_w, close_bt, window_cancel_button_cb);
435
436     g_signal_connect(sum_open_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
437
438     gtk_widget_show_all(sum_open_w);
439     window_present(sum_open_w);
440 }
441
442
443 void
444 register_tap_listener_gtkmtp3_summary(void)
445 {
446 }