Huge thanks to our Platinum Members Endace and LiveAction,
and our Silver Member Veeam, for supporting the Wireshark Foundation and project.

Ethereal-dev: Re: [Ethereal-dev] Voip Calls analysis and Graph analysis

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Alejandro Vaquero <alejandrovaquero@xxxxxxxxx>
Date: Mon, 28 Feb 2005 21:03:53 -0700
Hi All,
    Find attached a patch to "Voip analysis" to:
- Add a horizontal scrollbar in the "Graph" to scroll the "comments"
- Fix a "state" bug in H323 and SIP calls
- Fix a bug that can make the "graph" to crash, and also clean up the "address" when the window is close

Regards
Alejandro

Alejandro Vaquero wrote:
Hi All,
    Here is another patch for:

voip_calls_dlg.c
    Change the "prepare filter" function to be protocol independent. Now it uses the "frame_num"s  from the Graph structure to create the filter. This also add support to MGCP and H323 LRQ/LCF filters that were not supported before.

graph_analysis.c:
    Change the mouse scroll wheel implementation to make a 3 line step change instead of 1 line.

Regards
Alejandro


Add support to filter MGCP and

Alejandro Vaquero wrote:
Thanks Lars,
  Also attached find a patch to graph_analysis.c to add support of mouse scroll wheel and directional keys (Up, down, left, and right) in the Graph Analysis.

Regards
Alejandro

Lars Roland wrote:

Lars Roland schrieb:

Having a short look at the patch, I have to disagree on an implementation detail:

I don't like to have the mgcp dissector allocating a mgcp_info_t structure for each dissection of an mgcp packet without freeing it. This could be considered to be a big memory leak.
Instead use a static array of mgcp_info_t structures. You can take the h225 or the q931 dissector as an example of such an implementation.



On Fri, 18 Feb 2005 13:00:00 -0700, Alejandro Vaquero
<alejandrovaquero@xxxxxxxxx> wrote:

Hi All,
   find attached a patch to add MGCP calls to the "Voip Analysis". The
implementation is oriented to MGCP Residential Gateways.


checked in along with the changes I've proposed above and an additional check for the presence of the mgcp plugin.

Regards,
Lars

_______________________________________________
Ethereal-dev mailing list
Ethereal-dev@xxxxxxxxxxxx
http://www.ethereal.com/mailman/listinfo/ethereal-dev


Index: graph_analysis.c =================================================================== --- graph_analysis.c (revision 13449) +++ graph_analysis.c (working copy) @@ -38,6 +38,7 @@ /* in /gtk ... */ #include <gtk/gtk.h> +#include <gdk/gdkkeysyms.h> #include "gtkglobals.h" #include "dlg_utils.h" @@ -647,6 +648,63 @@ } /****************************************************************************/ +static gint scroll_event(GtkWidget *widget, GdkEventButton *event _U_) +{ + graph_analysis_data_t *user_data; + + user_data=(graph_analysis_data_t *)OBJECT_GET_DATA(widget, "graph_analysis_data_t"); + + /* Up scroll */ + if (event->state == 0){ + if (user_data->dlg.first_item == 0) return TRUE; + user_data->dlg.first_item--; + + /* Down scroll */ + } else { + if ((user_data->dlg.first_item+user_data->dlg.v_scrollbar_adjustment->page_size+1 == user_data->num_items)) return TRUE; + user_data->dlg.first_item++; + } + dialog_graph_redraw(user_data); + + return TRUE; +} + +/****************************************************************************/ +static gint key_press_event(GtkWidget *widget, GdkEventKey *event _U_) +{ + graph_analysis_data_t *user_data; + + user_data=(graph_analysis_data_t *)OBJECT_GET_DATA(widget, "graph_analysis_data_t"); + + /* Up arrow */ + if (event->keyval == GDK_Up){ + if (user_data->dlg.selected_item == 0) return TRUE; + user_data->dlg.selected_item--; + if ( (user_data->dlg.selected_item<user_data->dlg.first_item) || (user_data->dlg.selected_item>user_data->dlg.first_item+user_data->dlg.v_scrollbar_adjustment->page_size) ) + user_data->dlg.first_item = user_data->dlg.selected_item; + /* Down arrow */ + } else if (event->keyval == GDK_Down){ + if (user_data->dlg.selected_item == user_data->num_items-1) return TRUE; + user_data->dlg.selected_item++; + if ( (user_data->dlg.selected_item<user_data->dlg.first_item) || (user_data->dlg.selected_item>user_data->dlg.first_item+user_data->dlg.v_scrollbar_adjustment->page_size) ) + user_data->dlg.first_item = (guint32)user_data->dlg.selected_item-(guint32)user_data->dlg.v_scrollbar_adjustment->page_size; + } else if (event->keyval == GDK_Left){ + if (user_data->dlg.first_node == 0) return TRUE; + user_data->dlg.first_node--; + } else if (event->keyval == GDK_Right){ + if ((user_data->dlg.first_node+user_data->dlg.h_scrollbar_adjustment->page_size+1 == user_data->num_nodes)) return TRUE; + user_data->dlg.first_node++; + } + + user_data->dlg.needs_redraw=TRUE; + dialog_graph_draw(user_data); + + cf_goto_frame(&cfile, user_data->dlg.items[user_data->dlg.selected_item-user_data->dlg.first_item].frame_num); + + return TRUE; +} + +/****************************************************************************/ static gint expose_event(GtkWidget *widget, GdkEventExpose *event) { graph_analysis_data_t *user_data; @@ -795,6 +853,8 @@ user_data->dlg.draw_area=gtk_drawing_area_new(); + GTK_WIDGET_SET_FLAGS(user_data->dlg.draw_area, GTK_CAN_FOCUS); + gtk_widget_grab_focus(user_data->dlg.draw_area); SIGNAL_CONNECT(user_data->dlg.draw_area, "destroy", quit, user_data); OBJECT_SET_DATA(user_data->dlg.draw_area, "graph_analysis_data_t", user_data); @@ -807,6 +867,8 @@ gtk_widget_add_events (user_data->dlg.draw_area, GDK_BUTTON_PRESS_MASK); SIGNAL_CONNECT(user_data->dlg.draw_area, "button_press_event", button_press_event, user_data); + SIGNAL_CONNECT(user_data->dlg.draw_area, "scroll_event", scroll_event, user_data); + SIGNAL_CONNECT(user_data->dlg.draw_area, "key_press_event", key_press_event, user_data); gtk_widget_show(user_data->dlg.draw_area); gtk_box_pack_start(GTK_BOX(vbox), user_data->dlg.draw_area, TRUE, TRUE, 0);

_______________________________________________ Ethereal-dev mailing list Ethereal-dev@xxxxxxxxxxxx http://www.ethereal.com/mailman/listinfo/ethereal-dev

Index: gtk/voip_calls_dlg.c =================================================================== --- gtk/voip_calls_dlg.c (revision 13474) +++ gtk/voip_calls_dlg.c (working copy) @@ -221,12 +221,11 @@ gchar c; GString *filter_string_fwd; gchar *filter_prepend; - sip_calls_info_t *tmp_sipinfo; - isup_calls_info_t *tmp_isupinfo; - h323_calls_info_t *tmp_h323info; - h245_address_t *h245_add = NULL; + gboolean isFirst = TRUE; GList* list; + graph_analysis_item_t *gai; + if (selected_call_fwd==NULL) return; @@ -242,51 +241,23 @@ } filter_string_fwd = g_string_new(filter_prepend); - switch(selected_call_fwd->protocol){ - case VOIP_SIP: - tmp_sipinfo = selected_call_fwd->prot_info; - g_string_sprintfa(filter_string_fwd, - "(sip.Call-ID == \"%s\") ", - tmp_sipinfo->call_identifier - ); - gtk_entry_append_text(GTK_ENTRY(main_display_filter_widget), filter_string_fwd->str); - break; - case VOIP_ISUP: - tmp_isupinfo = selected_call_fwd->prot_info; - g_string_sprintfa(filter_string_fwd, - "(isup.cic == %i and frame.number >=%i and frame.number<=%i and mtp3.network_indicator == %i and ((mtp3.dpc == %i) and (mtp3.opc == %i)) or((mtp3.dpc == %i) and (mtp3.opc == %i))) ", - tmp_isupinfo->cic,selected_call_fwd->first_frame_num, - selected_call_fwd->last_frame_num, - tmp_isupinfo->ni, tmp_isupinfo->dpc, tmp_isupinfo->opc, - tmp_isupinfo->opc, tmp_isupinfo->dpc - ); - gtk_entry_append_text(GTK_ENTRY(main_display_filter_widget), filter_string_fwd->str); - break; - case VOIP_H323: - tmp_h323info = selected_call_fwd->prot_info; - g_string_sprintfa(filter_string_fwd, - "((h225.guid == %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x || q931.call_ref == %x:%x || q931.call_ref == %x:%x) ", - (guint8)tmp_h323info->guid[0], (guint8)tmp_h323info->guid[1], (guint8)tmp_h323info->guid[2], - (guint8)tmp_h323info->guid[3], (guint8)tmp_h323info->guid[4], (guint8)tmp_h323info->guid[5], (guint8)tmp_h323info->guid[6], - (guint8)tmp_h323info->guid[7], (guint8)tmp_h323info->guid[8], (guint8)tmp_h323info->guid[9], (guint8)tmp_h323info->guid[10], - (guint8)tmp_h323info->guid[11], (guint8)tmp_h323info->guid[12], (guint8)tmp_h323info->guid[13], (guint8)tmp_h323info->guid[14], - (guint8)tmp_h323info->guid[15], (guint8)(tmp_h323info->q931_crv & 0xff), (guint8)((tmp_h323info->q931_crv & 0xff00)>>8) - , (guint8)(tmp_h323info->q931_crv2 & 0xff), (guint8)((tmp_h323info->q931_crv2 & 0xff00)>>8)); + + /* look in the Graph and get all the frame_num for this call */ + g_string_sprintfa(filter_string_fwd, " ("); + list = g_list_first(voip_calls_get_info()->graph_analysis->list); + while (list) + { + gai = list->data; + if (gai->conv_num == selected_call_fwd->call_num){ + g_string_sprintfa(filter_string_fwd,"%sframe.number == %d", isFirst?"":" or ", gai->frame_num ); + isFirst = FALSE; + } + list = g_list_next (list); + } + g_string_sprintfa(filter_string_fwd, ") "); - list = g_list_first(tmp_h323info->h245_list); - while (list) - { - h245_add=list->data; - g_string_sprintfa(filter_string_fwd, - " || (ip.addr == %s && tcp.port == %d && h245) ", - ip_to_str((guint8 *)&(h245_add->h245_address)), h245_add->h245_port); - list = g_list_next(list); - } - g_string_sprintfa(filter_string_fwd, ") "); - gtk_entry_append_text(GTK_ENTRY(main_display_filter_widget), filter_string_fwd->str); - break; + gtk_entry_append_text(GTK_ENTRY(main_display_filter_widget), filter_string_fwd->str); - } g_string_free(filter_string_fwd, TRUE); } Index: gtk/graph_analysis.c =================================================================== --- gtk/graph_analysis.c (revision 13474) +++ gtk/graph_analysis.c (working copy) @@ -662,12 +662,18 @@ /* Up scroll */ if (event->state == 0){ if (user_data->dlg.first_item == 0) return TRUE; - user_data->dlg.first_item--; + if (user_data->dlg.first_item < 3) + user_data->dlg.first_item = 0; + else + user_data->dlg.first_item -= 3; - /* Down scroll */ + /* Down scroll */ } else { if ((user_data->dlg.first_item+user_data->dlg.v_scrollbar_adjustment->page_size+1 == user_data->num_items)) return TRUE; - user_data->dlg.first_item++; + if ((user_data->dlg.first_item+user_data->dlg.v_scrollbar_adjustment->page_size+1) > (user_data->num_items-3)) + user_data->dlg.first_item = user_data->num_items-(guint32)user_data->dlg.v_scrollbar_adjustment->page_size-1; + else + user_data->dlg.first_item += 3; } dialog_graph_redraw(user_data);

_______________________________________________ Ethereal-dev mailing list Ethereal-dev@xxxxxxxxxxxx http://www.ethereal.com/mailman/listinfo/ethereal-dev
Index: gtk/graph_analysis.c
===================================================================
--- gtk/graph_analysis.c	(revision 13505)
+++ gtk/graph_analysis.c	(working copy)
@@ -83,6 +83,7 @@
 		user_data->nodes[i].type = AT_NONE;
 		user_data->nodes[i].len = 0;
 		g_free((void *)user_data->nodes[i].data);
+		user_data->nodes[i].data = NULL;
 	}
 	
 	user_data->dlg.first_node=0;
@@ -95,15 +96,31 @@
 /* Reset the user_data structure */
 static void graph_analysis_init_dlg(graph_analysis_data_t* user_data)
 {
+	int i;
+
+	user_data->num_nodes = 0;
+	user_data->num_items = 0;
+	for (i=0; i<MAX_NUM_NODES; i++){
+		user_data->nodes[i].type = AT_NONE;
+		user_data->nodes[i].len = 0;
+		user_data->nodes[i].data = NULL;
+	}
+	
+	user_data->dlg.first_node=0;
+	user_data->dlg.first_item=0;
+	user_data->dlg.left_x_border=0;
+	user_data->dlg.selected_item=0xFFFFFFFF;    /*not item selected */
     /* init dialog_graph */
     user_data->dlg.needs_redraw=TRUE;
     user_data->dlg.draw_area=NULL;
     user_data->dlg.pixmap=NULL;
+	user_data->dlg.draw_area_comments=NULL;
+    user_data->dlg.pixmap_comments=NULL;
     user_data->dlg.h_scrollbar=NULL;
     user_data->dlg.h_scrollbar_adjustment=NULL;
     user_data->dlg.v_scrollbar=NULL;
     user_data->dlg.v_scrollbar_adjustment=NULL;
-    user_data->dlg.pixmap_width=600;
+    user_data->dlg.pixmap_width=350;
     user_data->dlg.pixmap_height=400;
 	user_data->dlg.first_node=0;
 	user_data->dlg.first_item=0;
@@ -125,8 +142,9 @@
 		user_data->nodes[i].type = AT_NONE;
 		user_data->nodes[i].len = 0;
 		g_free((void *)user_data->nodes[i].data);
+		user_data->nodes[i].data = NULL;
 	}
-	g_free(user_data);
+	user_data->dlg.window = NULL;
 }
 
 
@@ -168,12 +186,12 @@
 }
 
 #define MAX_LABEL 50
-#define MAX_COMMENT 60
+#define MAX_COMMENT 100
 #define ITEM_HEIGHT 20
 #define NODE_WIDTH 100
 #define TOP_Y_BORDER 40
 #define BOTTOM_Y_BORDER 0
-#define COMMENT_WIDTH 250
+#define COMMENT_WIDTH 400
 
 /****************************************************************************/
 static void dialog_graph_draw(graph_analysis_data_t* user_data)
@@ -224,9 +242,17 @@
                            user_data->dlg.draw_area->allocation.width,
                            user_data->dlg.draw_area->allocation.height);
 
+        gdk_draw_rectangle(user_data->dlg.pixmap_comments,
+                           user_data->dlg.draw_area->style->white_gc,
+                           TRUE,
+                           0, 0,
+                           COMMENT_WIDTH,
+                           user_data->dlg.draw_area->allocation.height);
+
+
 		/* Calculate the y border */
         top_y_border=TOP_Y_BORDER;	/* to display the node address */
-        bottom_y_border=BOTTOM_Y_BORDER;
+        bottom_y_border=2;
 
         draw_height=user_data->dlg.pixmap_height-top_y_border-bottom_y_border;
 
@@ -305,7 +331,7 @@
         left_x_border=label_width+10;
 		user_data->dlg.left_x_border = left_x_border;
 
-        right_x_border=COMMENT_WIDTH;
+        right_x_border=2;
 
 		/* Calculate the number of nodes to display */
         draw_width=user_data->dlg.pixmap_width-right_x_border-left_x_border;
@@ -404,18 +430,18 @@
 #if GTK_MAJOR_VERSION < 2
 			label_width=gdk_string_width(small_font, label_string);
 			label_height=gdk_string_height(small_font, label_string);
-			gdk_draw_string(user_data->dlg.pixmap,
+			gdk_draw_string(user_data->dlg.pixmap_comments,
                 small_font,
-                user_data->dlg.draw_area->style->black_gc,
-                user_data->dlg.pixmap_width-right_x_border+3,
+                user_data->dlg.draw_area_comments->style->black_gc,
+                2,
                 top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2+label_height/4,
                 label_string);
 #else
 			pango_layout_set_text(small_layout, label_string, -1);
 			pango_layout_get_pixel_size(small_layout, &label_width, &label_height);
-	        gdk_draw_layout(user_data->dlg.pixmap,
+	        gdk_draw_layout(user_data->dlg.pixmap_comments,
                 user_data->dlg.draw_area->style->black_gc,
-                user_data->dlg.pixmap_width-right_x_border+3,
+                2,
                 top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2-label_height/2,
                 small_layout);
 #endif
@@ -586,12 +612,12 @@
 				FALSE,
 				left_x_border-1,
 				(user_data->dlg.selected_item-first_item)*ITEM_HEIGHT+TOP_Y_BORDER,
-				user_data->dlg.pixmap_width-COMMENT_WIDTH-left_x_border+1,
+				user_data->dlg.pixmap_width-left_x_border-right_x_border+1,
 				ITEM_HEIGHT);
 		}
 
 
-
+		/* refresh the draw areas */
         gdk_draw_pixmap(user_data->dlg.draw_area->window,
                         user_data->dlg.draw_area->style->fg_gc[GTK_WIDGET_STATE(user_data->dlg.draw_area)],
                         user_data->dlg.pixmap,
@@ -599,7 +625,14 @@
                         0, 0,
                         user_data->dlg.pixmap_width, user_data->dlg.pixmap_height);
 
+        gdk_draw_pixmap(user_data->dlg.draw_area_comments->window,
+                        user_data->dlg.draw_area_comments->style->fg_gc[GTK_WIDGET_STATE(user_data->dlg.draw_area_comments)],
+                        user_data->dlg.pixmap_comments,
+                        0, 0,
+                        0, 0,
+                        COMMENT_WIDTH, user_data->dlg.pixmap_height);
 
+
         /* update the h_scrollbar */
         user_data->dlg.h_scrollbar_adjustment->upper=(gfloat) user_data->num_nodes-1;
         user_data->dlg.h_scrollbar_adjustment->step_increment=1;
@@ -619,7 +652,6 @@
 
 		gtk_adjustment_changed(user_data->dlg.v_scrollbar_adjustment);
         gtk_adjustment_value_changed(user_data->dlg.v_scrollbar_adjustment);
-
 }
 
 /****************************************************************************/
@@ -630,19 +662,6 @@
 }
 
 /****************************************************************************/
-static gint quit(GtkWidget *widget, GdkEventExpose *event _U_)
-{
-        graph_analysis_data_t *user_data;
-
-        user_data=(graph_analysis_data_t *)OBJECT_GET_DATA(widget, "graph_analysis_data_t");
-
-		user_data->dlg.window = NULL;
-
-		user_data = NULL;
-        return TRUE;
-}
-
-/****************************************************************************/
 static gint button_press_event(GtkWidget *widget, GdkEventButton *event _U_)
 {
         graph_analysis_data_t *user_data;
@@ -750,6 +769,27 @@
         return FALSE;
 }
 
+/****************************************************************************/
+static gint expose_event_comments(GtkWidget *widget, GdkEventExpose *event)
+{
+	graph_analysis_data_t *user_data;
+
+	user_data=(graph_analysis_data_t *)OBJECT_GET_DATA(widget, "graph_analysis_data_t");
+        if(!user_data){
+                exit(10);
+        }
+
+
+        gdk_draw_pixmap(widget->window,
+                        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+                        user_data->dlg.pixmap_comments,
+                        event->area.x, event->area.y,
+                        event->area.x, event->area.y,
+                        event->area.width, event->area.height);
+
+        return FALSE;
+}
+
 static const GdkColor COLOR_GRAY = {0, 0x7fff, 0x7fff, 0x7fff};
 
 /****************************************************************************/
@@ -830,6 +870,38 @@
 }
 
 /****************************************************************************/
+static gint configure_event_comments(GtkWidget *widget, GdkEventConfigure *event _U_)
+{
+        graph_analysis_data_t *user_data;
+
+        user_data=(graph_analysis_data_t *)OBJECT_GET_DATA(widget, "graph_analysis_data_t");
+
+        if(!user_data){
+                exit(10);
+        }
+
+        if(user_data->dlg.pixmap_comments){
+                gdk_pixmap_unref(user_data->dlg.pixmap_comments);
+                user_data->dlg.pixmap_comments=NULL;
+        }
+
+        user_data->dlg.pixmap_comments=gdk_pixmap_new(widget->window,
+                        COMMENT_WIDTH,
+                        widget->allocation.height,
+                        -1);
+
+        gdk_draw_rectangle(user_data->dlg.pixmap_comments,
+                        widget->style->white_gc,
+                        TRUE,
+                        0, 0,
+                        COMMENT_WIDTH,
+                        widget->allocation.height);
+
+		dialog_graph_redraw(user_data);
+        return TRUE;
+}
+
+/****************************************************************************/
 static gint h_scrollbar_changed(GtkWidget *widget _U_, gpointer data)
 {
     graph_analysis_data_t *user_data=(graph_analysis_data_t *)data;
@@ -869,6 +941,8 @@
 {
 	    GtkWidget *vbox;
         GtkWidget *hbox;
+		GtkWidget *scroll_window;
+		GtkWidget *viewport;
 
         hbox=gtk_hbox_new(FALSE, 0);
         gtk_widget_show(hbox);
@@ -876,28 +950,45 @@
         vbox=gtk_vbox_new(FALSE, 0);
         gtk_widget_show(vbox);
 
+		/* create "comments" draw area */
+        user_data->dlg.draw_area_comments=gtk_drawing_area_new();
+        WIDGET_SET_SIZE(user_data->dlg.draw_area_comments, COMMENT_WIDTH, user_data->dlg.pixmap_height);
+		scroll_window=gtk_scrolled_window_new(NULL, NULL);
+		WIDGET_SET_SIZE(scroll_window, COMMENT_WIDTH/2, user_data->dlg.pixmap_height);
+		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll_window), GTK_POLICY_ALWAYS, GTK_POLICY_NEVER);
+		viewport = gtk_viewport_new(gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(scroll_window)), gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scroll_window)));
+		gtk_container_add(GTK_CONTAINER(viewport), user_data->dlg.draw_area_comments);
+		gtk_container_add(GTK_CONTAINER(scroll_window), viewport);
+		gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
+        OBJECT_SET_DATA(user_data->dlg.draw_area_comments, "graph_analysis_data_t", user_data);
+		gtk_widget_add_events (user_data->dlg.draw_area_comments, GDK_BUTTON_PRESS_MASK);
+		SIGNAL_CONNECT(user_data->dlg.draw_area_comments, "scroll_event",  scroll_event, user_data);
 
+		/* create main Graph draw area */
         user_data->dlg.draw_area=gtk_drawing_area_new();
 		GTK_WIDGET_SET_FLAGS(user_data->dlg.draw_area, GTK_CAN_FOCUS);
 		gtk_widget_grab_focus(user_data->dlg.draw_area);
-
-        SIGNAL_CONNECT(user_data->dlg.draw_area, "destroy", quit, user_data);
         OBJECT_SET_DATA(user_data->dlg.draw_area, "graph_analysis_data_t", user_data);
-
         WIDGET_SET_SIZE(user_data->dlg.draw_area, user_data->dlg.pixmap_width, user_data->dlg.pixmap_height);
 
         /* signals needed to handle backing pixmap */
         SIGNAL_CONNECT(user_data->dlg.draw_area, "expose_event", expose_event, NULL);
         SIGNAL_CONNECT(user_data->dlg.draw_area, "configure_event", configure_event, user_data);
+        /* signals needed to handle backing pixmap comments*/
+        SIGNAL_CONNECT(user_data->dlg.draw_area_comments, "expose_event", expose_event_comments, NULL);
+        SIGNAL_CONNECT(user_data->dlg.draw_area_comments, "configure_event", configure_event_comments, user_data);
 
-		gtk_widget_add_events (user_data->dlg.draw_area,
-			 GDK_BUTTON_PRESS_MASK);
+		gtk_widget_add_events (user_data->dlg.draw_area, GDK_BUTTON_PRESS_MASK);
 		SIGNAL_CONNECT(user_data->dlg.draw_area, "button_press_event", button_press_event, user_data);
 		SIGNAL_CONNECT(user_data->dlg.draw_area, "scroll_event",  scroll_event, user_data);
 		SIGNAL_CONNECT(user_data->dlg.draw_area, "key_press_event",  key_press_event, user_data);
-		
+
         gtk_widget_show(user_data->dlg.draw_area);
+		gtk_widget_show(user_data->dlg.draw_area_comments);
+		gtk_widget_show(viewport);
+	
         gtk_box_pack_start(GTK_BOX(vbox), user_data->dlg.draw_area, TRUE, TRUE, 0);
+		gtk_widget_show(scroll_window);
 
         /* create the associated h_scrollbar */
         user_data->dlg.h_scrollbar_adjustment=(GtkAdjustment *)gtk_adjustment_new(0,0,0,0,0,0);
@@ -908,6 +999,8 @@
 
         gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
 
+        gtk_box_pack_start(GTK_BOX(hbox), scroll_window, FALSE, FALSE, 0);
+
        /* create the associated v_scrollbar */
         user_data->dlg.v_scrollbar_adjustment=(GtkAdjustment *)gtk_adjustment_new(0,0,0,0,0,0);
         user_data->dlg.v_scrollbar=gtk_vscrollbar_new(user_data->dlg.v_scrollbar_adjustment);
@@ -944,6 +1037,7 @@
         window_set_cancel_button(user_data->dlg.window, bt_close, window_cancel_button_cb);
 
         SIGNAL_CONNECT(user_data->dlg.window, "delete_event", window_delete_event_cb, NULL);
+		SIGNAL_CONNECT(user_data->dlg.window, "destroy", on_destroy, user_data);
 
         gtk_widget_show(user_data->dlg.window);
         window_present(user_data->dlg.window);
Index: gtk/graph_analysis.h
===================================================================
--- gtk/graph_analysis.h	(revision 13505)
+++ gtk/graph_analysis.h	(working copy)
@@ -84,7 +84,9 @@
 	gboolean needs_redraw;
 	gint selected_row;
     GtkWidget *draw_area;
+	GtkWidget *draw_area_comments;
     GdkPixmap *pixmap;
+    GdkPixmap *pixmap_comments;
     GtkAdjustment *h_scrollbar_adjustment;
     GtkWidget *h_scrollbar;
 	GtkWidget *v_scrollbar;
Index: gtk/voip_calls.c
===================================================================
--- gtk/voip_calls.c	(revision 13505)
+++ gtk/voip_calls.c	(working copy)
@@ -10,7 +10,7 @@
  * Copyright 2004, Iskratel, Ltd, Kranj
  * By Miha Jemec <m.jemec@xxxxxxxxxxx>
  * 
- * H323, RTP and Graph Support
+ * H323, RTP, MGCP and Graph Support
  * By Alejandro Vaquero, alejandro.vaquero@xxxxxxxxx
  * Copyright 2005, Verso Technologies Inc.
  *
@@ -548,10 +548,12 @@
 
 			if ((strcmp(pi->request_method,"INVITE")==0)&&(ADDRESSES_EQUAL(&tmp_src,&(strinfo->initial_speaker)))){
 				tmp_sipinfo->invite_cseq = pi->tap_cseq_number;
+				strinfo->call_state = VOIP_CALL_SETUP;
 				comment = g_strdup_printf("SIP From: %s To:%s", strinfo->from_identity, strinfo->to_identity);
 			}
 			else if ((strcmp(pi->request_method,"ACK")==0)&&(pi->tap_cseq_number == tmp_sipinfo->invite_cseq)
-				&&(ADDRESSES_EQUAL(&tmp_src,&(strinfo->initial_speaker)))&&(tmp_sipinfo->sip_state==SIP_200_REC)){
+				&&(ADDRESSES_EQUAL(&tmp_src,&(strinfo->initial_speaker)))&&(tmp_sipinfo->sip_state==SIP_200_REC)
+				&&(strinfo->call_state == VOIP_CALL_SETUP)){
 				strinfo->call_state = VOIP_IN_CALL;
 				comment = g_strdup_printf("SIP Request");
 			}
@@ -1245,19 +1247,18 @@
 						strinfo->call_state=VOIP_REJECTED;
 						tapinfo->rejected_calls++;
 					}
+				} else {
+						strinfo->call_state=VOIP_COMPLETED;
+						tapinfo->completed_calls++;
 				}
-					else {
-						strinfo->call_state=VOIP_REJECTED;
-						tapinfo->rejected_calls++;
-					}
-					/* get the Q931 Release cause code */
-					if (q931_frame_num == pinfo->fd->num &&
-						q931_cause_value != 0xFF){		
-						comment = g_strdup_printf("H225 Q931 Rel Cause (%i):%s", q931_cause_value, val_to_str(q931_cause_value, q931_cause_code_vals, "<unknown>"));
-					} else {			/* Cause not set */
-						comment = g_strdup("H225 No Q931 Rel Cause");
-					}
-					break;
+				/* get the Q931 Release cause code */
+				if (q931_frame_num == pinfo->fd->num &&
+					q931_cause_value != 0xFF){		
+					comment = g_strdup_printf("H225 Q931 Rel Cause (%i):%s", q931_cause_value, val_to_str(q931_cause_value, q931_cause_code_vals, "<unknown>"));
+				} else {			/* Cause not set */
+					comment = g_strdup("H225 No Q931 Rel Cause");
+				}
+				break;
 			case H225_PROGRESS:
 			case H225_ALERTING:
 			case H225_CALL_PROCEDING: