EVERYTHING IN THE BUILDBOT IS GOING TO BE RED!!! Sorry!
[obnox/wireshark/wip.git] / gtk / voip_calls.c
index d69443fc1213d36a53467393527e1d333801dcdc..8d7b793fabc0ef5fa5d3dc33fe21c608d651918e 100644 (file)
@@ -10,7 +10,7 @@
  * Copyright 2004, Iskratel, Ltd, Kranj
  * By Miha Jemec <m.jemec@iskratel.si>
  * 
- * H323, RTP, MGCP and Graph Support
+ * H323, RTP, RTP Event, MGCP, AudioCodes (ISDN PRI and CAS) and Graph Support
  * By Alejandro Vaquero, alejandro.vaquero@verso.com
  * Copyright 2005, Verso Technologies Inc.
  *
 #include <epan/dissectors/packet-q931.h>
 #include <epan/dissectors/packet-sdp.h>
 #include <plugins/mgcp/packet-mgcp.h>
+#include <epan/dissectors/packet-actrace.h>
 #include <epan/dissectors/packet-rtp.h>
+#include <epan/dissectors/packet-rtp-events.h>
+#include <epan/conversation.h>
 #include "rtp_pt.h"
 
 #include "alert_box.h"
 #include "simple_dialog.h"
 
-char *voip_call_state_name[7]={
+const char *voip_call_state_name[7]={
        "CALL SETUP",
        "RINGING",
        "IN CALL",
@@ -71,23 +74,38 @@ char *voip_call_state_name[7]={
        };
 
 /* defines whether we can consider the call active */
-char *voip_protocol_name[4]={
+const char *voip_protocol_name[6]={
        "SIP",
        "ISUP",
        "H323",
-       "MGCP"
+       "MGCP",
+       "AC_ISDN",
+       "AC_CAS"
        };
 
+typedef struct {
+       gchar *frame_label;
+       gchar *comment;
+} graph_str;
+
+#define H245_MAX 6
+
+typedef struct {
+       guint32 frame_num;
+       gint8 labels_count;
+       graph_str labels[H245_MAX];
+} h245_labels_t;
 
+static h245_labels_t h245_labels;
 
 /****************************************************************************/
 /* the one and only global voip_calls_tapinfo_t structure */
 static voip_calls_tapinfo_t the_tapinfo_struct =
-       {0, NULL, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0};
+       {0, NULL, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 
 /* the one and only global voip_rtp_tapinfo_t structure */
 static voip_rtp_tapinfo_t the_tapinfo_rtp_struct =
-       {0, NULL, 0};
+       {0, NULL, 0, 0};
 
 /****************************************************************************/
 /* when there is a [re]reading of packet's */
@@ -172,15 +190,16 @@ void graph_analysis_data_init(void){
 
 /****************************************************************************/
 /* Add a new item into the graph */
-int add_to_graph(voip_calls_tapinfo_t *tapinfo _U_, packet_info *pinfo, gchar *frame_label, gchar *comment, guint16 call_num)
+static int add_to_graph(voip_calls_tapinfo_t *tapinfo _U_, packet_info *pinfo, const gchar *frame_label, gchar *comment, guint16 call_num, address *src_addr, address *dst_addr)
 {
        graph_analysis_item_t *gai;
 
        gai = g_malloc(sizeof(graph_analysis_item_t));
        gai->frame_num = pinfo->fd->num;
-       gai->time= (double)pinfo->fd->rel_secs + (double) pinfo->fd->rel_usecs/1000000;
-       COPY_ADDRESS(&(gai->src_addr),&(pinfo->src));
-       COPY_ADDRESS(&(gai->dst_addr),&(pinfo->dst));
+       gai->time= nstime_to_sec(&pinfo->fd->rel_ts);
+       COPY_ADDRESS(&(gai->src_addr),src_addr);
+       COPY_ADDRESS(&(gai->dst_addr),dst_addr);
+
        gai->port_src=pinfo->srcport;
        gai->port_dst=pinfo->destport;
        if (frame_label != NULL)
@@ -205,7 +224,7 @@ int add_to_graph(voip_calls_tapinfo_t *tapinfo _U_, packet_info *pinfo, gchar *f
 /****************************************************************************/
 /* Append str to frame_label and comment in a graph item */
 /* return 0 if the frame_num is not in the graph list */
-int append_to_frame_graph(voip_calls_tapinfo_t *tapinfo _U_, guint32 frame_num, const gchar *new_frame_label, const gchar *new_comment)
+static int append_to_frame_graph(voip_calls_tapinfo_t *tapinfo _U_, guint32 frame_num, const gchar *new_frame_label, const gchar *new_comment)
 {
        graph_analysis_item_t *gai;
        GList* list;
@@ -239,9 +258,45 @@ int append_to_frame_graph(voip_calls_tapinfo_t *tapinfo _U_, guint32 frame_num,
 
 }
 
+/****************************************************************************/
+/* Change the frame_label and comment in a graph item if not NULL*/
+/* return 0 if the frame_num is not in the graph list */
+static int change_frame_graph(voip_calls_tapinfo_t *tapinfo _U_, guint32 frame_num, const gchar *new_frame_label, const gchar *new_comment)
+{
+       graph_analysis_item_t *gai;
+       GList* list;
+       gchar *tmp_str = NULL;
+       gchar *tmp_str2 = NULL;
+
+       list = g_list_first(tapinfo->graph_analysis->list);
+       while (list)
+       {
+               gai = list->data;
+               if (gai->frame_num == frame_num){
+                       tmp_str = gai->frame_label;
+                       tmp_str2 = gai->comment;
+
+                       if (new_frame_label != NULL){
+                               gai->frame_label = g_strdup(new_frame_label);
+                               g_free(tmp_str);
+                       }
+
+                       if (new_comment != NULL){
+                               gai->comment = g_strdup(new_comment);
+                               g_free(tmp_str2);
+                       }
+                       break;
+               }
+               list = g_list_next (list);
+       }
+       if (tmp_str == NULL) return 0;          /* it is not in the list */
+       return 1;
+
+}
+
 /****************************************************************************/
 /* Change all the graph items with call_num to new_call_num */
-guint change_call_num_graph(voip_calls_tapinfo_t *tapinfo _U_, guint16 call_num, guint16 new_call_num)
+static guint change_call_num_graph(voip_calls_tapinfo_t *tapinfo _U_, guint16 call_num, guint16 new_call_num)
 {
        graph_analysis_item_t *gai;
        GList* list;
@@ -261,13 +316,95 @@ guint change_call_num_graph(voip_calls_tapinfo_t *tapinfo _U_, guint16 call_num,
        return items_changed;
 }
 
+/* XXX just copied from gtk/rpc_stat.c */
+void protect_thread_critical_region(void);
+void unprotect_thread_critical_region(void);
+
+/****************************************************************************/
+/* ***************************TAP for RTP Events*****************************/
+/****************************************************************************/
+
+/****************************************************************************/
+/* whenever a rtp event packet is seen by the tap listener */
+static int 
+rtp_event_packet(void *ptr _U_, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *rtp_event_info)
+{
+       const struct _rtp_event_info *pi = rtp_event_info;
+       voip_rtp_tapinfo_t *tapinfo = &the_tapinfo_rtp_struct;
+       voip_rtp_stream_info_t *tmp_listinfo;
+       voip_rtp_stream_info_t *strinfo = NULL;
+       GList* list;
+
+       /* do not consider RTP events packets without a setup frame */
+       if (pi->info_setup_frame_num == 0){
+               return 0;
+       }
+
+       /* check wether we already have a RTP stream with this setup frame in the list */
+       list = g_list_first(tapinfo->list);
+       while (list)
+       {
+               tmp_listinfo=list->data;
+               if ( (tmp_listinfo->setup_frame_number == pi->info_setup_frame_num) 
+                       && (tmp_listinfo->end_stream == FALSE) && (tmp_listinfo->rtp_event == -1)){
+                               strinfo = (voip_rtp_stream_info_t*)(list->data);
+                               strinfo->rtp_event = pi->info_rtp_evt;
+                               break;
+               }
+               list = g_list_next (list);
+       }
+
+
+       return 0;
+}
+
+/****************************************************************************/
+static gboolean have_rtp_event_tap_listener=FALSE;
+
+void
+rtp_event_init_tap(void)
+{
+       GString *error_string;
+
+
+       if(have_rtp_event_tap_listener==FALSE)
+       {
+               error_string = register_tap_listener("rtpevent", &(the_tapinfo_rtp_struct.rtp_event_dummy),
+                       NULL,
+                       NULL,
+                       rtp_event_packet,
+                       NULL
+                       );
+                       
+               if (error_string != NULL) {
+                       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                                     error_string->str);
+                       g_string_free(error_string, TRUE);
+                       exit(1);
+               }
+               have_rtp_event_tap_listener=TRUE;
+       }
+}
+
+/****************************************************************************/
+
+void
+remove_tap_listener_rtp_event(void)
+{
+       protect_thread_critical_region();
+       remove_tap_listener(&(the_tapinfo_rtp_struct.rtp_event_dummy));
+       unprotect_thread_critical_region();
+
+       have_rtp_event_tap_listener=FALSE;
+}
+
 /****************************************************************************/
 /* ***************************TAP for RTP **********************************/
 /****************************************************************************/
 
 /****************************************************************************/
 /* when there is a [re]reading of RTP packet's */
-void voip_rtp_reset(void *ptr _U_)
+static void voip_rtp_reset(void *ptr _U_)
 {
        voip_rtp_tapinfo_t *tapinfo = &the_tapinfo_rtp_struct;
        GList* list;
@@ -293,6 +430,7 @@ RTP_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const vo
        voip_rtp_stream_info_t *tmp_listinfo;
        voip_rtp_stream_info_t *strinfo = NULL;
        GList* list;
+       struct _rtp_conversation_info *p_conv_data = NULL;
 
        const struct _rtp_info *pi = RTPinfo;
 
@@ -330,26 +468,39 @@ RTP_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const vo
                strinfo->ssrc = pi->info_sync_src;
                strinfo->end_stream = FALSE;
                strinfo->pt = pi->info_payload_type;
+               strinfo->pt_str = NULL;
+               /* if it is dynamic payload, let use the conv data to see if it is defined */
+               if ( (strinfo->pt>95) && (strinfo->pt<128) ) {
+                       /* Use existing packet info if available */
+                       p_conv_data = p_get_proto_data(pinfo->fd, proto_get_id_by_filter_name("rtp"));
+                       if (p_conv_data)
+                               strinfo->pt_str = g_strdup(g_hash_table_lookup(p_conv_data->rtp_dyn_payload, &strinfo->pt));
+               }
+               if (!strinfo->pt_str) strinfo->pt_str = g_strdup(val_to_str(strinfo->pt, rtp_payload_type_short_vals, "%u"));
                strinfo->npackets = 0;
                strinfo->first_frame_num = pinfo->fd->num;
-               strinfo->start_rel_sec = pinfo->fd->rel_secs;
-               strinfo->start_rel_usec = pinfo->fd->rel_usecs;
+               strinfo->start_rel_sec = pinfo->fd->rel_ts.secs;
+               strinfo->start_rel_usec = pinfo->fd->rel_ts.nsecs/1000;
                strinfo->setup_frame_number = pi->info_setup_frame_num;
+               strinfo->rtp_event = -1;
                tapinfo->list = g_list_append(tapinfo->list, strinfo);
        }
 
        if (strinfo!=NULL){
                /* Add the info to the existing RTP stream */
                strinfo->npackets++;
-               strinfo->stop_rel_sec = pinfo->fd->rel_secs;
-               strinfo->stop_rel_usec = pinfo->fd->rel_usecs;
+               strinfo->stop_rel_sec = pinfo->fd->rel_ts.secs;
+               strinfo->stop_rel_usec = pinfo->fd->rel_ts.nsecs/1000;
        }
+
+       the_tapinfo_struct.redraw = TRUE;
+
        return 1;
 }
 
 /****************************************************************************/
 /* whenever a redraw in the RTP tap listener */
-void RTP_packet_draw(void *prs _U_)
+static void RTP_packet_draw(void *prs _U_)
 {
        voip_rtp_tapinfo_t *rtp_tapinfo = &the_tapinfo_rtp_struct;
        GList* rtp_streams_list;
@@ -394,7 +545,8 @@ void RTP_packet_draw(void *prs _U_)
                                                new_gai->port_src = rtp_listinfo->src_port;
                                                new_gai->port_dst = rtp_listinfo->dest_port;
                                                duration = (rtp_listinfo->stop_rel_sec*1000000 + rtp_listinfo->stop_rel_usec) - (rtp_listinfo->start_rel_sec*1000000 + rtp_listinfo->start_rel_usec);
-                                               new_gai->frame_label = g_strdup_printf("RTP (%s)", val_to_str(rtp_listinfo->pt, rtp_payload_type_short_vals, "%u"));
+                                               new_gai->frame_label = g_strdup_printf("RTP (%s) %s", rtp_listinfo->pt_str, (rtp_listinfo->rtp_event == -1)?"":val_to_str(rtp_listinfo->rtp_event, rtp_event_type_values, "Uknown RTP Event")); 
+                                               g_free(rtp_listinfo->pt_str);
                                                new_gai->comment = g_strdup_printf("RTP Num packets:%d  Duration:%d.%03ds ssrc:%d", rtp_listinfo->npackets, duration/1000000,(duration%1000000)/1000, rtp_listinfo->ssrc);
                                                new_gai->conv_num = conv_num;
                                                new_gai->display=FALSE;
@@ -440,12 +592,6 @@ rtp_init_tap(void)
        }
 }
 
-
-
-/* XXX just copied from gtk/rpc_stat.c */
-void protect_thread_critical_region(void);
-void unprotect_thread_critical_region(void);
-
 /****************************************************************************/
 void
 remove_tap_listener_rtp(void)
@@ -457,6 +603,10 @@ remove_tap_listener_rtp(void)
        have_RTP_tap_listener=FALSE;
 }
 
+/****************************************************************************/
+static gchar *sdp_summary = NULL;
+static guint32 sdp_frame_num = 0;
+
 /****************************************************************************/
 /* ***************************TAP for SIP **********************************/
 /****************************************************************************/
@@ -511,8 +661,8 @@ SIPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, con
                        COPY_ADDRESS(&(strinfo->initial_speaker),&(pinfo->src));
                        strinfo->first_frame_num=pinfo->fd->num;
                        strinfo->selected=FALSE;
-                       strinfo->start_sec=pinfo->fd->rel_secs;
-                       strinfo->start_usec=pinfo->fd->rel_usecs;
+                       strinfo->start_sec=pinfo->fd->rel_ts.secs;
+                       strinfo->start_usec=pinfo->fd->rel_ts.nsecs/1000;
                        strinfo->protocol=VOIP_SIP;
                        strinfo->prot_info=g_malloc(sizeof(sip_calls_info_t));
                        tmp_sipinfo=strinfo->prot_info;
@@ -525,10 +675,6 @@ SIPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, con
                }
        }
 
-       g_free(pi->tap_from_addr);
-       g_free(pi->tap_to_addr);
-       g_free(pi->tap_call_id);
-
        if (strinfo!=NULL){
 
                /* let's analyze the call state */
@@ -580,26 +726,36 @@ SIPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, con
                        }
                }
 
-               strinfo->stop_sec=pinfo->fd->rel_secs;
-               strinfo->stop_usec=pinfo->fd->rel_usecs;
+               strinfo->stop_sec=pinfo->fd->rel_ts.secs;
+               strinfo->stop_usec=pinfo->fd->rel_ts.nsecs/1000;
                strinfo->last_frame_num=pinfo->fd->num;
                ++(strinfo->npackets);
                /* increment the packets counter of all calls */
                ++(tapinfo->npackets);
 
                /* add to the graph */
-               add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num);  
+               add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num, &(pinfo->src), &(pinfo->dst));  
                g_free(comment);
                g_free(frame_label);
                g_free((void *)tmp_src.data);
                g_free((void *)tmp_dst.data);
+
+               /* add SDP info if apply */
+               if ( (sdp_summary != NULL) && (sdp_frame_num == pinfo->fd->num) ){
+                               append_to_frame_graph(tapinfo, pinfo->fd->num, sdp_summary, NULL);
+                               g_free(sdp_summary);
+                               sdp_summary = NULL;
+               }
        }
+
+       tapinfo->redraw = TRUE;
+
        return 1;  /* refresh output */
 }
 
 
 /****************************************************************************/
-const voip_calls_tapinfo_t* voip_calls_get_info(void)
+voip_calls_tapinfo_t* voip_calls_get_info(void)
 {
        return &the_tapinfo_struct;
 }
@@ -654,86 +810,15 @@ remove_tap_listener_sip_calls(void)
 /* ***************************TAP for ISUP **********************************/
 /****************************************************************************/
 
-static gchar           isup_called_number[255], isup_calling_number[255];
-static guint16         isup_cic;
-static guint8          isup_message_type;
-static guint8          isup_cause_value;
-static guint32         isup_frame_num;
+static guint32         mtp3_opc, mtp3_dpc;
+static guint8          mtp3_ni;
+static         guint32         mtp3_frame_num;
+
 
 /****************************************************************************/
 /* whenever a isup_ packet is seen by the tap listener */
 static int 
 isup_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *isup_info _U_)
-{
-       /*voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct; unused */
-       const isup_tap_rec_t *pi = isup_info;
-
-       if (pi->calling_number!=NULL){
-               strcpy(isup_calling_number, pi->calling_number);
-       }
-       if (pi->called_number!=NULL){
-               strcpy(isup_called_number, pi->called_number);
-       }
-       isup_message_type = pi->message_type;
-       isup_cause_value = pi->cause_value;
-       isup_cic = pinfo->circuit_id;
-
-       isup_frame_num = pinfo->fd->num;
-       
-       return 0;
-}
-
-/****************************************************************************/
-
-static gboolean have_isup_tap_listener=FALSE;
-
-void
-isup_calls_init_tap(void)
-{
-       GString *error_string;
-
-
-       if(have_isup_tap_listener==FALSE)
-       {
-               error_string = register_tap_listener("isup", &(the_tapinfo_struct.isup_dummy),
-                       NULL,
-                       voip_calls_dlg_reset, 
-                       isup_calls_packet, 
-                       voip_calls_dlg_draw
-                       );
-       
-               if (error_string != NULL) {
-                       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                                     error_string->str);
-                       g_string_free(error_string, TRUE);
-                       exit(1);
-               }
-               have_isup_tap_listener=TRUE;
-       }
-}
-
-/****************************************************************************/
-
-void
-remove_tap_listener_isup_calls(void)
-{
-       protect_thread_critical_region();
-       remove_tap_listener(&(the_tapinfo_struct.isup_dummy));
-       unprotect_thread_critical_region();
-
-       have_isup_tap_listener=FALSE;
-}
-
-
-/****************************************************************************/
-/* ***************************TAP for MTP3 **********************************/
-/****************************************************************************/
-
-
-/****************************************************************************/
-/* whenever a mtp3_ packet is seen by the tap listener */
-static int 
-mtp3_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *mtp3_info _U_)
 {
        voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
        voip_calls_info_t *tmp_listinfo;
@@ -741,33 +826,35 @@ mtp3_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, co
        isup_calls_info_t *tmp_isupinfo;
        gboolean found = FALSE;
        gboolean forward = FALSE;
-       gboolean right_pair = TRUE;
+       gboolean right_pair;
        GList* list;
        gchar *frame_label = NULL;
        gchar *comment = NULL;
        int i;
 
-       const mtp3_tap_rec_t *pi = mtp3_info;
+       /*voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct; unused */
+       const isup_tap_rec_t *pi = isup_info;
+
 
-       /* check if the upper layer is ISUP matching the frame number */
-       if (isup_frame_num != pinfo->fd->num) return 0;
+       /* check if the lower layer is MTP matching the frame number */
+       if (mtp3_frame_num != pinfo->fd->num) return 0;
        
        /* check wether we already have a call with these parameters in the list */
        list = g_list_first(tapinfo->strinfo_list);
        while (list)
        {
+               right_pair = TRUE;
                tmp_listinfo=list->data;
                if ((tmp_listinfo->protocol == VOIP_ISUP)&&(tmp_listinfo->call_active_state==VOIP_ACTIVE)){
                        tmp_isupinfo = tmp_listinfo->prot_info;
-                       if ((tmp_isupinfo->cic == isup_cic)&&(tmp_isupinfo->ni == pi->addr_opc.ni)) {
-                               if ((tmp_isupinfo->opc == pi->addr_opc.pc)&&(tmp_isupinfo->dpc == pi->addr_dpc.pc)){
+                       if ((tmp_isupinfo->cic == pinfo->circuit_id)&&(tmp_isupinfo->ni == mtp3_ni)) {
+                               if ((tmp_isupinfo->opc == mtp3_opc)&&(tmp_isupinfo->dpc == mtp3_dpc)){
                                         forward = TRUE;
                                 }
-                                else if ((tmp_isupinfo->dpc == pi->addr_opc.pc)&&(tmp_isupinfo->opc == pi->addr_dpc.pc)){
+                                else if ((tmp_isupinfo->dpc == mtp3_opc)&&(tmp_isupinfo->opc == mtp3_dpc)){
                                         forward = FALSE;
                                 }
                                 else{
-                                        /* XXX: what about forward is it FALSE as declared or should it be true */
                                         right_pair = FALSE;
                                 }
                                 if (right_pair){
@@ -776,7 +863,7 @@ mtp3_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, co
                                        if (tmp_listinfo->call_state == VOIP_CALL_SETUP){
                                                found = TRUE;
                                        }
-                                       else if (isup_message_type != 1){
+                                       else if (pi->message_type != 1){
                                                found = TRUE;
                                        }
                                        else{
@@ -796,7 +883,7 @@ mtp3_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, co
           -i.e. if this session is a call*/
 
 
-       if ((strinfo==NULL) &&(isup_message_type==1)){
+       if ((strinfo==NULL) &&(pi->message_type==1)){
 
                strinfo = g_malloc(sizeof(voip_calls_info_t));
                strinfo->call_active_state = VOIP_ACTIVE;
@@ -804,16 +891,20 @@ mtp3_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, co
                COPY_ADDRESS(&(strinfo->initial_speaker),&(pinfo->src));
                strinfo->selected=FALSE;
                strinfo->first_frame_num=pinfo->fd->num;
-               strinfo->start_sec=pinfo->fd->rel_secs;
-               strinfo->start_usec=pinfo->fd->rel_usecs;
+               strinfo->start_sec=pinfo->fd->rel_ts.secs;
+               strinfo->start_usec=pinfo->fd->rel_ts.nsecs/1000;
                strinfo->protocol=VOIP_ISUP;
-               strinfo->from_identity=g_strdup(isup_calling_number);
-               strinfo->to_identity=g_strdup(isup_called_number);
+               if (pi->calling_number!=NULL){
+                       strinfo->from_identity=g_strdup(pi->calling_number);
+               }
+               if (pi->called_number!=NULL){
+                       strinfo->to_identity=g_strdup(pi->called_number);
+               }
                strinfo->prot_info=g_malloc(sizeof(isup_calls_info_t));
                tmp_isupinfo=strinfo->prot_info;
-               tmp_isupinfo->opc = pi->addr_opc.pc;
-               tmp_isupinfo->dpc = pi->addr_dpc.pc;
-               tmp_isupinfo->ni = pi->addr_opc.ni;
+               tmp_isupinfo->opc = mtp3_opc;
+               tmp_isupinfo->dpc = mtp3_dpc;
+               tmp_isupinfo->ni = mtp3_ni;
                tmp_isupinfo->cic = pinfo->circuit_id;
                strinfo->npackets = 0;
                strinfo->call_num = tapinfo->ncalls++;
@@ -821,17 +912,17 @@ mtp3_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, co
        }
 
        if (strinfo!=NULL){
-               strinfo->stop_sec=pinfo->fd->rel_secs;
-               strinfo->stop_usec=pinfo->fd->rel_usecs;
+               strinfo->stop_sec=pinfo->fd->rel_ts.secs;
+               strinfo->stop_usec=pinfo->fd->rel_ts.nsecs/1000;
                strinfo->last_frame_num=pinfo->fd->num;
                ++(strinfo->npackets);
 
                /* Let's analyze the call state */
 
 
-               for (i=0;(isup_message_type_value[i].strptr!=NULL)&& (isup_message_type_value[i].value!=isup_message_type);i++);
+               for (i=0;(isup_message_type_value[i].strptr!=NULL)&& (isup_message_type_value[i].value!=pi->message_type);i++);
 
-               if (isup_message_type_value[i].value==isup_message_type){
+               if (isup_message_type_value[i].value==pi->message_type){
                        frame_label = g_strdup(isup_message_type_value_acro[i].strptr);
                }
                else{
@@ -839,25 +930,27 @@ mtp3_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, co
                }
 
                if (strinfo->npackets == 1){ /* this is the first packet, that must be an IAM */
-                       comment = g_strdup_printf("Call from %s to %s",
-                        isup_calling_number, isup_called_number);
+                       if ((pi->calling_number!=NULL)&&(pi->called_number !=NULL)){
+                               comment = g_strdup_printf("Call from %s to %s",
+                                pi->calling_number, pi->called_number);
+                        }
                }
                else if (strinfo->npackets == 2){ /* in the second packet we show the SPs */
                        if (forward){
                                comment = g_strdup_printf("%i-%i -> %i-%i. Cic:%i",
-                                pi->addr_opc.ni, pi->addr_opc.pc,
-                                pi->addr_opc.ni, pi->addr_dpc.pc, pinfo->circuit_id);
+                                mtp3_ni, mtp3_opc,
+                                mtp3_ni, mtp3_dpc, pinfo->circuit_id);
 
                        }
                        else{
                                comment = g_strdup_printf("%i-%i -> %i-%i. Cic:%i",
-                                pi->addr_opc.ni, pi->addr_dpc.pc,
-                                pi->addr_opc.ni, pi->addr_opc.pc, pinfo->circuit_id);
+                                mtp3_ni, mtp3_dpc,
+                                mtp3_ni, mtp3_opc, pinfo->circuit_id);
 
                        }
                }
 
-               switch(isup_message_type){
+               switch(pi->message_type){
                        case 1: /* IAM */
                                strinfo->call_state=VOIP_CALL_SETUP;
                                break;
@@ -879,12 +972,12 @@ mtp3_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, co
                                        strinfo->call_state = VOIP_COMPLETED;
                                        tapinfo->completed_calls++;
                                }
-                               for (i=0;(q931_cause_code_vals[i].strptr!=NULL)&& (q931_cause_code_vals[i].value!=isup_cause_value);i++);
-                               if (q931_cause_code_vals[i].value==isup_cause_value){
-                                       comment = g_strdup_printf("Cause %i - %s",isup_cause_value, q931_cause_code_vals[i].strptr);
+                               for (i=0;(q931_cause_code_vals[i].strptr!=NULL)&& (q931_cause_code_vals[i].value!=pi->cause_value);i++);
+                               if (q931_cause_code_vals[i].value==pi->cause_value){
+                                       comment = g_strdup_printf("Cause %i - %s",pi->cause_value, q931_cause_code_vals[i].strptr);
                                }
                                else{
-                                       comment = g_strdup_printf("Cause %i",isup_cause_value);
+                                       comment = g_strdup_printf("Cause %i",pi->cause_value);
                                }
                                break;
                }
@@ -893,13 +986,78 @@ mtp3_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, co
                ++(tapinfo->npackets);
 
                /* add to the graph */
-               add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num);  
+               add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num, &(pinfo->src), &(pinfo->dst));  
                g_free(comment);
                g_free(frame_label);
        }
 
+       tapinfo->redraw = TRUE;
 
-       return 1;
+       return 1;  /* refresh output */
+}
+
+/****************************************************************************/
+
+static gboolean have_isup_tap_listener=FALSE;
+
+void
+isup_calls_init_tap(void)
+{
+       GString *error_string;
+
+
+       if(have_isup_tap_listener==FALSE)
+       {
+               error_string = register_tap_listener("isup", &(the_tapinfo_struct.isup_dummy),
+                       NULL,
+                       voip_calls_dlg_reset, 
+                       isup_calls_packet, 
+                       voip_calls_dlg_draw
+                       );
+       
+               if (error_string != NULL) {
+                       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                                     error_string->str);
+                       g_string_free(error_string, TRUE);
+                       exit(1);
+               }
+               have_isup_tap_listener=TRUE;
+       }
+}
+
+/****************************************************************************/
+
+void
+remove_tap_listener_isup_calls(void)
+{
+       protect_thread_critical_region();
+       remove_tap_listener(&(the_tapinfo_struct.isup_dummy));
+       unprotect_thread_critical_region();
+
+       have_isup_tap_listener=FALSE;
+}
+
+
+/****************************************************************************/
+/* ***************************TAP for MTP3 **********************************/
+/****************************************************************************/
+
+
+/****************************************************************************/
+/* whenever a mtp3_ packet is seen by the tap listener */
+static int 
+mtp3_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *mtp3_info _U_)
+{
+       const mtp3_tap_rec_t *pi = mtp3_info;
+
+       /* keep the data in memory to use when the ISUP information arrives */
+
+       mtp3_opc = pi->addr_opc.pc;
+       mtp3_dpc = pi->addr_dpc.pc;
+       mtp3_ni = pi->addr_opc.ni;
+       mtp3_frame_num = pinfo->fd->num;
+
+       return 0;
 }
 
 /****************************************************************************/
@@ -931,54 +1089,300 @@ mtp3_calls_init_tap(void)
        }
 }
 
-/****************************************************************************/
+/****************************************************************************/
+
+void
+remove_tap_listener_mtp3_calls(void)
+{
+       protect_thread_critical_region();
+       remove_tap_listener(&(the_tapinfo_struct.mtp3_dummy));
+       unprotect_thread_critical_region();
+
+       have_mtp3_tap_listener=FALSE;
+}
+
+/****************************************************************************/
+/* ***************************TAP for Q931 **********************************/
+/****************************************************************************/
+void h245_add_to_graph(guint32 new_frame_num);
+#define GUID_LEN       16
+static const guint8 guid_allzero[GUID_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+/* defines specific H323 data */
+
+static gchar *q931_calling_number;
+static gchar *q931_called_number;
+static guint8 q931_cause_value;
+static gint32 q931_crv;
+static guint32 q931_frame_num;
+
+static guint32 h225_frame_num = 0;
+static guint16 h225_call_num = 0;
+static h225_cs_type h225_cstype = H225_OTHER;
+static gboolean h225_is_faststart;
+
+static guint32 actrace_frame_num = 0;
+static gint32 actrace_trunk = 0;
+static gint32 actrace_direction = 0;
+
+
+/****************************************************************************/
+/* whenever a q931_ packet is seen by the tap listener */
+static int 
+q931_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *q931_info _U_)
+{
+       GList *list,*list2;
+       voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct; 
+       h323_calls_info_t *tmp_h323info,*tmp2_h323info;
+       actrace_isdn_calls_info_t *tmp_actrace_isdn_info;
+       voip_calls_info_t *tmp_listinfo;
+       voip_calls_info_t *strinfo = NULL;
+       h245_address_t *h245_add = NULL;
+       gchar *comment;
+
+       const q931_packet_info *pi = q931_info;
+
+       /* free previously allocated q931_calling/ed_number */
+       g_free(q931_calling_number);
+       g_free(q931_called_number);
+       
+       if (pi->calling_number!=NULL)
+               q931_calling_number = g_strdup(pi->calling_number);
+       else
+               q931_calling_number = g_strdup("");
+
+       if (pi->called_number!=NULL)
+               q931_called_number = g_strdup(pi->called_number);
+       else
+               q931_called_number = g_strdup("");
+       q931_cause_value = pi->cause_value;
+       q931_frame_num = pinfo->fd->num;
+       q931_crv = pi->crv;
+
+
+       /* add staff to H323 calls */
+       if (h225_frame_num == q931_frame_num) {
+               tmp_h323info = NULL;
+               list = g_list_first(tapinfo->strinfo_list);
+               while (list)
+               {
+                       tmp_listinfo=list->data;
+                       if ( (tmp_listinfo->protocol == VOIP_H323) && (tmp_listinfo->call_num == h225_call_num) ){
+                               tmp_h323info = tmp_listinfo->prot_info;
+                               strinfo = (voip_calls_info_t*)(list->data);
+
+                               /* Add the CRV to the h323 call */
+                               if (tmp_h323info->q931_crv == -1) {
+                                       tmp_h323info->q931_crv = q931_crv;
+                               } else if (tmp_h323info->q931_crv != q931_crv) {
+                                       tmp_h323info->q931_crv2 = q931_crv;
+                               }
+                               break;
+                       }
+                       list = g_list_next (list);
+               }
+
+               if (strinfo != NULL) {
+                       comment = NULL;
+                       if (h225_cstype == H225_SETUP) {
+                               /* set te calling and called number from the Q931 packet */
+                               if (q931_calling_number != NULL){
+                                       g_free(strinfo->from_identity);
+                                       strinfo->from_identity=g_strdup(q931_calling_number);
+                               }
+                               if (q931_called_number != NULL){
+                                       g_free(strinfo->to_identity);
+                                       strinfo->to_identity=g_strdup(q931_called_number);
+                               }
+
+                               /* check if there is an LRQ/LCF that match this Setup */
+                               /* TODO: we are just checking the DialedNumer in LRQ/LCF agains the Setup 
+                                       we should also check if the h225 signaling IP and port match the destination 
+                                       Setup ip and port */
+                               list = g_list_first(tapinfo->strinfo_list);
+                               while (list)
+                               {
+                                       tmp_listinfo=list->data;
+                                       if (tmp_listinfo->protocol == VOIP_H323){
+                                               tmp2_h323info = tmp_listinfo->prot_info;
+                                               
+                                               /* check if the called number match a LRQ/LCF */
+                                               if ( (strcmp(strinfo->to_identity, tmp_listinfo->to_identity)==0)  
+                                                        && (memcmp(tmp2_h323info->guid, guid_allzero, GUID_LEN) == 0) ){ 
+                                                       /* change the call graph to the LRQ/LCF to belong to this call */
+                                                       strinfo->npackets += change_call_num_graph(tapinfo, tmp_listinfo->call_num, strinfo->call_num);
+                                                       
+                                                       /* remove this LRQ/LCF call entry because we have found the Setup that match them */
+                                                       g_free(tmp_listinfo->from_identity);
+                                                       g_free(tmp_listinfo->to_identity);
+                                                       g_free(tmp2_h323info->guid);
+                                                       
+                                                       list2 = g_list_first(tmp2_h323info->h245_list);
+                                                       while (list2)
+                                                       {
+                                                               h245_add=list2->data;
+                                                               g_free((void *)h245_add->h245_address.data);
+                                                               g_free(list2->data);
+                                                               list2 = g_list_next(list2);
+                                                       }
+                                                       g_list_free(tmp_h323info->h245_list);
+                                                       tmp_h323info->h245_list = NULL;
+                                                       g_free(tmp_listinfo->prot_info);
+                                                       tapinfo->strinfo_list = g_list_remove(tapinfo->strinfo_list, tmp_listinfo);
+                                                       break;
+                                               }
+                                       }
+                               list = g_list_next (list);
+                               }
+
+                               comment = g_strdup_printf("H225 From: %s To:%s  TunnH245:%s FS:%s", strinfo->from_identity, strinfo->to_identity, (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"), 
+                                                         (h225_is_faststart==TRUE?"on":"off"));
+                       } else if (h225_cstype == H225_RELEASE_COMPLET) {
+                               /* get the Q931 Release cause code */
+                               if (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");
+                               }
+                       }
+                       /* change the graph comment for this new one */
+                       if (comment != NULL) {
+                               change_frame_graph(tapinfo, h225_frame_num, NULL, comment);
+                               g_free(comment);
+                       }
+               }
+               /* we reset the h225_frame_num to 0 because there could be empty h225 in the same frame
+                  as non empty h225 (e.g connect), so we don't have to be here twice */
+               h225_frame_num = 0;
+
+       /* add staff to H245 */
+       } else if (h245_labels.frame_num == q931_frame_num) {
+       /* there are empty H225 frames that don't have guid (guaid=0) but they have h245 info, 
+          so the only way to match those frames is with the Q931 CRV number */ 
+               list = g_list_first(tapinfo->strinfo_list);
+               while (list)
+               {
+                       tmp_listinfo=list->data;
+                       if (tmp_listinfo->protocol == VOIP_H323){
+                               tmp_h323info = tmp_listinfo->prot_info;
+                               if ( ((tmp_h323info->q931_crv == q931_crv) || (tmp_h323info->q931_crv2 == q931_crv)) && (q931_crv!=-1)){
+
+                                       comment = g_strdup("");
+
+                                       /* if the frame number exists in graph, append to it*/
+                                       if (!append_to_frame_graph(tapinfo, q931_frame_num, "", comment)) {
+                                               /* if not exist, add to the graph */
+                                               add_to_graph(tapinfo, pinfo, "", comment, tmp_listinfo->call_num, &(pinfo->src), &(pinfo->dst));
+                                               ++(tmp_listinfo->npackets);
+                                               /* increment the packets counter of all calls */
+                                               ++(tapinfo->npackets);
+                                       }
+                                       
+                                       /* Add the H245 info if exists to the Graph */
+                                       h245_add_to_graph(pinfo->fd->num);
+                                       g_free(comment);
+                                       break;
+                               }
+                       }
+                       list = g_list_next (list);
+               }
+
+       /* add staff to ACTRACE */
+       } else if (actrace_frame_num == q931_frame_num) {
+               address pstn_add;
+               gchar *comment = NULL;
+
+               strinfo = NULL;
+               list = g_list_first(tapinfo->strinfo_list);
+               while (list)
+               {
+                       tmp_listinfo=list->data;
+                       if ( tmp_listinfo->protocol == VOIP_AC_ISDN ){
+                               tmp_actrace_isdn_info = tmp_listinfo->prot_info;
+                               /* TODO: Also check the IP of the Blade, and if the call is complete (no active) */
+                               if ( (tmp_actrace_isdn_info->crv == q931_crv) && (tmp_actrace_isdn_info->trunk == actrace_trunk) ) {
+                                       strinfo = (voip_calls_info_t*)(list->data);
+                                       break;
+                               }
+                       }
+                       list = g_list_next (list);
+               }
+
+               SET_ADDRESS(&pstn_add, AT_STRINGZ, 5, g_strdup("PSTN"));
 
-void
-remove_tap_listener_mtp3_calls(void)
-{
-       protect_thread_critical_region();
-       remove_tap_listener(&(the_tapinfo_struct.mtp3_dummy));
-       unprotect_thread_critical_region();
+               /* if it is a new call, add it to the list */
+               if (!strinfo) {
+                       strinfo = g_malloc(sizeof(voip_calls_info_t));
+                       strinfo->call_active_state = VOIP_ACTIVE;
+                       strinfo->call_state = VOIP_CALL_SETUP;
+                       strinfo->from_identity=g_strdup(q931_calling_number);
+                       strinfo->to_identity=g_strdup(q931_called_number);
+                       COPY_ADDRESS(&(strinfo->initial_speaker),actrace_direction?&pstn_add:&(pinfo->src));
+                       strinfo->first_frame_num=pinfo->fd->num;
+                       strinfo->selected=FALSE;
+                       strinfo->start_sec=pinfo->fd->rel_ts.secs;
+                       strinfo->start_usec=pinfo->fd->rel_ts.nsecs/1000;
+                       strinfo->protocol=VOIP_AC_ISDN;
+                       strinfo->prot_info=g_malloc(sizeof(actrace_isdn_calls_info_t));
+                       tmp_actrace_isdn_info=strinfo->prot_info;
+                       tmp_actrace_isdn_info->crv=q931_crv;
+                       tmp_actrace_isdn_info->trunk=actrace_trunk;
+                       strinfo->npackets = 0;
+                       strinfo->call_num = tapinfo->ncalls++;
+                       tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
+               }
 
-       have_mtp3_tap_listener=FALSE;
-}
+               strinfo->stop_sec=pinfo->fd->rel_ts.secs;
+               strinfo->stop_usec=pinfo->fd->rel_ts.nsecs/1000;
+               strinfo->last_frame_num=pinfo->fd->num;
+               ++(strinfo->npackets);
+               /* increment the packets counter of all calls */
+               ++(tapinfo->npackets);
 
-/****************************************************************************/
-/* ***************************TAP for Q931 **********************************/
-/****************************************************************************/
+               switch(pi->message_type){
+               case Q931_SETUP:
+                       comment = g_strdup_printf("AC_ISDN trunk:%u Calling: %s  Called:%s", actrace_trunk, q931_calling_number, q931_called_number);
+                       strinfo->call_state=VOIP_CALL_SETUP;
+                       break;
+               case Q931_CONNECT:
+                       strinfo->call_state=VOIP_IN_CALL;
+                       break;
+               case Q931_RELEASE_COMPLETE:
+               case Q931_RELEASE:
+               case Q931_DISCONNECT:
+                       if (strinfo->call_state==VOIP_CALL_SETUP){
+                               if (ADDRESSES_EQUAL(&(strinfo->initial_speaker), actrace_direction?&pstn_add:&(pinfo->src) )){  /* forward direction */
+                                       strinfo->call_state=VOIP_CANCELLED;
+                               }
+                               else{                                                                                           /* reverse */
+                                       strinfo->call_state=VOIP_REJECTED;
+                                       tapinfo->rejected_calls++;
+                               }
+                       } else if ( (strinfo->call_state!=VOIP_CANCELLED) && (strinfo->call_state!=VOIP_REJECTED) ){
+                                       strinfo->call_state=VOIP_COMPLETED;
+                                       tapinfo->completed_calls++;
+                       }
+                       if (q931_cause_value != 0xFF){          
+                               comment = g_strdup_printf("AC_ISDN trunk:%u Q931 Rel Cause (%i):%s", actrace_trunk, q931_cause_value, val_to_str(q931_cause_value, q931_cause_code_vals, "<unknown>"));
+                       } else { /* Cause not set */
+                               comment = g_strdup("AC_ISDN No Q931 Rel Cause");
+                       }
+                       break;
+               }
 
-static gchar *q931_calling_number;
-static gchar *q931_called_number;
-static guint8 q931_cause_value;
-static gint32 q931_crv;
-static guint32 q931_frame_num;
+               if (!comment)
+                       comment = g_strdup_printf("AC_ISDN  trunk:%u", actrace_trunk );
 
-/****************************************************************************/
-/* whenever a q931_ packet is seen by the tap listener */
-static int 
-q931_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *q931_info _U_)
-{
-       /*voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct; */
-       const q931_packet_info *pi = q931_info;
+               add_to_graph(tapinfo, pinfo, val_to_str(pi->message_type, q931_message_type_vals, "<unknown>") , comment, strinfo->call_num, 
+                               actrace_direction?&pstn_add:&(pinfo->src),
+                               actrace_direction?&(pinfo->src):&pstn_add);
 
-       /* free previously allocated q931_calling/ed_number */
-       g_free(q931_calling_number);
-       g_free(q931_called_number);
-       
-       if (pi->calling_number!=NULL)
-               q931_calling_number = g_strdup(pi->calling_number);
-       else
-               q931_calling_number = g_strdup("");
+               g_free(comment);
+               g_free((char *)pstn_add.data);
+       }
 
-       if (pi->called_number!=NULL)
-               q931_called_number = g_strdup(pi->called_number);
-       else
-               q931_called_number = g_strdup("");
-       q931_cause_value = pi->cause_value;
-       q931_frame_num = pinfo->fd->num;
-       q931_crv = pi->crv;
+       tapinfo->redraw = TRUE;
 
-       return 0;
+       return 1;  /* refresh output */
 }
 
 /****************************************************************************/
@@ -1025,12 +1429,7 @@ remove_tap_listener_q931_calls(void)
 /****************************TAP for H323 ***********************************/
 /****************************************************************************/
 
-#define GUID_LEN       16
-static const guint8 guid_allzero[GUID_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-/* defines specific H323 data */
-
-
-void add_h245_Address(h323_calls_info_t *h323info,  h245_address_t *h245_address)
+static void add_h245_Address(h323_calls_info_t *h323info,  h245_address_t *h245_address)
 {
        h323info->h245_list = g_list_append(h323info->h245_list, h245_address);                         
 }
@@ -1044,38 +1443,22 @@ H225calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, con
        voip_calls_info_t *tmp_listinfo;
        voip_calls_info_t *strinfo = NULL;
        h323_calls_info_t *tmp_h323info = NULL;
-       h323_calls_info_t *tmp2_h323info;
        gchar *frame_label;
        gchar *comment;
-       GList *list, *list2;
+       GList *list;
        address tmp_src, tmp_dst;
        h245_address_t *h245_add = NULL;
-       guint foo;
        
        const h225_packet_info *pi = H225info;
        
        /* if not guid and RAS and not LRQ, LCF or LRJ return because did not belong to a call */
-       if ((memcmp(pi->guid, guid_allzero, GUID_LEN) == 0) && (pi->msg_type == H225_RAS) && ((pi->msg_tag < 18) || (pi->msg_tag > 20)))
-               return 0;
+       /* OR, if not guid and is H225 return because doesn't belong to a call */
+       if ((memcmp(pi->guid, guid_allzero, GUID_LEN) == 0))
+               if ( ((pi->msg_type == H225_RAS) && ((pi->msg_tag < 18) || (pi->msg_tag > 20))) || (pi->msg_type != H225_RAS) )
+                       return 0;
        
-       
-       if ( (memcmp(pi->guid, guid_allzero, GUID_LEN) == 0) && (q931_frame_num == pinfo->fd->num) ){
-               /* check wether we already have a call with this Q931 CRV */
-               list = g_list_first(tapinfo->strinfo_list);
-               while (list)
-               {
-                       tmp_listinfo=list->data;
-                       if (tmp_listinfo->protocol == VOIP_H323){
-                               tmp_h323info = tmp_listinfo->prot_info;
-                               if ( ((tmp_h323info->q931_crv == q931_crv) || (tmp_h323info->q931_crv2 == q931_crv)) && (q931_crv!=-1)){
-                                       strinfo = (voip_calls_info_t*)(list->data);
-                                       break;
-                               }
-                       }
-                       list = g_list_next (list);
-               }
-               if (strinfo==NULL)      return 0;               
-       } else if ( (pi->msg_type == H225_RAS) && ((pi->msg_tag == 19) || (pi->msg_tag == 20))) { /* RAS LCF or LRJ*/
+       /* if it is RAS LCF or LRJ*/
+       if ( (pi->msg_type == H225_RAS) && ((pi->msg_tag == 19) || (pi->msg_tag == 20))) { 
                /* if the LCF/LRJ doesn't match to a LRQ, just return */
                if (!pi->request_available) return 0;
                
@@ -1110,6 +1493,9 @@ H225calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, con
                }
        }
        
+       h225_cstype = pi->cs_type;
+       h225_is_faststart = pi->is_faststart;
+
        /* not in the list? then create a new entry */
        if ((strinfo==NULL)){
                strinfo = g_malloc(sizeof(voip_calls_info_t));
@@ -1120,8 +1506,8 @@ H225calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, con
                COPY_ADDRESS(&(strinfo->initial_speaker),&(pinfo->src));
                strinfo->selected=FALSE;
                strinfo->first_frame_num=pinfo->fd->num;
-               strinfo->start_sec=pinfo->fd->rel_secs;
-               strinfo->start_usec=pinfo->fd->rel_usecs;
+               strinfo->start_sec=pinfo->fd->rel_ts.secs;
+               strinfo->start_usec=pinfo->fd->rel_ts.nsecs/1000;
                strinfo->protocol=VOIP_H323;
                strinfo->prot_info=g_malloc(sizeof(h323_calls_info_t));
                tmp_h323info = strinfo->prot_info;
@@ -1144,13 +1530,16 @@ H225calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, con
 
        if (strinfo!=NULL){
 
+               h225_frame_num = pinfo->fd->num;
+               h225_call_num = strinfo->call_num;
+
                /* let's analyze the call state */
 
                COPY_ADDRESS(&(tmp_src),&(pinfo->src));
                COPY_ADDRESS(&(tmp_dst),&(pinfo->dst));
 
-               strinfo->stop_sec=pinfo->fd->rel_secs;
-               strinfo->stop_usec=pinfo->fd->rel_usecs;
+               strinfo->stop_sec=pinfo->fd->rel_ts.secs;
+               strinfo->stop_usec=pinfo->fd->rel_ts.nsecs/1000;
                strinfo->last_frame_num=pinfo->fd->num;
                ++(strinfo->npackets);
                /* increment the packets counter of all calls */
@@ -1162,11 +1551,6 @@ H225calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, con
 
                /* change the status */
                if (pi->msg_type == H225_CS){
-                       if (tmp_h323info->q931_crv == -1) {
-                               tmp_h323info->q931_crv = q931_crv;
-                       } else if (tmp_h323info->q931_crv != q931_crv) {
-                               tmp_h323info->q931_crv2 = q931_crv;
-                       }
 
                        /* this is still IPv4 only, because the dissector is */
                        if (pi->is_h245 == TRUE){
@@ -1186,63 +1570,12 @@ H225calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, con
                        switch(pi->cs_type){
                        case H225_SETUP:
                                tmp_h323info->is_faststart_Setup = pi->is_faststart;
-                               /* set te calling and called number from the Q931 packet */
-                               if (q931_frame_num == pinfo->fd->num){
-                                       if (q931_calling_number != NULL){
-                                               g_free(strinfo->from_identity);
-                                               strinfo->from_identity=g_strdup(q931_calling_number);
-                                       }
-                                       if (q931_called_number != NULL){
-                                               g_free(strinfo->to_identity);
-                                               strinfo->to_identity=g_strdup(q931_called_number);
-                                       }
-                               }
-                                       /* check if there is an LRQ/LCF that match this Setup */
-                                       /* TODO: we are just checking the DialedNumer in LRQ/LCF agains the Setup 
-                                       we should also check if the h225 signaling IP and port match the destination 
-                                       Setup ip and port */
-                                       list = g_list_first(tapinfo->strinfo_list);
-                               foo=    g_list_length(list);
-                               while (list)
-                               {
-                                       tmp_listinfo=list->data;
-                                       if (tmp_listinfo->protocol == VOIP_H323){
-                                               tmp2_h323info = tmp_listinfo->prot_info;
-                                               
-                                               /* check if there called number match a LRQ/LCF */
-                                               if ( (strcmp(strinfo->to_identity, tmp_listinfo->to_identity)==0)  
-                                                        && (memcmp(tmp2_h323info->guid, guid_allzero, GUID_LEN) == 0) ){ 
-                                                       /* change the call graph to the LRQ/LCF to belong to this call */
-                                                       strinfo->npackets += change_call_num_graph(tapinfo, tmp_listinfo->call_num, strinfo->call_num);
-                                                       
-                                                       /* remove this LRQ/LCF call entry because we have found the Setup that match them */
-                                                       g_free(tmp_listinfo->from_identity);
-                                                       g_free(tmp_listinfo->to_identity);
-                                                       g_free(tmp2_h323info->guid);
-                                                       
-                                                       list2 = g_list_first(tmp2_h323info->h245_list);
-                                                       while (list2)
-                                                       {
-                                                               h245_add=list2->data;
-                                                               g_free((void *)h245_add->h245_address.data);
-                                                               g_free(list2->data);
-                                                               list2 = g_list_next(list2);
-                                                       }
-                                                       g_list_free(tmp_h323info->h245_list);
-                                                       tmp_h323info->h245_list = NULL;
-                                                       g_free(tmp_listinfo->prot_info);
-                                                       tapinfo->strinfo_list = g_list_remove(tapinfo->strinfo_list, tmp_listinfo);
-                                                       break;
-                                               }
-                                       }
-                               list = g_list_next (list);
-                               }
-                                       foo = g_list_length(list);
+
                                /* Set the Setup address if it was not set */
                                if (tmp_h323info->h225SetupAddr.type == AT_NONE) 
                                  COPY_ADDRESS(&(tmp_h323info->h225SetupAddr), &(pinfo->src));
                                        strinfo->call_state=VOIP_CALL_SETUP;
-                               comment = g_strdup_printf("H225 From: %s To:%s  TunnH245:%s FS:%s", strinfo->from_identity, strinfo->to_identity, (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"), 
+                               comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"), 
                                                                                  (pi->is_faststart==TRUE?"on":"off"));
                                break;
                        case H225_CONNECT:
@@ -1265,13 +1598,7 @@ H225calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, con
                                                strinfo->call_state=VOIP_COMPLETED;
                                                tapinfo->completed_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");
-                               }
+                               comment = g_strdup("H225 No Q931 Rel Cause");
                                break;
                        case H225_PROGRESS:
                        case H225_ALERTING:
@@ -1284,8 +1611,8 @@ H225calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, con
                                comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"), 
                                                                                  (pi->is_faststart==TRUE?"on":"off"));
                                
-                       } /* switch pi->cs_type*/
-               } /* if pi->msg_type == H225_CS */
+                       } 
+               } 
                else if (pi->msg_type == H225_RAS){
                switch(pi->msg_tag){
                        case 18:  /* LRQ */
@@ -1314,16 +1641,21 @@ H225calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, con
        /* if the frame number exists in graph, append to it*/
        if (!append_to_frame_graph(tapinfo, pinfo->fd->num, pi->frame_label, comment)) {
                /* if not exist, add to the graph */
-               add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num);
+               add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num, &(pinfo->src), &(pinfo->dst));
                g_free((void *)tmp_src.data);
                g_free((void *)tmp_dst.data);
        }
 
+       /* Add the H245 info if exists to the Graph */
+       h245_add_to_graph(pinfo->fd->num);
+
        g_free(frame_label);
        g_free(comment);
        
-       } /* if strinfo!=NULL */
+       } 
        
+       tapinfo->redraw = TRUE;
+
        return 1;  /* refresh output */
 }
 
@@ -1374,6 +1706,54 @@ remove_tap_listener_h225_calls(void)
        have_H225_tap_listener=FALSE;
 }
 
+/* Add the h245 label info to the graph */ 
+void h245_add_to_graph(guint32 new_frame_num)
+{
+       gint8 n;
+       
+       if (new_frame_num != h245_labels.frame_num) return;
+
+       for (n=0; n<h245_labels.labels_count; n++) {
+               append_to_frame_graph(&the_tapinfo_struct, new_frame_num, h245_labels.labels[n].frame_label, h245_labels.labels[n].comment);
+               g_free(h245_labels.labels[n].frame_label);
+               h245_labels.labels[n].frame_label = NULL;
+               g_free(h245_labels.labels[n].comment);
+               h245_labels.labels[n].comment = NULL;
+       }
+       h245_labels.frame_num = 0;
+       h245_labels.labels_count = 0;
+}
+
+/* free the h245_labels if the frame number is different */ 
+static void h245_free_labels(guint32 new_frame_num)
+{
+       gint8 n;
+       
+       if (new_frame_num == h245_labels.frame_num) return;
+
+       for (n=0; n<h245_labels.labels_count; n++) {
+               g_free(h245_labels.labels[n].frame_label);
+               h245_labels.labels[n].frame_label = NULL;
+               g_free(h245_labels.labels[n].comment);
+               h245_labels.labels[n].comment = NULL;
+       }
+       h245_labels.frame_num = 0;
+       h245_labels.labels_count = 0;
+}
+
+/* add the frame_label and comment to h245_labels and free the actual one if it is different frame num */ 
+static void h245_add_label(guint32 new_frame_num, gchar *frame_label, gchar *comment)
+{
+       h245_free_labels(new_frame_num);
+
+       h245_labels.frame_num = new_frame_num;
+       h245_labels.labels[h245_labels.labels_count].frame_label = g_strdup(frame_label);
+       h245_labels.labels[h245_labels.labels_count].comment = g_strdup(comment);
+
+       if (h245_labels.labels_count < (H245_MAX-1))
+               h245_labels.labels_count++;
+
+}
 
 /****************************************************************************/
 /* whenever a H245dg packet is seen by the tap listener (when H245 tunneling is ON) */
@@ -1393,12 +1773,7 @@ H245dgcalls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, c
 
        const h245_packet_info *pi = H245info;
 
-       /* if H245 tunneling is on, append to graph */
-       if (append_to_frame_graph(tapinfo, pinfo->fd->num, pi->frame_label, pi->comment)) return 1;
-
-
-       /* it is not Tunneling or it is not in the list. So check if there is no tunneling
-          and there is a call with this H245 address */
+       /* check if Tunneling is OFF and we have a call with this H245 add */
        list = g_list_first(tapinfo->strinfo_list);
        while (list)
        {
@@ -1431,14 +1806,30 @@ H245dgcalls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, c
                list = g_list_next(list);
        }
 
+       /* Tunnel is OFF, and we matched the h245 add so we add it to graph */
        if (strinfo!=NULL){
+               ++(strinfo->npackets);
+               /* increment the packets counter of all calls */
+               ++(tapinfo->npackets);
                frame_label = g_strdup(pi->frame_label);
                comment = g_strdup(pi->comment);
-               add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num);
+               /* if the frame number exists in graph, append to it*/
+               if (!append_to_frame_graph(tapinfo, pinfo->fd->num, frame_label, comment)) {
+                       /* if not exist, add to the graph */
+                       add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num, &(pinfo->src), &(pinfo->dst));
+               }
                g_free(frame_label);
                g_free(comment);
+       } else { 
+       /* Tunnel is ON, so we save the label info to use it into h225 or q931 tap. OR may be 
+                tunnel OFF but we did not matched the h245 add, in this case nobady will set this label 
+                since the frame_num will not match */ 
+       
+               h245_add_label(pinfo->fd->num, (gchar *) pi->frame_label, (gchar *) pi->comment);
        }
 
+       tapinfo->redraw = TRUE;
+
        return 1;  /* refresh output */
 }
 
@@ -1488,9 +1879,6 @@ remove_tap_listener_h245dg_calls(void)
        have_H245dg_tap_listener=FALSE;
 }
 
-static gchar *sdp_summary = NULL;
-static guint32 sdp_frame_num = 0;
-
 /****************************************************************************/
 /****************************TAP for SDP PROTOCOL ***************************/
 /****************************************************************************/
@@ -1501,8 +1889,8 @@ SDPcalls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, cons
        voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
        const sdp_packet_info *pi = SDPinfo;
 
-       /* There are protocols like MGCP where the SDP is called before the tap for the
-          MGCP packet, in those cases we assign the SPD summary to global lastSDPsummary
+       /* There are protocols like MGCP/SIP where the SDP is called before the tap for the
+          MGCP/SIP packet, in those cases we assign the SPD summary to global lastSDPsummary
           to use it later 
        */
        g_free(sdp_summary);
@@ -1511,6 +1899,8 @@ SDPcalls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, cons
        sdp_summary = g_strdup_printf("SDP (%s)", pi->summary_str);
        append_to_frame_graph(tapinfo, pinfo->fd->num, sdp_summary, NULL);
 
+       tapinfo->redraw = TRUE;
+
        return 1;  /* refresh output */
 }
 
@@ -1570,7 +1960,7 @@ remove_tap_listener_sdp_calls(void)
    This function will look for a signal/event in the SignalReq/ObsEvent string
    and return true if it is found 
 */
-gboolean isSignal(gchar *signal, gchar *signalStr)
+static gboolean isSignal(const gchar *signal, const gchar *signalStr)
 {
        gint i; 
        gchar **resultArray;
@@ -1598,7 +1988,7 @@ gboolean isSignal(gchar *signal, gchar *signalStr)
    This function will get the Caller ID info and replace the current string
    This is how it looks the caller Id: rg, ci(02/16/08/29, "3035550002","Ale Sipura 2")
 */
-void mgcpCallerID(gchar *signalStr, gchar **callerId)
+static void mgcpCallerID(gchar *signalStr, gchar **callerId)
 {
        gchar **arrayStr;
        
@@ -1625,7 +2015,7 @@ void mgcpCallerID(gchar *signalStr, gchar **callerId)
    This function will get the Dialed Digits and replace the current string
    This is how it looks the dialed digits 5,5,5,0,0,0,2,#,*
 */
-void mgcpDialedDigits(gchar *signalStr, gchar **dialedDigits)
+static void mgcpDialedDigits(gchar *signalStr, gchar **dialedDigits)
 {
        gchar *tmpStr;
        gchar resultStr[50];
@@ -1701,7 +2091,7 @@ MGCPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, co
                                                   check first if it is an ended call. We consider an ended call after 1sec we don't 
                                                   get a packet in this Endpoint and the call has been released
                                                */
-                                               diff_time = (pinfo->fd->rel_secs + (double)pinfo->fd->rel_secs/1000000) - (tmp_listinfo->stop_sec + (double)tmp_listinfo->stop_usec/1000000);
+                                               diff_time = nstime_to_sec(&pinfo->fd->rel_ts) - tmp_listinfo->stop_sec + (double)tmp_listinfo->stop_usec/1000000;
                                                if ( ((tmp_listinfo->call_state == VOIP_CANCELLED) || (tmp_listinfo->call_state == VOIP_COMPLETED)  || (tmp_listinfo->call_state == VOIP_REJECTED)) && (diff_time > 1) ){
                                                        tmp_listinfo->call_active_state = VOIP_INACTIVE;
                                                } else {
@@ -1772,8 +2162,8 @@ MGCPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, co
                COPY_ADDRESS(&(strinfo->initial_speaker),&(pinfo->src));
                strinfo->first_frame_num=pinfo->fd->num;
                strinfo->selected=FALSE;
-               strinfo->start_sec=pinfo->fd->rel_secs;
-               strinfo->start_usec=pinfo->fd->rel_usecs;
+               strinfo->start_sec=pinfo->fd->rel_ts.secs;
+               strinfo->start_usec=pinfo->fd->rel_ts.nsecs/1000;
                strinfo->protocol=VOIP_MGCP;
                strinfo->prot_info=g_malloc(sizeof(mgcp_calls_info_t));
                tmp_mgcpinfo=strinfo->prot_info;
@@ -1859,15 +2249,15 @@ MGCPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, co
 
        comment = g_strdup_printf("MGCP %s %s%s", tmp_mgcpinfo->endpointId, (pi->mgcp_type == MGCP_REQUEST)?"Request":"Response", pi->is_duplicate?" Duplicate":"");
 
-       strinfo->stop_sec=pinfo->fd->rel_secs;
-       strinfo->stop_usec=pinfo->fd->rel_usecs;
+       strinfo->stop_sec=pinfo->fd->rel_ts.secs;
+       strinfo->stop_usec=pinfo->fd->rel_ts.nsecs/1000;
        strinfo->last_frame_num=pinfo->fd->num;
        ++(strinfo->npackets);
        /* increment the packets counter of all calls */
        ++(tapinfo->npackets);
 
        /* add to the graph */
-       add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num);  
+       add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num, &(pinfo->src), &(pinfo->dst));  
        g_free(comment);
        g_free(frame_label);
 
@@ -1878,6 +2268,8 @@ MGCPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, co
                        sdp_summary = NULL;
        }
 
+       tapinfo->redraw = TRUE;
+
        return 1;  /* refresh output */
 }
 
@@ -1929,6 +2321,138 @@ remove_tap_listener_mgcp_calls(void)
 }
 
 
+/****************************************************************************/
+/****************************TAP for ACTRACE (AudioCodes trace)**************/
+/****************************************************************************/
+
+/* whenever a ACTRACE packet is seen by the tap listener */
+static int 
+ACTRACEcalls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *ACTRACEinfo)
+{
+       voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
+       const actrace_info_t *pi = ACTRACEinfo;
+       GList *list;
+       actrace_cas_calls_info_t *tmp_actrace_cas_info;
+       voip_calls_info_t *tmp_listinfo;
+       voip_calls_info_t *strinfo = NULL;
+
+
+       actrace_frame_num = pinfo->fd->num;
+       actrace_trunk = pi->trunk;
+       actrace_direction = pi->direction;
+
+       if (pi->type == 1){ /* is CAS protocol */
+               address pstn_add;
+               gchar *comment = NULL;
+
+               strinfo = NULL;
+               list = g_list_first(tapinfo->strinfo_list);
+               while (list)
+               {
+                       tmp_listinfo=list->data;
+                       if ( tmp_listinfo->protocol == VOIP_AC_CAS ){
+                               tmp_actrace_cas_info = tmp_listinfo->prot_info;
+                               /* TODO: Also check the IP of the Blade, and if the call is complete (no active) */
+                               if ( (tmp_actrace_cas_info->bchannel == pi->cas_bchannel) && (tmp_actrace_cas_info->trunk == actrace_trunk) ) {
+                                       strinfo = (voip_calls_info_t*)(list->data);
+                                       break;
+                               }
+                       }
+                       list = g_list_next (list);
+               }
+
+               SET_ADDRESS(&pstn_add, AT_STRINGZ, 5, g_strdup("PSTN"));
+
+               /* if it is a new call, add it to the list */
+               if (!strinfo) {
+                       strinfo = g_malloc(sizeof(voip_calls_info_t));
+                       strinfo->call_active_state = VOIP_ACTIVE;
+                       strinfo->call_state = VOIP_CALL_SETUP;
+                       strinfo->from_identity=g_strdup("N/A");
+                       strinfo->to_identity=g_strdup("N/A");
+                       COPY_ADDRESS(&(strinfo->initial_speaker),actrace_direction?&pstn_add:&(pinfo->src));
+                       strinfo->first_frame_num=pinfo->fd->num;
+                       strinfo->selected=FALSE;
+                       strinfo->start_sec=pinfo->fd->rel_ts.secs;
+                       strinfo->start_usec=pinfo->fd->rel_ts.nsecs/1000;
+                       strinfo->protocol=VOIP_AC_CAS;
+                       strinfo->prot_info=g_malloc(sizeof(actrace_cas_calls_info_t));
+                       tmp_actrace_cas_info=strinfo->prot_info;
+                       tmp_actrace_cas_info->bchannel=pi->cas_bchannel;
+                       tmp_actrace_cas_info->trunk=actrace_trunk;
+                       strinfo->npackets = 0;
+                       strinfo->call_num = tapinfo->ncalls++;
+                       tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
+               }
+
+               strinfo->stop_sec=pinfo->fd->rel_ts.secs;
+               strinfo->stop_usec=pinfo->fd->rel_ts.nsecs/1000;
+               strinfo->last_frame_num=pinfo->fd->num;
+               ++(strinfo->npackets);
+               /* increment the packets counter of all calls */
+               ++(tapinfo->npackets);
+
+               if (!comment)
+                       comment = g_strdup_printf("AC_CAS  trunk:%u", actrace_trunk );
+
+               add_to_graph(tapinfo, pinfo, pi->cas_frame_label , comment, strinfo->call_num, 
+                               actrace_direction?&pstn_add:&(pinfo->src),
+                               actrace_direction?&(pinfo->src):&pstn_add);
+
+               g_free(comment);
+               g_free((char *)pstn_add.data);
+       }
+
+       tapinfo->redraw = TRUE;
+
+       return 1;  /* refresh output */
+}
+
+
+/****************************************************************************/
+/* TAP INTERFACE */
+/****************************************************************************/
+static gboolean have_actrace_tap_listener=FALSE;
+/****************************************************************************/
+void
+actrace_calls_init_tap(void)
+{
+       GString *error_string;
+
+       if(have_actrace_tap_listener==FALSE)
+       {
+               /* don't register tap listener, if we have it already */
+               error_string = register_tap_listener("actrace", &(the_tapinfo_struct.actrace_dummy), NULL,
+                       voip_calls_dlg_reset, 
+                       ACTRACEcalls_packet, 
+                       voip_calls_dlg_draw
+                       );
+                       
+               if (error_string != NULL) {
+                       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                                     error_string->str);
+                       g_string_free(error_string, TRUE);
+                       exit(1);
+               }
+               have_actrace_tap_listener=TRUE;
+       }
+}
+
+
+/* XXX just copied from gtk/rpc_stat.c */
+void protect_thread_critical_region(void);
+void unprotect_thread_critical_region(void);
+
+/****************************************************************************/
+void
+remove_tap_listener_actrace_calls(void)
+{
+       protect_thread_critical_region();
+       remove_tap_listener(&(the_tapinfo_struct.actrace_dummy));
+       unprotect_thread_critical_region();
+
+       have_actrace_tap_listener=FALSE;
+}
 
 /****************************************************************************/
 /* ***************************TAP for OTHER PROTOCOL **********************************/
@@ -1949,6 +2473,8 @@ prot_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, co
                ++(tapinfo->npackets);
        }
 
+       tapinfo->redraw = TRUE;
+
        return 1;
 }
 */
@@ -1992,4 +2518,3 @@ remove_tap_listener_prot__calls(void)
        have_prot__tap_listener=FALSE;
 }
 */
-