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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 "ui/simple_dialog.h"
52 #include "ui/gtk/gui_stat_menu.h"
53 #include "ui/gtk/dlg_utils.h"
54 #include "ui/gtk/gui_utils.h"
55 #include "ui/gtk/filter_dlg.h"
56 #include "ui/gtk/gsm_map_stat.h"
58 #include "ui/gtk/old-gtk-compat.h"
72 N_COLUMN
/* The number of columns */
77 GtkWidget
* create_list(void)
80 GtkListStore
*list_store
;
82 GtkTreeViewColumn
*column
;
83 GtkCellRenderer
*renderer
;
84 GtkTreeSortable
*sortable
;
85 GtkTreeView
*list_view
;
86 GtkTreeSelection
*selection
;
88 /* Create the store */
89 list_store
= gtk_list_store_new(N_COLUMN
, /* Total number of columns XXX*/
91 G_TYPE_STRING
, /* Operation Code */
92 G_TYPE_INT
, /* Invokes */
93 G_TYPE_INT
, /* Num Bytes */
94 G_TYPE_FLOAT
, /* Avg Bytes */
95 G_TYPE_INT
, /* RetResult */
96 G_TYPE_INT
, /* Num Bytes */
97 G_TYPE_FLOAT
, /* Avg Bytes */
98 G_TYPE_INT
, /* Total Bytes */
99 G_TYPE_FLOAT
); /* Avg Bytes */
102 list
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store
));
104 list_view
= GTK_TREE_VIEW(list
);
105 sortable
= GTK_TREE_SORTABLE(list_store
);
107 /* Speed up the list display */
108 gtk_tree_view_set_fixed_height_mode(list_view
, TRUE
);
110 /* Setup the sortable columns */
111 gtk_tree_sortable_set_sort_column_id(sortable
, ID_COLUMN
, GTK_SORT_ASCENDING
);
112 gtk_tree_view_set_headers_clickable(list_view
, FALSE
);
114 /* The view now holds a reference. We can get rid of our own reference */
115 g_object_unref (G_OBJECT (list_store
));
118 * Create the first column packet, associating the "text" attribute of the
119 * cell_renderer to the first column of the model
122 renderer
= gtk_cell_renderer_text_new ();
123 column
= gtk_tree_view_column_new_with_attributes ("ID", renderer
,
127 gtk_tree_view_column_set_sort_column_id(column
, ID_COLUMN
);
128 gtk_tree_view_column_set_resizable(column
, TRUE
);
129 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_FIXED
);
130 gtk_tree_view_column_set_min_width(column
, 40);
132 /* Add the column to the view. */
133 gtk_tree_view_append_column (list_view
, column
);
135 /* 2:nd column..Operation Code. */
136 renderer
= gtk_cell_renderer_text_new ();
137 column
= gtk_tree_view_column_new_with_attributes ("Operation Code", renderer
,
138 "text", OP_CODE_COLUMN
,
140 gtk_tree_view_column_set_sort_column_id(column
, OP_CODE_COLUMN
);
141 gtk_tree_view_column_set_resizable(column
, TRUE
);
142 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_FIXED
);
143 gtk_tree_view_column_set_min_width(column
, 210);
144 gtk_tree_view_append_column (list_view
, column
);
146 /* 3:d column..Invokes. */
147 renderer
= gtk_cell_renderer_text_new ();
148 column
= gtk_tree_view_column_new_with_attributes ("Invokes", renderer
,
149 "text", INVOKES_COLUMN
,
151 gtk_tree_view_column_set_sort_column_id(column
, INVOKES_COLUMN
);
152 gtk_tree_view_column_set_resizable(column
, TRUE
);
153 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_FIXED
);
154 gtk_tree_view_column_set_min_width(column
, 60);
155 gtk_tree_view_append_column (list_view
, column
);
157 /* 4:th column.. Num Bytes. */
158 renderer
= gtk_cell_renderer_text_new ();
159 column
= gtk_tree_view_column_new_with_attributes ("Num Bytes", renderer
,
160 "text", NUM_BYTES_FWD_COLUMN
,
164 gtk_tree_view_column_set_sort_column_id(column
, NUM_BYTES_FWD_COLUMN
);
165 gtk_tree_view_column_set_resizable(column
, TRUE
);
166 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_FIXED
);
167 gtk_tree_view_column_set_min_width(column
, 100);
168 gtk_tree_view_append_column (list_view
, column
);
170 /* 5:th column.. Avg Bytes. */
171 renderer
= gtk_cell_renderer_text_new ();
172 column
= gtk_tree_view_column_new_with_attributes ("Avg Bytes", renderer
,
173 "text", AVG_BYTES_FWD_COLUMN
,
175 gtk_tree_view_column_set_cell_data_func(column
, renderer
, float_data_func
,
176 GINT_TO_POINTER(AVG_BYTES_FWD_COLUMN
), NULL
);
178 gtk_tree_view_column_set_sort_column_id(column
, AVG_BYTES_FWD_COLUMN
);
179 gtk_tree_view_column_set_resizable(column
, TRUE
);
180 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_FIXED
);
181 gtk_tree_view_column_set_min_width(column
, 80);
182 gtk_tree_view_append_column (list_view
, column
);
184 /* 6:d column..Invokes. */
185 renderer
= gtk_cell_renderer_text_new ();
186 column
= gtk_tree_view_column_new_with_attributes ("ReturnResult", renderer
,
187 "text", RET_RES_COLUMN
,
189 gtk_tree_view_column_set_sort_column_id(column
, RET_RES_COLUMN
);
190 gtk_tree_view_column_set_resizable(column
, TRUE
);
191 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_FIXED
);
192 gtk_tree_view_column_set_min_width(column
, 60);
193 gtk_tree_view_append_column (list_view
, column
);
195 /* 7:th column.. Num Bytes. */
196 renderer
= gtk_cell_renderer_text_new ();
197 column
= gtk_tree_view_column_new_with_attributes ("Num Bytes", renderer
,
198 "text", NUM_BYTES_REV_COLUMN
,
202 gtk_tree_view_column_set_sort_column_id(column
, NUM_BYTES_FWD_COLUMN
);
203 gtk_tree_view_column_set_resizable(column
, TRUE
);
204 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_FIXED
);
205 gtk_tree_view_column_set_min_width(column
, 100);
206 gtk_tree_view_append_column (list_view
, column
);
208 /* 8:th column.. Avg Bytes. */
209 renderer
= gtk_cell_renderer_text_new ();
210 column
= gtk_tree_view_column_new_with_attributes ("Avg Bytes", renderer
,
211 "text", AVG_BYTES_REV_COLUMN
,
213 gtk_tree_view_column_set_cell_data_func(column
, renderer
, float_data_func
,
214 GINT_TO_POINTER(AVG_BYTES_REV_COLUMN
), NULL
);
217 gtk_tree_view_column_set_sort_column_id(column
, AVG_BYTES_REV_COLUMN
);
218 gtk_tree_view_column_set_resizable(column
, TRUE
);
219 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_FIXED
);
220 gtk_tree_view_column_set_min_width(column
, 80);
221 gtk_tree_view_append_column (list_view
, column
);
223 /* 9:th column.. Total Bytes. */
224 renderer
= gtk_cell_renderer_text_new ();
225 column
= gtk_tree_view_column_new_with_attributes ("Total Bytes", renderer
,
226 "text", TOT_BYTES_COLUMN
,
230 gtk_tree_view_column_set_sort_column_id(column
, NUM_BYTES_FWD_COLUMN
);
231 gtk_tree_view_column_set_resizable(column
, TRUE
);
232 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_FIXED
);
233 gtk_tree_view_column_set_min_width(column
, 100);
234 gtk_tree_view_append_column (list_view
, column
);
236 /* 10:th column.. Avg Bytes. */
237 renderer
= gtk_cell_renderer_text_new ();
238 column
= gtk_tree_view_column_new_with_attributes ("Avg Bytes", renderer
,
239 "text", AVG_BYTES_COLUMN
,
241 gtk_tree_view_column_set_cell_data_func(column
, renderer
, float_data_func
,
242 GINT_TO_POINTER(AVG_BYTES_COLUMN
), NULL
);
244 gtk_tree_view_column_set_sort_column_id(column
, AVG_BYTES_COLUMN
);
245 gtk_tree_view_column_set_resizable(column
, TRUE
);
246 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_FIXED
);
247 gtk_tree_view_column_set_min_width(column
, 60);
248 gtk_tree_view_append_column (list_view
, column
);
250 /* Now enable the sorting of each column */
251 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(list_view
), TRUE
);
252 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(list_view
), TRUE
);
254 /* Setup the selection handler */
255 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(list
));
256 gtk_tree_selection_set_mode(selection
, GTK_SELECTION_SINGLE
);
262 typedef struct _gsm_map_stat_dlg_t
{
264 GtkWidget
*scrolled_win
;
266 } gsm_map_stat_dlg_t
;
268 static gsm_map_stat_dlg_t dlg
;
271 * used by gsm_map_summary.c
273 gsm_map_stat_t gsm_map_stat
;
280 gsm_map_stat_t
*stat_p
= (gsm_map_stat_t
*)tapdata
;
282 memset(stat_p
, 0, sizeof(gsm_map_stat_t
));
289 packet_info
*pinfo _U_
,
290 epan_dissect_t
*edt _U_
,
293 gsm_map_stat_t
*stat_p
= (gsm_map_stat_t
*)tapdata
;
294 const gsm_map_tap_rec_t
*data_p
= (gsm_map_tap_rec_t
*)data
;
296 #if 0 /* always false because message_type is 8 bit value */
297 if (data_p
->opr_code_idx
> sizeof(stat_p
->opr_code
))
300 * unknown message type !!!
308 stat_p
->opr_code
[data_p
->opr_code_idx
]++;
309 stat_p
->size
[data_p
->opr_code_idx
] += data_p
->size
;
313 stat_p
->opr_code_rr
[data_p
->opr_code_idx
]++;
314 stat_p
->size_rr
[data_p
->opr_code_idx
] += data_p
->size
;
325 gsm_map_stat_t
*stat_p
= (gsm_map_stat_t
*)tapdata
;
327 GtkListStore
*list_store
;
330 if (dlg
.win
&& tapdata
)
332 list_store
= GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (dlg
.table
))); /* Get store */
335 while (gsm_map_opr_code_strings
[i
].strptr
){
336 float avrage_bytes_fwd
;
337 float avrage_bytes_rev
;
338 float avrage_bytes_tot
;
340 if (stat_p
->opr_code
[i
] >0){
341 avrage_bytes_fwd
=(float)stat_p
->size
[i
]/(float)stat_p
->opr_code
[i
];
343 avrage_bytes_fwd
= 0;
345 if (stat_p
->opr_code_rr
[i
] >0){
346 avrage_bytes_rev
= (float)stat_p
->size_rr
[i
]/(float)stat_p
->opr_code_rr
[i
];
348 avrage_bytes_rev
= 0;
350 if ((stat_p
->opr_code
[i
] + stat_p
->opr_code_rr
[i
])>0){
351 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
]);
353 avrage_bytes_tot
= 0;
355 /* Creates a new row at position. iter will be changed to point to this new row.
356 * If position is larger than the number of rows on the list, then the new row will be appended to the list.
357 * The row will be filled with the values given to this function.
359 * should generally be preferred when inserting rows in a sorted list store.
361 gtk_list_store_insert_with_values( list_store
, &iter
, G_MAXINT
,
362 ID_COLUMN
, gsm_map_opr_code_strings
[i
].value
,
363 OP_CODE_COLUMN
, (char*)gsm_map_opr_code_strings
[i
].strptr
,
364 INVOKES_COLUMN
, stat_p
->opr_code
[i
],
365 NUM_BYTES_FWD_COLUMN
, (gint
)stat_p
->size
[i
],
366 AVG_BYTES_FWD_COLUMN
, avrage_bytes_fwd
,
367 RET_RES_COLUMN
, stat_p
->opr_code_rr
[i
],
368 NUM_BYTES_REV_COLUMN
, stat_p
->size_rr
[i
],
369 AVG_BYTES_REV_COLUMN
, avrage_bytes_rev
,
370 TOT_BYTES_COLUMN
, stat_p
->size
[i
] + stat_p
->size_rr
[i
],
371 AVG_BYTES_COLUMN
, avrage_bytes_tot
,
379 gsm_map_stat_gtk_win_destroy_cb(
383 memset((void *) user_data
, 0, sizeof(gsm_map_stat_dlg_t
));
388 gsm_map_stat_gtk_win_create(
389 gsm_map_stat_dlg_t
*dlg_p
,
397 dlg_p
->win
= dlg_window_new(title
); /* transient_for top_level */
398 gtk_window_set_destroy_with_parent (GTK_WINDOW(dlg_p
->win
), TRUE
);
399 gtk_window_set_default_size(GTK_WINDOW(dlg_p
->win
), 560, 390);
401 vbox
= ws_gtk_box_new(GTK_ORIENTATION_VERTICAL
, 3, FALSE
);
402 gtk_container_add(GTK_CONTAINER(dlg_p
->win
), vbox
);
403 gtk_container_set_border_width(GTK_CONTAINER(vbox
), 12);
405 dlg_p
->scrolled_win
= scrolled_window_new(NULL
, NULL
);
406 gtk_box_pack_start(GTK_BOX(vbox
), dlg_p
->scrolled_win
, TRUE
, TRUE
, 0);
408 dlg_p
->table
= create_list();
409 gtk_widget_show(dlg_p
->table
);
411 gtk_container_add(GTK_CONTAINER(dlg_p
->scrolled_win
), dlg_p
->table
);
414 bbox
= dlg_button_row_new(GTK_STOCK_CLOSE
, NULL
);
415 gtk_box_pack_start(GTK_BOX(vbox
), bbox
, FALSE
, FALSE
, 0);
417 bt_close
= (GtkWidget
*)g_object_get_data(G_OBJECT(bbox
), GTK_STOCK_CLOSE
);
418 window_set_cancel_button(dlg_p
->win
, bt_close
, window_cancel_button_cb
);
420 g_signal_connect(dlg_p
->win
, "delete_event", G_CALLBACK(window_delete_event_cb
), NULL
);
421 g_signal_connect(dlg_p
->win
, "destroy", G_CALLBACK(gsm_map_stat_gtk_win_destroy_cb
), dlg_p
);
423 gtk_widget_show_all(dlg_p
->win
);
424 window_present(dlg_p
->win
);
428 gsm_map_stat_gtk_cb(GtkAction
*action _U_
, gpointer user_data _U_
)
433 * if the window is already open, bring it to front
436 gdk_window_raise(gtk_widget_get_window(dlg
.win
));
440 gsm_map_stat_gtk_win_create(&dlg
, "GSM MAP Operation Statistics");
442 gsm_map_stat_draw(&gsm_map_stat
);
447 gsm_map_stat_gtk_init(const char *opt_arg _U_
,
450 gsm_map_stat_gtk_cb(NULL
, NULL
);
455 register_tap_listener_gtkgsm_map_stat(void)
460 memset((void *) &gsm_map_stat
, 0, sizeof(gsm_map_stat_t
));
463 register_tap_listener("gsm_map", &gsm_map_stat
, NULL
, 0,
470 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
, "%s", err_p
->str
);
471 g_string_free(err_p
, TRUE
);
476 register_stat_cmd_arg("gsm_map", gsm_map_stat_gtk_init
,NULL
);