2 * Routines for QSIG packet dissection
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 #include <epan/packet.h>
31 #include <epan/prefs.h>
32 #include <epan/strutil.h>
33 #include <epan/emem.h>
34 #include <epan/asn1.h>
36 #include "packet-ber.h"
37 #include "packet-qsig.h"
43 /* Shifted codeset values */
53 #define QSIG_IE_TRANSIT_COUNTER 0x31
54 #define QSIG_IE_PARTY_CATEGORY 0x32
56 static const value_string qsig_str_ie_type_cs4[] = {
57 { QSIG_IE_TRANSIT_COUNTER , "Transit counter" },
60 static const value_string qsig_str_ie_type_cs5[] = {
61 { QSIG_IE_PARTY_CATEGORY , "Party category" },
65 static const value_string *qsig_str_ie_type[] = {
77 static const value_string qsig_str_pc[] = {
79 { 0x01 , "extension" },
80 { 0x02 , "operator" },
81 { 0x03 , "emergency extension" },
85 static const value_string qsig_str_service[] = {
92 { 14844, "QSIG-DND(O)" },
94 { 15050, "QSIG-AOC" },
96 { 15054, "QSIG-CINT" },
97 { 15506, "QSIG-MWI" },
98 { 15507, "SYNC-SIG" },
99 { 15772, "QSIG-CMN" },
100 { 15992, "QSIG-CPI(P)" },
101 { 17876, "QSIG-PUMR" },
102 { 17878, "QSIG-PUMCH" },
103 { 19460, "QSIG-SSCT" },
104 { 15429, "QSIG-WTMLR" },
105 { 15431, "QSIG-WTMCH" },
106 { 15433, "QSIG-WTMAU" },
107 { 21407, "QSIG-SD" },
108 { 21889, "QSIG-CIDL" },
111 { 3471, "QSIG-MCM" },
112 { 3472, "QSIG-MID" },
116 static const value_string qsig_str_service_name[] = {
117 { 13868, "Name-Operations" },
118 { 13873, "Call-Diversion-Operations" },
119 { 13874, "Path-Replacement-Operations" },
120 { 13869, "Call-Transfer-Operations" },
121 { 13870, "SS-CC-Operations" },
122 { 14843, "Call-Offer-Operations" },
123 { 14844, "Do-Not-Disturb-Operations" },
124 { 14846, "Call-Intrusion-Operations" },
125 { 15050, "SS-AOC-Operation" },
126 { 15052, "Recall-Operation" },
127 { 15054, "Call-Interception-Operations" },
128 { 15506, "SS-MWI-Operations" },
129 { 15507, "Synchronization-Operations" },
130 { 15772, "Common-Information-Operations" },
131 { 15992, "Call-Interruption-Operation" },
132 { 17876, "PUM-Registration-Operation" },
133 { 17878, "Private-User-Mobility-Call-Handling-Operations" },
134 { 19460, "Single-Step-Call-Transfer-Operations" },
135 { 15429, "WTM-Location-Registration-Operations" },
136 { 15431, "Wireless-Terminal-Call-Handling-Operations" },
137 { 15433, "WTM-Authentication-Operations" },
138 { 21407, "SS-SD-Operations" },
139 { 21889, "Call-Identification-and-Call-Linkage-Operations" },
140 { 325, "Short-Message-Service-Operations" },
141 { 344, "SS-MCR-Operations" },
142 { 3471, "SS-MCM-Operations" },
143 { 3472, "SS-MID-Operations" },
148 static const gint32 op2srv_tab[] = {
272 static const value_string qsig_str_operation[] = {
273 { 0, "callingName" },
275 { 2, "connectedName" },
277 { 4, "pathReplacePropose" },
278 { 5, "pathReplaceSetup" },
279 { 6, "pathReplaceRetain" },
280 { 7, "callTransferIdentify" },
281 { 8, "callTransferAbandon" },
282 { 9, "callTransferInitiate" },
283 { 10, "callTransferSetup" },
284 { 11, "callTransferActive" },
285 { 12, "callTransferComplete" },
286 { 13, "callTransferUpdate" },
287 { 14, "subaddressTransfer" },
288 { 15, "activateDiversionQ" },
289 { 16, "deactivateDiversionQ" },
290 { 17, "interrogateDiversionQ" },
291 { 18, "checkRestriction" },
292 { 19, "callRerouteing" },
293 { 20, "divertingLegInformation1" },
294 { 21, "divertingLegInformation2" },
295 { 22, "divertingLegInformation3" },
296 { 23, "cfnrDivertedLegFailed" },
297 /* 24 Reserved (corresponding integer value used by ISO for MLPP) */
298 /* 25 Reserved (corresponding integer value used by ISO for MLPP) */
299 /* 26 Reserved (corresponding integer value used by ISO for MLPP) */
300 { 27, "ccnrRequest" },
302 { 29, "ccExecPossible" },
303 { 30, "ccPathReserve" },
307 { 34, "callOfferRequest" },
308 { 35, "doNotDisturbActivateQ" },
309 { 36, "doNotDisturbDeactivateQ" },
310 { 37, "doNotDisturbInterrogateQ" },
311 { 38, "doNotDisturbOverrideQ" },
312 { 39, "doNotDisturbOvrExecuteQ" },
313 { 40, "ccbsRequest" },
314 { 41, "pathRetain" }, /* common for QSIG-CO, QSIG-DND(O), QSIG-CI */
315 { 42, "serviceAvailable" }, /* common for QSIG-CO, QSIG-DND(O), QSIG-CI */
316 { 43, "callIntrusionRequest" },
317 { 44, "callIntrusionGetCIPL" },
318 { 45, "callIntrusionIsolate" },
319 { 46, "callIntrusionForcedRelease" },
320 { 47, "callIntrusionWOBRequest" },
321 { 48, "callIntrusionCompleted" },
322 { 49, "cfbOverride" }, /* common for QSIG-CO, QSIG-CI */
326 { 53, "pisnEnquiry" },
327 { 54, "wtmiEnquiry" },
328 { 55, "wtmiDivert" },
329 { 56, "wtmiInform" },
330 { 57, "recallAlerting" },
331 { 58, "recallAnswered" },
332 { 59, "chargeRequest" },
333 { 60, "getFinalCharge" },
335 { 62, "aocInterim" },
337 { 64, "aocComplete" },
338 { 65, "aocDivChargeReq" },
339 { 66, "cintLegInformation1" },
340 { 67, "cintLegInformation2" },
341 { 68, "cintCondition" },
342 { 69, "cintDisable" },
343 { 70, "cintEnable" },
345 { 72, "authWtmUser" },
346 { 73, "getWtatParam" },
347 { 74, "wtatParamEnq" },
348 { 75, "getWtanParam" },
349 { 76, "wtanParamEnq" },
350 { 77, "transferAuthParam" },
351 { 78, "synchronizationRequest" },
352 { 79, "synchronizationInfo" },
353 { 80, "mwiActivate/mCMNewMsg" }, /* common for QSIG-MWI, QSIG-MCM */
354 { 81, "mwiDeactivate/mCMNoNewMsg" }, /* common for QSIG-MWI, QSIG-MCM */
355 { 82, "mwiInterrogate/mCMUpdateReq" }, /* common for QSIG-MWI, QSIG-MCM */
356 /* 83 Reserved (corresponding integer value used by ISO for RRC) ISO/IEC 13241 */
357 { 84, "cmnRequest" },
359 { 86, "pathReplaceInvite" },
360 { 87, "callInterruptionRequest" },
361 { 88, "callProtectionRequest" },
362 { 89, "pumRegistr" },
365 { 92, "pumInterrog" },
366 { 93, "pumiEnquiry" },
367 { 94, "pumiDivert" },
368 { 95, "pumiInform" },
371 { 98, "locInfoCheck" },
372 { 99, "ssctInitiate" },
373 { 100, "ssctSetup" },
374 { 101, "ssctPostDial" },
375 { 102, "ssctDigitInfo" },
378 { 105, "callIdentificationAssign" },
379 { 106, "callIdentificationUpdate" },
380 { 107, "smsSubmit" },
381 { 108, "smsDeliver" },
382 { 109, "smsStatusReport" },
383 { 110, "smsCommand" },
385 { 112, "mCRequest" },
386 { 113, "mCAlerting" },
388 { 115, "mCMUpdate" },
389 { 116, "mCMService" },
390 { 117, "mCMInterrogate" },
391 { 118, "mCMailboxFull" },
392 { 119, "mIDMailboxAuth" },
393 { 120, "mIDMailboxID" },
397 typedef struct _qsig_op_t {
399 new_dissector_t arg_pdu;
400 new_dissector_t res_pdu;
403 /* Initialize the protocol and registered fields */
405 static int hf_qsig_operation = -1;
406 static int hf_qsig_service = -1;
407 static int hf_qsig_ie_type = -1;
408 static int hf_qsig_ie_type_cs4 = -1;
409 static int hf_qsig_ie_type_cs5 = -1;
410 static int hf_qsig_ie_len = -1;
411 static int hf_qsig_ie_data = -1;
412 static int hf_qsig_tc = -1;
413 static int hf_qsig_pc = -1;
414 #include "packet-qsig-hf.c"
416 static int *hf_qsig_ie_type_arr[] = {
421 &hf_qsig_ie_type_cs4,
422 &hf_qsig_ie_type_cs5,
427 /* Initialize the subtree pointers */
428 static gint ett_qsig = -1;
429 static gint ett_qsig_ie = -1;
430 #include "packet-qsig-ett.c"
435 static dissector_handle_t data_handle = NULL;
437 /* Gloabl variables */
440 #include "packet-qsig-fn.c"
442 static const qsig_op_t qsig_tab[] = {
443 /* 0 */ { 0, dissect_NameArg_PDU, NULL },
444 /* 1 */ { 1, dissect_NameArg_PDU, NULL },
445 /* 2 */ { 2, dissect_NameArg_PDU, NULL },
446 /* 3 */ { 3, dissect_NameArg_PDU, NULL },
447 /* 4 */ { 4, NULL, NULL },
448 /* 5 */ { 5, NULL, NULL },
449 /* 6 */ { 6, NULL, NULL },
450 /* 7 */ { 7, NULL, NULL },
451 /* 8 */ { 8, NULL, NULL },
452 /* 9 */ { 9, NULL, NULL },
453 /* 10 */ { 10, NULL, NULL },
454 /* 11 */ { 11, NULL, NULL },
455 /* 12 */ { 12, NULL, NULL },
456 /* 13 */ { 13, NULL, NULL },
457 /* 14 */ { 14, NULL, NULL },
458 /* 15 */ { 15, dissect_ARG_activateDiversionQ_PDU, dissect_RES_activateDiversionQ_PDU },
459 /* 16 */ { 16, dissect_ARG_deactivateDiversionQ_PDU, dissect_RES_deactivateDiversionQ_PDU },
460 /* 17 */ { 17, dissect_ARG_interrogateDiversionQ_PDU, dissect_IntResultList_PDU },
461 /* 18 */ { 18, dissect_ARG_checkRestriction_PDU, dissect_RES_checkRestriction_PDU },
462 /* 19 */ { 19, dissect_ARG_callRerouteing_PDU, dissect_RES_callRerouteing_PDU },
463 /* 20 */ { 20, dissect_ARG_divertingLegInformation1_PDU, NULL },
464 /* 21 */ { 21, dissect_ARG_divertingLegInformation2_PDU, NULL },
465 /* 22 */ { 22, dissect_ARG_divertingLegInformation3_PDU, NULL },
466 /* 23 */ { 23, dissect_ARG_cfnrDivertedLegFailed_PDU, NULL },
467 /* 27 */ { 27, NULL, NULL },
468 /* 28 */ { 28, NULL, NULL },
469 /* 29 */ { 29, NULL, NULL },
470 /* 30 */ { 30, NULL, NULL },
471 /* 31 */ { 31, NULL, NULL },
472 /* 32 */ { 32, NULL, NULL },
473 /* 33 */ { 33, NULL, NULL },
474 /* 34 */ { 34, NULL, NULL },
475 /* 35 */ { 35, NULL, NULL },
476 /* 36 */ { 36, NULL, NULL },
477 /* 37 */ { 37, NULL, NULL },
478 /* 38 */ { 38, NULL, NULL },
479 /* 39 */ { 39, NULL, NULL },
480 /* 40 */ { 40, NULL, NULL },
481 /* 41 */ { 41, NULL, NULL },
482 /* 42 */ { 42, NULL, NULL },
483 /* 43 */ { 43, NULL, NULL },
484 /* 44 */ { 44, NULL, NULL },
485 /* 45 */ { 45, NULL, NULL },
486 /* 46 */ { 46, NULL, NULL },
487 /* 47 */ { 47, NULL, NULL },
488 /* 48 */ { 48, NULL, NULL },
489 /* 49 */ { 49, NULL, NULL },
490 /* 50 */ { 50, NULL, NULL },
491 /* 51 */ { 51, NULL, NULL },
492 /* 52 */ { 52, NULL, NULL },
493 /* 53 */ { 53, NULL, NULL },
494 /* 54 */ { 54, NULL, NULL },
495 /* 55 */ { 55, NULL, NULL },
496 /* 56 */ { 56, NULL, NULL },
497 /* 57 */ { 57, NULL, NULL },
498 /* 58 */ { 58, NULL, NULL },
499 /* 59 */ { 59, NULL, NULL },
500 /* 60 */ { 60, NULL, NULL },
501 /* 61 */ { 61, NULL, NULL },
502 /* 62 */ { 62, NULL, NULL },
503 /* 63 */ { 63, NULL, NULL },
504 /* 64 */ { 64, NULL, NULL },
505 /* 65 */ { 65, NULL, NULL },
506 /* 66 */ { 66, NULL, NULL },
507 /* 67 */ { 67, NULL, NULL },
508 /* 68 */ { 68, NULL, NULL },
509 /* 69 */ { 69, NULL, NULL },
510 /* 70 */ { 70, NULL, NULL },
511 /* 71 */ { 71, NULL, NULL },
512 /* 72 */ { 72, NULL, NULL },
513 /* 73 */ { 73, NULL, NULL },
514 /* 74 */ { 74, NULL, NULL },
515 /* 75 */ { 75, NULL, NULL },
516 /* 76 */ { 76, NULL, NULL },
517 /* 77 */ { 77, NULL, NULL },
518 /* 78 */ { 78, NULL, NULL },
519 /* 79 */ { 79, NULL, NULL },
520 /* 80 */ { 80, NULL, NULL },
521 /* 81 */ { 81, NULL, NULL },
522 /* 82 */ { 82, NULL, NULL },
523 /* 84 */ { 84, NULL, NULL },
524 /* 85 */ { 85, NULL, NULL },
525 /* 86 */ { 86, NULL, NULL },
526 /* 87 */ { 87, NULL, NULL },
527 /* 88 */ { 88, NULL, NULL },
528 /* 89 */ { 89, NULL, NULL },
529 /* 90 */ { 90, NULL, NULL },
530 /* 91 */ { 91, NULL, NULL },
531 /* 92 */ { 92, NULL, NULL },
532 /* 93 */ { 93, NULL, NULL },
533 /* 94 */ { 94, NULL, NULL },
534 /* 95 */ { 95, NULL, NULL },
535 /* 96 */ { 96, NULL, NULL },
536 /* 97 */ { 97, NULL, NULL },
537 /* 98 */ { 98, NULL, NULL },
538 /* 99 */ { 99, NULL, NULL },
539 /* 100 */ { 100, NULL, NULL },
540 /* 101 */ { 101, NULL, NULL },
541 /* 102 */ { 102, NULL, NULL },
542 /* 103 */ { 103, NULL, NULL },
543 /* 104 */ { 104, NULL, NULL },
544 /* 105 */ { 105, NULL, NULL },
545 /* 106 */ { 106, NULL, NULL },
546 /* 107 */ { 107, NULL, NULL },
547 /* 108 */ { 108, NULL, NULL },
548 /* 109 */ { 109, NULL, NULL },
549 /* 110 */ { 110, NULL, NULL },
550 /* 111 */ { 111, NULL, NULL },
551 /* 112 */ { 112, NULL, NULL },
552 /* 113 */ { 113, NULL, NULL },
553 /* 114 */ { 114, NULL, NULL },
554 /* 115 */ { 115, NULL, NULL },
555 /* 116 */ { 116, NULL, NULL },
556 /* 117 */ { 117, NULL, NULL },
557 /* 118 */ { 118, NULL, NULL },
558 /* 119 */ { 119, NULL, NULL },
559 /* 120 */ { 120, NULL, NULL },
562 static const qsig_op_t *get_op(gint32 opcode) {
565 /* search from the end to get the last occurence if the operation is redefined in some newer specification */
566 for (i = array_length(qsig_tab) - 1; i >= 0; i--)
567 if (qsig_tab[i].opcode == opcode)
572 static gint32 get_service(gint32 opcode) {
573 if ((opcode < 0) || (opcode >= (int)array_length(op2srv_tab)))
575 return op2srv_tab[opcode];
578 /*--- dissect_qsig_arg ------------------------------------------------------*/
580 dissect_qsig_arg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
583 gint32 opcode, service;
584 const qsig_op_t *op_ptr;
586 proto_item *ti, *ti_tmp;
587 proto_tree *qsig_tree;
590 rctx = get_rose_ctx(pinfo->private_data);
591 DISSECTOR_ASSERT(rctx);
592 if (rctx->d.pdu != 1) /* invoke */
594 if (rctx->d.code != 0) /* local */
596 opcode = rctx->d.code_local;
597 op_ptr = get_op(opcode);
600 service = get_service(opcode);
602 ti = proto_tree_add_item(tree, proto_qsig, tvb, offset, tvb_length(tvb), FALSE);
603 qsig_tree = proto_item_add_subtree(ti, ett_qsig);
605 proto_tree_add_uint(qsig_tree, hf_qsig_operation, tvb, 0, 0, opcode);
606 p = match_strval(opcode, VALS(qsig_str_operation));
608 proto_item_append_text(ti, ": %s", p);
609 proto_item_append_text(rctx->d.code_item, " - %s", p);
610 if (rctx->apdu_depth >= 0)
611 proto_item_append_text(proto_item_get_parent_nth(proto_tree_get_parent(tree), rctx->apdu_depth), " %s", p);
614 ti_tmp = proto_tree_add_uint(qsig_tree, hf_qsig_service, tvb, 0, 0, service);
615 p = match_strval(service, VALS(qsig_str_service_name));
616 if (p) proto_item_append_text(ti_tmp, " - %s", p);
619 offset = op_ptr->arg_pdu(tvb, pinfo, qsig_tree);
621 if (tvb_length_remaining(tvb, offset) > 0) {
622 proto_tree_add_text(qsig_tree, tvb, offset, -1, "UNSUPPORTED ARGUMENT TYPE (QSIG)");
623 offset += tvb_length_remaining(tvb, offset);
629 /*--- dissect_qsig_res -------------------------------------------------------*/
631 dissect_qsig_res(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
634 gint32 opcode, service;
635 const qsig_op_t *op_ptr;
637 proto_item *ti, *ti_tmp;
638 proto_tree *qsig_tree;
641 rctx = get_rose_ctx(pinfo->private_data);
642 DISSECTOR_ASSERT(rctx);
643 if (rctx->d.pdu != 2) /* returnResult */
645 if (rctx->d.code != 0) /* local */
647 opcode = rctx->d.code_local;
648 op_ptr = get_op(opcode);
651 service = get_service(opcode);
653 ti = proto_tree_add_item(tree, proto_qsig, tvb, offset, tvb_length(tvb), FALSE);
654 qsig_tree = proto_item_add_subtree(ti, ett_qsig);
656 proto_tree_add_uint(qsig_tree, hf_qsig_operation, tvb, 0, 0, opcode);
657 p = match_strval(opcode, VALS(qsig_str_operation));
659 proto_item_append_text(ti, ": %s", p);
660 proto_item_append_text(rctx->d.code_item, " - %s", p);
661 if (rctx->apdu_depth >= 0)
662 proto_item_append_text(proto_item_get_parent_nth(proto_tree_get_parent(tree), rctx->apdu_depth), " %s", p);
665 ti_tmp = proto_tree_add_uint(qsig_tree, hf_qsig_service, tvb, 0, 0, service);
666 p = match_strval(service, VALS(qsig_str_service_name));
667 if (p) proto_item_append_text(ti_tmp, " - %s", p);
670 offset = op_ptr->res_pdu(tvb, pinfo, qsig_tree);
672 if (tvb_length_remaining(tvb, offset) > 0) {
673 proto_tree_add_text(qsig_tree, tvb, offset, -1, "UNSUPPORTED RESULT TYPE (QSIG)");
674 offset += tvb_length_remaining(tvb, offset);
680 /*--- dissect_qsig_transit_counter_ie ---------------------------------------*/
682 dissect_qsig_transit_counter_ie(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int length _U_) {
683 proto_tree_add_item(tree, hf_qsig_tc, tvb, offset, 1, FALSE);
687 /*--- dissect_qsig_party_category_ie ----------------------------------------*/
689 dissect_qsig_party_category_ie(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int length _U_) {
690 proto_tree_add_item(tree, hf_qsig_pc, tvb, offset, 1, FALSE);
695 /*--- dissect_qsig_ie -------------------------------------------------------*/
697 dissect_qsig_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int codeset) {
699 proto_item *ti, *ti_ie;
701 guint8 ie_type, ie_len;
705 ti = proto_tree_add_item_hidden(tree, proto_qsig, tvb, offset, -1, FALSE);
707 ie_type = tvb_get_guint8(tvb, offset);
708 ie_len = tvb_get_guint8(tvb, offset + 1);
710 ti_ie = proto_tree_add_text(tree, tvb, offset, -1, "%s",
711 val_to_str(ie_type, VALS(qsig_str_ie_type[codeset]), "unknown (0x%02X)"));
712 ie_tree = proto_item_add_subtree(ti_ie, ett_qsig_ie);
713 proto_tree_add_item(ie_tree, *hf_qsig_ie_type_arr[codeset], tvb, offset, 1, FALSE);
714 proto_tree_add_item_hidden(ie_tree, hf_qsig_ie_type, tvb, offset, 1, FALSE);
715 proto_tree_add_item(ie_tree, hf_qsig_ie_len, tvb, offset + 1, 1, FALSE);
717 if (tvb_length_remaining(tvb, offset) <= 0)
719 switch ((codeset << 8) | ie_type) {
720 case CS4 | QSIG_IE_TRANSIT_COUNTER :
721 dissect_qsig_transit_counter_ie(tvb, offset, pinfo, ie_tree, ie_len);
723 case CS5 | QSIG_IE_PARTY_CATEGORY :
724 dissect_qsig_party_category_ie(tvb, offset, pinfo, ie_tree, ie_len);
728 if (tree) proto_tree_add_item(ie_tree, hf_qsig_ie_data, tvb, offset, ie_len, FALSE);
732 /*--- dissect_qsig_ie_cs4 ---------------------------------------------------*/
734 dissect_qsig_ie_cs4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
735 dissect_qsig_ie(tvb, pinfo, tree, 4);
737 /*--- dissect_qsig_ie_cs5 ---------------------------------------------------*/
739 dissect_qsig_ie_cs5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
740 dissect_qsig_ie(tvb, pinfo, tree, 5);
743 /*--- proto_register_qsig ---------------------------------------------------*/
744 void proto_register_qsig(void) {
747 static hf_register_info hf[] = {
748 { &hf_qsig_operation, { "Operation", "qsig.operation",
749 FT_UINT8, BASE_DEC, VALS(qsig_str_operation), 0x0,
750 "Operation", HFILL }},
751 { &hf_qsig_service, { "Service", "qsig.service",
752 FT_UINT8, BASE_DEC, VALS(qsig_str_service), 0x0,
753 "Supplementary Service", HFILL }},
754 { &hf_qsig_ie_type, { "Type", "qsig.ie.type",
755 FT_UINT8, BASE_HEX, NULL, 0x0,
756 "Information Element Type", HFILL }},
757 { &hf_qsig_ie_type_cs4, { "Type", "qsig.ie.type.cs4",
758 FT_UINT8, BASE_HEX, VALS(qsig_str_ie_type_cs4), 0x0,
759 "Information Element Type (Codeset 4)", HFILL }},
760 { &hf_qsig_ie_type_cs5, { "Type", "qsig.ie.type.cs5",
761 FT_UINT8, BASE_HEX, VALS(qsig_str_ie_type_cs5), 0x0,
762 "Information Element Type (Codeset 5)", HFILL }},
763 { &hf_qsig_ie_len, { "Length", "qsig.ie.len",
764 FT_UINT8, BASE_DEC, NULL, 0x0,
765 "Information Element Length", HFILL }},
766 { &hf_qsig_ie_data, { "Data", "qsig.ie.data",
767 FT_BYTES, BASE_HEX, NULL, 0x0,
769 { &hf_qsig_tc, { "Transit count", "qsig.tc",
770 FT_UINT8, BASE_DEC, NULL, 0x1F,
771 "Transit count", HFILL }},
772 { &hf_qsig_pc, { "Party category", "qsig.pc",
773 FT_UINT8, BASE_HEX, VALS(qsig_str_pc), 0x07,
774 "Party category", HFILL }},
775 #include "packet-qsig-hfarr.c"
778 /* List of subtrees */
779 static gint *ett[] = {
782 #include "packet-qsig-ettarr.c"
785 /* Register protocol and dissector */
786 proto_qsig = proto_register_protocol(PNAME, PSNAME, PFNAME);
788 /* Register fields and subtrees */
789 proto_register_field_array(proto_qsig, hf, array_length(hf));
790 proto_register_subtree_array(ett, array_length(ett));
795 /*--- proto_reg_handoff_qsig ------------------------------------------------*/
796 void proto_reg_handoff_qsig(void) {
798 dissector_handle_t qsig_arg_handle;
799 dissector_handle_t qsig_res_handle;
800 dissector_handle_t qsig_ie_handle;
802 data_handle = find_dissector("data");
804 if (find_dissector_table("q932.ros.local.arg")) {
805 qsig_arg_handle = new_create_dissector_handle(dissect_qsig_arg, proto_qsig);
806 qsig_res_handle = new_create_dissector_handle(dissect_qsig_res, proto_qsig);
807 for (i=0; i<(int)array_length(qsig_tab); i++) {
808 dissector_add("q932.ros.local.arg", qsig_tab[i].opcode, qsig_arg_handle);
809 dissector_add("q932.ros.local.res", qsig_tab[i].opcode, qsig_res_handle);
813 qsig_ie_handle = create_dissector_handle(dissect_qsig_ie_cs4, proto_qsig);
814 /* QSIG-TC - Transit counter */
815 dissector_add("q931.ie", CS4 | QSIG_IE_TRANSIT_COUNTER, qsig_ie_handle);
817 qsig_ie_handle = create_dissector_handle(dissect_qsig_ie_cs5, proto_qsig);
818 /* SSIG-BC - Party category */
819 dissector_add("q931.ie", CS5 | QSIG_IE_PARTY_CATEGORY, qsig_ie_handle);
823 /*---------------------------------------------------------------------------*/