aboutsummaryrefslogtreecommitdiffstats
path: root/asn1/isdn-sup/packet-isdn-sup-template.c
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2013-02-18 19:34:04 +0000
committerAnders Broman <anders.broman@ericsson.com>2013-02-18 19:34:04 +0000
commitb38062ff8f502b985ad6ebfb5fcc3b640203eafd (patch)
tree9d02e051b0c7a402af8b1b015877d9b50bae978a /asn1/isdn-sup/packet-isdn-sup-template.c
parent6a420594ab263a819d082fa871e63e64fc78d249 (diff)
Dissect more supplementarry services
svn path=/trunk/; revision=47738
Diffstat (limited to 'asn1/isdn-sup/packet-isdn-sup-template.c')
-rw-r--r--asn1/isdn-sup/packet-isdn-sup-template.c84
1 files changed, 80 insertions, 4 deletions
diff --git a/asn1/isdn-sup/packet-isdn-sup-template.c b/asn1/isdn-sup/packet-isdn-sup-template.c
index b96762e226..30a40f1333 100644
--- a/asn1/isdn-sup/packet-isdn-sup-template.c
+++ b/asn1/isdn-sup/packet-isdn-sup-template.c
@@ -40,6 +40,7 @@
/* Initialize the protocol and registered fields */
static int proto_isdn_sup = -1;
static int hf_isdn_sup_operation = -1;
+static int hf_isdn_sup_error = -1;
/* Global variables */
@@ -54,17 +55,23 @@ typedef struct _isdn_sup_op_t {
new_dissector_t res_pdu;
} isdn_sup_op_t;
+
+typedef struct isdn_sup_err_t {
+ gint32 errcode;
+ new_dissector_t err_pdu;
+} isdn_sup_err_t;
+
static const value_string isdn_sup_str_operation[] = {
#include "packet-isdn-sup-table10.c"
{ 0, NULL}
};
-#if 0
+
static const value_string isdn_sup_str_error[] = {
#include "packet-isdn-sup-table20.c"
{ 0, NULL}
};
-#endif
+
static int hf_isdn_sup = -1;
#include "packet-isdn-sup-hf.c"
@@ -86,11 +93,11 @@ static const isdn_sup_op_t isdn_sup_op_tab[] = {
#include "packet-isdn-sup-table11.c"
};
-#if 0
+
static const isdn_sup_err_t isdn_sup_err_tab[] = {
#include "packet-isdn-sup-table21.c"
};
-#endif
+
static const isdn_sup_op_t *get_op(gint32 opcode) {
int i;
@@ -102,6 +109,16 @@ static const isdn_sup_op_t *get_op(gint32 opcode) {
return NULL;
}
+static const isdn_sup_err_t *get_err(gint32 errcode) {
+ int i;
+
+ /* search from the end to get the last occurence if the operation is redefined in some newer specification */
+ for (i = array_length(isdn_sup_err_tab) - 1; i >= 0; i--)
+ if (isdn_sup_err_tab[i].errcode == errcode)
+ return &isdn_sup_err_tab[i];
+ return NULL;
+}
+
/*--- dissect_isdn_sup_arg ------------------------------------------------------*/
static int
dissect_isdn_sup_arg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
@@ -197,6 +214,51 @@ dissect_isdn_sup_res(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *
}
+/*--- dissect_isdn_sup_err ------------------------------------------------------*/
+static int
+dissect_isdn_sup_err(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
+ int offset;
+ rose_ctx_t *rctx;
+ gint32 errcode;
+ const isdn_sup_err_t *err_ptr;
+ const gchar *p;
+ proto_item *ti;
+ proto_tree *isdn_sup_tree;
+
+ offset = 0;
+ rctx = get_rose_ctx(pinfo->private_data);
+ DISSECTOR_ASSERT(rctx);
+ if (rctx->d.pdu != 3) /* returnError */
+ return offset;
+ if (rctx->d.code != 0) /* local */
+ return offset;
+ errcode = rctx->d.code_local;
+ err_ptr = get_err(errcode);
+ if (!err_ptr)
+ return offset;
+
+ ti = proto_tree_add_item(tree, proto_isdn_sup, tvb, offset, tvb_length(tvb), ENC_NA);
+ isdn_sup_tree = proto_item_add_subtree(ti, ett_isdn_sup);
+
+ proto_tree_add_uint(isdn_sup_tree, hf_isdn_sup_error, tvb, 0, 0, errcode);
+ p = match_strval(errcode, VALS(isdn_sup_str_error));
+ if (p) {
+ proto_item_append_text(ti, ": %s", p);
+ proto_item_append_text(rctx->d.code_item, " - %s", p);
+ if (rctx->apdu_depth >= 0)
+ proto_item_append_text(proto_item_get_parent_nth(proto_tree_get_parent(tree), rctx->apdu_depth), " %s", p);
+ }
+
+ if (err_ptr->err_pdu)
+ offset = err_ptr->err_pdu(tvb, pinfo, isdn_sup_tree, NULL);
+ else
+ if (tvb_length_remaining(tvb, offset) > 0) {
+ proto_tree_add_text(isdn_sup_tree, tvb, offset, -1, "UNSUPPORTED ERROR TYPE (ETSI sup)");
+ offset += tvb_length_remaining(tvb, offset);
+ }
+
+ return offset;
+}
/*--- proto_reg_handoff_isdn_sup ---------------------------------------*/
@@ -208,6 +270,7 @@ void proto_reg_handoff_isdn_sup(void) {
#endif
dissector_handle_t isdn_sup_arg_handle;
dissector_handle_t isdn_sup_res_handle;
+ dissector_handle_t isdn_sup_err_handle;
#if 0
q931_handle = find_dissector("q931");
@@ -220,6 +283,13 @@ void proto_reg_handoff_isdn_sup(void) {
dissector_add_uint("q932.ros.etsi.local.res", isdn_sup_op_tab[i].opcode, isdn_sup_res_handle);
}
+ isdn_sup_err_handle = new_create_dissector_handle(dissect_isdn_sup_err, proto_isdn_sup);
+
+ for (i=0; i<(int)array_length(isdn_sup_err_tab); i++) {
+ dissector_add_uint("q932.ros.etsi.local.err", isdn_sup_err_tab[i].errcode, isdn_sup_err_handle);
+ }
+
+
}
void proto_register_isdn_sup(void) {
@@ -236,6 +306,12 @@ void proto_register_isdn_sup(void) {
FT_UINT8, BASE_DEC, VALS(isdn_sup_str_operation), 0x0,
NULL, HFILL }
},
+ { &hf_isdn_sup_error,
+ { "Error", "isdn_sup.error",
+ FT_UINT8, BASE_DEC, VALS(isdn_sup_str_error), 0x0,
+ NULL, HFILL }
+ },
+
#include "packet-isdn-sup-hfarr.c"
};