479d2f7fc09fcbd39616da827ae9b21bfa6d1d90
[obnox/wireshark/wip.git] / gtk / h225_ras_srt.c
1 /* h225_ras_srt.c
2  * h225 RAS Service Response Time statistics for ethereal
3  * Copyright 2003 Lars Roland
4  *
5  * $Id: h225_ras_srt.c,v 1.12 2004/02/22 18:44:01 ulfl Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #ifdef HAVE_SYS_TYPES_H
31 # include <sys/types.h>
32 #endif
33
34 #include <string.h>
35
36 #include <gtk/gtk.h>
37
38 #include <epan/packet_info.h>
39 #include <epan/epan.h>
40 #include <epan/value_string.h>
41
42 #include "tap_menu.h"
43 #include "../tap.h"
44 #include "../register.h"
45 #include "../packet-h225.h"
46 #include "../timestats.h"
47 #include "gtk_stat_util.h"
48 #include "compat_macros.h"
49 #include "../simple_dialog.h"
50 #include "dlg_utils.h"
51 #include "../file.h"
52 #include "../globals.h"
53 #include "../tap_dfilter_dlg.h"
54 #include "tap_dfilter_dlg.h"
55 #include "ui_util.h"
56
57
58 extern GtkWidget *main_display_filter_widget;
59
60 void gtk_h225rassrt_init(char *optarg);
61
62 tap_dfilter_dlg h225_rassrt_dlg = {"H.225 RAS Service Response Time", "h225,srt", gtk_h225rassrt_init, -1};
63
64 /* following values represent the size of their valuestring arrays */
65 #define NUM_RAS_STATS 7
66
67 static const value_string ras_message_category[] = {
68   {  0, "Gatekeeper    "},
69   {  1, "Registration  "},
70   {  2, "UnRegistration"},
71   {  3, "Admission     "},
72   {  4, "Bandwidth     "},
73   {  5, "Disengage     "},
74   {  6, "Location      "},
75   {  0, NULL }
76 };
77
78 typedef enum _ras_type {
79         RAS_REQUEST,
80         RAS_CONFIRM,
81         RAS_REJECT,
82         RAS_OTHER
83 }ras_type;
84
85 typedef enum _ras_category {
86         RAS_GATEKEEPER,
87         RAS_REGISTRATION,
88         RAS_UNREGISTRATION,
89         RAS_ADMISSION,
90         RAS_BANDWIDTH,
91         RAS_DISENGAGE,
92         RAS_LOCATION,
93         RAS_OTHERS
94 }ras_category;
95
96 /* Summary of response-time calculations*/
97 typedef struct _h225_rtd_t {
98         guint32 open_req_num;
99         guint32 disc_rsp_num;
100         guint32 req_dup_num;
101         guint32 rsp_dup_num;
102         timestat_t stats;
103 } h225_rtd_t;
104
105 /* used to keep track of the statistics for an entire program interface */
106 typedef struct _h225rassrt_t {
107         GtkWidget *win;
108         GtkWidget *vbox;
109         char *filter;
110         GtkWidget *scrolled_window;
111         GtkCList *table;
112         h225_rtd_t ras_rtd[NUM_RAS_STATS];
113 } h225rassrt_t;
114
115
116 static void
117 h225rassrt_reset(void *phs)
118 {
119         h225rassrt_t *hs=(h225rassrt_t *)phs;
120         int i;
121
122         for(i=0;i<NUM_RAS_STATS;i++) {
123                 hs->ras_rtd[i].stats.num = 0;
124                 hs->ras_rtd[i].stats.min_num = 0;
125                 hs->ras_rtd[i].stats.max_num = 0;
126                 hs->ras_rtd[i].stats.min.secs = 0;
127                 hs->ras_rtd[i].stats.min.nsecs = 0;
128                 hs->ras_rtd[i].stats.max.secs = 0;
129                 hs->ras_rtd[i].stats.max.nsecs = 0;
130                 hs->ras_rtd[i].stats.tot.secs = 0;
131                 hs->ras_rtd[i].stats.tot.nsecs = 0;
132                 hs->ras_rtd[i].open_req_num = 0;
133                 hs->ras_rtd[i].disc_rsp_num = 0;
134                 hs->ras_rtd[i].req_dup_num = 0;
135                 hs->ras_rtd[i].rsp_dup_num = 0;
136         }
137
138 }
139
140
141 static int
142 h225rassrt_packet(void *phs, packet_info *pinfo _U_, epan_dissect_t *edt _U_, void *phi)
143 {
144         h225rassrt_t *hs=(h225rassrt_t *)phs;
145         h225_packet_info *pi=phi;
146
147         ras_type rasmsg_type = RAS_OTHER;
148         ras_category rascategory = RAS_OTHERS;
149
150         if (pi->msg_type != H225_RAS || pi->msg_tag == -1) {
151                 /* No RAS Message or uninitialized msg_tag -> return */
152                 return 0;
153         }
154
155         if (pi->msg_tag < 21) {
156                 /* */
157                 rascategory = pi->msg_tag / 3;
158                 rasmsg_type = pi->msg_tag % 3;
159         }
160         else {
161                 /* No SRT yet (ToDo) */
162                 return 0;
163         }
164
165         switch(rasmsg_type) {
166
167         case RAS_REQUEST:
168                 if(pi->is_duplicate){
169                         hs->ras_rtd[rascategory].req_dup_num++;
170                 }
171                 else {
172                         hs->ras_rtd[rascategory].open_req_num++;
173                 }
174                 break;
175
176         case RAS_CONFIRM:
177                 /* no break - delay stats are identical for Confirm and Reject  */
178         case RAS_REJECT:
179                 if(pi->is_duplicate){
180                         /* Duplicate is ignored */
181                         hs->ras_rtd[rascategory].rsp_dup_num++;
182                 }
183                 else if (!pi->request_available) {
184                         /* no request was seen, ignore response  */
185                         hs->ras_rtd[rascategory].disc_rsp_num++;
186                 }
187                 else {
188                         hs->ras_rtd[rascategory].open_req_num--;
189                         time_stat_update(&(hs->ras_rtd[rascategory].stats),&(pi->delta_time), pinfo);
190                 }
191                 break;
192
193         default:
194                 return 0;
195                 break;
196         }
197         return 1;
198 }
199
200 static void
201 h225rassrt_draw(void *phs)
202 {
203         h225rassrt_t *hs=(h225rassrt_t *)phs;
204         int i;
205         char *str[11];
206
207         for(i=0;i<11;i++) {
208                 str[i]=g_malloc(sizeof(char[256]));
209         }
210         /* Now print Message and Reason Counter Table */
211         /* clear list before printing */
212         gtk_clist_clear(hs->table);
213
214         for(i=0;i<NUM_RAS_STATS;i++) {
215                 /* nothing seen, nothing to do */
216                 if(hs->ras_rtd[i].stats.num==0){
217                         continue;
218                 }
219
220                 sprintf(str[0], "%s", val_to_str(i,ras_message_category,"Other"));
221                 sprintf(str[1], "%7d", hs->ras_rtd[i].stats.num);
222                 sprintf(str[2], "%8.2f msec", nstime_to_msec(&(hs->ras_rtd[i].stats.min)));
223                 sprintf(str[3], "%8.2f msec", nstime_to_msec(&(hs->ras_rtd[i].stats.max)));;
224                 sprintf(str[4], "%8.2f msec", get_average(&(hs->ras_rtd[i].stats.tot), hs->ras_rtd[i].stats.num));
225                 sprintf(str[5], "%6u", hs->ras_rtd[i].stats.min_num);
226                 sprintf(str[6], "%6u", hs->ras_rtd[i].stats.max_num);
227                 sprintf(str[7], "%4u", hs->ras_rtd[i].open_req_num);
228                 sprintf(str[8], "%4u", hs->ras_rtd[i].disc_rsp_num);
229                 sprintf(str[9], "%4u", hs->ras_rtd[i].req_dup_num);
230                 sprintf(str[10], "%4u", hs->ras_rtd[i].rsp_dup_num);
231                 gtk_clist_append(GTK_CLIST(hs->table), str);
232         }
233
234         gtk_widget_show(GTK_WIDGET(hs->table));
235
236 }
237
238 void protect_thread_critical_region(void);
239 void unprotect_thread_critical_region(void);
240 static void
241 win_destroy_cb(GtkWindow *win _U_, gpointer data)
242 {
243         h225rassrt_t *hs=(h225rassrt_t *)data;
244
245         protect_thread_critical_region();
246         remove_tap_listener(hs);
247         unprotect_thread_critical_region();
248
249         if(hs->filter){
250                 g_free(hs->filter);
251                 hs->filter=NULL;
252         }
253         g_free(hs);
254 }
255
256
257 static gchar *titles[]={"RAS-Type",
258                         "Measurements",
259                         "Min RTT",
260                         "Max RTT",
261                         "Avg RTT",
262                         "Min in Frame",
263                         "Max in Frame",
264                         "Open Requests",
265                         "Discarded Responses",
266                         "Repeated Requests",
267                         "Repeated Responses" };
268
269 void
270 gtk_h225rassrt_init(char *optarg)
271 {
272         h225rassrt_t *hs;
273         char *filter=NULL;
274         GString *error_string;
275
276         if(strncmp(optarg,"h225,srt,",9) == 0){
277                 filter=optarg+9;
278         } else {
279                 filter=g_malloc(1);
280                 *filter='\0';
281         }
282
283         hs=g_malloc(sizeof(h225rassrt_t));
284         hs->filter=g_malloc(strlen(filter)+1);
285         strcpy(hs->filter, filter);
286
287         h225rassrt_reset(hs);
288
289         hs->win=window_new(GTK_WINDOW_TOPLEVEL, NULL);
290         SIGNAL_CONNECT(hs->win, "destroy", win_destroy_cb, hs);
291
292         hs->vbox=gtk_vbox_new(FALSE, 0);
293
294         init_main_stat_window(hs->win, hs->vbox, "ITU-T H.225 RAS Service Response Time", filter);
295
296         /* init a scrolled window*/
297         hs->scrolled_window = scrolled_window_new(NULL, NULL);
298         WIDGET_SET_SIZE(hs->scrolled_window, 600, 160);
299
300         hs->table = create_stat_table(hs->scrolled_window, hs->vbox, 11, titles);
301
302         error_string=register_tap_listener("h225", hs, filter, h225rassrt_reset, h225rassrt_packet, h225rassrt_draw);
303         if(error_string){
304                 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, error_string->str);
305                 g_string_free(error_string, TRUE);
306                 g_free(hs->filter);
307                 g_free(hs);
308                 return;
309         }
310
311         gtk_widget_show_all(hs->win);
312         redissect_packets(&cfile);
313 }
314
315 void
316 register_tap_listener_gtk_h225rassrt(void)
317 {
318         register_ethereal_tap("h225,srt", gtk_h225rassrt_init);
319
320         register_tap_menu_item("ITU-T H.225/RAS (Service Response Time ...)", REGISTER_TAP_LAYER_APPLICATION,
321             gtk_tap_dfilter_dlg_cb, NULL, NULL, &(h225_rassrt_dlg));
322 }