3 * Copyright 2003, 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 the GSM A-Interface:
40 #include "epan/packet_info.h"
41 #include "epan/epan.h"
42 #include "epan/value_string.h"
43 #include <epan/stat_cmd_args.h>
45 #include <epan/dissectors/packet-bssap.h>
46 #include <epan/dissectors/packet-gsm_a_common.h>
48 #include "../stat_menu.h"
49 #include "ui/simple_dialog.h"
51 #include "ui/gtk/gui_stat_menu.h"
52 #include "ui/gtk/dlg_utils.h"
53 #include "ui/gtk/filter_dlg.h"
54 #include "ui/gtk/gui_utils.h"
56 #include "ui/gtk/old-gtk-compat.h"
63 N_COLUMN
/* The number of columns */
66 typedef struct _gsm_a_stat_dlg_t
{
68 GtkWidget
*scrolled_win
;
72 typedef struct _gsm_a_stat_t
{
73 int bssmap_message_type
[0xff];
74 int dtap_mm_message_type
[0xff];
75 int dtap_rr_message_type
[0xff];
76 int dtap_cc_message_type
[0xff];
77 int dtap_gmm_message_type
[0xff];
78 int dtap_sms_message_type
[0xff];
79 int dtap_sm_message_type
[0xff];
80 int dtap_ss_message_type
[0xff];
81 int dtap_tp_message_type
[0xff];
82 int sacch_rr_message_type
[0xff];
86 static gsm_a_stat_dlg_t dlg_bssmap
;
87 static gsm_a_stat_dlg_t dlg_dtap_mm
;
88 static gsm_a_stat_dlg_t dlg_dtap_rr
;
89 static gsm_a_stat_dlg_t dlg_dtap_cc
;
90 static gsm_a_stat_dlg_t dlg_dtap_gmm
;
91 static gsm_a_stat_dlg_t dlg_dtap_sms
;
92 static gsm_a_stat_dlg_t dlg_dtap_sm
;
93 static gsm_a_stat_dlg_t dlg_dtap_ss
;
94 static gsm_a_stat_dlg_t dlg_dtap_tp
;
95 static gsm_a_stat_dlg_t dlg_sacch_rr
;
96 static gsm_a_stat_t gsm_a_stat
;
100 GtkWidget
* create_list(void)
103 GtkListStore
*list_store
;
105 GtkTreeViewColumn
*column
;
106 GtkCellRenderer
*renderer
;
107 GtkTreeSortable
*sortable
;
108 GtkTreeView
*list_view
;
109 GtkTreeSelection
*selection
;
111 /* Create the store */
112 list_store
= gtk_list_store_new(N_COLUMN
, /* Total number of columns XXX*/
113 G_TYPE_UINT
, /* IEI */
114 G_TYPE_STRING
, /* Message Name */
115 G_TYPE_UINT
); /* Count */
118 list
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store
));
120 list_view
= GTK_TREE_VIEW(list
);
121 sortable
= GTK_TREE_SORTABLE(list_store
);
123 /* Speed up the list display */
124 gtk_tree_view_set_fixed_height_mode(list_view
, TRUE
);
126 /* Setup the sortable columns */
127 gtk_tree_sortable_set_sort_column_id(sortable
, IEI_COLUMN
, GTK_SORT_ASCENDING
);
128 gtk_tree_view_set_headers_clickable(list_view
, FALSE
);
130 /* The view now holds a reference. We can get rid of our own reference */
131 g_object_unref (G_OBJECT (list_store
));
134 * Create the first column packet, associating the "text" attribute of the
135 * cell_renderer to the first column of the model
137 renderer
= gtk_cell_renderer_text_new ();
138 column
= gtk_tree_view_column_new_with_attributes ("IEI", renderer
,
142 /* gtk_tree_view_column_set_cell_data_func(column, renderer, present_as_hex_func,
143 GINT_TO_POINTER(IEI_COLUMN), NULL);
146 gtk_tree_view_column_set_sort_column_id(column
, IEI_COLUMN
);
147 gtk_tree_view_column_set_resizable(column
, TRUE
);
148 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_FIXED
);
149 gtk_tree_view_column_set_min_width(column
, 50);
151 /* Add the column to the view. */
152 gtk_tree_view_append_column (list_view
, column
);
154 /* Second column.. Message Name. */
155 renderer
= gtk_cell_renderer_text_new ();
156 column
= gtk_tree_view_column_new_with_attributes ("Message Name", renderer
,
157 "text", MSG_NAME_COLUMN
,
159 gtk_tree_view_column_set_sort_column_id(column
, MSG_NAME_COLUMN
);
160 gtk_tree_view_column_set_resizable(column
, TRUE
);
161 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_FIXED
);
162 gtk_tree_view_column_set_min_width(column
, 280);
163 gtk_tree_view_append_column (list_view
, column
);
165 /* Third column.. Count. */
166 renderer
= gtk_cell_renderer_text_new ();
167 column
= gtk_tree_view_column_new_with_attributes ("Count", renderer
,
168 "text", COUNT_COLUMN
,
172 gtk_tree_view_column_set_sort_column_id(column
, COUNT_COLUMN
);
173 gtk_tree_view_column_set_resizable(column
, TRUE
);
174 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_FIXED
);
175 gtk_tree_view_column_set_min_width(column
, 50);
176 gtk_tree_view_append_column (list_view
, column
);
178 /* Now enable the sorting of each column */
179 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(list_view
), TRUE
);
180 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(list_view
), TRUE
);
182 /* Setup the selection handler */
183 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(list
));
184 gtk_tree_selection_set_mode(selection
, GTK_SELECTION_SINGLE
);
193 gsm_a_stat_t
*stat_p
= (gsm_a_stat_t
*)tapdata
;
195 memset(stat_p
, 0, sizeof(gsm_a_stat_t
));
202 packet_info
*pinfo _U_
,
203 epan_dissect_t
*edt _U_
,
206 gsm_a_stat_t
*stat_p
= (gsm_a_stat_t
*)tapdata
;
207 const gsm_a_tap_rec_t
*data_p
= (gsm_a_tap_rec_t
*)data
;
209 switch (data_p
->pdu_type
)
211 case BSSAP_PDU_TYPE_BSSMAP
:
212 stat_p
->bssmap_message_type
[data_p
->message_type
]++;
215 case BSSAP_PDU_TYPE_DTAP
:
216 switch (data_p
->protocol_disc
)
219 stat_p
->dtap_cc_message_type
[data_p
->message_type
]++;
222 stat_p
->dtap_mm_message_type
[data_p
->message_type
]++;
225 stat_p
->dtap_rr_message_type
[data_p
->message_type
]++;
228 stat_p
->dtap_gmm_message_type
[data_p
->message_type
]++;
231 stat_p
->dtap_sms_message_type
[data_p
->message_type
]++;
234 stat_p
->dtap_sm_message_type
[data_p
->message_type
]++;
237 stat_p
->dtap_ss_message_type
[data_p
->message_type
]++;
240 stat_p
->dtap_tp_message_type
[data_p
->message_type
]++;
250 case GSM_A_PDU_TYPE_SACCH
:
251 switch (data_p
->protocol_disc
)
254 stat_p
->sacch_rr_message_type
[data_p
->message_type
]++;
257 /* unknown Short PD */
264 * unknown PDU type !!!
275 gsm_a_stat_dlg_t
*dlg_p
,
277 const value_string
*msg_strings
)
279 GtkListStore
*list_store
;
284 if (dlg_p
->win
!= NULL
){
286 list_store
= GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (dlg_p
->table
))); /* Get store */
288 while (msg_strings
[i
].strptr
){
289 /* Creates a new row at position. iter will be changed to point to this new row.
290 * If position is larger than the number of rows on the list, then the new row will be appended to the list.
291 * The row will be filled with the values given to this function.
293 * should generally be preferred when inserting rows in a sorted list store.
295 gtk_list_store_insert_with_values( list_store
, &iter
, G_MAXINT
,
296 IEI_COLUMN
, msg_strings
[i
].value
,
297 MSG_NAME_COLUMN
, (char *)msg_strings
[i
].strptr
,
298 COUNT_COLUMN
, message_count
[msg_strings
[i
].value
],
309 gsm_a_stat_t
*stat_p
= (gsm_a_stat_t
*)tapdata
;
311 if (!tapdata
) return;
313 if (dlg_bssmap
.win
!= NULL
)
315 gsm_a_stat_draw_aux(&dlg_bssmap
,
316 stat_p
->bssmap_message_type
,
317 gsm_a_bssmap_msg_strings
);
320 if (dlg_dtap_mm
.win
!= NULL
)
322 gsm_a_stat_draw_aux(&dlg_dtap_mm
,
323 stat_p
->dtap_mm_message_type
,
324 gsm_a_dtap_msg_mm_strings
);
327 if (dlg_dtap_rr
.win
!= NULL
)
329 gsm_a_stat_draw_aux(&dlg_dtap_rr
,
330 stat_p
->dtap_rr_message_type
,
331 gsm_a_dtap_msg_rr_strings
);
334 if (dlg_dtap_cc
.win
!= NULL
)
336 gsm_a_stat_draw_aux(&dlg_dtap_cc
,
337 stat_p
->dtap_cc_message_type
,
338 gsm_a_dtap_msg_cc_strings
);
341 if (dlg_dtap_gmm
.win
!= NULL
)
343 gsm_a_stat_draw_aux(&dlg_dtap_gmm
,
344 stat_p
->dtap_gmm_message_type
,
345 gsm_a_dtap_msg_gmm_strings
);
348 if (dlg_dtap_sms
.win
!= NULL
)
350 gsm_a_stat_draw_aux(&dlg_dtap_sms
,
351 stat_p
->dtap_sms_message_type
,
352 gsm_a_dtap_msg_sms_strings
);
355 if (dlg_dtap_sm
.win
!= NULL
)
357 gsm_a_stat_draw_aux(&dlg_dtap_sm
,
358 stat_p
->dtap_sm_message_type
,
359 gsm_a_dtap_msg_sm_strings
);
362 if (dlg_dtap_ss
.win
!= NULL
)
364 gsm_a_stat_draw_aux(&dlg_dtap_ss
,
365 stat_p
->dtap_ss_message_type
,
366 gsm_a_dtap_msg_ss_strings
);
369 if (dlg_dtap_tp
.win
!= NULL
)
371 gsm_a_stat_draw_aux(&dlg_dtap_tp
,
372 stat_p
->dtap_tp_message_type
,
373 gsm_a_dtap_msg_tp_strings
);
376 if (dlg_sacch_rr
.win
!= NULL
)
378 gsm_a_stat_draw_aux(&dlg_sacch_rr
,
379 stat_p
->sacch_rr_message_type
,
380 gsm_a_rr_short_pd_msg_strings
);
387 gsm_a_stat_gtk_win_destroy_cb(
391 memset((void *) user_data
, 0, sizeof(gsm_a_stat_dlg_t
));
396 gsm_a_stat_gtk_win_create(
397 gsm_a_stat_dlg_t
*dlg_p
,
405 dlg_p
->win
= dlg_window_new(title
); /* transient_for top_level */
406 gtk_window_set_destroy_with_parent (GTK_WINDOW(dlg_p
->win
), TRUE
);
407 gtk_window_set_default_size(GTK_WINDOW(dlg_p
->win
), 490, 500);
409 vbox
= ws_gtk_box_new(GTK_ORIENTATION_VERTICAL
, 3, FALSE
);
410 gtk_container_add(GTK_CONTAINER(dlg_p
->win
), vbox
);
411 gtk_container_set_border_width(GTK_CONTAINER(vbox
), 12);
413 dlg_p
->scrolled_win
= scrolled_window_new(NULL
, NULL
);
414 gtk_box_pack_start(GTK_BOX(vbox
), dlg_p
->scrolled_win
, TRUE
, TRUE
, 0);
416 dlg_p
->table
= create_list();
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
= (GtkWidget
*)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_a_stat_gtk_win_destroy_cb
), dlg_p
);
429 gtk_widget_show_all(dlg_p
->win
);
430 window_present(dlg_p
->win
);
433 void gsm_a_stat_gtk_bssmap_cb(GtkAction
*action _U_
, gpointer user_data _U_
)
439 * if the window is already open, bring it to front
443 gdk_window_raise(gtk_widget_get_window(dlg_bssmap
.win
));
447 gsm_a_stat_gtk_win_create(&dlg_bssmap
, "GSM A-I/F BSSMAP Statistics");
448 gsm_a_stat_draw(&gsm_a_stat
);
453 gsm_a_stat_gtk_bssmap_init(
454 const char *opt_arg _U_
,
457 gsm_a_stat_gtk_bssmap_cb(NULL
, NULL
);
461 gsm_a_stat_gtk_dtap_cb(
462 GtkAction
*action _U_
,
463 gpointer user_data _U_
,
464 gsm_a_stat_dlg_t
*dlg_dtap_p
,
466 const value_string
*dtap_msg_strings _U_
)
470 * if the window is already open, bring it to front
474 gdk_window_raise(gtk_widget_get_window(dlg_dtap_p
->win
));
478 gsm_a_stat_gtk_win_create(dlg_dtap_p
, title
);
480 gsm_a_stat_draw(&gsm_a_stat
);
484 gsm_a_stat_gtk_dtap_mm_cb(GtkAction
*action
, gpointer user_data
)
486 gsm_a_stat_gtk_dtap_cb(action
, user_data
, &dlg_dtap_mm
,
487 "GSM A-I/F DTAP Mobility Management Statistics",
488 gsm_a_dtap_msg_mm_strings
);
492 gsm_a_stat_gtk_dtap_mm_init(const char *opt_arg _U_
,
495 gsm_a_stat_gtk_dtap_mm_cb(NULL
, NULL
);
499 gsm_a_stat_gtk_dtap_rr_cb(GtkAction
*action
, gpointer user_data
)
501 gsm_a_stat_gtk_dtap_cb(action
, user_data
, &dlg_dtap_rr
,
502 "GSM A-I/F DTAP Radio Resource Management Statistics",
503 gsm_a_dtap_msg_rr_strings
);
507 gsm_a_stat_gtk_dtap_rr_init(const char *opt_arg _U_
,
510 gsm_a_stat_gtk_dtap_rr_cb(NULL
, NULL
);
514 gsm_a_stat_gtk_dtap_cc_cb(GtkAction
*action
, gpointer user_data
)
516 gsm_a_stat_gtk_dtap_cb(action
, user_data
, &dlg_dtap_cc
,
517 "GSM A-I/F DTAP Call Control Statistics",
518 gsm_a_dtap_msg_cc_strings
);
522 gsm_a_stat_gtk_dtap_cc_init(const char *opt_arg _U_
,
525 gsm_a_stat_gtk_dtap_cc_cb(NULL
, NULL
);
529 gsm_a_stat_gtk_dtap_gmm_cb(GtkAction
*action
, gpointer user_data
)
531 gsm_a_stat_gtk_dtap_cb(action
, user_data
, &dlg_dtap_gmm
,
532 "GSM A-I/F DTAP GPRS Mobility Management Statistics",
533 gsm_a_dtap_msg_gmm_strings
);
537 gsm_a_stat_gtk_dtap_gmm_init(const char *opt_arg _U_
,
540 gsm_a_stat_gtk_dtap_gmm_cb(NULL
, NULL
);
544 gsm_a_stat_gtk_dtap_sms_cb(GtkAction
*action
, gpointer user_data
)
546 gsm_a_stat_gtk_dtap_cb(action
, user_data
, &dlg_dtap_sms
,
547 "GSM A-I/F DTAP Short Message Service Statistics",
548 gsm_a_dtap_msg_sms_strings
);
552 gsm_a_stat_gtk_dtap_sms_init(const char *opt_arg _U_
,
555 gsm_a_stat_gtk_dtap_sms_cb(NULL
, NULL
);
559 gsm_a_stat_gtk_dtap_sm_cb(GtkAction
*action
, gpointer user_data
)
561 gsm_a_stat_gtk_dtap_cb(action
, user_data
, &dlg_dtap_sm
,
562 "GSM A-I/F DTAP GPRS Session Management Statistics",
563 gsm_a_dtap_msg_sm_strings
);
567 gsm_a_stat_gtk_dtap_sm_init(const char *opt_arg _U_
,
570 gsm_a_stat_gtk_dtap_sm_cb(NULL
, NULL
);
574 gsm_a_stat_gtk_dtap_ss_cb(GtkAction
*action
, gpointer user_data
)
576 gsm_a_stat_gtk_dtap_cb(action
, user_data
, &dlg_dtap_ss
,
577 "GSM A-I/F DTAP Supplementary Services Statistics",
578 gsm_a_dtap_msg_ss_strings
);
582 gsm_a_stat_gtk_dtap_ss_init(
583 const char *opt_arg _U_
,
586 gsm_a_stat_gtk_dtap_ss_cb(NULL
, NULL
);
590 gsm_a_stat_gtk_dtap_tp_cb(GtkAction
*action
, gpointer user_data
)
592 gsm_a_stat_gtk_dtap_cb(action
, user_data
, &dlg_dtap_tp
,
593 "GSM A-I/F DTAP Special Conformance Testing Functions Statistics",
594 gsm_a_dtap_msg_tp_strings
);
598 gsm_a_stat_gtk_dtap_tp_init(
599 const char *opt_arg _U_
,
602 gsm_a_stat_gtk_dtap_tp_cb(NULL
, NULL
);
606 gsm_a_stat_gtk_sacch_rr_cb(GtkAction
*action _U_
, gpointer user_data _U_
)
610 * if the window is already open, bring it to front
612 if (dlg_sacch_rr
.win
)
614 gdk_window_raise(gtk_widget_get_window(dlg_sacch_rr
.win
));
618 gsm_a_stat_gtk_win_create(&dlg_sacch_rr
, "GSM A-I/F SACCH Statistics");
619 gsm_a_stat_draw(&gsm_a_stat
);
623 gsm_a_stat_gtk_sacch_rr_init(
624 const char *opt_arg _U_
,
627 gsm_a_stat_gtk_sacch_rr_cb(NULL
, NULL
);
631 register_tap_listener_gtkgsm_a_stat(void)
636 memset((void *) &gsm_a_stat
, 0, sizeof(gsm_a_stat_t
));
639 register_tap_listener("gsm_a", &gsm_a_stat
, NULL
, 0,
646 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
, "%s", err_p
->str
);
647 g_string_free(err_p
, TRUE
);
652 register_stat_cmd_arg("gsm_a,bssmap", gsm_a_stat_gtk_bssmap_init
,NULL
);
654 register_stat_cmd_arg("gsm_a,dtap_mm", gsm_a_stat_gtk_dtap_mm_init
,NULL
);
656 register_stat_cmd_arg("gsm_a,dtap_rr", gsm_a_stat_gtk_dtap_rr_init
,NULL
);
658 register_stat_cmd_arg("gsm_a,dtap_cc", gsm_a_stat_gtk_dtap_cc_init
,NULL
);
660 register_stat_cmd_arg("gsm_a,dtap_gmm", gsm_a_stat_gtk_dtap_gmm_init
,NULL
);
662 register_stat_cmd_arg("gsm_a,dtap_sms", gsm_a_stat_gtk_dtap_sms_init
,NULL
);
664 register_stat_cmd_arg("gsm_a,dtap_sm", gsm_a_stat_gtk_dtap_sm_init
,NULL
);
666 register_stat_cmd_arg("gsm_a,dtap_ss", gsm_a_stat_gtk_dtap_ss_init
,NULL
);
668 register_stat_cmd_arg("gsm_a,dtap_tp", gsm_a_stat_gtk_dtap_tp_init
,NULL
);
670 register_stat_cmd_arg("gsm_a,sacch", gsm_a_stat_gtk_sacch_rr_init
,NULL
);