aboutsummaryrefslogtreecommitdiffstats
path: root/ui/gtk/service_response_time_table.c
diff options
context:
space:
mode:
Diffstat (limited to 'ui/gtk/service_response_time_table.c')
-rw-r--r--ui/gtk/service_response_time_table.c515
1 files changed, 380 insertions, 135 deletions
diff --git a/ui/gtk/service_response_time_table.c b/ui/gtk/service_response_time_table.c
index 0915707c4d..efc3869246 100644
--- a/ui/gtk/service_response_time_table.c
+++ b/ui/gtk/service_response_time_table.c
@@ -24,15 +24,24 @@
#include "config.h"
+#include <gtk/gtk.h>
#include "epan/packet_info.h"
+#include "epan/proto.h"
#include "ui/simple_dialog.h"
#include "ui/utf8_entities.h"
-#include "ui/gtk/service_response_time_table.h"
#include "ui/gtk/filter_utils.h"
#include "ui/gtk/gui_utils.h"
+#include "ui/gtk/dlg_utils.h"
+#include "ui/gtk/service_response_time_table.h"
+#include "ui/gtk/tap_param_dlg.h"
+#include "ui/gtk/main.h"
+
+/* XXX - Part of temporary hack */
+#include "epan/conversation.h"
+#include "epan/dissectors/packet-scsi.h"
#define NANOSECS_PER_SEC 1000000000
@@ -48,11 +57,20 @@ enum
N_COLUMNS
};
+typedef struct _srt_t {
+ const char *type;
+ const char *filter;
+ gtk_srt_t gtk_data;
+ register_srt_t* srt;
+ srt_data_t data;
+} srt_t;
+
static void
srt_select_filter_cb(GtkWidget *widget _U_, gpointer callback_data, guint callback_action)
{
- srt_stat_table *rst = (srt_stat_table *)callback_data;
+ gtk_srt_table_t *rst_table = (gtk_srt_table_t*)callback_data;
+ srt_stat_table* rst = rst_table->rst;
char *str = NULL;
GtkTreeIter iter;
GtkTreeModel *model;
@@ -63,7 +81,7 @@ srt_select_filter_cb(GtkWidget *widget _U_, gpointer callback_data, guint callba
return;
}
- sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(rst->table));
+ sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(rst_table->table));
if (!gtk_tree_selection_get_selected(sel, &model, &iter))
return;
@@ -82,7 +100,7 @@ srt_select_filter_cb(GtkWidget *widget _U_, gpointer callback_data, guint callba
}
static gboolean
-srt_show_popup_menu_cb(void *widg _U_, GdkEvent *event, srt_stat_table *rst)
+srt_show_popup_menu_cb(void *widg _U_, GdkEvent *event, gtk_srt_table_t *rst)
{
GdkEventButton *bevent = (GdkEventButton *)event;
@@ -291,7 +309,7 @@ static const GtkActionEntry service_resp_t__popup_entries[] = {
};
static void
-srt_create_popup_menu(srt_stat_table *rst)
+srt_create_popup_menu(gtk_srt_table_t* rst_table)
{
GtkUIManager *ui_manager;
GtkActionGroup *action_group;
@@ -301,7 +319,7 @@ srt_create_popup_menu(srt_stat_table *rst)
gtk_action_group_add_actions (action_group, /* the action group */
(GtkActionEntry *)service_resp_t__popup_entries, /* an array of action descriptions */
G_N_ELEMENTS(service_resp_t__popup_entries), /* the number of entries */
- rst); /* data to pass to the action callbacks */
+ rst_table); /* data to pass to the action callbacks */
ui_manager = gtk_ui_manager_new ();
gtk_ui_manager_insert_action_group (ui_manager,
@@ -315,9 +333,9 @@ srt_create_popup_menu(srt_stat_table *rst)
g_error_free (error);
error = NULL;
}
- rst->menu = gtk_ui_manager_get_widget(ui_manager, "/ServiceRespTFilterPopup");
- g_signal_connect(rst->table, "button_press_event", G_CALLBACK(srt_show_popup_menu_cb), rst);
+ rst_table->menu = gtk_ui_manager_get_widget(ui_manager, "/ServiceRespTFilterPopup");
+ g_signal_connect(rst_table->table, "button_press_event", G_CALLBACK(srt_show_popup_menu_cb), rst_table);
}
/* ---------------- */
@@ -388,11 +406,57 @@ srt_time_sort_func(GtkTreeModel *model,
return ret;
}
-/*
-XXX Resizable columns are ugly when there's more than on table cf. SMB
-*/
+static void
+srt_set_title(srt_t *ss)
+{
+ gchar *str;
+
+ str = g_strdup_printf("%s Service Response Time statistics", proto_get_protocol_short_name(find_protocol_by_id(get_srt_proto_id(ss->srt))));
+ set_window_title(ss->gtk_data.win, str);
+ g_free(str);
+}
+
+
+static gtk_srt_table_t*
+get_gtk_table_from_srt(srt_stat_table* rst, gtk_srt_t* gtk)
+{
+ guint i;
+ gtk_srt_table_t* srt;
+
+ for (i = 0; i < gtk->gtk_srt_array->len; i++) {
+ srt = g_array_index(gtk->gtk_srt_array, gtk_srt_table_t*, i);
+
+ if (srt->rst == rst)
+ return srt;
+ }
+
+ return NULL;
+}
+
void
-init_srt_table(srt_stat_table *rst, int num_procs, GtkWidget *vbox, const char *filter_string)
+free_table_data(srt_stat_table* rst, void* gui_data)
+{
+ gtk_srt_t* gtk_data = (gtk_srt_t*)gui_data;
+ gtk_srt_table_t* gtk_table = get_gtk_table_from_srt(rst, gtk_data);
+ g_assert(gtk_table);
+
+ g_free(gtk_table);
+}
+
+static void
+win_destroy_cb(GtkWindow *win _U_, gpointer data)
+{
+ srt_t *ss=(srt_t *)data;
+
+ remove_tap_listener(&ss->data);
+
+ free_srt_table(ss->srt, ss->data.srt_array, free_table_data, &ss->gtk_data);
+
+ g_free(ss);
+}
+
+void
+init_gtk_srt_table(srt_stat_table* rst, void* gui_data)
{
int i;
GtkListStore *store;
@@ -400,10 +464,34 @@ init_srt_table(srt_stat_table *rst, int num_procs, GtkWidget *vbox, const char *
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
GtkTreeSortable *sortable;
+ GtkWidget *label;
+ GtkWidget *tab_page;
+ gtk_srt_t *ss = (gtk_srt_t*)gui_data;
+ GtkWidget *parent_box = ss->vbox;
GtkTreeSelection *sel;
+ gtk_srt_table_t *gtk_table_data = g_new0(gtk_srt_table_t, 1);
static const char *default_titles[] = { "Index", "Procedure", "Calls", "Min SRT (s)", "Max SRT (s)", "Avg SRT (s)", "Sum SRT (s)" };
+ /* Create GTK data for the table here */
+ gtk_table_data->rst = rst;
+ g_array_insert_val(ss->gtk_srt_array, ss->gtk_srt_array->len, gtk_table_data);
+
+ /* Create the label for the table here */
+ label=gtk_label_new(rst->name);
+ if (ss->main_nb == NULL)
+ {
+ gtk_box_pack_start(GTK_BOX(ss->vbox), label, FALSE, FALSE, 0);
+ }
+ else
+ {
+ GtkWidget *tab_label=gtk_label_new(rst->short_name);
+ tab_page = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 6, FALSE);
+ gtk_notebook_append_page(GTK_NOTEBOOK(ss->main_nb), tab_page, tab_label);
+ gtk_box_pack_start(GTK_BOX(tab_page), label, FALSE, FALSE, 0);
+ parent_box = tab_page;
+ }
+
/* Create the store */
store = gtk_list_store_new (N_COLUMNS, /* Total number of columns */
G_TYPE_INT, /* Index */
@@ -416,17 +504,12 @@ init_srt_table(srt_stat_table *rst, int num_procs, GtkWidget *vbox, const char *
/* Create a view */
tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
- rst->table = GTK_TREE_VIEW(tree);
+ gtk_table_data->table = GTK_TREE_VIEW(tree);
sortable = GTK_TREE_SORTABLE(store);
/* The view now holds a reference. We can get rid of our own reference */
g_object_unref (G_OBJECT (store));
- if(filter_string){
- rst->filter_string=g_strdup(filter_string);
- } else {
- rst->filter_string=NULL;
- }
for (i = 0; i < N_COLUMNS; i++) {
renderer = gtk_cell_renderer_text_new ();
if (i != PROCEDURE_COLUMN) {
@@ -446,15 +529,18 @@ init_srt_table(srt_stat_table *rst, int num_procs, GtkWidget *vbox, const char *
column = gtk_tree_view_column_new_with_attributes (default_titles[i], renderer, NULL);
gtk_tree_view_column_set_cell_data_func(column, renderer, srt_avg_func, GINT_TO_POINTER(i), NULL);
break;
- default:
- column = gtk_tree_view_column_new_with_attributes (default_titles[i], renderer, "text",
+ case PROCEDURE_COLUMN:
+ column = gtk_tree_view_column_new_with_attributes (((rst->proc_column_name != NULL) ? rst->proc_column_name : default_titles[i]), renderer, "text",
i, NULL);
break;
+ default:
+ column = gtk_tree_view_column_new_with_attributes (default_titles[i], renderer, "text", i, NULL);
+ break;
}
gtk_tree_view_column_set_sort_column_id(column, i);
gtk_tree_view_column_set_resizable(column, TRUE);
- gtk_tree_view_append_column (rst->table, column);
+ gtk_tree_view_append_column (gtk_table_data->table, column);
if (i == CALLS_COLUMN) {
/* XXX revert order sort */
gtk_tree_view_column_clicked(column);
@@ -462,156 +548,315 @@ init_srt_table(srt_stat_table *rst, int num_procs, GtkWidget *vbox, const char *
}
}
- rst->scrolled_window=scrolled_window_new(NULL, NULL);
- gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(rst->scrolled_window),
+ gtk_table_data->scrolled_window=scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(gtk_table_data->scrolled_window),
GTK_SHADOW_IN);
- gtk_container_add(GTK_CONTAINER(rst->scrolled_window), GTK_WIDGET (rst->table));
- gtk_box_pack_start(GTK_BOX(vbox), rst->scrolled_window, TRUE, TRUE, 0);
+ gtk_container_add(GTK_CONTAINER(gtk_table_data->scrolled_window), GTK_WIDGET (gtk_table_data->table));
+ gtk_box_pack_start(GTK_BOX(parent_box), gtk_table_data->scrolled_window, TRUE, TRUE, 0);
- gtk_tree_view_set_reorderable (rst->table, FALSE);
+ gtk_tree_view_set_reorderable (gtk_table_data->table, FALSE);
/* Now enable the sorting of each column */
- gtk_tree_view_set_rules_hint(rst->table, TRUE);
- gtk_tree_view_set_headers_clickable(rst->table, TRUE);
+ gtk_tree_view_set_rules_hint(gtk_table_data->table, TRUE);
+ gtk_tree_view_set_headers_clickable(gtk_table_data->table, TRUE);
- gtk_widget_show(rst->scrolled_window);
-
- rst->num_procs=num_procs;
- rst->procedures=(srt_procedure_t *)g_malloc(sizeof(srt_procedure_t)*num_procs);
- for(i=0;i<num_procs;i++){
- time_stat_init(&rst->procedures[i].stats);
- rst->procedures[i].index = 0;
- rst->procedures[i].procedure = NULL;
- }
+ gtk_widget_show(gtk_table_data->scrolled_window);
- sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(rst->table));
+ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtk_table_data->table));
gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
+
/* create popup menu for this table */
if(rst->filter_string){
- srt_create_popup_menu(rst);
+ srt_create_popup_menu(gtk_table_data);
}
}
void
-init_srt_table_row(srt_stat_table *rst, int indx, const char *procedure)
-{
- /* we have discovered a new procedure. Extend the table accordingly */
- if(indx>=rst->num_procs){
- int old_num_procs=rst->num_procs;
- int i;
-
- rst->num_procs=indx+1;
- rst->procedures=(srt_procedure_t *)g_realloc(rst->procedures, sizeof(srt_procedure_t)*(rst->num_procs));
- for(i=old_num_procs;i<rst->num_procs;i++){
- time_stat_init(&rst->procedures[i].stats);
- rst->procedures[i].index = i;
- rst->procedures[i].procedure=NULL;
- }
- }
- rst->procedures[indx].index = indx;
- rst->procedures[indx].procedure=g_strdup(procedure);
-}
+draw_srt_table_data(srt_stat_table *rst, gtk_srt_t* gtk_data)
+{
+ int idx, new_idx;
+ GtkTreeIter iter;
+ gboolean first = TRUE;
+ gtk_srt_table_t* gtk_table;
+ GtkListStore *store;
+ gboolean iter_valid;
-void
-add_srt_table_data(srt_stat_table *rst, int indx, const nstime_t *req_time, packet_info *pinfo)
-{
- srt_procedure_t *rp;
- nstime_t t, delta;
-
- g_assert(indx >= 0 && indx < rst->num_procs);
- rp=&rst->procedures[indx];
-
- /*
- * If the count of calls for this procedure is currently zero, it's
- * going to become non-zero, so add a row for it (we don't want
- * rows for procedures that have no calls - especially if the
- * procedure has no calls because the index doesn't correspond
- * to a procedure, but is an unused/reserved value).
- *
- * (Yes, this means that the rows aren't in order by anything
- * interesting. That's why we have the table sorted by a column.)
- */
+ gtk_table = get_gtk_table_from_srt(rst, gtk_data);
+ g_assert(gtk_table);
- if (rp->stats.num==0){
- GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model(rst->table));
- gtk_list_store_append(store, &rp->iter);
- gtk_list_store_set(store, &rp->iter,
- INDEX_COLUMN, rp->index,
- PROCEDURE_COLUMN, rp->procedure,
- CALLS_COLUMN, rp->stats.num,
- MIN_SRT_COLUMN, NULL,
- MAX_SRT_COLUMN, NULL,
- AVG_SRT_COLUMN, (guint64)0,
- SUM_SRT_COLUMN, (guint64)0,
- -1);
- }
+ store = GTK_LIST_STORE(gtk_tree_view_get_model(gtk_table->table));
+ iter_valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
- /* calculate time delta between request and reply */
- t=pinfo->fd->abs_ts;
- nstime_delta(&delta, &t, req_time);
+ new_idx = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), NULL);
- time_stat_update(&rp->stats, &delta, pinfo);
-}
+ /* Update list items (which may not be in "idx" order), then add new items */
+ while (iter_valid || (new_idx < rst->num_procs)) {
+ srt_procedure_t* procedure;
+ guint64 td;
+ guint64 sum;
-void
-draw_srt_table_data(srt_stat_table *rst)
-{
- int i;
- guint64 td;
- guint64 sum;
- GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model(rst->table));
+ if (iter_valid) {
+ gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, INDEX_COLUMN, &idx, -1);
+ } else {
+ idx = new_idx;
+ new_idx++;
+ }
- for(i=0;i<rst->num_procs;i++){
- /* ignore procedures with no calls (they don't have rows) */
- if(rst->procedures[i].stats.num==0){
+ procedure = &rst->procedures[idx];
+ if ((procedure->procedure == NULL) || (procedure->stats.num == 0)) {
+ iter_valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
continue;
}
+
+ if (first) {
+ g_object_ref(store);
+ gtk_tree_view_set_model(GTK_TREE_VIEW(gtk_table->table), NULL);
+
+ first = FALSE;
+ }
+
/* Scale the average SRT in units of 1us and round to the nearest us.
- tot.secs is a time_t which may be 32 or 64 bits (or even floating)
- depending uon the platform. After casting tot.secs to 64 bits, it
- would take a capture with a duration of over 136 *years* to
- overflow the secs portion of td. */
- td = ((guint64)(rst->procedures[i].stats.tot.secs))*NANOSECS_PER_SEC + rst->procedures[i].stats.tot.nsecs;
+ tot.secs is a time_t which may be 32 or 64 bits (or even floating)
+ depending uon the platform. After casting tot.secs to 64 bits, it
+ would take a capture with a duration of over 136 *years* to
+ overflow the secs portion of td. */
+ td = ((guint64)(procedure->stats.tot.secs))*NANOSECS_PER_SEC + procedure->stats.tot.nsecs;
sum = (td + 500) / 1000;
- td = ((td / rst->procedures[i].stats.num) + 500) / 1000;
-
- gtk_list_store_set(store, &rst->procedures[i].iter,
- CALLS_COLUMN, rst->procedures[i].stats.num,
- MIN_SRT_COLUMN, &rst->procedures[i].stats.min,
- MAX_SRT_COLUMN, &rst->procedures[i].stats.max,
- AVG_SRT_COLUMN, td,
- SUM_SRT_COLUMN, sum,
- -1);
+ td = ((td / procedure->stats.num) + 500) / 1000;
+
+ if (iter_valid) {
+ /* Existing row. Only changeable entries */
+
+ gtk_list_store_set(store, &iter,
+ PROCEDURE_COLUMN, procedure->procedure,
+ CALLS_COLUMN, procedure->stats.num,
+ MIN_SRT_COLUMN, &procedure->stats.min,
+ MAX_SRT_COLUMN, &procedure->stats.max,
+ AVG_SRT_COLUMN, td,
+ SUM_SRT_COLUMN, sum,
+ -1);
+ } else {
+ /* New row. All entries, including fixed ones */
+ gtk_list_store_insert_with_values(store, &iter, G_MAXINT,
+ PROCEDURE_COLUMN, procedure->procedure,
+ CALLS_COLUMN, procedure->stats.num,
+ MIN_SRT_COLUMN, &procedure->stats.min,
+ MAX_SRT_COLUMN, &procedure->stats.max,
+ AVG_SRT_COLUMN, td,
+ SUM_SRT_COLUMN, sum,
+ INDEX_COLUMN, idx,
+ -1);
+ }
+
+ iter_valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
+ }
+
+ if (!first) {
+ gtk_tree_view_set_model(GTK_TREE_VIEW(gtk_table->table), GTK_TREE_MODEL(store));
+ g_object_unref(store);
}
}
+static void
+srt_draw(void *arg)
+{
+ guint i = 0;
+ srt_stat_table *srt_table;
+ srt_data_t *srt = (srt_data_t*)arg;
+ srt_t *ss = (srt_t*)srt->user_data;
+
+ for (i = 0; i < srt->srt_array->len; i++)
+ {
+ srt_table = g_array_index(srt->srt_array, srt_stat_table*, i);
+ draw_srt_table_data(srt_table, &ss->gtk_data);
+ }
+}
void
-reset_srt_table_data(srt_stat_table *rst)
+reset_table_data(srt_stat_table* rst, void* gui_data)
{
- int i;
GtkListStore *store;
+ gtk_srt_t* gtk_data = (gtk_srt_t*)gui_data;
+ gtk_srt_table_t* gtk_table = get_gtk_table_from_srt(rst, gtk_data);
+ g_assert(gtk_table);
- for(i=0;i<rst->num_procs;i++){
- time_stat_init(&rst->procedures[i].stats);
- }
- store = GTK_LIST_STORE(gtk_tree_view_get_model(rst->table));
+ store = GTK_LIST_STORE(gtk_tree_view_get_model(gtk_table->table));
gtk_list_store_clear(store);
}
-void
-free_srt_table_data(srt_stat_table *rst)
+static void
+srt_reset(void *arg)
{
- int i;
+ srt_data_t *srt = (srt_data_t*)arg;
+ srt_t *ss = (srt_t *)srt->user_data;
+
+ reset_srt_table(ss->data.srt_array, reset_table_data, &ss->gtk_data);
+
+ srt_set_title(ss);
+}
+
+static void
+init_srt_tables(register_srt_t* srt, const char *filter)
+{
+ srt_t *ss;
+ gchar *str;
+ GtkWidget *label;
+ char *filter_string;
+ GString *error_string;
+ GtkWidget *bbox;
+ GtkWidget *close_bt;
+
+ ss = g_new0(srt_t, 1);
- for(i=0;i<rst->num_procs;i++){
- g_free(rst->procedures[i].procedure);
- rst->procedures[i].procedure=NULL;
+ str = g_strdup_printf("%s-stat", proto_get_protocol_filter_name(get_srt_proto_id(srt)));
+ ss->gtk_data.win=dlg_window_new(str); /* transient_for top_level */
+ g_free(str);
+ gtk_window_set_destroy_with_parent (GTK_WINDOW(ss->gtk_data.win), TRUE);
+ gtk_window_set_default_size(GTK_WINDOW(ss->gtk_data.win), SRT_PREFERRED_WIDTH, 600);
+
+ str = g_strdup_printf("%s Service Response Time statistics", proto_get_protocol_short_name(find_protocol_by_id(get_srt_proto_id(srt))));
+ set_window_title(ss->gtk_data.win, str);
+
+ ss->gtk_data.vbox=ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
+ gtk_container_add(GTK_CONTAINER(ss->gtk_data.win), ss->gtk_data.vbox);
+ gtk_container_set_border_width(GTK_CONTAINER(ss->gtk_data.vbox), 12);
+
+ label=gtk_label_new(str);
+ gtk_box_pack_start(GTK_BOX(ss->gtk_data.vbox), label, FALSE, FALSE, 0);
+ g_free(str);
+
+ filter_string = g_strdup_printf("Filter: %s", filter ? filter : "");
+ label=gtk_label_new(filter_string);
+ gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+ g_free(filter_string);
+ gtk_box_pack_start(GTK_BOX(ss->gtk_data.vbox), label, FALSE, FALSE, 0);
+
+ /* up to 3 tables is reasonable real estate to display tables. Any more than
+ * that and we need to switch to a tab view
+ */
+ if (get_srt_max_tables(srt) > 3)
+ {
+ ss->gtk_data.main_nb = gtk_notebook_new();
+ gtk_box_pack_start(GTK_BOX(ss->gtk_data.vbox), ss->gtk_data.main_nb, TRUE, TRUE, 0);
}
- g_free(rst->filter_string);
- rst->filter_string=NULL;
- g_free(rst->procedures);
- rst->procedures=NULL;
- rst->num_procs=0;
+
+ /* We must display TOP LEVEL Widget before calling srt_table_dissector_init() */
+ gtk_widget_show_all(ss->gtk_data.win);
+
+ ss->type = proto_get_protocol_short_name(find_protocol_by_id(get_srt_proto_id(srt)));
+ ss->filter = g_strdup(filter);
+ ss->srt = srt;
+ ss->gtk_data.gtk_srt_array = g_array_new(FALSE, TRUE, sizeof(gtk_srt_table_t*));
+ ss->data.srt_array = g_array_new(FALSE, TRUE, sizeof(srt_stat_table*));
+ ss->data.user_data = ss;
+
+ srt_table_dissector_init(srt, ss->data.srt_array, init_gtk_srt_table, &ss->gtk_data);
+
+ error_string = register_tap_listener(get_srt_tap_listener_name(srt), &ss->data, filter, 0, srt_reset, get_srt_packet_func(srt), srt_draw);
+ if(error_string){
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
+ g_string_free(error_string, TRUE);
+ free_srt_table(ss->srt, ss->data.srt_array, NULL, NULL);
+ g_free(ss);
+ return;
+ }
+
+ /* Button row. */
+ bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
+ gtk_box_pack_end(GTK_BOX(ss->gtk_data.vbox), bbox, FALSE, FALSE, 0);
+
+ close_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
+ window_set_cancel_button(ss->gtk_data.win, close_bt, window_cancel_button_cb);
+
+ g_signal_connect(ss->gtk_data.win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
+ g_signal_connect(ss->gtk_data.win, "destroy", G_CALLBACK(win_destroy_cb), ss);
+
+ gtk_widget_show_all(ss->gtk_data.win);
+ window_present(ss->gtk_data.win);
+
+ cf_retap_packets(&cfile);
+ gdk_window_raise(gtk_widget_get_window(ss->gtk_data.win));
+}
+
+static void
+gtk_srtstat_init(const char *opt_arg, void *userdata _U_)
+{
+ gchar** dissector_name;
+ register_srt_t *srt;
+ const char *filter=NULL;
+ char* err;
+
+ /* Use first comma to find dissector name */
+ dissector_name = g_strsplit(opt_arg, ",", -1);
+ g_assert(dissector_name[0]);
+
+ /* Use dissector name to find SRT table */
+ srt = get_srt_table_by_name(dissector_name[0]);
+ g_assert(srt);
+
+ srt_table_get_filter(srt, opt_arg, &filter, &err);
+
+ if (err != NULL)
+ {
+ gchar* cmd_str = srt_table_get_tap_string(srt);
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "invalid \"-z %s,%s\" argument", cmd_str, err);
+ g_free(cmd_str);
+ g_free(err);
+ return;
+ }
+
+ init_srt_tables(srt, filter);
+}
+
+static tap_param srt_stat_params[] = {
+ { PARAM_FILTER, "filter", "Filter", NULL, TRUE }
+};
+
+/* XXX - Temporary hack/workaround until a more generic approach can be implemented */
+static const enum_val_t scsi_command_sets[] = {
+ { "sbc", "SBC (disk)", SCSI_DEV_SBC },
+ { "ssc", "SSC (tape)", SCSI_DEV_SSC },
+ { "mmc", "MMC (cd/dvd)", SCSI_DEV_CDROM },
+ { "smc", "SMC (tape robot)", SCSI_DEV_SMC },
+ { "osd", "OSD (object based)", SCSI_DEV_OSD },
+ { NULL, NULL, 0 }
+};
+
+static tap_param scsi_stat_params[] = {
+ { PARAM_ENUM, "cmdset", "Command set", scsi_command_sets, FALSE },
+ { PARAM_FILTER, "filter", "Filter", NULL, TRUE }
+};
+
+
+void register_service_response_tables(gpointer data, gpointer user_data _U_)
+{
+ register_srt_t *srt = (register_srt_t*)data;
+ const char* short_name = proto_get_protocol_short_name(find_protocol_by_id(get_srt_proto_id(srt)));
+ tap_param_dlg* srt_dlg;
+
+ /* XXX - These dissectors haven't been converted over to due to an "interactive input dialog" for their
+ tap data. Let those specific dialogs register for themselves */
+ if ((strcmp(short_name, "RPC") == 0) ||
+ (strcmp(short_name, "DCERPC") == 0))
+ return;
+
+ srt_dlg = g_new(tap_param_dlg, 1);
+
+ srt_dlg->win_title = g_strdup_printf("%s SRT Statistics", short_name);
+ srt_dlg->init_string = srt_table_get_tap_string(srt);
+ srt_dlg->tap_init_cb = gtk_srtstat_init;
+ srt_dlg->index = -1;
+ if (get_srt_proto_id(srt) == proto_get_id_by_filter_name("scsi"))
+ {
+ srt_dlg->nparams = G_N_ELEMENTS(scsi_stat_params);
+ srt_dlg->params = scsi_stat_params;
+ }
+ else
+ {
+ srt_dlg->nparams = G_N_ELEMENTS(srt_stat_params);
+ srt_dlg->params = srt_stat_params;
+ }
+
+ register_param_stat(srt_dlg, short_name, REGISTER_STAT_GROUP_RESPONSE_TIME);
}