3 * Copyright 2004, Michael Lum <mlum [AT] telostech.com>
4 * In association with Telos Technology Inc.
6 * MUCH code modified from service_response_time_table.c.
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 * This TAP provides statistics for GSM MAP Operations:
40 #include <epan/epan.h>
41 #include <epan/packet.h>
42 #include <epan/packet_info.h>
43 #include <epan/value_string.h>
44 #include <epan/stat_cmd_args.h>
46 #include <epan/asn1.h>
47 #include <epan/dissectors/packet-gsm_map.h>
49 #include "../stat_menu.h"
50 #include "../simple_dialog.h"
52 #include "gtk/gui_stat_menu.h"
53 #include "gtk/dlg_utils.h"
54 #include "gtk/gui_utils.h"
55 #include "gtk/filter_dlg.h"
56 #include "gtk/gsm_map_stat.h"
71 N_COLUMN /* The number of columns */
76 GtkWidget* create_list(void)
79 GtkListStore *list_store;
81 GtkTreeViewColumn *column;
82 GtkCellRenderer *renderer;
83 GtkTreeSortable *sortable;
84 GtkTreeView *list_view;
85 GtkTreeSelection *selection;
87 /* Create the store */
88 list_store = gtk_list_store_new(N_COLUMN, /* Total number of columns XXX*/
90 G_TYPE_STRING, /* Operation Code */
91 G_TYPE_INT, /* Invokes */
92 G_TYPE_INT, /* Num Bytes */
93 G_TYPE_FLOAT, /* Avg Bytes */
94 G_TYPE_INT, /* RetResult */
95 G_TYPE_INT, /* Num Bytes */
96 G_TYPE_FLOAT, /* Avg Bytes */
97 G_TYPE_INT, /* Total Bytes */
98 G_TYPE_FLOAT); /* Avg Bytes */
101 list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
103 list_view = GTK_TREE_VIEW(list);
104 sortable = GTK_TREE_SORTABLE(list_store);
106 #if GTK_CHECK_VERSION(2,6,0)
107 /* Speed up the list display */
108 gtk_tree_view_set_fixed_height_mode(list_view, TRUE);
111 /* Setup the sortable columns */
112 gtk_tree_sortable_set_sort_column_id(sortable, ID_COLUMN, GTK_SORT_ASCENDING);
113 gtk_tree_view_set_headers_clickable(list_view, FALSE);
115 /* The view now holds a reference. We can get rid of our own reference */
116 g_object_unref (G_OBJECT (list_store));
119 * Create the first column packet, associating the "text" attribute of the
120 * cell_renderer to the first column of the model
123 renderer = gtk_cell_renderer_text_new ();
124 column = gtk_tree_view_column_new_with_attributes ("ID", renderer,
128 gtk_tree_view_column_set_sort_column_id(column, ID_COLUMN);
129 gtk_tree_view_column_set_resizable(column, TRUE);
130 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
131 gtk_tree_view_column_set_min_width(column, 40);
133 /* Add the column to the view. */
134 gtk_tree_view_append_column (list_view, column);
136 /* 2:nd column..Operation Code. */
137 renderer = gtk_cell_renderer_text_new ();
138 column = gtk_tree_view_column_new_with_attributes ("Operation Code", renderer,
139 "text", OP_CODE_COLUMN,
141 gtk_tree_view_column_set_sort_column_id(column, OP_CODE_COLUMN);
142 gtk_tree_view_column_set_resizable(column, TRUE);
143 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
144 gtk_tree_view_column_set_min_width(column, 210);
145 gtk_tree_view_append_column (list_view, column);
147 /* 3:d column..Invokes. */
148 renderer = gtk_cell_renderer_text_new ();
149 column = gtk_tree_view_column_new_with_attributes ("Invokes", renderer,
150 "text", INVOKES_COLUMN,
152 gtk_tree_view_column_set_sort_column_id(column, INVOKES_COLUMN);
153 gtk_tree_view_column_set_resizable(column, TRUE);
154 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
155 gtk_tree_view_column_set_min_width(column, 60);
156 gtk_tree_view_append_column (list_view, column);
158 /* 4:th column.. Num Bytes. */
159 renderer = gtk_cell_renderer_text_new ();
160 column = gtk_tree_view_column_new_with_attributes ("Num Bytes", renderer,
161 "text", NUM_BYTES_FWD_COLUMN,
165 gtk_tree_view_column_set_sort_column_id(column, NUM_BYTES_FWD_COLUMN);
166 gtk_tree_view_column_set_resizable(column, TRUE);
167 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
168 gtk_tree_view_column_set_min_width(column, 100);
169 gtk_tree_view_append_column (list_view, column);
171 /* 5:th column.. Avg Bytes. */
172 renderer = gtk_cell_renderer_text_new ();
173 column = gtk_tree_view_column_new_with_attributes ("Avg Bytes", renderer,
174 "text", AVG_BYTES_FWD_COLUMN,
176 gtk_tree_view_column_set_cell_data_func(column, renderer, float_data_func,
177 GINT_TO_POINTER(AVG_BYTES_FWD_COLUMN), NULL);
179 gtk_tree_view_column_set_sort_column_id(column, AVG_BYTES_FWD_COLUMN);
180 gtk_tree_view_column_set_resizable(column, TRUE);
181 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
182 gtk_tree_view_column_set_min_width(column, 80);
183 gtk_tree_view_append_column (list_view, column);
185 /* 6:d column..Invokes. */
186 renderer = gtk_cell_renderer_text_new ();
187 column = gtk_tree_view_column_new_with_attributes ("ReturnResult", renderer,
188 "text", RET_RES_COLUMN,
190 gtk_tree_view_column_set_sort_column_id(column, RET_RES_COLUMN);
191 gtk_tree_view_column_set_resizable(column, TRUE);
192 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
193 gtk_tree_view_column_set_min_width(column, 60);
194 gtk_tree_view_append_column (list_view, column);
196 /* 7:th column.. Num Bytes. */
197 renderer = gtk_cell_renderer_text_new ();
198 column = gtk_tree_view_column_new_with_attributes ("Num Bytes", renderer,
199 "text", NUM_BYTES_REV_COLUMN,
203 gtk_tree_view_column_set_sort_column_id(column, NUM_BYTES_FWD_COLUMN);
204 gtk_tree_view_column_set_resizable(column, TRUE);
205 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
206 gtk_tree_view_column_set_min_width(column, 100);
207 gtk_tree_view_append_column (list_view, column);
209 /* 8:th column.. Avg Bytes. */
210 renderer = gtk_cell_renderer_text_new ();
211 column = gtk_tree_view_column_new_with_attributes ("Avg Bytes", renderer,
212 "text", AVG_BYTES_REV_COLUMN,
214 gtk_tree_view_column_set_cell_data_func(column, renderer, float_data_func,
215 GINT_TO_POINTER(AVG_BYTES_REV_COLUMN), NULL);
218 gtk_tree_view_column_set_sort_column_id(column, AVG_BYTES_REV_COLUMN);
219 gtk_tree_view_column_set_resizable(column, TRUE);
220 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
221 gtk_tree_view_column_set_min_width(column, 80);
222 gtk_tree_view_append_column (list_view, column);
224 /* 9:th column.. Total Bytes. */
225 renderer = gtk_cell_renderer_text_new ();
226 column = gtk_tree_view_column_new_with_attributes ("Total Bytes", renderer,
227 "text", TOT_BYTES_COLUMN,
231 gtk_tree_view_column_set_sort_column_id(column, NUM_BYTES_FWD_COLUMN);
232 gtk_tree_view_column_set_resizable(column, TRUE);
233 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
234 gtk_tree_view_column_set_min_width(column, 100);
235 gtk_tree_view_append_column (list_view, column);
237 /* 10:th column.. Avg Bytes. */
238 renderer = gtk_cell_renderer_text_new ();
239 column = gtk_tree_view_column_new_with_attributes ("Avg Bytes", renderer,
240 "text", AVG_BYTES_COLUMN,
242 gtk_tree_view_column_set_cell_data_func(column, renderer, float_data_func,
243 GINT_TO_POINTER(AVG_BYTES_COLUMN), NULL);
245 gtk_tree_view_column_set_sort_column_id(column, AVG_BYTES_COLUMN);
246 gtk_tree_view_column_set_resizable(column, TRUE);
247 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
248 gtk_tree_view_column_set_min_width(column, 60);
249 gtk_tree_view_append_column (list_view, column);
251 /* Now enable the sorting of each column */
252 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(list_view), TRUE);
253 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(list_view), TRUE);
255 /* Setup the selection handler */
256 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list));
257 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
263 typedef struct _gsm_map_stat_dlg_t {
265 GtkWidget *scrolled_win;
267 } gsm_map_stat_dlg_t;
269 static gsm_map_stat_dlg_t dlg;
272 * used by gsm_map_summary.c
274 gsm_map_stat_t gsm_map_stat;
281 gsm_map_stat_t *stat_p = tapdata;
283 memset(stat_p, 0, sizeof(gsm_map_stat_t));
290 packet_info *pinfo _U_,
291 epan_dissect_t *edt _U_,
294 gsm_map_stat_t *stat_p = tapdata;
295 const gsm_map_tap_rec_t *data_p = data;
297 #if 0 /* always false because message_type is 8 bit value */
298 if (data_p->opr_code_idx > sizeof(stat_p->opr_code))
301 * unknown message type !!!
309 stat_p->opr_code[data_p->opr_code_idx]++;
310 stat_p->size[data_p->opr_code_idx] += data_p->size;
314 stat_p->opr_code_rr[data_p->opr_code_idx]++;
315 stat_p->size_rr[data_p->opr_code_idx] += data_p->size;
326 gsm_map_stat_t *stat_p = tapdata;
328 GtkListStore *list_store;
331 if (dlg.win && tapdata)
333 list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (dlg.table))); /* Get store */
336 while (gsm_map_opr_code_strings[i].strptr){
337 float avrage_bytes_fwd;
338 float avrage_bytes_rev;
339 float avrage_bytes_tot;
341 if (stat_p->opr_code[i] >0){
342 avrage_bytes_fwd =(float)stat_p->size[i]/(float)stat_p->opr_code[i];
344 avrage_bytes_fwd = 0;
346 if (stat_p->opr_code_rr[i] >0){
347 avrage_bytes_rev = (float)stat_p->size_rr[i]/(float)stat_p->opr_code_rr[i];
349 avrage_bytes_rev = 0;
351 if ((stat_p->opr_code[i] + stat_p->opr_code_rr[i])>0){
352 avrage_bytes_tot = (float)(stat_p->size[i] +stat_p->size_rr[i])/(float)(stat_p->opr_code[i] + stat_p->opr_code_rr[i]);
354 avrage_bytes_tot = 0;
356 /* Creates a new row at position. iter will be changed to point to this new row.
357 * If position is larger than the number of rows on the list, then the new row will be appended to the list.
358 * The row will be filled with the values given to this function.
360 * should generally be preferred when inserting rows in a sorted list store.
362 #if GTK_CHECK_VERSION(2,6,0)
363 gtk_list_store_insert_with_values( list_store , &iter, G_MAXINT,
365 gtk_list_store_append (list_store, &iter);
366 gtk_list_store_set (list_store, &iter,
368 ID_COLUMN, gsm_map_opr_code_strings[i].value,
369 OP_CODE_COLUMN, (char*)gsm_map_opr_code_strings[i].strptr,
370 INVOKES_COLUMN, stat_p->opr_code[i],
371 NUM_BYTES_FWD_COLUMN, (gint)stat_p->size[i],
372 AVG_BYTES_FWD_COLUMN, avrage_bytes_fwd,
373 RET_RES_COLUMN, stat_p->opr_code_rr[i],
374 NUM_BYTES_REV_COLUMN, stat_p->size_rr[i],
375 AVG_BYTES_REV_COLUMN, avrage_bytes_rev,
376 TOT_BYTES_COLUMN, stat_p->size[i] + stat_p->size_rr[i],
377 AVG_BYTES_COLUMN, avrage_bytes_tot,
385 gsm_map_stat_gtk_win_destroy_cb(
389 memset((void *) user_data, 0, sizeof(gsm_map_stat_dlg_t));
394 gsm_map_stat_gtk_win_create(
395 gsm_map_stat_dlg_t *dlg_p,
403 dlg_p->win = dlg_window_new(title); /* transient_for top_level */
404 gtk_window_set_destroy_with_parent (GTK_WINDOW(dlg_p->win), TRUE);
405 gtk_window_set_default_size(GTK_WINDOW(dlg_p->win), 560, 390);
407 vbox = gtk_vbox_new(FALSE, 3);
408 gtk_container_add(GTK_CONTAINER(dlg_p->win), vbox);
409 gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
411 dlg_p->scrolled_win = scrolled_window_new(NULL, NULL);
412 gtk_box_pack_start(GTK_BOX(vbox), dlg_p->scrolled_win, TRUE, TRUE, 0);
414 dlg_p->table = create_list();
415 gtk_widget_show(dlg_p->table);
417 gtk_container_add(GTK_CONTAINER(dlg_p->scrolled_win), dlg_p->table);
420 bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
421 gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
423 bt_close = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
424 window_set_cancel_button(dlg_p->win, bt_close, window_cancel_button_cb);
426 g_signal_connect(dlg_p->win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
427 g_signal_connect(dlg_p->win, "destroy", G_CALLBACK(gsm_map_stat_gtk_win_destroy_cb), dlg_p);
429 gtk_widget_show_all(dlg_p->win);
430 window_present(dlg_p->win);
442 * if the window is already open, bring it to front
445 gdk_window_raise(dlg.win->window);
449 gsm_map_stat_gtk_win_create(&dlg, "GSM MAP Operation Statistics");
451 gsm_map_stat_draw(&gsm_map_stat);
456 gsm_map_stat_gtk_init(const char *optarg _U_,
459 gsm_map_stat_gtk_cb(NULL, NULL);
464 register_tap_listener_gtkgsm_map_stat(void)
469 memset((void *) &gsm_map_stat, 0, sizeof(gsm_map_stat_t));
472 register_tap_listener("gsm_map", &gsm_map_stat, NULL, 0,
479 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_p->str);
480 g_string_free(err_p, TRUE);
485 register_stat_menu_item("_GSM/MAP Operation", REGISTER_STAT_GROUP_TELEPHONY,
486 gsm_map_stat_gtk_cb, NULL, NULL, NULL);
487 register_stat_cmd_arg("gsm_map", gsm_map_stat_gtk_init,NULL);