Witness: enum witness_notifyResponse_type
[wireshark-wip.git] / asn1 / qsig / packet-qsig-template.c
blob67069b29a7c7fa43bac6cb0bf827f1083c7b9e44
1 /* packet-qsig.c
2 * Routines for QSIG packet dissection
3 * 2007 Tomas Kukosa
5 * $Id$
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include "config.h"
28 #include <epan/packet.h>
29 #include <epan/strutil.h>
30 #include <epan/asn1.h>
32 #include "packet-ber.h"
33 #include "packet-qsig.h"
35 #define PNAME "QSIG"
36 #define PSNAME "QSIG"
37 #define PFNAME "qsig"
39 /* Shifted codeset values */
40 #define CS0 0x000
41 #define CS1 0x100
42 #define CS2 0x200
43 #define CS3 0x300
44 #define CS4 0x400
45 #define CS5 0x500
46 #define CS6 0x600
47 #define CS7 0x700
49 #define QSIG_IE_TRANSIT_COUNTER 0x31
50 #define QSIG_IE_PARTY_CATEGORY 0x32
52 void proto_register_qsig(void);
53 void proto_reg_handoff_qsig(void);
55 static const value_string qsig_str_ie_type_cs4[] = {
56 { QSIG_IE_TRANSIT_COUNTER , "Transit counter" },
57 { 0, NULL}
59 static const value_string qsig_str_ie_type_cs5[] = {
60 { QSIG_IE_PARTY_CATEGORY , "Party category" },
61 { 0, NULL}
63 /* Codeset array */
64 static const value_string *qsig_str_ie_type[] = {
65 NULL,
66 NULL,
67 NULL,
68 NULL,
69 qsig_str_ie_type_cs4,
70 qsig_str_ie_type_cs5,
71 NULL,
72 NULL,
76 static const value_string qsig_str_pc[] = {
77 { 0x00 , "unknown" },
78 { 0x01 , "extension" },
79 { 0x02 , "operator" },
80 { 0x03 , "emergency extension" },
81 { 0, NULL}
84 static const value_string qsig_str_service[] = {
85 { 13868, "QSIG-NA" },
86 { 13873, "QSIG-CF" },
87 { 13874, "QSIG-PR" },
88 { 13869, "QSIG-CT" },
89 { 13870, "QSIG-CC" },
90 { 14843, "QSIG-CO" },
91 { 14844, "QSIG-DND(O)" },
92 { 14846, "QSIG-CI" },
93 { 15050, "QSIG-AOC" },
94 { 15052, "QSIG-RE" },
95 { 15054, "QSIG-CINT" },
96 { 15506, "QSIG-MWI" },
97 { 15507, "SYNC-SIG" },
98 { 15772, "QSIG-CMN" },
99 { 15992, "QSIG-CPI(P)" },
100 { 17876, "QSIG-PUMR" },
101 { 17878, "QSIG-PUMCH" },
102 { 19460, "QSIG-SSCT" },
103 { 15429, "QSIG-WTMLR" },
104 { 15431, "QSIG-WTMCH" },
105 { 15433, "QSIG-WTMAU" },
106 { 21407, "QSIG-SD" },
107 { 21889, "QSIG-CIDL" },
108 { 325, "QSIG-SMS" },
109 { 344, "QSIG-MCR" },
110 { 3471, "QSIG-MCM" },
111 { 3472, "QSIG-MID" },
112 { 0, NULL}
115 static const value_string qsig_str_service_name[] = {
116 { 13868, "Name-Operations" },
117 { 13873, "Call-Diversion-Operations" },
118 { 13874, "Path-Replacement-Operations" },
119 { 13869, "Call-Transfer-Operations" },
120 { 13870, "SS-CC-Operations" },
121 { 14843, "Call-Offer-Operations" },
122 { 14844, "Do-Not-Disturb-Operations" },
123 { 14846, "Call-Intrusion-Operations" },
124 { 15050, "SS-AOC-Operation" },
125 { 15052, "Recall-Operation" },
126 { 15054, "Call-Interception-Operations" },
127 { 15506, "SS-MWI-Operations" },
128 { 15507, "Synchronization-Operations" },
129 { 15772, "Common-Information-Operations" },
130 { 15992, "Call-Interruption-Operation" },
131 { 17876, "PUM-Registration-Operation" },
132 { 17878, "Private-User-Mobility-Call-Handling-Operations" },
133 { 19460, "Single-Step-Call-Transfer-Operations" },
134 { 15429, "WTM-Location-Registration-Operations" },
135 { 15431, "Wireless-Terminal-Call-Handling-Operations" },
136 { 15433, "WTM-Authentication-Operations" },
137 { 21407, "SS-SD-Operations" },
138 { 21889, "Call-Identification-and-Call-Linkage-Operations" },
139 { 325, "Short-Message-Service-Operations" },
140 { 344, "SS-MCR-Operations" },
141 { 3471, "SS-MCM-Operations" },
142 { 3472, "SS-MID-Operations" },
143 { 0, NULL}
146 #define NO_SRV (-1)
147 static const gint32 op2srv_tab[] = {
148 /* 0 */ 13868,
149 /* 1 */ 13868,
150 /* 2 */ 13868,
151 /* 3 */ 13868,
152 /* 4 */ 13874,
153 /* 5 */ 13874,
154 /* 6 */ 13874,
155 /* 7 */ 13869,
156 /* 8 */ 13869,
157 /* 9 */ 13869,
158 /* 10 */ 13869,
159 /* 11 */ 13869,
160 /* 12 */ 13869,
161 /* 13 */ 13869,
162 /* 14 */ 13869,
163 /* 15 */ 13873,
164 /* 16 */ 13873,
165 /* 17 */ 13873,
166 /* 18 */ 13873,
167 /* 19 */ 13873,
168 /* 20 */ 13873,
169 /* 21 */ 13873,
170 /* 22 */ 13873,
171 /* 23 */ 13873,
172 /* 24 */ NO_SRV,
173 /* 25 */ NO_SRV,
174 /* 26 */ NO_SRV,
175 /* 27 */ 13870,
176 /* 28 */ 13870,
177 /* 29 */ 13870,
178 /* 30 */ 13870,
179 /* 31 */ 13870,
180 /* 32 */ 13870,
181 /* 33 */ 13870,
182 /* 34 */ 14843,
183 /* 35 */ 14844,
184 /* 36 */ 14844,
185 /* 37 */ 14844,
186 /* 38 */ 14844,
187 /* 39 */ 14844,
188 /* 40 */ 13870,
189 /* 41 */ 90001,
190 /* 42 */ 90001,
191 /* 43 */ 14846,
192 /* 44 */ 14846,
193 /* 45 */ 14846,
194 /* 46 */ 14846,
195 /* 47 */ 14846,
196 /* 48 */ 14846,
197 /* 49 */ 90001,
198 /* 50 */ 15429,
199 /* 51 */ 15429,
200 /* 52 */ 15429,
201 /* 53 */ 15429,
202 /* 54 */ 15431,
203 /* 55 */ 15431,
204 /* 56 */ 15431,
205 /* 57 */ 15052,
206 /* 58 */ 15052,
207 /* 59 */ 15050,
208 /* 60 */ 15050,
209 /* 61 */ 15050,
210 /* 62 */ 15050,
211 /* 63 */ 15050,
212 /* 64 */ 15050,
213 /* 65 */ 15050,
214 /* 66 */ 15054,
215 /* 67 */ 15054,
216 /* 68 */ 15054,
217 /* 69 */ 15054,
218 /* 70 */ 15054,
219 /* 71 */ 15431,
220 /* 72 */ 15433,
221 /* 73 */ 15433,
222 /* 74 */ 15433,
223 /* 75 */ 15433,
224 /* 76 */ 15433,
225 /* 77 */ 15433,
226 /* 78 */ 15507,
227 /* 79 */ 15507,
228 /* 80 */ 3471,
229 /* 81 */ 3471,
230 /* 82 */ 3471,
231 /* 83 */ NO_SRV,
232 /* 84 */ 15772,
233 /* 85 */ 15772,
234 /* 86 */ 13874,
235 /* 87 */ 15992,
236 /* 88 */ 15992,
237 /* 89 */ 17876,
238 /* 90 */ 17876,
239 /* 91 */ 17876,
240 /* 92 */ 17876,
241 /* 93 */ 17878,
242 /* 94 */ 17878,
243 /* 95 */ 17878,
244 /* 96 */ 17878,
245 /* 97 */ 15429,
246 /* 98 */ 15429,
247 /* 99 */ 19460,
248 /* 100 */ 19460,
249 /* 101 */ 19460,
250 /* 102 */ 19460,
251 /* 103 */ 21407,
252 /* 104 */ 21407,
253 /* 105 */ 21889,
254 /* 106 */ 21889,
255 /* 107 */ 325,
256 /* 108 */ 325,
257 /* 109 */ 325,
258 /* 110 */ 325,
259 /* 111 */ 325,
260 /* 112 */ 344,
261 /* 113 */ 344,
262 /* 114 */ 344,
263 /* 115 */ 3471,
264 /* 116 */ 3471,
265 /* 117 */ 3471,
266 /* 118 */ 3471,
267 /* 119 */ 3472,
268 /* 120 */ 3472,
271 static const value_string qsig_str_operation[] = {
272 #include "packet-qsig-table10.c"
273 { 0, NULL}
276 static const value_string qsig_str_error[] = {
277 #include "packet-qsig-table20.c"
278 { 0, NULL}
281 /* Initialize the protocol and registered fields */
282 static int proto_qsig = -1;
283 static int hf_qsig_operation = -1;
284 static int hf_qsig_service = -1;
285 static int hf_qsig_error = -1;
286 static int hf_qsig_ie_type = -1;
287 static int hf_qsig_ie_type_cs4 = -1;
288 static int hf_qsig_ie_type_cs5 = -1;
289 static int hf_qsig_ie_len = -1;
290 static int hf_qsig_ie_data = -1;
291 static int hf_qsig_tc = -1;
292 static int hf_qsig_pc = -1;
293 #include "packet-qsig-hf.c"
295 static int *hf_qsig_ie_type_arr[] = {
296 NULL,
297 NULL,
298 NULL,
299 NULL,
300 &hf_qsig_ie_type_cs4,
301 &hf_qsig_ie_type_cs5,
302 NULL,
303 NULL,
306 /* Initialize the subtree pointers */
307 static gint ett_qsig = -1;
308 static gint ett_qsig_ie = -1;
309 static gint ett_qsig_unknown_extension = -1;
310 #include "packet-qsig-ett.c"
311 static gint ett_cnq_PSS1InformationElement = -1;
313 /* Preferences */
315 /* Subdissectors */
316 static dissector_handle_t q931_ie_handle = NULL;
318 /* Global variables */
319 static const char *extension_oid = NULL;
320 static GHashTable *qsig_opcode2oid_hashtable = NULL;
321 static GHashTable *qsig_oid2op_hashtable = NULL;
323 /* Dissector tables */
324 static dissector_table_t extension_dissector_table;
326 #include "packet-qsig-fn.c"
328 typedef struct _qsig_op_t {
329 gint32 opcode;
330 new_dissector_t arg_pdu;
331 new_dissector_t res_pdu;
332 } qsig_op_t;
334 static const qsig_op_t qsig_op_tab[] = {
335 #include "packet-qsig-table11.c"
338 typedef struct _qsig_err_t {
339 gint32 errcode;
340 new_dissector_t err_pdu;
341 } qsig_err_t;
343 static const qsig_err_t qsig_err_tab[] = {
344 #include "packet-qsig-table21.c"
347 static const qsig_op_t *get_op(gint32 opcode) {
348 int i;
350 /* search from the end to get the last occurrence if the operation is redefined in some newer specification */
351 for (i = array_length(qsig_op_tab) - 1; i >= 0; i--)
352 if (qsig_op_tab[i].opcode == opcode)
353 return &qsig_op_tab[i];
354 return NULL;
357 static gint32 get_service(gint32 opcode) {
358 if ((opcode < 0) || (opcode >= (int)array_length(op2srv_tab)))
359 return NO_SRV;
360 return op2srv_tab[opcode];
363 static const qsig_err_t *get_err(gint32 errcode) {
364 int i;
366 /* search from the end to get the last occurrence if the operation is redefined in some newer specification */
367 for (i = array_length(qsig_err_tab) - 1; i >= 0; i--)
368 if (qsig_err_tab[i].errcode == errcode)
369 return &qsig_err_tab[i];
370 return NULL;
373 /*--- dissect_qsig_arg ------------------------------------------------------*/
374 static int
375 dissect_qsig_arg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) {
376 int offset;
377 rose_ctx_t *rctx = get_rose_ctx(data);
378 gint32 opcode = 0, service;
379 const qsig_op_t *op_ptr;
380 const gchar *p;
381 proto_item *ti, *ti_tmp;
382 proto_tree *qsig_tree;
384 offset = 0;
386 DISSECTOR_ASSERT(rctx);
387 if (rctx->d.pdu != 1) /* invoke */
388 return offset;
389 if (rctx->d.code == 0) { /* local */
390 opcode = rctx->d.code_local;
391 op_ptr = get_op(opcode);
392 } else if (rctx->d.code == 1) { /* global */
393 op_ptr = (qsig_op_t *)g_hash_table_lookup(qsig_oid2op_hashtable, rctx->d.code_global);
394 if (op_ptr) opcode = op_ptr->opcode;
395 } else {
396 return offset;
398 if (!op_ptr)
399 return offset;
400 service = get_service(opcode);
402 ti = proto_tree_add_item(tree, proto_qsig, tvb, offset, tvb_length(tvb), ENC_NA);
403 qsig_tree = proto_item_add_subtree(ti, ett_qsig);
405 proto_tree_add_uint(qsig_tree, hf_qsig_operation, tvb, 0, 0, opcode);
406 p = try_val_to_str(opcode, VALS(qsig_str_operation));
407 if (p) {
408 proto_item_append_text(ti, ": %s", p);
409 proto_item_append_text(rctx->d.code_item, " - %s", p);
410 if (rctx->apdu_depth >= 0)
411 proto_item_append_text(proto_item_get_parent_nth(proto_tree_get_parent(tree), rctx->apdu_depth), " %s", p);
414 ti_tmp = proto_tree_add_uint(qsig_tree, hf_qsig_service, tvb, 0, 0, service);
415 p = try_val_to_str(service, VALS(qsig_str_service_name));
416 if (p) proto_item_append_text(ti_tmp, " - %s", p);
418 if (op_ptr->arg_pdu)
419 offset = op_ptr->arg_pdu(tvb, pinfo, qsig_tree, NULL);
420 else
421 if (tvb_length_remaining(tvb, offset) > 0) {
422 proto_tree_add_text(qsig_tree, tvb, offset, -1, "UNSUPPORTED ARGUMENT TYPE (QSIG)");
423 offset += tvb_length_remaining(tvb, offset);
426 return offset;
429 /*--- dissect_qsig_res -------------------------------------------------------*/
430 static int
431 dissect_qsig_res(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) {
432 gint offset;
433 rose_ctx_t *rctx = get_rose_ctx(data);
434 gint32 opcode, service;
435 const qsig_op_t *op_ptr;
436 const gchar *p;
437 proto_item *ti, *ti_tmp;
438 proto_tree *qsig_tree;
440 offset = 0;
442 DISSECTOR_ASSERT(rctx);
443 if (rctx->d.pdu != 2) /* returnResult */
444 return offset;
445 if (rctx->d.code != 0) /* local */
446 return offset;
447 opcode = rctx->d.code_local;
448 op_ptr = get_op(opcode);
449 if (!op_ptr)
450 return offset;
451 service = get_service(opcode);
453 ti = proto_tree_add_item(tree, proto_qsig, tvb, offset, tvb_length(tvb), ENC_NA);
454 qsig_tree = proto_item_add_subtree(ti, ett_qsig);
456 proto_tree_add_uint(qsig_tree, hf_qsig_operation, tvb, 0, 0, opcode);
457 p = try_val_to_str(opcode, VALS(qsig_str_operation));
458 if (p) {
459 proto_item_append_text(ti, ": %s", p);
460 proto_item_append_text(rctx->d.code_item, " - %s", p);
461 if (rctx->apdu_depth >= 0)
462 proto_item_append_text(proto_item_get_parent_nth(proto_tree_get_parent(tree), rctx->apdu_depth), " %s", p);
465 ti_tmp = proto_tree_add_uint(qsig_tree, hf_qsig_service, tvb, 0, 0, service);
466 p = try_val_to_str(service, VALS(qsig_str_service_name));
467 if (p) proto_item_append_text(ti_tmp, " - %s", p);
469 if (op_ptr->res_pdu)
470 offset = op_ptr->res_pdu(tvb, pinfo, qsig_tree, NULL);
471 else
472 if (tvb_length_remaining(tvb, offset) > 0) {
473 proto_tree_add_text(qsig_tree, tvb, offset, -1, "UNSUPPORTED RESULT TYPE (QSIG)");
474 offset += tvb_length_remaining(tvb, offset);
477 return offset;
480 /*--- dissect_qsig_err ------------------------------------------------------*/
481 static int
482 dissect_qsig_err(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) {
483 int offset;
484 rose_ctx_t *rctx = get_rose_ctx(data);
485 gint32 errcode;
486 const qsig_err_t *err_ptr;
487 const gchar *p;
488 proto_item *ti;
489 proto_tree *qsig_tree;
491 offset = 0;
493 DISSECTOR_ASSERT(rctx);
494 if (rctx->d.pdu != 3) /* returnError */
495 return offset;
496 if (rctx->d.code != 0) /* local */
497 return offset;
498 errcode = rctx->d.code_local;
499 err_ptr = get_err(errcode);
500 if (!err_ptr)
501 return offset;
503 ti = proto_tree_add_item(tree, proto_qsig, tvb, offset, tvb_length(tvb), ENC_NA);
504 qsig_tree = proto_item_add_subtree(ti, ett_qsig);
506 proto_tree_add_uint(qsig_tree, hf_qsig_error, tvb, 0, 0, errcode);
507 p = try_val_to_str(errcode, VALS(qsig_str_error));
508 if (p) {
509 proto_item_append_text(ti, ": %s", p);
510 proto_item_append_text(rctx->d.code_item, " - %s", p);
511 if (rctx->apdu_depth >= 0)
512 proto_item_append_text(proto_item_get_parent_nth(proto_tree_get_parent(tree), rctx->apdu_depth), " %s", p);
515 if (err_ptr->err_pdu)
516 offset = err_ptr->err_pdu(tvb, pinfo, qsig_tree, NULL);
517 else
518 if (tvb_length_remaining(tvb, offset) > 0) {
519 proto_tree_add_text(qsig_tree, tvb, offset, -1, "UNSUPPORTED ERROR TYPE (QSIG)");
520 offset += tvb_length_remaining(tvb, offset);
523 return offset;
526 /*--- dissect_qsig_transit_counter_ie ---------------------------------------*/
527 static int
528 dissect_qsig_transit_counter_ie(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int length _U_) {
529 proto_tree_add_item(tree, hf_qsig_tc, tvb, offset, 1, ENC_BIG_ENDIAN);
530 offset++;
531 return offset;
533 /*--- dissect_qsig_party_category_ie ----------------------------------------*/
534 static int
535 dissect_qsig_party_category_ie(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int length _U_) {
536 proto_tree_add_item(tree, hf_qsig_pc, tvb, offset, 1, ENC_BIG_ENDIAN);
537 offset++;
538 return offset;
541 /*--- dissect_qsig_ie -------------------------------------------------------*/
542 static void
543 dissect_qsig_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int codeset) {
544 gint offset;
545 proto_item *ti, *ti_ie, *hidden_item;
546 proto_tree *ie_tree;
547 guint8 ie_type, ie_len;
549 offset = 0;
551 ti = proto_tree_add_item(tree, proto_qsig, tvb, offset, -1, ENC_NA);
552 PROTO_ITEM_SET_HIDDEN(ti);
554 ie_type = tvb_get_guint8(tvb, offset);
555 ie_len = tvb_get_guint8(tvb, offset + 1);
557 ti_ie = proto_tree_add_text(tree, tvb, offset, -1, "%s",
558 val_to_str(ie_type, VALS(qsig_str_ie_type[codeset]), "unknown (0x%02X)"));
559 ie_tree = proto_item_add_subtree(ti_ie, ett_qsig_ie);
560 proto_tree_add_item(ie_tree, *hf_qsig_ie_type_arr[codeset], tvb, offset, 1, ENC_BIG_ENDIAN);
561 hidden_item = proto_tree_add_item(ie_tree, hf_qsig_ie_type, tvb, offset, 1, ENC_BIG_ENDIAN);
562 PROTO_ITEM_SET_HIDDEN(hidden_item);
563 proto_tree_add_item(ie_tree, hf_qsig_ie_len, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
564 offset += 2;
565 if (tvb_length_remaining(tvb, offset) <= 0)
566 return;
567 switch ((codeset << 8) | ie_type) {
568 case CS4 | QSIG_IE_TRANSIT_COUNTER :
569 dissect_qsig_transit_counter_ie(tvb, offset, pinfo, ie_tree, ie_len);
570 break;
571 case CS5 | QSIG_IE_PARTY_CATEGORY :
572 dissect_qsig_party_category_ie(tvb, offset, pinfo, ie_tree, ie_len);
573 break;
574 default:
575 if (ie_len > 0) {
576 if (tree) proto_tree_add_item(ie_tree, hf_qsig_ie_data, tvb, offset, ie_len, ENC_NA);
580 /*--- dissect_qsig_ie_cs4 ---------------------------------------------------*/
581 static void
582 dissect_qsig_ie_cs4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
583 dissect_qsig_ie(tvb, pinfo, tree, 4);
585 /*--- dissect_qsig_ie_cs5 ---------------------------------------------------*/
586 static void
587 dissect_qsig_ie_cs5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
588 dissect_qsig_ie(tvb, pinfo, tree, 5);
591 /*--- qsig_init_tables ---------------------------------------------------------*/
592 static void qsig_init_tables(void) {
593 guint i;
594 gint opcode, *key;
595 gchar *oid;
597 if (qsig_opcode2oid_hashtable)
598 g_hash_table_destroy(qsig_opcode2oid_hashtable);
599 qsig_opcode2oid_hashtable = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free);
601 if (qsig_oid2op_hashtable)
602 g_hash_table_destroy(qsig_oid2op_hashtable);
603 qsig_oid2op_hashtable = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
605 /* fill-in global OIDs */
606 for (i=0; i<array_length(qsig_op_tab); i++) {
607 opcode = qsig_op_tab[i].opcode;
608 oid = g_strdup_printf("1.3.12.9.%d", opcode);
609 key = (gint *)g_malloc(sizeof(gint));
610 *key = opcode;
611 g_hash_table_insert(qsig_opcode2oid_hashtable, key, oid);
612 g_hash_table_insert(qsig_oid2op_hashtable, g_strdup(oid), (gpointer)&qsig_op_tab[i]);
617 /*--- proto_register_qsig ---------------------------------------------------*/
618 void proto_register_qsig(void) {
620 /* List of fields */
621 static hf_register_info hf[] = {
622 { &hf_qsig_operation, { "Operation", "qsig.operation",
623 FT_UINT8, BASE_DEC, VALS(qsig_str_operation), 0x0,
624 NULL, HFILL }},
625 { &hf_qsig_service, { "Service", "qsig.service",
626 FT_UINT8, BASE_DEC, VALS(qsig_str_service), 0x0,
627 "Supplementary Service", HFILL }},
628 { &hf_qsig_error, { "Error", "qsig.error",
629 FT_UINT8, BASE_DEC, VALS(qsig_str_error), 0x0,
630 NULL, HFILL }},
631 { &hf_qsig_ie_type, { "Type", "qsig.ie.type",
632 FT_UINT8, BASE_HEX, NULL, 0x0,
633 "Information Element Type", HFILL }},
634 { &hf_qsig_ie_type_cs4, { "Type", "qsig.ie.type.cs4",
635 FT_UINT8, BASE_HEX, VALS(qsig_str_ie_type_cs4), 0x0,
636 "Information Element Type (Codeset 4)", HFILL }},
637 { &hf_qsig_ie_type_cs5, { "Type", "qsig.ie.type.cs5",
638 FT_UINT8, BASE_HEX, VALS(qsig_str_ie_type_cs5), 0x0,
639 "Information Element Type (Codeset 5)", HFILL }},
640 { &hf_qsig_ie_len, { "Length", "qsig.ie.len",
641 FT_UINT8, BASE_DEC, NULL, 0x0,
642 "Information Element Length", HFILL }},
643 { &hf_qsig_ie_data, { "Data", "qsig.ie.data",
644 FT_BYTES, BASE_NONE, NULL, 0x0,
645 NULL, HFILL }},
646 { &hf_qsig_tc, { "Transit count", "qsig.tc",
647 FT_UINT8, BASE_DEC, NULL, 0x1F,
648 NULL, HFILL }},
649 { &hf_qsig_pc, { "Party category", "qsig.pc",
650 FT_UINT8, BASE_HEX, VALS(qsig_str_pc), 0x07,
651 NULL, HFILL }},
652 #include "packet-qsig-hfarr.c"
655 /* List of subtrees */
656 static gint *ett[] = {
657 &ett_qsig,
658 &ett_qsig_ie,
659 &ett_qsig_unknown_extension,
660 #include "packet-qsig-ettarr.c"
661 &ett_cnq_PSS1InformationElement,
664 /* Register protocol and dissector */
665 proto_qsig = proto_register_protocol(PNAME, PSNAME, PFNAME);
667 /* Register fields and subtrees */
668 proto_register_field_array(proto_qsig, hf, array_length(hf));
669 proto_register_subtree_array(ett, array_length(ett));
671 /* Register dissector tables */
672 extension_dissector_table = register_dissector_table("qsig.ext", "QSIG Extension", FT_STRING, BASE_NONE);
674 qsig_init_tables();
678 /*--- proto_reg_handoff_qsig ------------------------------------------------*/
679 void proto_reg_handoff_qsig(void) {
680 int i;
681 gint key;
682 const gchar *oid;
683 dissector_handle_t q931_handle;
684 dissector_handle_t qsig_arg_handle;
685 dissector_handle_t qsig_res_handle;
686 dissector_handle_t qsig_err_handle;
687 dissector_handle_t qsig_ie_handle;
689 q931_handle = find_dissector("q931");
690 q931_ie_handle = find_dissector("q931.ie");
692 qsig_arg_handle = new_create_dissector_handle(dissect_qsig_arg, proto_qsig);
693 qsig_res_handle = new_create_dissector_handle(dissect_qsig_res, proto_qsig);
694 for (i=0; i<(int)array_length(qsig_op_tab); i++) {
695 dissector_add_uint("q932.ros.local.arg", qsig_op_tab[i].opcode, qsig_arg_handle);
696 dissector_add_uint("q932.ros.local.res", qsig_op_tab[i].opcode, qsig_res_handle);
697 key = qsig_op_tab[i].opcode;
698 oid = (const gchar *)g_hash_table_lookup(qsig_opcode2oid_hashtable, &key);
699 if (oid) {
700 dissector_add_string("q932.ros.global.arg", oid, qsig_arg_handle);
701 dissector_add_string("q932.ros.global.res", oid, qsig_res_handle);
704 qsig_err_handle = new_create_dissector_handle(dissect_qsig_err, proto_qsig);
705 for (i=0; i<(int)array_length(qsig_err_tab); i++) {
706 dissector_add_uint("q932.ros.local.err", qsig_err_tab[i].errcode, qsig_err_handle);
709 qsig_ie_handle = create_dissector_handle(dissect_qsig_ie_cs4, proto_qsig);
710 /* QSIG-TC - Transit counter */
711 dissector_add_uint("q931.ie", CS4 | QSIG_IE_TRANSIT_COUNTER, qsig_ie_handle);
713 qsig_ie_handle = create_dissector_handle(dissect_qsig_ie_cs5, proto_qsig);
714 /* SSIG-BC - Party category */
715 dissector_add_uint("q931.ie", CS5 | QSIG_IE_PARTY_CATEGORY, qsig_ie_handle);
717 /* RFC 3204, 3.2 QSIG Media Type */
718 dissector_add_string("media_type", "application/qsig", q931_handle);
722 /*---------------------------------------------------------------------------*/