2 * mgcp-statistics for ethereal
3 * Copyright 2003 Lars Roland
5 * $Id: mgcp_stat.c,v 1.18 2003/12/04 00:45:39 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
9 * Copyright 1998 Gerald Combs
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.
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.
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.
32 #ifdef HAVE_SYS_TYPES_H
33 # include <sys/types.h>
38 #include "../epan/packet_info.h"
39 #include "../epan/epan.h"
42 #include "../epan/value_string.h"
43 #include "../register.h"
44 #include "../plugins/mgcp/packet-mgcp.h"
45 #include "../timestats.h"
46 #include "gtk_stat_util.h"
47 #include "compat_macros.h"
48 #include "../simple_dialog.h"
49 #include "dlg_utils.h"
51 #include "../globals.h"
53 extern GtkWidget *main_display_filter_widget;
55 #define NUM_TIMESTATS 10
57 /* used to keep track of the statistics for an entire program interface */
58 typedef struct _mgcpstat_t {
62 GtkWidget *scrolled_window;
64 timestat_t rtd[NUM_TIMESTATS];
71 static const value_string mgcp_mesage_type[] = {
84 static GtkWidget *dlg=NULL;
85 static GtkWidget *filter_entry;
89 mgcpstat_reset(void *pms)
91 mgcpstat_t *ms=(mgcpstat_t *)pms;
95 for(i=0;i<NUM_TIMESTATS;i++) {
99 ms->rtd[i].min.secs=0;
100 ms->rtd[i].min.nsecs=0;
101 ms->rtd[i].max.secs=0;
102 ms->rtd[i].max.nsecs=0;
103 ms->rtd[i].tot.secs=0;
104 ms->rtd[i].tot.nsecs=0;
113 dlg=gtk_window_new(GTK_WINDOW_TOPLEVEL);
114 title = g_strdup_printf("MGCP SRT statistics: %s", cf_get_display_name(&cfile));
115 gtk_window_set_title(GTK_WINDOW(dlg), title);
121 mgcpstat_packet(void *pms, packet_info *pinfo, epan_dissect_t *edt _U_, void *pmi)
123 mgcpstat_t *ms=(mgcpstat_t *)pms;
127 switch (mi->mgcp_type) {
130 if(mi->is_duplicate){
131 /* Duplicate is ignored */
142 if(mi->is_duplicate){
143 /* Duplicate is ignored */
147 else if (!mi->request_available) {
148 /* no request was seen */
154 /* calculate time delta between request and response */
155 delta.secs=pinfo->fd->abs_secs-mi->req_time.secs;
156 delta.nsecs=pinfo->fd->abs_usecs*1000-mi->req_time.nsecs;
158 delta.nsecs+=1000000000;
162 if (strncasecmp(mi->code, "EPCF", 4) == 0 ) {
163 time_stat_update(&(ms->rtd[0]),&delta, pinfo);
165 else if (strncasecmp(mi->code, "CRCX", 4) == 0 ) {
166 time_stat_update(&(ms->rtd[1]),&delta, pinfo);
168 else if (strncasecmp(mi->code, "MDCX", 4) == 0 ) {
169 time_stat_update(&(ms->rtd[2]),&delta, pinfo);
171 else if (strncasecmp(mi->code, "DLCX", 4) == 0 ) {
172 time_stat_update(&(ms->rtd[3]),&delta, pinfo);
174 else if (strncasecmp(mi->code, "RQNT", 4) == 0 ) {
175 time_stat_update(&(ms->rtd[4]),&delta, pinfo);
177 else if (strncasecmp(mi->code, "NTFY", 4) == 0 ) {
178 time_stat_update(&(ms->rtd[5]),&delta, pinfo);
180 else if (strncasecmp(mi->code, "AUEP", 4) == 0 ) {
181 time_stat_update(&(ms->rtd[6]),&delta, pinfo);
183 else if (strncasecmp(mi->code, "AUCX", 4) == 0 ) {
184 time_stat_update(&(ms->rtd[7]),&delta, pinfo);
186 else if (strncasecmp(mi->code, "RSIP", 4) == 0 ) {
187 time_stat_update(&(ms->rtd[8]),&delta, pinfo);
190 time_stat_update(&(ms->rtd[9]),&delta, pinfo);
204 mgcpstat_draw(void *pms)
206 mgcpstat_t *ms=(mgcpstat_t *)pms;
208 /* gtk1 using a scrollable clist*/
212 str[i]=g_malloc(sizeof(char[256]));
215 /* clear list before printing */
216 gtk_clist_clear(ms->table);
218 for(i=0;i<NUM_TIMESTATS;i++) {
219 /* nothing seen, nothing to do */
220 if(ms->rtd[i].num==0){
224 sprintf(str[0], "%s", val_to_str(i,mgcp_mesage_type,"Other"));
225 sprintf(str[1], "%d", ms->rtd[i].num);
226 sprintf(str[2], "%8.2f msec", nstime_to_msec(&(ms->rtd[i].min)));
227 sprintf(str[3], "%8.2f msec", nstime_to_msec(&(ms->rtd[i].max)));
228 sprintf(str[4], "%8.2f msec", get_average(&(ms->rtd[i].tot), ms->rtd[i].num));
229 sprintf(str[5], "%6u", ms->rtd[i].min_num);
230 sprintf(str[6], "%6u", ms->rtd[i].max_num);
231 gtk_clist_append(ms->table, str);
234 gtk_widget_show(GTK_WIDGET(ms->table));
240 void protect_thread_critical_region(void);
241 void unprotect_thread_critical_region(void);
243 win_destroy_cb(GtkWindow *win _U_, gpointer data)
245 mgcpstat_t *ms=(mgcpstat_t *)data;
247 protect_thread_critical_region();
248 remove_tap_listener(ms);
249 unprotect_thread_critical_region();
258 static gchar *titles[]={"Type",
267 gtk_mgcpstat_init(char *optarg)
271 GString *error_string;
273 if(strncmp(optarg,"mgcp,srt,",9) == 0){
280 ms=g_malloc(sizeof(mgcpstat_t));
281 ms->filter=g_malloc(strlen(filter)+1);
282 strcpy(ms->filter, filter);
286 ms->win=gtk_window_new(GTK_WINDOW_TOPLEVEL);
287 SIGNAL_CONNECT(ms->win, "destroy", win_destroy_cb, ms);
289 ms->vbox=gtk_vbox_new(FALSE, 0);
291 init_main_stat_window(ms->win, ms->vbox, "MGCP Service Response Time (SRT) Statistics", filter);
293 /* GTK1 using a scrollable clist*/
294 /* init a scrolled window*/
295 ms->scrolled_window = gtk_scrolled_window_new(NULL, NULL);
296 WIDGET_SET_SIZE(ms->scrolled_window, 550, 150);
298 ms->table = create_stat_table(ms->scrolled_window, ms->vbox, 7, titles);
300 error_string=register_tap_listener("mgcp", ms, filter, mgcpstat_reset, mgcpstat_packet, mgcpstat_draw);
302 simple_dialog(ESD_TYPE_WARN, NULL, error_string->str);
303 g_string_free(error_string, TRUE);
309 gtk_widget_show_all(ms->win);
310 redissect_packets(&cfile);
321 dlg_cancel_cb(GtkWidget *cancel_bt _U_, gpointer parent_w)
323 gtk_widget_destroy(GTK_WIDGET(parent_w));
327 mgcpstat_start_button_clicked(GtkWidget *item _U_, gpointer data _U_)
332 filter=(char *)gtk_entry_get_text(GTK_ENTRY(filter_entry));
334 gtk_mgcpstat_init("mgcp,srt");
336 sprintf(str,"mgcp,srt,%s", filter);
337 gtk_mgcpstat_init(str);
344 gtk_mgcpstat_cb(GtkWidget *w _U_, gpointer d _U_)
349 GtkWidget *filter_box, *filter_label;
350 GtkWidget *bbox, *start_button, *cancel_button;
352 /* if the window is already open, bring it to front */
354 gdk_window_raise(dlg->window);
358 title = g_strdup_printf("Ethereal: Compute MGCP SRT statistics: %s", cf_get_display_name(&cfile));
360 dlg=dlg_window_new(title);
362 SIGNAL_CONNECT(dlg, "destroy", dlg_destroy_cb, NULL);
364 dlg_box=gtk_vbox_new(FALSE, 10);
365 gtk_container_border_width(GTK_CONTAINER(dlg_box), 10);
366 gtk_container_add(GTK_CONTAINER(dlg), dlg_box);
367 gtk_widget_show(dlg_box);
370 filter_box=gtk_hbox_new(FALSE, 3);
373 filter_label=gtk_label_new("Filter:");
374 gtk_box_pack_start(GTK_BOX(filter_box), filter_label, FALSE, FALSE, 0);
375 gtk_widget_show(filter_label);
378 filter_entry=gtk_entry_new();
379 gtk_widget_set_usize(filter_entry, 300, -2);
380 gtk_box_pack_start(GTK_BOX(filter_box), filter_entry, TRUE, TRUE, 0);
381 filter=gtk_entry_get_text(GTK_ENTRY(main_display_filter_widget));
383 gtk_entry_set_text(GTK_ENTRY(filter_entry), filter);
385 gtk_widget_show(filter_entry);
387 gtk_box_pack_start(GTK_BOX(dlg_box), filter_box, TRUE, TRUE, 0);
388 gtk_widget_show(filter_box);
391 bbox = gtk_hbutton_box_new();
392 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_DEFAULT_STYLE);
393 gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
394 gtk_box_pack_start(GTK_BOX(dlg_box), bbox, FALSE, FALSE, 0);
395 gtk_widget_show(bbox);
397 /* the start button */
398 start_button=gtk_button_new_with_label("Create Stat");
399 SIGNAL_CONNECT_OBJECT(start_button, "clicked",
400 mgcpstat_start_button_clicked, NULL);
401 gtk_box_pack_start(GTK_BOX(bbox), start_button, TRUE, TRUE, 0);
402 GTK_WIDGET_SET_FLAGS(start_button, GTK_CAN_DEFAULT);
403 gtk_widget_grab_default(start_button);
404 gtk_widget_show(start_button);
406 #if GTK_MAJOR_VERSION < 2
407 cancel_button=gtk_button_new_with_label("Cancel");
409 cancel_button=gtk_button_new_from_stock(GTK_STOCK_CANCEL);
411 SIGNAL_CONNECT(cancel_button, "clicked", dlg_cancel_cb, dlg);
412 GTK_WIDGET_SET_FLAGS(cancel_button, GTK_CAN_DEFAULT);
413 gtk_box_pack_start(GTK_BOX(bbox), cancel_button, TRUE, TRUE, 0);
414 gtk_widget_show(cancel_button);
416 /* Catch the "activate" signal on the filter text entry, so that
417 if the user types Return there, we act as if the "Create Stat"
418 button had been selected, as happens if Return is typed if
419 some widget that *doesn't* handle the Return key has the input
421 dlg_set_activate(filter_entry, start_button);
423 /* Catch the "key_press_event" signal in the window, so that we can
424 catch the ESC key being pressed and act as if the "Cancel" button
425 had been selected. */
426 dlg_set_cancel(dlg, cancel_button);
428 /* Give the initial focus to the "Filter" entry box. */
429 gtk_widget_grab_focus(filter_entry);
431 gtk_widget_show_all(dlg);
435 register_tap_listener_gtkmgcpstat(void)
437 register_ethereal_tap("mgcp,srt", gtk_mgcpstat_init);
441 register_tap_menu_gtkmgcpstat(void)
443 if (find_tap_id("mgcp"))
444 register_tap_menu_item("Statistics/Service Response Time/MGCP...",
445 gtk_mgcpstat_cb, NULL, NULL);