Introduce preferences to set the strictness of Invoke/response
[obnox/wireshark/wip.git] / epan / dissectors / packet-ansi_tcap.c
index 34a9aa8475501584ab52d17f5ed1616ff14617f1..232e231fabd65d2105e7927ce280b22aad8fbe28 100644 (file)
@@ -1,7 +1,7 @@
 /* Do not modify this file.                                                   */
 /* It is created automatically by the ASN.1 to Wireshark dissector compiler   */
-/* .\packet-ansi_tcap.c                                                       */
-/* ../../tools/asn2wrs.py -b -X -T -e -p ansi_tcap -c ansi_tcap.cnf -s packet-ansi_tcap-template TCAP-Remote-Operations-Information-Objects.asn TCAPPackage.asn */
+/* packet-ansi_tcap.c                                                         */
+/* ../../tools/asn2wrs.py -b -p ansi_tcap -c ./ansi_tcap.cnf -s ./packet-ansi_tcap-template -D . TCAP-Remote-Operations-Information-Objects.asn TCAPPackage.asn */
 
 /* Input file: packet-ansi_tcap-template.c */
 
 #include <glib.h>
 #include <epan/packet.h>
 #include <epan/prefs.h>
-#include <epan/conversation.h>
-#include <epan/oid_resolv.h>
+#include <epan/oids.h>
 #include <epan/emem.h>
 #include <epan/asn1.h>
+#include <epan/strutil.h>
 
-#include <stdio.h>
 #include <string.h>
 #include "packet-ber.h"
 #include "packet-tcap.h"
 #include "packet-ansi_tcap.h"
-#include "epan/tcap-persistentdata.h"
+#include <epan/tcap-persistentdata.h>
 
 #define PNAME  "ANSI Transaction Capabilities Application Part"
 #define PSNAME "ANSI_TCAP"
 #define PFNAME "ansi_tcap"
 
+
+/* Preferences defaults */
+gint ansi_tcap_response_matching_type = 0;
+
 /* Initialize the protocol and registered fields */
-int proto_ansi_tcap = -1;
-static int hf_ansi_tcap_tag = -1;
-static int hf_ansi_tcap_length = -1;
-static int hf_ansi_tcap_data = -1;
-static int hf_ansi_tcap_tid = -1;
+static int proto_ansi_tcap = -1;
 
-int hf_ansi_tcapsrt_SessionId=-1;
-int hf_ansi_tcapsrt_Duplicate=-1;
-int hf_ansi_tcapsrt_BeginSession=-1;
-int hf_ansi_tcapsrt_EndSession=-1;
-int hf_ansi_tcapsrt_SessionTime=-1;
+static int hf_ansi_tcapsrt_SessionId = -1;
+static int hf_ansi_tcapsrt_Duplicate = -1;
+static int hf_ansi_tcapsrt_BeginSession = -1;
+static int hf_ansi_tcapsrt_EndSession = -1;
+static int hf_ansi_tcapsrt_SessionTime = -1;
 
 
 /*--- Included file: packet-ansi_tcap-hf.c ---*/
 #line 1 "packet-ansi_tcap-hf.c"
-static int hf_ansi_tcap_national = -1;            /* INTEGER_M32768_32767 */
-static int hf_ansi_tcap_private = -1;             /* INTEGER */
+static int hf_ansi_tcap_national = -1;            /* T_national */
+static int hf_ansi_tcap_private = -1;             /* T_private */
 static int hf_ansi_tcap_national_01 = -1;         /* INTEGER_M128_127 */
-static int hf_ansi_tcap_unidirectional = -1;      /* UniTransactionPDU */
-static int hf_ansi_tcap_queryWithPerm = -1;       /* TransactionPDU */
-static int hf_ansi_tcap_queryWithoutPerm = -1;    /* TransactionPDU */
-static int hf_ansi_tcap_response = -1;            /* TransactionPDU */
-static int hf_ansi_tcap_conversationWithPerm = -1;  /* TransactionPDU */
-static int hf_ansi_tcap_conversationWithoutPerm = -1;  /* TransactionPDU */
-static int hf_ansi_tcap_abort = -1;               /* Abort */
+static int hf_ansi_tcap_private_01 = -1;          /* INTEGER */
+static int hf_ansi_tcap_unidirectional = -1;      /* T_unidirectional */
+static int hf_ansi_tcap_queryWithPerm = -1;       /* T_queryWithPerm */
+static int hf_ansi_tcap_queryWithoutPerm = -1;    /* T_queryWithoutPerm */
+static int hf_ansi_tcap_response = -1;            /* T_response */
+static int hf_ansi_tcap_conversationWithPerm = -1;  /* T_conversationWithPerm */
+static int hf_ansi_tcap_conversationWithoutPerm = -1;  /* T_conversationWithoutPerm */
+static int hf_ansi_tcap_abort = -1;               /* T_abort */
 static int hf_ansi_tcap_identifier = -1;          /* TransactionID */
 static int hf_ansi_tcap_dialoguePortion = -1;     /* DialoguePortion */
 static int hf_ansi_tcap_componentPortion = -1;    /* ComponentSequence */
@@ -123,7 +123,7 @@ static int hf_ansi_tcap_paramSequence = -1;       /* T_paramSequence */
 static int hf_ansi_tcap_paramSet = -1;            /* T_paramSet */
 
 /*--- End of included file: packet-ansi_tcap-hf.c ---*/
-#line 64 "packet-ansi_tcap-template.c"
+#line 63 "packet-ansi_tcap-template.c"
 
 /* Initialize the subtree pointers */
 static gint ett_tcap = -1;
@@ -131,11 +131,10 @@ static gint ett_param = -1;
 
 static gint ett_otid = -1;
 static gint ett_dtid = -1;
-gint ett_ansi_tcap_stat = -1;
+static gint ett_ansi_tcap_stat = -1;
 
 static struct tcapsrt_info_t * gp_tcapsrt_info;
 static gboolean tcap_subdissector_used=FALSE;
-static dissector_handle_t requested_subdissector_handle = NULL;
 
 static struct tcaphash_context_t * gp_tcap_context=NULL;
 
@@ -166,20 +165,14 @@ static gint ett_ansi_tcap_T_paramSequence = -1;
 static gint ett_ansi_tcap_T_paramSet = -1;
 
 /*--- End of included file: packet-ansi_tcap-ett.c ---*/
-#line 80 "packet-ansi_tcap-template.c"
+#line 78 "packet-ansi_tcap-template.c"
 
 #define MAX_SSN 254
-static range_t *global_ssn_range;
-static range_t *ssn_range;
-struct tcap_private_t tcap_private;
 
-gboolean g_ansi_tcap_HandleSRT=FALSE;
 extern gboolean gtcap_PersistentSRT;
-extern gboolean gtcap_DisplaySRT;
 extern guint gtcap_RepetitionTimeout;
 extern guint gtcap_LostTimeout;
 
-static dissector_handle_t      tcap_handle = NULL;
 static dissector_table_t ber_oid_dissector_table=NULL;
 static const char * cur_oid;
 static const char * tcapext_oid;
@@ -187,25 +180,35 @@ static proto_tree * tcap_top_tree=NULL;
 static proto_tree * tcap_stat_tree=NULL;
 static proto_item * tcap_stat_item=NULL;
 
-static dissector_handle_t data_handle;
+static dissector_handle_t ansi_map_handle;
 
-static dissector_table_t sccp_ssn_table;
+struct ansi_tcap_private_t ansi_tcap_private;
+#define MAX_TID_STR_LEN 1024
+
+static void ansi_tcap_ctx_init(struct ansi_tcap_private_t *a_tcap_ctx) {
+  memset(a_tcap_ctx, '\0', sizeof(*a_tcap_ctx));
+  a_tcap_ctx->signature = ANSI_TCAP_CTX_SIGNATURE;
+  a_tcap_ctx->oid_is_present = FALSE;
+  a_tcap_ctx->TransactionID_str = NULL;
+}
+
+static void dissect_ansi_tcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree);
 
-static void raz_tcap_private(struct tcap_private_t * p_tcap_private);
+/*
+static dissector_handle_t tcap_handle = NULL;
+static dissector_table_t sccp_ssn_table;
 
 static GHashTable* ansi_sub_dissectors = NULL;
 static GHashTable* itu_sub_dissectors = NULL;
 
-static void dissect_ansi_tcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree);
-/*
-extern void add_ansi_tcap_subdissector(guint32 ssn, dissector_handle_t dissector) {
+  extern void add_ansi_tcap_subdissector(guint32 ssn, dissector_handle_t dissector) {
     g_hash_table_insert(ansi_sub_dissectors,GUINT_TO_POINTER(ssn),dissector);
-    dissector_add("sccp.ssn",ssn,tcap_handle);
+    dissector_add_uint("sccp.ssn",ssn,tcap_handle);
 }
 
 extern void delete_ansi_tcap_subdissector(guint32 ssn, dissector_handle_t dissector _U_) {
     g_hash_table_remove(ansi_sub_dissectors,GUINT_TO_POINTER(ssn));
-    dissector_delete("sccp.ssn",ssn,tcap_handle);
+    dissector_delete_uint("sccp.ssn",ssn,tcap_handle);
 }
 
 dissector_handle_t get_ansi_tcap_subdissector(guint32 ssn) {
@@ -213,7 +216,210 @@ dissector_handle_t get_ansi_tcap_subdissector(guint32 ssn) {
 }
 */
 
+/* Transaction tracking */
+/* Transaction table */
+struct ansi_tcap_invokedata_t {
+    gint OperationCode;
+      /*
+         0 : national,
+         1 : private
+      */
+    gint32 OperationCode_private;
+    gint32 OperationCode_national;
+};
+
+static GHashTable *TransactionId_table=NULL;
+
+static void
+TransactionId_table_cleanup(gpointer key , gpointer value, gpointer user_data _U_){
+
+        struct ansi_tcap_invokedata_t *ansi_tcap_saved_invokedata = value;
+        gchar *TransactionId_str = key;
+
+        g_free(TransactionId_str);
+        g_free(ansi_tcap_saved_invokedata);
+
+}
+
+void
+ansi_tcap_init_transaction_table(void){
 
+        /* Destroy any existing memory chunks / hashes. */
+        if (TransactionId_table){
+                g_hash_table_foreach(TransactionId_table, TransactionId_table_cleanup, NULL);
+                g_hash_table_destroy(TransactionId_table);
+                TransactionId_table = NULL;
+        }
+
+        TransactionId_table = g_hash_table_new(g_str_hash, g_str_equal);
+
+}
+
+static void
+ansi_tcap_init_protocol(void)
+{
+        ansi_tcap_init_transaction_table();
+}
+
+/* Store Invoke information needed for the corresponding reply */
+static void
+save_invoke_data(packet_info *pinfo, proto_tree *tree _U_, tvbuff_t *tvb _U_){
+  struct ansi_tcap_invokedata_t *ansi_tcap_saved_invokedata;
+  address* src = &(pinfo->src);
+  address* dst = &(pinfo->dst);
+  char *buf;
+
+  if ((!pinfo->fd->flags.visited)&&(ansi_tcap_private.TransactionID_str)){
+
+          /* Only do this once XXX I hope its the right thing to do */
+          /* The hash string needs to contain src and dest to distiguish differnt flows */
+          buf = ep_alloc(MAX_TID_STR_LEN);
+          buf[0] = '\0';
+                 switch(ansi_tcap_response_matching_type){
+                               case 0:
+                                       g_snprintf(buf,MAX_TID_STR_LEN,"%s",ansi_tcap_private.TransactionID_str);
+                                       break;
+                               case 1:
+                                       g_snprintf(buf,MAX_TID_STR_LEN,"%s%s",ansi_tcap_private.TransactionID_str,ep_address_to_str(src));
+                                       break;
+                               default:
+                                       g_snprintf(buf,MAX_TID_STR_LEN,"%s%s%s",ansi_tcap_private.TransactionID_str,ep_address_to_str(src),ep_address_to_str(dst));
+                                       break;
+                       }
+
+          /* If the entry allready exists don't owervrite it */
+          ansi_tcap_saved_invokedata = g_hash_table_lookup(TransactionId_table,buf);
+          if(ansi_tcap_saved_invokedata)
+                  return;
+
+          ansi_tcap_saved_invokedata = g_malloc(sizeof(struct ansi_tcap_invokedata_t));
+          ansi_tcap_saved_invokedata->OperationCode = ansi_tcap_private.d.OperationCode;
+          ansi_tcap_saved_invokedata->OperationCode_national = ansi_tcap_private.d.OperationCode_national;
+          ansi_tcap_saved_invokedata->OperationCode_private = ansi_tcap_private.d.OperationCode_private;
+
+          g_hash_table_insert(TransactionId_table,
+                        g_strdup(buf),
+                        ansi_tcap_saved_invokedata);
+          /*
+          g_warning("Tcap Invoke Hash string %s",buf);
+          */
+  }
+}
+
+static gboolean
+find_saved_invokedata(packet_info *pinfo, proto_tree *tree _U_, tvbuff_t *tvb _U_){
+  struct ansi_tcap_invokedata_t *ansi_tcap_saved_invokedata;
+  address* src = &(pinfo->src);
+  address* dst = &(pinfo->dst);
+  char *buf;
+
+  if (!ansi_tcap_private.TransactionID_str) {
+    return FALSE;
+  }
+
+  /* The hash string needs to contain src and dest to distiguish differnt flows */
+  buf = ep_alloc(MAX_TID_STR_LEN);
+  buf[0] = '\0';
+  /* Reverse order to invoke */
+  g_snprintf(buf, MAX_TID_STR_LEN, "%s%s%s",
+        ansi_tcap_private.TransactionID_str, ep_address_to_str(dst),
+        ep_address_to_str(src));
+  switch(ansi_tcap_response_matching_type){
+               case 0:
+                       g_snprintf(buf,MAX_TID_STR_LEN,"%s",ansi_tcap_private.TransactionID_str);
+                       break;
+               case 1:
+                       g_snprintf(buf,MAX_TID_STR_LEN,"%s%s",ansi_tcap_private.TransactionID_str,ep_address_to_str(dst));
+                       break;
+               default:
+                       g_snprintf(buf,MAX_TID_STR_LEN,"%s%s%s",ansi_tcap_private.TransactionID_str,ep_address_to_str(dst),ep_address_to_str(src));
+                       break;
+       }
+
+  ansi_tcap_saved_invokedata = g_hash_table_lookup(TransactionId_table, buf);
+  if(ansi_tcap_saved_invokedata){
+          ansi_tcap_private.d.OperationCode                      = ansi_tcap_saved_invokedata->OperationCode;
+          ansi_tcap_private.d.OperationCode_national = ansi_tcap_saved_invokedata->OperationCode_national;
+          ansi_tcap_private.d.OperationCode_private  = ansi_tcap_saved_invokedata->OperationCode_private;
+          return TRUE;
+  }
+  return FALSE;
+}
+
+/* As currently ANSI MAP is the only possible sub dissector this function
+ *  must be improved to handle general cases.
+ *
+ *
+ *
+ * TODO:
+ * 1)Handle national codes
+ *     Design option
+ *     - Create a ansi.tcap.national dissector table and have dissectors for
+ *       national codes register there and let ansi tcap call them.
+ * 2)Handle Private codes properly
+ *     Design question
+ *     Unclear how to differentiate between different private "code sets".
+ *     Use SCCP SSN table as before? or a ansi.tcap.private dissector table?
+ *
+ */
+static gboolean
+find_tcap_subdissector(tvbuff_t *tvb, asn1_ctx_t *actx, proto_tree *tree){
+        proto_item *item;
+
+        /* If "DialoguePortion objectApplicationId ObjectIDApplicationContext
+         * points to the subdissector this code can be used.
+         *
+        if(ansi_tcap_private.d.oid_is_present){
+                call_ber_oid_callback(ansi_tcap_private.objectApplicationId_oid, tvb, 0, actx-pinfo, tree);
+                return TRUE;
+        }
+        */
+        if(ansi_tcap_private.d.pdu == 1){
+                /* Save Invoke data for this transaction */
+                save_invoke_data(actx->pinfo, tree, tvb);
+        }else{
+                /* Get saved data for this transaction */
+                if(find_saved_invokedata(actx->pinfo, tree, tvb)){
+                        if(ansi_tcap_private.d.OperationCode == 0){
+                                /* national */
+                                item = proto_tree_add_int(tree, hf_ansi_tcap_national, tvb, 0, 0, ansi_tcap_private.d.OperationCode_national);
+                        }else{
+                                item = proto_tree_add_int(tree, hf_ansi_tcap_private, tvb, 0, 0, ansi_tcap_private.d.OperationCode_private);
+                        }
+                        PROTO_ITEM_SET_GENERATED(item);
+                        ansi_tcap_private.d.OperationCode_item = item;
+                }
+        }
+        if(ansi_tcap_private.d.OperationCode == 0){
+                /* national */
+                item = proto_tree_add_text(tree, tvb, 0, -1,
+                        "Dissector for ANSI TCAP NATIONAL code:%u not implemented. Contact Wireshark developers if you want this supported",
+                        ansi_tcap_private.d.OperationCode_national);
+                PROTO_ITEM_SET_GENERATED(item);
+                return FALSE;
+        }else if(ansi_tcap_private.d.OperationCode == 1){
+                /* private */
+                if((ansi_tcap_private.d.OperationCode_private & 0x0900) != 0x0900){
+                        item = proto_tree_add_text(tree, tvb, 0, -1,
+                                "Dissector for ANSI TCAP PRIVATE code:%u not implemented. Contact Wireshark developers if you want this supported",
+                                ansi_tcap_private.d.OperationCode_private);
+                        PROTO_ITEM_SET_GENERATED(item);
+                        return FALSE;
+                }
+        }
+        /* This is abit of a hack as it assumes the private codes with a "family" of 0x09 is ANSI MAP
+         * See TODO above.
+         * N.S0005-0 v 1.0 TCAP Formats and Procedures 5-16 Application Services
+         * 6.3.2 Component Portion
+         * The Operation Code is partitioned into an Operation Family followed by a
+         * Specifier associated with each Operation Family member. For TIA/EIA-41 the
+         * Operation Family is coded as decimal 9. Bit H of the Operation Family is always
+         * coded as 0.
+         */
+        call_dissector(ansi_map_handle, tvb, actx->pinfo, tcap_top_tree);
+
+        return TRUE;
+}
 
 
 /*--- Included file: packet-ansi_tcap-fn.c ---*/
@@ -221,9 +427,9 @@ dissector_handle_t get_ansi_tcap_subdissector(guint32 ssn) {
 
 
 static int
-dissect_ansi_tcap_INTEGER_M32768_32767(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
+dissect_ansi_tcap_T_national(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
-                                  NULL);
+                                                &ansi_tcap_private.d.OperationCode_national);
 
   return offset;
 }
@@ -231,9 +437,9 @@ dissect_ansi_tcap_INTEGER_M32768_32767(gboolean implicit_tag _U_, tvbuff_t *tvb
 
 
 static int
-dissect_ansi_tcap_INTEGER(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
+dissect_ansi_tcap_T_private(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
-                                  NULL);
+                                                &ansi_tcap_private.d.OperationCode_private);
 
   return offset;
 }
@@ -246,8 +452,8 @@ static const value_string ansi_tcap_OperationCode_vals[] = {
 };
 
 static const ber_choice_t OperationCode_choice[] = {
-  {  16, &hf_ansi_tcap_national  , BER_CLASS_PRI, 16, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_INTEGER_M32768_32767 },
-  {  17, &hf_ansi_tcap_private   , BER_CLASS_PRI, 17, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_INTEGER },
+  {  16, &hf_ansi_tcap_national  , BER_CLASS_PRI, 16, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_national },
+  {  17, &hf_ansi_tcap_private   , BER_CLASS_PRI, 17, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_private },
   { 0, NULL, 0, 0, 0, NULL }
 };
 
@@ -255,7 +461,10 @@ static int
 dissect_ansi_tcap_OperationCode(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
   offset = dissect_ber_choice(actx, tree, tvb, offset,
                                  OperationCode_choice, hf_index, ett_ansi_tcap_OperationCode,
-                                 NULL);
+                                 &ansi_tcap_private.d.OperationCode);
+
+#line 17 "ansi_tcap.cnf"
+  ansi_tcap_private.d.OperationCode_item = actx->created_item;
 
   return offset;
 }
@@ -265,7 +474,17 @@ dissect_ansi_tcap_OperationCode(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, in
 static int
 dissect_ansi_tcap_INTEGER_M128_127(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
-                                  NULL);
+                                                NULL);
+
+  return offset;
+}
+
+
+
+static int
+dissect_ansi_tcap_INTEGER(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
+  offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
+                                                NULL);
 
   return offset;
 }
@@ -279,7 +498,7 @@ static const value_string ansi_tcap_ErrorCode_vals[] = {
 
 static const ber_choice_t ErrorCode_choice[] = {
   {  19, &hf_ansi_tcap_national_01, BER_CLASS_PRI, 19, 0, dissect_ansi_tcap_INTEGER_M128_127 },
-  {  20, &hf_ansi_tcap_private   , BER_CLASS_PRI, 20, 0, dissect_ansi_tcap_INTEGER },
+  {  20, &hf_ansi_tcap_private_01, BER_CLASS_PRI, 20, 0, dissect_ansi_tcap_INTEGER },
   { 0, NULL, 0, 0, 0, NULL }
 };
 
@@ -295,19 +514,49 @@ dissect_ansi_tcap_ErrorCode(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int of
 
 
 static int
-dissect_ansi_tcap_Priority(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-  offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
-                                  NULL);
+dissect_ansi_tcap_TransactionID_U(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
+#line 90 "ansi_tcap.cnf"
 
-  return offset;
-}
+tvbuff_t *next_tvb;
+guint8 len;
 
+  offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
+                                       &next_tvb);
+
+
+if(next_tvb) {
+       len = tvb_length_remaining(next_tvb, 0);
+       if(len !=0){
+               /* 0 octets for the Unidirectional, 
+                * 4 octets for Query, Response & Abort
+                * 8 octets for Conversation in the order Originating then Responding TID
+                * 
+                * In order to match this it seems like we should only use the last 4 octets
+                * in the 8 octets case.
+                */
+               if (len > 4){
+                       ansi_tcap_private.TransactionID_str = tvb_bytes_to_str(next_tvb, 4,len-4);
+               }else{
+                       ansi_tcap_private.TransactionID_str = tvb_bytes_to_str(next_tvb, 0,len);
+               }
+       }
+       switch(len) {
+       case 1:
+               gp_tcapsrt_info->src_tid=tvb_get_guint8(next_tvb, 0);
+               break;
+       case 2:
+               gp_tcapsrt_info->src_tid=tvb_get_ntohs(next_tvb, 0);
+               break;
+       case 4:
+               gp_tcapsrt_info->src_tid=tvb_get_ntohl(next_tvb, 0);
+               break;
+       default:
+               gp_tcapsrt_info->src_tid=0;
+               break;
+       }
+}
 
 
-static int
-dissect_ansi_tcap_OCTET_STRING(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-  offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
-                                       NULL);
 
   return offset;
 }
@@ -317,7 +566,7 @@ dissect_ansi_tcap_OCTET_STRING(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int
 static int
 dissect_ansi_tcap_TransactionID(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
   offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
-                                      hf_index, BER_CLASS_PRI, 7, TRUE, dissect_ansi_tcap_OCTET_STRING);
+                                      hf_index, BER_CLASS_PRI, 7, TRUE, dissect_ansi_tcap_TransactionID_U);
 
   return offset;
 }
@@ -365,9 +614,18 @@ dissect_ansi_tcap_OBJECT_IDENTIFIER(gboolean implicit_tag _U_, tvbuff_t *tvb _U_
 
 static int
 dissect_ansi_tcap_ObjectIDApplicationContext(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-  offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
+#line 54 "ansi_tcap.cnf"
+
+ static const char * oid_str;
+
+   offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
                                       hf_index, BER_CLASS_PRI, 28, TRUE, dissect_ansi_tcap_OBJECT_IDENTIFIER);
 
+       ansi_tcap_private.objectApplicationId_oid= (void*) oid_str;
+       ansi_tcap_private.oid_is_present=TRUE;
+
+
+
   return offset;
 }
 
@@ -525,14 +783,11 @@ dissect_ansi_tcap_T_componentIDs(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, i
 
 static int
 dissect_ansi_tcap_T_parameter(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 11 "ansi_tcap.cnf"
-tvbuff_t       *parameter_tvb;
-
-  offset = dissect_ber_octet_string(TRUE, actx, tree, tvb, offset, hf_index,
-                                       &parameter_tvb);
-  if(!parameter_tvb)
-       return offset;
+#line 23 "ansi_tcap.cnf"
 
+  if(find_tcap_subdissector(tvb, actx, tree))
+    offset = tvb_length(tvb);
+  
 
 
 
@@ -549,6 +804,11 @@ static const ber_sequence_t Invoke_sequence[] = {
 
 static int
 dissect_ansi_tcap_Invoke(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
+#line 29 "ansi_tcap.cnf"
+  ansi_tcap_private.d.pdu = 1;
+
+
+
   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
                                    Invoke_sequence, hf_index, ett_ansi_tcap_Invoke);
 
@@ -569,15 +829,9 @@ dissect_ansi_tcap_T_componentID(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, in
 
 static int
 dissect_ansi_tcap_T_parameter_01(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 23 "ansi_tcap.cnf"
-tvbuff_t       *parameter_tvb;
-
-proto_tree_add_text(tree, tvb, offset, -1, "ReturnResult/result/result");
-
-  offset = dissect_ber_octet_string(TRUE, actx, tree, tvb, offset, hf_index,
-                                       &parameter_tvb);
-
-
+#line 36 "ansi_tcap.cnf"
+  if(find_tcap_subdissector(tvb, actx, tree))
+    offset = tvb_length(tvb);
 
 
 
@@ -593,6 +847,12 @@ static const ber_sequence_t ReturnResult_sequence[] = {
 
 static int
 dissect_ansi_tcap_ReturnResult(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
+#line 40 "ansi_tcap.cnf"
+  ansi_tcap_private.d.pdu = 2;
+
+
+
+
   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
                                    ReturnResult_sequence, hf_index, ett_ansi_tcap_ReturnResult);
 
@@ -613,13 +873,9 @@ dissect_ansi_tcap_T_componentID_01(gboolean implicit_tag _U_, tvbuff_t *tvb _U_,
 
 static int
 dissect_ansi_tcap_T_parameter_02(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 37 "ansi_tcap.cnf"
-tvbuff_t       *parameter_tvb;
-
-proto_tree_add_text(tree, tvb, offset, -1, "ReturnError/parameter");
-
-  offset = dissect_ber_octet_string(TRUE, actx, tree, tvb, offset, hf_index,
-                                       &parameter_tvb);
+#line 46 "ansi_tcap.cnf"
+  if(find_tcap_subdissector(tvb, actx, tree))
+    offset = tvb_length(tvb);
 
 
 
@@ -636,6 +892,10 @@ static const ber_sequence_t ReturnError_sequence[] = {
 
 static int
 dissect_ansi_tcap_ReturnError(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
+#line 50 "ansi_tcap.cnf"
+  ansi_tcap_private.d.pdu = 3;
+
+
   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
                                    ReturnError_sequence, hf_index, ett_ansi_tcap_ReturnError);
 
@@ -683,7 +943,7 @@ static const value_string ansi_tcap_Problem_vals[] = {
 static int
 dissect_ansi_tcap_Problem(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
-                                  NULL);
+                                                NULL);
 
   return offset;
 }
@@ -822,6 +1082,20 @@ dissect_ansi_tcap_UniTransactionPDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_
 }
 
 
+
+static int
+dissect_ansi_tcap_T_unidirectional(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
+#line 62 "ansi_tcap.cnf"
+gp_tcapsrt_info->ope=TC_ANSI_ALL;
+col_set_str(actx->pinfo->cinfo, COL_INFO, "unidirectional ");
+
+
+  offset = dissect_ansi_tcap_UniTransactionPDU(implicit_tag, tvb, offset, actx, tree, hf_index);
+
+  return offset;
+}
+
+
 static const ber_sequence_t TransactionPDU_sequence[] = {
   { &hf_ansi_tcap_identifier, BER_CLASS_PRI, 7, BER_FLAGS_NOOWNTAG, dissect_ansi_tcap_TransactionID },
   { &hf_ansi_tcap_dialoguePortion, BER_CLASS_PRI, 25, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_ansi_tcap_DialoguePortion },
@@ -838,6 +1112,76 @@ dissect_ansi_tcap_TransactionPDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, i
 }
 
 
+
+static int
+dissect_ansi_tcap_T_queryWithPerm(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
+#line 66 "ansi_tcap.cnf"
+gp_tcapsrt_info->ope=TC_ANSI_ALL;
+col_set_str(actx->pinfo->cinfo, COL_INFO, "queryWithPerm ");
+
+
+  offset = dissect_ansi_tcap_TransactionPDU(implicit_tag, tvb, offset, actx, tree, hf_index);
+
+  return offset;
+}
+
+
+
+static int
+dissect_ansi_tcap_T_queryWithoutPerm(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
+#line 70 "ansi_tcap.cnf"
+gp_tcapsrt_info->ope=TC_ANSI_ALL;
+col_set_str(actx->pinfo->cinfo, COL_INFO, "queryWithoutPerm ");
+
+
+  offset = dissect_ansi_tcap_TransactionPDU(implicit_tag, tvb, offset, actx, tree, hf_index);
+
+  return offset;
+}
+
+
+
+static int
+dissect_ansi_tcap_T_response(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
+#line 74 "ansi_tcap.cnf"
+gp_tcapsrt_info->ope=TC_ANSI_ALL;
+col_set_str(actx->pinfo->cinfo, COL_INFO, "response ");
+
+
+  offset = dissect_ansi_tcap_TransactionPDU(implicit_tag, tvb, offset, actx, tree, hf_index);
+
+  return offset;
+}
+
+
+
+static int
+dissect_ansi_tcap_T_conversationWithPerm(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
+#line 78 "ansi_tcap.cnf"
+gp_tcapsrt_info->ope=TC_ANSI_ALL;
+col_set_str(actx->pinfo->cinfo, COL_INFO, "conversationWithPerm ");
+
+
+  offset = dissect_ansi_tcap_TransactionPDU(implicit_tag, tvb, offset, actx, tree, hf_index);
+
+  return offset;
+}
+
+
+
+static int
+dissect_ansi_tcap_T_conversationWithoutPerm(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
+#line 82 "ansi_tcap.cnf"
+gp_tcapsrt_info->ope=TC_ANSI_ALL;
+col_set_str(actx->pinfo->cinfo, COL_INFO, "conversationWithoutPerm ");
+
+
+  offset = dissect_ansi_tcap_TransactionPDU(implicit_tag, tvb, offset, actx, tree, hf_index);
+
+  return offset;
+}
+
+
 static const value_string ansi_tcap_P_Abort_cause_U_vals[] = {
   {   1, "unrecognizedPackageType" },
   {   2, "incorrectTransactionPortion" },
@@ -856,7 +1200,7 @@ static const value_string ansi_tcap_P_Abort_cause_U_vals[] = {
 static int
 dissect_ansi_tcap_P_Abort_cause_U(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
-                                  NULL);
+                                                NULL);
 
   return offset;
 }
@@ -920,6 +1264,20 @@ dissect_ansi_tcap_Abort(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset
 }
 
 
+
+static int
+dissect_ansi_tcap_T_abort(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
+#line 86 "ansi_tcap.cnf"
+gp_tcapsrt_info->ope=TC_ANSI_ABORT;
+col_set_str(actx->pinfo->cinfo, COL_INFO, "Abort ");
+
+
+  offset = dissect_ansi_tcap_Abort(implicit_tag, tvb, offset, actx, tree, hf_index);
+
+  return offset;
+}
+
+
 static const value_string ansi_tcap_PackageType_vals[] = {
   {   1, "unidirectional" },
   {   2, "queryWithPerm" },
@@ -932,13 +1290,13 @@ static const value_string ansi_tcap_PackageType_vals[] = {
 };
 
 static const ber_choice_t PackageType_choice[] = {
-  {   1, &hf_ansi_tcap_unidirectional, BER_CLASS_PRI, 1, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_UniTransactionPDU },
-  {   2, &hf_ansi_tcap_queryWithPerm, BER_CLASS_PRI, 2, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_TransactionPDU },
-  {   3, &hf_ansi_tcap_queryWithoutPerm, BER_CLASS_PRI, 3, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_TransactionPDU },
-  {   4, &hf_ansi_tcap_response  , BER_CLASS_PRI, 4, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_TransactionPDU },
-  {   5, &hf_ansi_tcap_conversationWithPerm, BER_CLASS_PRI, 5, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_TransactionPDU },
-  {   6, &hf_ansi_tcap_conversationWithoutPerm, BER_CLASS_PRI, 6, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_TransactionPDU },
-  {  22, &hf_ansi_tcap_abort     , BER_CLASS_PRI, 22, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_Abort },
+  {   1, &hf_ansi_tcap_unidirectional, BER_CLASS_PRI, 1, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_unidirectional },
+  {   2, &hf_ansi_tcap_queryWithPerm, BER_CLASS_PRI, 2, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_queryWithPerm },
+  {   3, &hf_ansi_tcap_queryWithoutPerm, BER_CLASS_PRI, 3, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_queryWithoutPerm },
+  {   4, &hf_ansi_tcap_response  , BER_CLASS_PRI, 4, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_response },
+  {   5, &hf_ansi_tcap_conversationWithPerm, BER_CLASS_PRI, 5, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_conversationWithPerm },
+  {   6, &hf_ansi_tcap_conversationWithoutPerm, BER_CLASS_PRI, 6, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_conversationWithoutPerm },
+  {  22, &hf_ansi_tcap_abort     , BER_CLASS_PRI, 22, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_abort },
   { 0, NULL, 0, 0, 0, NULL }
 };
 
@@ -953,7 +1311,7 @@ dissect_ansi_tcap_PackageType(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int
 
 
 /*--- End of included file: packet-ansi_tcap-fn.c ---*/
-#line 129 "packet-ansi_tcap-template.c"
+#line 334 "packet-ansi_tcap-template.c"
 
 
 
@@ -961,21 +1319,22 @@ dissect_ansi_tcap_PackageType(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int
 static void
 dissect_ansi_tcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
 {
-    proto_item         *item=NULL;
-    proto_tree         *tree=NULL;
-    proto_item         *stat_item=NULL;
-    proto_tree         *stat_tree=NULL;
-       gint                    offset = 0;
+    proto_item          *item=NULL;
+    proto_tree          *tree=NULL;
+#if 0
+    proto_item          *stat_item=NULL;
+    proto_tree          *stat_tree=NULL;
+        gint                    offset = 0;
     struct tcaphash_context_t * p_tcap_context;
     dissector_handle_t subdissector_handle;
-       asn1_ctx_t asn1_ctx;
-       asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
+#endif
+        asn1_ctx_t asn1_ctx;
+
+        asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
+        ansi_tcap_ctx_init(&ansi_tcap_private);
 
     tcap_top_tree = parent_tree;
-    if (check_col(pinfo->cinfo, COL_PROTOCOL))
-    {
-               col_set_str(pinfo->cinfo, COL_PROTOCOL, "ANSI TCAP");
-    }
+    col_set_str(pinfo->cinfo, COL_PROTOCOL, "ANSI TCAP");
 
     /* create display subtree for the protocol */
     if(parent_tree){
@@ -986,53 +1345,49 @@ dissect_ansi_tcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
     }
     cur_oid = NULL;
     tcapext_oid = NULL;
-    raz_tcap_private(&tcap_private);
 
-    pinfo->private_data = &tcap_private;
+    pinfo->private_data = &ansi_tcap_private;
     gp_tcapsrt_info=tcapsrt_razinfo();
     tcap_subdissector_used=FALSE;
     gp_tcap_context=NULL;
     dissect_ansi_tcap_PackageType(FALSE, tvb, 0, &asn1_ctx, tree, -1);
 
+#if 0 /* Skip this part for now it will be rewritten */
     if (g_ansi_tcap_HandleSRT && !tcap_subdissector_used ) {
-               if (gtcap_DisplaySRT && tree) {
-                       stat_item = proto_tree_add_text(tree, tvb, 0, 0, "Stat");
-                       PROTO_ITEM_SET_GENERATED(stat_item);
-                       stat_tree = proto_item_add_subtree(stat_item, ett_ansi_tcap_stat);
-               }
-               p_tcap_context=tcapsrt_call_matching(tvb, pinfo, stat_tree, gp_tcapsrt_info);
-               tcap_private.context=p_tcap_context;
-
-               /* If the current message is TCAP only,
-                * save the Application contexte name for the next messages
-                */
-               if ( p_tcap_context && cur_oid && !p_tcap_context->oid_present ) {
-                       /* Save the application context and the sub dissector */
-                       ber_oid_dissector_table = find_dissector_table("ber.oid");
-                       strncpy(p_tcap_context->oid,cur_oid, LENGTH_OID);
-                       if ( (subdissector_handle = dissector_get_string_handle(ber_oid_dissector_table, cur_oid)) ) {
-                               p_tcap_context->subdissector_handle=subdissector_handle;
-                               p_tcap_context->oid_present=TRUE;
-                       }
-               }
-               if (g_ansi_tcap_HandleSRT && p_tcap_context && p_tcap_context->callback) {
-                       /* Callback fonction for the upper layer */
-                       (p_tcap_context->callback)(tvb, pinfo, stat_tree, p_tcap_context);
-               }
-       }
+                if (gtcap_DisplaySRT && tree) {
+                        stat_item = proto_tree_add_text(tree, tvb, 0, 0, "Stat");
+                        PROTO_ITEM_SET_GENERATED(stat_item);
+                        stat_tree = proto_item_add_subtree(stat_item, ett_ansi_tcap_stat);
+                }
+                p_tcap_context=tcapsrt_call_matching(tvb, pinfo, stat_tree, gp_tcapsrt_info);
+                ansi_tcap_private.context=p_tcap_context;
+
+                /* If the current message is TCAP only,
+                 * save the Application contexte name for the next messages
+                 */
+                if ( p_tcap_context && cur_oid && !p_tcap_context->oid_present ) {
+                        /* Save the application context and the sub dissector */
+                        g_strlcpy(p_tcap_context->oid, cur_oid, sizeof(p_tcap_context->oid));
+                        if ( (subdissector_handle = dissector_get_string_handle(ber_oid_dissector_table, cur_oid)) ) {
+                                p_tcap_context->subdissector_handle=subdissector_handle;
+                                p_tcap_context->oid_present=TRUE;
+                        }
+                }
+                if (g_ansi_tcap_HandleSRT && p_tcap_context && p_tcap_context->callback) {
+                        /* Callback fonction for the upper layer */
+                        (p_tcap_context->callback)(tvb, pinfo, stat_tree, p_tcap_context);
+                }
+        }
+#endif
 }
 
-static void raz_tcap_private(struct tcap_private_t * p_tcap_private)
-{
-  memset(p_tcap_private,0,sizeof(struct tcap_private_t) );
-}
 
 void
 proto_reg_handoff_ansi_tcap(void)
 {
 
-       data_handle = find_dissector("data");
-
+        ansi_map_handle = find_dissector("ansi_map");
+        ber_oid_dissector_table = find_dissector_table("ber.oid");
 }
 
 
@@ -1040,275 +1395,261 @@ proto_reg_handoff_ansi_tcap(void)
 void
 proto_register_ansi_tcap(void)
 {
+    module_t    *ansi_tcap_module;
+
 
 /* Setup list of header fields  See Section 1.6.1 for details*/
     static hf_register_info hf[] = {
-       { &hf_ansi_tcap_tag,
-               { "Tag",           "tcap.msgtype",
-               FT_UINT8, BASE_HEX, NULL, 0,
-               "", HFILL }
-       },
-       { &hf_ansi_tcap_length,
-               { "Length", "tcap.len",
-               FT_UINT8, BASE_HEX, NULL, 0,
-               "", HFILL }
-       },
-       { &hf_ansi_tcap_data,
-               { "Data", "tcap.data",
-               FT_BYTES, BASE_HEX, NULL, 0,
-               "", HFILL }
-       },
-               { &hf_ansi_tcap_tid,
-               { "Transaction Id", "tcap.tid",
-               FT_BYTES, BASE_HEX, NULL, 0,
-               "", HFILL }
-       },
-       /* Tcap Service Response Time */
-       { &hf_ansi_tcapsrt_SessionId,
-         { "Session Id",
-           "tcap.srt.session_id",
-           FT_UINT32, BASE_DEC, NULL, 0x0,
-           "", HFILL }
-       },
-       { &hf_ansi_tcapsrt_BeginSession,
-         { "Begin Session",
-           "tcap.srt.begin",
-           FT_FRAMENUM, BASE_NONE, NULL, 0x0,
-           "SRT Begin of Session", HFILL }
-       },
-       { &hf_ansi_tcapsrt_EndSession,
-         { "End Session",
-           "tcap.srt.end",
-           FT_FRAMENUM, BASE_NONE, NULL, 0x0,
-           "SRT End of Session", HFILL }
-       },
-       { &hf_ansi_tcapsrt_SessionTime,
-         { "Session duration",
-           "tcap.srt.sessiontime",
-           FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
-           "Duration of the TCAP session", HFILL }
-       },
-       { &hf_ansi_tcapsrt_Duplicate,
-         { "Request Duplicate",
-           "tcap.srt.duplicate",
-           FT_UINT32, BASE_DEC, NULL, 0x0,
-           "", HFILL }
-       },
+        /* Tcap Service Response Time */
+        { &hf_ansi_tcapsrt_SessionId,
+          { "Session Id",
+            "ansi_tcap.srt.session_id",
+            FT_UINT32, BASE_DEC, NULL, 0x0,
+            NULL, HFILL }
+        },
+        { &hf_ansi_tcapsrt_BeginSession,
+          { "Begin Session",
+            "ansi_tcap.srt.begin",
+            FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+            "SRT Begin of Session", HFILL }
+        },
+        { &hf_ansi_tcapsrt_EndSession,
+          { "End Session",
+            "ansi_tcap.srt.end",
+            FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+            "SRT End of Session", HFILL }
+        },
+        { &hf_ansi_tcapsrt_SessionTime,
+          { "Session duration",
+            "ansi_tcap.srt.sessiontime",
+            FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
+            "Duration of the TCAP session", HFILL }
+        },
+        { &hf_ansi_tcapsrt_Duplicate,
+          { "Request Duplicate",
+            "ansi_tcap.srt.duplicate",
+            FT_UINT32, BASE_DEC, NULL, 0x0,
+            NULL, HFILL }
+        },
 
 /*--- Included file: packet-ansi_tcap-hfarr.c ---*/
 #line 1 "packet-ansi_tcap-hfarr.c"
     { &hf_ansi_tcap_national,
       { "national", "ansi_tcap.national",
         FT_INT32, BASE_DEC, NULL, 0,
-        "ansi_tcap.INTEGER_M32768_32767", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_private,
       { "private", "ansi_tcap.private",
         FT_INT32, BASE_DEC, NULL, 0,
-        "ansi_tcap.INTEGER", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_national_01,
       { "national", "ansi_tcap.national",
         FT_INT32, BASE_DEC, NULL, 0,
-        "ansi_tcap.INTEGER_M128_127", HFILL }},
+        "INTEGER_M128_127", HFILL }},
+    { &hf_ansi_tcap_private_01,
+      { "private", "ansi_tcap.private",
+        FT_INT32, BASE_DEC, NULL, 0,
+        "INTEGER", HFILL }},
     { &hf_ansi_tcap_unidirectional,
       { "unidirectional", "ansi_tcap.unidirectional",
         FT_NONE, BASE_NONE, NULL, 0,
-        "ansi_tcap.UniTransactionPDU", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_queryWithPerm,
       { "queryWithPerm", "ansi_tcap.queryWithPerm",
         FT_NONE, BASE_NONE, NULL, 0,
-        "ansi_tcap.TransactionPDU", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_queryWithoutPerm,
       { "queryWithoutPerm", "ansi_tcap.queryWithoutPerm",
         FT_NONE, BASE_NONE, NULL, 0,
-        "ansi_tcap.TransactionPDU", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_response,
       { "response", "ansi_tcap.response",
         FT_NONE, BASE_NONE, NULL, 0,
-        "ansi_tcap.TransactionPDU", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_conversationWithPerm,
       { "conversationWithPerm", "ansi_tcap.conversationWithPerm",
         FT_NONE, BASE_NONE, NULL, 0,
-        "ansi_tcap.TransactionPDU", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_conversationWithoutPerm,
       { "conversationWithoutPerm", "ansi_tcap.conversationWithoutPerm",
         FT_NONE, BASE_NONE, NULL, 0,
-        "ansi_tcap.TransactionPDU", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_abort,
       { "abort", "ansi_tcap.abort",
         FT_NONE, BASE_NONE, NULL, 0,
-        "ansi_tcap.Abort", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_identifier,
       { "identifier", "ansi_tcap.identifier",
-        FT_BYTES, BASE_HEX, NULL, 0,
-        "ansi_tcap.TransactionID", HFILL }},
+        FT_BYTES, BASE_NONE, NULL, 0,
+        "TransactionID", HFILL }},
     { &hf_ansi_tcap_dialoguePortion,
       { "dialoguePortion", "ansi_tcap.dialoguePortion",
         FT_NONE, BASE_NONE, NULL, 0,
-        "ansi_tcap.DialoguePortion", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_componentPortion,
       { "componentPortion", "ansi_tcap.componentPortion",
         FT_UINT32, BASE_DEC, NULL, 0,
-        "ansi_tcap.ComponentSequence", HFILL }},
+        "ComponentSequence", HFILL }},
     { &hf_ansi_tcap_dialogPortion,
       { "dialogPortion", "ansi_tcap.dialogPortion",
         FT_NONE, BASE_NONE, NULL, 0,
-        "ansi_tcap.DialoguePortion", HFILL }},
+        "DialoguePortion", HFILL }},
     { &hf_ansi_tcap_causeInformation,
       { "causeInformation", "ansi_tcap.causeInformation",
         FT_UINT32, BASE_DEC, VALS(ansi_tcap_T_causeInformation_vals), 0,
-        "ansi_tcap.T_causeInformation", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_abortCause,
       { "abortCause", "ansi_tcap.abortCause",
-        FT_INT32, BASE_DEC, NULL, 0,
-        "ansi_tcap.P_Abort_cause", HFILL }},
+        FT_INT32, BASE_DEC, VALS(ansi_tcap_P_Abort_cause_U_vals), 0,
+        "P_Abort_cause", HFILL }},
     { &hf_ansi_tcap_userInformation,
       { "userInformation", "ansi_tcap.userInformation",
         FT_NONE, BASE_NONE, NULL, 0,
-        "ansi_tcap.UserAbortInformation", HFILL }},
+        "UserAbortInformation", HFILL }},
     { &hf_ansi_tcap_version,
       { "version", "ansi_tcap.version",
-        FT_BYTES, BASE_HEX, NULL, 0,
-        "ansi_tcap.ProtocolVersion", HFILL }},
+        FT_BYTES, BASE_NONE, NULL, 0,
+        "ProtocolVersion", HFILL }},
     { &hf_ansi_tcap_applicationContext,
       { "applicationContext", "ansi_tcap.applicationContext",
         FT_UINT32, BASE_DEC, VALS(ansi_tcap_T_applicationContext_vals), 0,
-        "ansi_tcap.T_applicationContext", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_integerApplicationId,
       { "integerApplicationId", "ansi_tcap.integerApplicationId",
         FT_INT32, BASE_DEC, NULL, 0,
-        "ansi_tcap.IntegerApplicationContext", HFILL }},
+        "IntegerApplicationContext", HFILL }},
     { &hf_ansi_tcap_objectApplicationId,
       { "objectApplicationId", "ansi_tcap.objectApplicationId",
         FT_OID, BASE_NONE, NULL, 0,
-        "ansi_tcap.ObjectIDApplicationContext", HFILL }},
+        "ObjectIDApplicationContext", HFILL }},
     { &hf_ansi_tcap_userInformation_01,
       { "userInformation", "ansi_tcap.userInformation",
         FT_UINT32, BASE_DEC, NULL, 0,
-        "ansi_tcap.UserInformation", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_securityContext,
       { "securityContext", "ansi_tcap.securityContext",
         FT_UINT32, BASE_DEC, VALS(ansi_tcap_T_securityContext_vals), 0,
-        "ansi_tcap.T_securityContext", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_integerSecurityId,
       { "integerSecurityId", "ansi_tcap.integerSecurityId",
         FT_INT32, BASE_DEC, NULL, 0,
-        "ansi_tcap.INTEGER", HFILL }},
+        "INTEGER", HFILL }},
     { &hf_ansi_tcap_objectSecurityId,
       { "objectSecurityId", "ansi_tcap.objectSecurityId",
         FT_OID, BASE_NONE, NULL, 0,
-        "ansi_tcap.OBJECT_IDENTIFIER", HFILL }},
+        "OBJECT_IDENTIFIER", HFILL }},
     { &hf_ansi_tcap_confidentiality,
       { "confidentiality", "ansi_tcap.confidentiality",
         FT_NONE, BASE_NONE, NULL, 0,
-        "ansi_tcap.Confidentiality", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap__untag_item,
-      { "Item", "ansi_tcap._untag_item",
+      { "_untag item", "ansi_tcap._untag_item",
         FT_NONE, BASE_NONE, NULL, 0,
-        "ansi_tcap.EXTERNAL", HFILL }},
+        "EXTERNAL", HFILL }},
     { &hf_ansi_tcap_confidentialityId,
       { "confidentialityId", "ansi_tcap.confidentialityId",
         FT_UINT32, BASE_DEC, VALS(ansi_tcap_T_confidentialityId_vals), 0,
-        "ansi_tcap.T_confidentialityId", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_integerConfidentialityId,
       { "integerConfidentialityId", "ansi_tcap.integerConfidentialityId",
         FT_INT32, BASE_DEC, NULL, 0,
-        "ansi_tcap.INTEGER", HFILL }},
+        "INTEGER", HFILL }},
     { &hf_ansi_tcap_objectConfidentialityId,
       { "objectConfidentialityId", "ansi_tcap.objectConfidentialityId",
         FT_OID, BASE_NONE, NULL, 0,
-        "ansi_tcap.OBJECT_IDENTIFIER", HFILL }},
+        "OBJECT_IDENTIFIER", HFILL }},
     { &hf_ansi_tcap__untag_item_01,
-      { "Item", "ansi_tcap._untag_item",
+      { "ComponentPDU", "ansi_tcap.ComponentPDU",
         FT_UINT32, BASE_DEC, VALS(ansi_tcap_ComponentPDU_vals), 0,
-        "ansi_tcap.ComponentPDU", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_invokeLast,
       { "invokeLast", "ansi_tcap.invokeLast",
         FT_NONE, BASE_NONE, NULL, 0,
-        "ansi_tcap.Invoke", HFILL }},
+        "Invoke", HFILL }},
     { &hf_ansi_tcap_returnResultLast,
       { "returnResultLast", "ansi_tcap.returnResultLast",
         FT_NONE, BASE_NONE, NULL, 0,
-        "ansi_tcap.ReturnResult", HFILL }},
+        "ReturnResult", HFILL }},
     { &hf_ansi_tcap_returnError,
       { "returnError", "ansi_tcap.returnError",
         FT_NONE, BASE_NONE, NULL, 0,
-        "ansi_tcap.ReturnError", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_reject,
       { "reject", "ansi_tcap.reject",
         FT_NONE, BASE_NONE, NULL, 0,
-        "ansi_tcap.Reject", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_invokeNotLast,
       { "invokeNotLast", "ansi_tcap.invokeNotLast",
         FT_NONE, BASE_NONE, NULL, 0,
-        "ansi_tcap.Invoke", HFILL }},
+        "Invoke", HFILL }},
     { &hf_ansi_tcap_returnResultNotLast,
       { "returnResultNotLast", "ansi_tcap.returnResultNotLast",
         FT_NONE, BASE_NONE, NULL, 0,
-        "ansi_tcap.ReturnResult", HFILL }},
+        "ReturnResult", HFILL }},
     { &hf_ansi_tcap_componentIDs,
       { "componentIDs", "ansi_tcap.componentIDs",
-        FT_BYTES, BASE_HEX, NULL, 0,
-        "ansi_tcap.T_componentIDs", HFILL }},
+        FT_BYTES, BASE_NONE, NULL, 0,
+        NULL, HFILL }},
     { &hf_ansi_tcap_operationCode,
       { "operationCode", "ansi_tcap.operationCode",
         FT_UINT32, BASE_DEC, VALS(ansi_tcap_OperationCode_vals), 0,
-        "ansi_tcap.OperationCode", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_parameter,
       { "parameter", "ansi_tcap.parameter",
-        FT_BYTES, BASE_HEX, NULL, 0,
-        "ansi_tcap.T_parameter", HFILL }},
+        FT_NONE, BASE_NONE, NULL, 0,
+        NULL, HFILL }},
     { &hf_ansi_tcap_componentID,
       { "componentID", "ansi_tcap.componentID",
-        FT_BYTES, BASE_HEX, NULL, 0,
-        "ansi_tcap.T_componentID", HFILL }},
+        FT_BYTES, BASE_NONE, NULL, 0,
+        NULL, HFILL }},
     { &hf_ansi_tcap_parameter_01,
       { "parameter", "ansi_tcap.parameter",
-        FT_BYTES, BASE_HEX, NULL, 0,
-        "ansi_tcap.T_parameter_01", HFILL }},
+        FT_NONE, BASE_NONE, NULL, 0,
+        "T_parameter_01", HFILL }},
     { &hf_ansi_tcap_componentID_01,
       { "componentID", "ansi_tcap.componentID",
-        FT_BYTES, BASE_HEX, NULL, 0,
-        "ansi_tcap.T_componentID_01", HFILL }},
+        FT_BYTES, BASE_NONE, NULL, 0,
+        "T_componentID_01", HFILL }},
     { &hf_ansi_tcap_errorCode,
       { "errorCode", "ansi_tcap.errorCode",
         FT_UINT32, BASE_DEC, VALS(ansi_tcap_ErrorCode_vals), 0,
-        "ansi_tcap.ErrorCode", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_parameter_02,
       { "parameter", "ansi_tcap.parameter",
-        FT_BYTES, BASE_HEX, NULL, 0,
-        "ansi_tcap.T_parameter_02", HFILL }},
+        FT_NONE, BASE_NONE, NULL, 0,
+        "T_parameter_02", HFILL }},
     { &hf_ansi_tcap_componentID_02,
       { "componentID", "ansi_tcap.componentID",
-        FT_BYTES, BASE_HEX, NULL, 0,
-        "ansi_tcap.OCTET_STRING_SIZE_0_1", HFILL }},
+        FT_BYTES, BASE_NONE, NULL, 0,
+        "OCTET_STRING_SIZE_0_1", HFILL }},
     { &hf_ansi_tcap_rejectProblem,
       { "rejectProblem", "ansi_tcap.rejectProblem",
         FT_INT32, BASE_DEC, VALS(ansi_tcap_Problem_vals), 0,
-        "ansi_tcap.Problem", HFILL }},
+        "Problem", HFILL }},
     { &hf_ansi_tcap_parameter_03,
       { "parameter", "ansi_tcap.parameter",
         FT_UINT32, BASE_DEC, VALS(ansi_tcap_T_parameter_03_vals), 0,
-        "ansi_tcap.T_parameter_03", HFILL }},
+        "T_parameter_03", HFILL }},
     { &hf_ansi_tcap_paramSequence,
       { "paramSequence", "ansi_tcap.paramSequence",
         FT_NONE, BASE_NONE, NULL, 0,
-        "ansi_tcap.T_paramSequence", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_paramSet,
       { "paramSet", "ansi_tcap.paramSet",
         FT_NONE, BASE_NONE, NULL, 0,
-        "ansi_tcap.T_paramSet", HFILL }},
+        NULL, HFILL }},
 
 /*--- End of included file: packet-ansi_tcap-hfarr.c ---*/
-#line 270 "packet-ansi_tcap-template.c"
+#line 454 "packet-ansi_tcap-template.c"
     };
 
 /* Setup protocol subtree array */
     static gint *ett[] = {
-       &ett_tcap,
-       &ett_param,
-       &ett_otid,
-       &ett_dtid,
-       &ett_ansi_tcap_stat,
+        &ett_tcap,
+        &ett_param,
+        &ett_otid,
+        &ett_dtid,
+        &ett_ansi_tcap_stat,
 
 /*--- Included file: packet-ansi_tcap-ettarr.c ---*/
 #line 1 "packet-ansi_tcap-ettarr.c"
@@ -1336,36 +1677,33 @@ proto_register_ansi_tcap(void)
     &ett_ansi_tcap_T_paramSet,
 
 /*--- End of included file: packet-ansi_tcap-ettarr.c ---*/
-#line 280 "packet-ansi_tcap-template.c"
+#line 464 "packet-ansi_tcap-template.c"
     };
 
-    /*static enum_val_t tcap_options[] = {
-       { "itu", "ITU",  ITU_TCAP_STANDARD },
-       { "ansi", "ANSI", ANSI_TCAP_STANDARD },
-       { NULL, NULL, 0 }
-    };*/
+       static enum_val_t ansi_tcap_response_matching_type_values[] = {
+               {"Only Transaction ID will be used in Invoke/response matching",                                        "Transaction ID only", 0},
+               {"Transaction ID and Source will be used in Invoke/response matching",                          "Transaction ID and Source", 1}, 
+               {"Transaction ID Source and Destination will be used in Invoke/response matching",      "Transaction ID Source and Destination", 2},
+               {NULL, NULL, -1}
+       };
 
 
 /* Register the protocol name and description */
     proto_ansi_tcap = proto_register_protocol(PNAME, PSNAME, PFNAME);
-       register_dissector("ansi_tcap", dissect_ansi_tcap, proto_ansi_tcap);
+        register_dissector("ansi_tcap", dissect_ansi_tcap, proto_ansi_tcap);
 
 /* Required function calls to register the header fields and subtrees used */
     proto_register_field_array(proto_ansi_tcap, hf, array_length(hf));
     proto_register_subtree_array(ett, array_length(ett));
 
+    ansi_tcap_module = prefs_register_protocol(proto_ansi_tcap, proto_reg_handoff_ansi_tcap);
 
-}
-
-
-
-
-
-
-
-
-
-
+       prefs_register_enum_preference(ansi_tcap_module, "transaction.matchtype",
+                                      "Type of matching invoke/response",
+                                      "Type of matching invoke/response, risk of missmatch if loose matching choosen",
+                                      &ansi_tcap_response_matching_type, ansi_tcap_response_matching_type_values, FALSE);
 
+    register_init_routine(&ansi_tcap_init_protocol);
+}