diff options
author | Anders Broman <anders.broman@ericsson.com> | 2013-02-18 19:34:04 +0000 |
---|---|---|
committer | Anders Broman <anders.broman@ericsson.com> | 2013-02-18 19:34:04 +0000 |
commit | b38062ff8f502b985ad6ebfb5fcc3b640203eafd (patch) | |
tree | 9d02e051b0c7a402af8b1b015877d9b50bae978a /asn1/isdn-sup/packet-isdn-sup-template.c | |
parent | 6a420594ab263a819d082fa871e63e64fc78d249 (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.c | 84 |
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" }; |