Fixup: tvb_get_string(z) -> tvb_get_string(z)_enc
[metze/wireshark/wip.git] / epan / dissectors / packet-q933.c
1 /* packet-q933.c
2  * Routines for Q.933 frame disassembly
3  * Guy Harris <guy@alum.mit.edu>
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23
24 #include "config.h"
25
26 #include <glib.h>
27 #include <epan/packet.h>
28 #include <epan/strutil.h>
29 #include <epan/nlpid.h>
30
31 void proto_register_q933(void);
32 void proto_reg_handoff_q933(void);
33
34 static int proto_q933                                   = -1;
35 static int hf_q933_discriminator                        = -1;
36 static int hf_q933_coding_standard                      = -1;
37 static int hf_q933_information_transfer_capability      = -1;
38 static int hf_q933_transfer_mode                        = -1;
39 static int hf_q933_uil1                                 = -1;
40 static int hf_q933_call_ref_len                         = -1;
41 static int hf_q933_call_ref_flag                        = -1;
42 static int hf_q933_call_ref                             = -1;
43 static int hf_q933_message_type                         = -1;
44 static int hf_q933_cause_location                       = -1;
45 static int hf_q933_cause_value                          = -1;
46 static int hf_q933_number_type                          = -1;
47 static int hf_q933_numbering_plan                       = -1;
48 static int hf_q933_extension_ind                        = -1;
49 static int hf_q933_calling_party_number                 = -1;
50 static int hf_q933_called_party_number                  = -1;
51 static int hf_q933_connected_number                     = -1;
52 /* static int hf_q933_redirecting_number                        = -1; */
53 static int hf_q933_screening_ind                        = -1;
54 static int hf_q933_presentation_ind                     = -1;
55 static int hf_q933_report_type                          = -1;
56 static int hf_q933_link_verf_txseq                      = -1;
57 static int hf_q933_link_verf_rxseq                      = -1;
58
59 static gint ett_q933                                    = -1;
60 static gint ett_q933_ie                                 = -1;
61
62 /*
63  * Q.933 message types.
64  */
65 #define Q933_ESCAPE             0x00
66 #define Q933_ALERTING           0x01
67 #define Q933_CALL_PROCEEDING    0x02
68 #define Q933_CONNECT            0x07
69 #define Q933_CONNECT_ACK        0x0F
70 #define Q933_PROGRESS           0x03
71 #define Q933_SETUP              0x05
72 #define Q933_DISCONNECT         0x45
73 #define Q933_RELEASE            0x4D
74 #define Q933_RELEASE_COMPLETE   0x5A
75 #define Q933_SEGMENT            0x60
76 #define Q933_STATUS             0x7D
77 #define Q933_STATUS_ENQUIRY     0x75
78
79 static const value_string q933_message_type_vals[] = {
80         { Q933_ESCAPE,                  "ESCAPE" },
81         { Q933_ALERTING,                "ALERTING" },
82         { Q933_CALL_PROCEEDING,         "CALL PROCEEDING" },
83         { Q933_CONNECT,                 "CONNECT" },
84         { Q933_CONNECT_ACK,             "CONNECT ACKNOWLEDGE" },
85         { Q933_PROGRESS,                "PROGRESS" },
86         { Q933_SETUP,                   "SETUP" },
87         { Q933_DISCONNECT,              "DISCONNECT" },
88         { Q933_RELEASE,                 "RELEASE" },
89         { Q933_RELEASE_COMPLETE,        "RELEASE COMPLETE" },
90         { Q933_SEGMENT,                 "SEGMENT" },
91         { Q933_STATUS,                  "STATUS" },
92         { Q933_STATUS_ENQUIRY,          "STATUS ENQUIRY" },
93         { 0,                            NULL }
94 };
95
96 static const true_false_string tfs_call_ref_flag = {
97         "Message sent to originating side",
98         "Message sent from originating side"
99 };
100
101 /*
102  * Information elements.
103  */
104
105 /* Shifted codeset values */
106 #define CS0 0x000
107 #define CS1 0x100
108 #define CS2 0x200
109 #define CS3 0x300
110 #define CS4 0x400
111 #define CS5 0x500
112 #define CS6 0x600
113 #define CS7 0x700
114
115 #define Q933_IE_SO_MASK 0x80    /* single-octet/variable-length mask */
116 /*
117  * Single-octet IEs.
118  */
119 #define Q933_IE_SO_IDENTIFIER_MASK      0xf0    /* IE identifier mask */
120 #define Q933_IE_SO_IDENTIFIER_SHIFT     4       /* IE identifier shift */
121 #define Q933_IE_SO_IE_MASK              0x0F    /* IE mask */
122
123 #define Q933_IE_SHIFT                   0x90
124 #define Q933_IE_SHIFT_NON_LOCKING       0x08    /* non-locking shift */
125 #define Q933_IE_SHIFT_CODESET           0x07    /* codeset */
126
127 #define Q933_IE_REPEAT_INDICATOR        0xD0
128
129 /*
130  * Variable-length IEs.
131  */
132 #define Q933_IE_VL_EXTENSION            0x80    /* Extension flag */
133 /*      extension bit. The bit value "0" indicates that the octet continues through the         */
134 /*      next octet. The bit value "1" indicates that this octet is the last octet               */
135
136 static const true_false_string q933_extension_ind_value = {
137   "last octet",
138   "information continues through the next octet",
139
140 };
141
142
143 /*
144  * Codeset 0 (default).
145  */
146 #define Q933_IE_SEGMENTED_MESSAGE       0x00
147 #define Q933_IE_BEARER_CAPABILITY       0x04
148 #define Q933_IE_CAUSE                   0x08
149 #define Q933_IE_CALL_STATE              0x14
150 #define Q933_IE_CHANNEL_IDENTIFICATION  0x18
151 #define Q933_IE_DLCI                    0x19
152 #define Q933_IE_PROGRESS_INDICATOR      0x1E
153 #define Q933_IE_NETWORK_SPECIFIC_FACIL  0x20    /* Network Specific Facilities */
154 #define Q933_IE_DISPLAY                 0x28
155 #define Q933_IE_E2E_TRANSIT_DELAY       0x42    /* End-to-end Transit Delay */
156 #define Q933_IE_TD_SELECTION_AND_INT    0x43    /* Transit Delay Selection and Indication */
157 #define Q933_IE_PL_BINARY_PARAMETERS    0x44    /* Packet layer binary parameters */
158 #define Q933_IE_LL_CORE_PARAMETERS      0x48    /* Link layer core parameters */
159 #define Q933_IE_LL_PROTOCOL_PARAMETERS  0x49    /* Link layer protocol parameters */
160 #define Q933_IE_REVERSE_CHARGE_IND      0x4A    /* Reverse charging indication */
161 #define Q933_IE_CONNECTED_NUMBER        0x4C    /* Connected Number */
162 #define Q933_IE_CONNECTED_SUBADDR       0x4D    /* Connected sub-address */
163 #define Q933_IE_X_213_PRIORITY          0x50    /* X.213 priority */
164 #define Q933_IE_REPORT_TYPE             0x51
165 #define Q933_IE_LINK_INTEGRITY_VERF     0x53    /* Link integrity verification */
166 #define Q933_IE_PVC_STATUS              0x57
167 #define Q933_IE_CALLING_PARTY_NUMBER    0x6C    /* Calling Party Number */
168 #define Q933_IE_CALLING_PARTY_SUBADDR   0x6D    /* Calling Party Subaddress */
169 #define Q933_IE_CALLED_PARTY_NUMBER     0x70    /* Called Party Number */
170 #define Q933_IE_CALLED_PARTY_SUBADDR    0x71    /* Called Party Subaddress */
171 #define Q933_IE_TRANSIT_NETWORK_SEL     0x78    /* Transit Network Selection */
172 #define Q933_IE_LOW_LAYER_COMPAT        0x7C    /* Low-Layer Compatibility */
173 #define Q933_IE_HIGH_LAYER_COMPAT       0x7D    /* High-Layer Compatibility */
174 #define Q933_IE_USER_USER               0x7E    /* User-User */
175 #define Q933_IE_ESCAPE                  0x7F    /* Escape for extension */
176
177 /* Codeset 0 */
178 static const value_string q933_info_element_vals0[] = {
179         { Q933_IE_SEGMENTED_MESSAGE,            "Segmented message" },
180         { Q933_IE_BEARER_CAPABILITY,            "Bearer capability" },
181         { Q933_IE_CAUSE,                        "Cause" },
182         { Q933_IE_CALL_STATE,                   "Call state" },
183         { Q933_IE_CHANNEL_IDENTIFICATION,       "Channel identification" },
184         { Q933_IE_DLCI,                         "Data link connection identifier" },
185         { Q933_IE_PROGRESS_INDICATOR,           "Progress indicator" },
186         { Q933_IE_NETWORK_SPECIFIC_FACIL,       "Network specific facilities" },
187         { Q933_IE_E2E_TRANSIT_DELAY,            "End-to-end transit delay" },
188         { Q933_IE_TD_SELECTION_AND_INT,         "Transit delay selection and indication" },
189         { Q933_IE_PL_BINARY_PARAMETERS,         "Packet layer binary parameters" },
190         { Q933_IE_LL_CORE_PARAMETERS,           "Link layer core parameters" },
191         { Q933_IE_LL_PROTOCOL_PARAMETERS,       "Link layer protocol parameters" },
192         { Q933_IE_REVERSE_CHARGE_IND,           "Reverse charging indication" },
193         { Q933_IE_CONNECTED_NUMBER,             "Connected number" },
194         { Q933_IE_CONNECTED_SUBADDR,            "Connected subaddress" },
195         { Q933_IE_X_213_PRIORITY,               "X.213 priority" },
196         { Q933_IE_REPORT_TYPE,                  "Report type" },
197         { Q933_IE_LINK_INTEGRITY_VERF,          "Link integrity verification" },
198         { Q933_IE_PVC_STATUS,                   "PVC status" },
199         { Q933_IE_CALLING_PARTY_NUMBER,         "Calling party number" },
200         { Q933_IE_CALLING_PARTY_SUBADDR,        "Calling party subaddress" },
201         { Q933_IE_CALLED_PARTY_NUMBER,          "Called party number" },
202         { Q933_IE_CALLED_PARTY_SUBADDR,         "Called party subaddress" },
203         { Q933_IE_TRANSIT_NETWORK_SEL,          "Transit network selection" },
204         { Q933_IE_LOW_LAYER_COMPAT,             "Low-layer compatibility" },
205         { Q933_IE_HIGH_LAYER_COMPAT,            "High-layer compatibility" },
206         { Q933_IE_USER_USER,                    "User-user" },
207         { Q933_IE_ESCAPE,                       "Escape" },
208         { 0,                                    NULL }
209 };
210 /* Codeset 1 */
211 static const value_string q933_info_element_vals1[] = {
212         { 0,                                    NULL }
213 };
214 /* Codeset 2 */
215 static const value_string q933_info_element_vals2[] = {
216         { 0,                                    NULL }
217 };
218 /* Codeset 3 */
219 static const value_string q933_info_element_vals3[] = {
220         { 0,                                    NULL }
221 };
222 /* Codeset 4 */
223 static const value_string q933_info_element_vals4[] = {
224         { 0,                                    NULL }
225 };
226
227 /* Codeset 5 */
228 #define Q933_IE_ANSI_REPORT_TYPE         0x01
229 #define Q933_IE_ANSI_LINK_INTEGRITY_VERF 0x03
230 #define Q933_IE_ANSI_PVC_STATUS          0x07
231
232 /* Codeset 5 */
233 static const value_string q933_info_element_vals5[] = {
234         { Q933_IE_ANSI_REPORT_TYPE,             "Report type (ANSI)" },
235         { Q933_IE_REPORT_TYPE,                  "Report type (CCITT)" },
236         { Q933_IE_ANSI_LINK_INTEGRITY_VERF,     "Keep Alive (ANSI)" },
237         { Q933_IE_LINK_INTEGRITY_VERF,          "Keep Alive (CCITT)" },
238         { Q933_IE_ANSI_PVC_STATUS,              "PVC Status (ANSI)" },
239         { Q933_IE_PVC_STATUS,                   "PVC Status (CCITT)" },
240         { 0,                                    NULL }
241 };
242 /* Codeset 6 */
243 static const value_string q933_info_element_vals6[] = {
244         { 0,                                    NULL }
245 };
246 /* Codeset 7 */
247 static const value_string q933_info_element_vals7[] = {
248         { 0,                                    NULL }
249 };
250
251 /* Codeset array */
252 #define NUM_INFO_ELEMENT_VALS   (Q933_IE_SHIFT_CODESET+1)
253 static const value_string *q933_info_element_vals[NUM_INFO_ELEMENT_VALS] = {
254   q933_info_element_vals0,
255   q933_info_element_vals1,
256   q933_info_element_vals2,
257   q933_info_element_vals3,
258   q933_info_element_vals4,
259   q933_info_element_vals5,
260   q933_info_element_vals6,
261   q933_info_element_vals7,
262 };
263
264 static const value_string q933_repeat_indication_vals[] = {
265         { 0x2, "Prioritized list" },
266         { 0,   NULL }
267 };
268
269 /*
270  * ITU-standardized coding.
271  */
272 #define Q933_ITU_STANDARDIZED_CODING    0x00
273
274 /*
275  * Dissect a Segmented message information element.
276  */
277 static void
278 dissect_q933_segmented_message_ie(tvbuff_t *tvb, int offset, int len,
279     proto_tree *tree)
280 {
281         if (len != 2) {
282                 proto_tree_add_text(tree, tvb, offset, len,
283                     "Segmented message: length is %d, should be 2", len);
284                 return;
285         }
286         if (tvb_get_guint8(tvb, offset) & 0x80) {
287                 proto_tree_add_text(tree, tvb, offset, 1,
288                     "First segment: %u segments remaining",
289                     tvb_get_guint8(tvb, offset) & 0x7F);
290         } else {
291                 proto_tree_add_text(tree, tvb, offset, 1,
292                     "Not first segment: %u segments remaining",
293                     tvb_get_guint8(tvb, offset) & 0x7F);
294         }
295         proto_tree_add_text(tree, tvb, offset + 1, 1,
296             "Segmented message type: %u", tvb_get_guint8(tvb, offset + 1));
297 }
298
299 /*
300  * Dissect a Bearer capability or Low-layer compatibility information element.
301  */
302 static const value_string q933_coding_standard_vals[] = {
303         { 0x0, "ITU-T standardized coding" },
304         { 0x1, "ISO/IEC standard" },
305         { 0x2, "National standard" },
306         { 0x3, "Standard defined for this particular network" },
307         { 0,    NULL }
308 };
309
310 static const value_string q933_information_transfer_capability_vals[] = {
311         { 0x08, "Unrestricted digital information" },
312         { 0,    NULL }
313 };
314
315 static const value_string q933_transfer_mode_vals[] = {
316         { 0x01, "Frame mode" },
317         { 0,    NULL }
318 };
319
320 static const value_string q933_uil1_vals[] = {
321         { 0x01, "V.110/I.460/X.30 rate adaption" },
322         { 0x02, "Recommendation G.711 u-law" },
323         { 0x03, "Recommendation G.711 A-law" },
324         { 0x04, "Recommendation G.721 32 kbit/s ADPCM and Recommendation I.460" },
325         { 0x05, "Recommendation H.221 and H.242" },
326         { 0x06, "Recommendation H.223 and H.245" },
327         { 0x07, "Non-ITU-T-standardized rate adaption" },
328         { 0x08, "V.120 rate adaption" },
329         { 0x09, "X.31 HDLC flag stuffing" },
330         { 0,    NULL },
331 };
332
333 static const value_string q933_l1_user_rate_vals[] = {
334         { 0x00, "Rate indicated by E-bits" },
335         { 0x01, "0.6 kbit/s" },
336         { 0x02, "1.2 kbit/s" },
337         { 0x03, "2.4 kbit/s" },
338         { 0x04, "3.6 kbit/s" },
339         { 0x05, "4.8 kbit/s" },
340         { 0x06, "7.2 kbit/s" },
341         { 0x07, "8 kbit/s" },
342         { 0x08, "9.6 kbit/s" },
343         { 0x09, "14.4 kbit/s" },
344         { 0x0A, "16 kbit/s" },
345         { 0x0B, "19.2 kbit/s" },
346         { 0x0C, "32 kbit/s" },
347         { 0x0E, "48 kbit/s" },
348         { 0x0F, "56 kbit/s" },
349         { 0x10, "64 kbit/s "},
350         { 0x15, "0.1345 kbit/s" },
351         { 0x16, "0.100 kbit/s" },
352         { 0x17, "0.075/1.2 kbit/s" },
353         { 0x18, "1.2/0.075 kbit/s" },
354         { 0x19, "0.050 kbit/s" },
355         { 0x1A, "0.075 kbit/s" },
356         { 0x1B, "0.110 kbit/s" },
357         { 0x1C, "0.150 kbit/s" },
358         { 0x1D, "0.200 kbit/s" },
359         { 0x1E, "0.300 kbit/s" },
360         { 0x1F, "12 kbit/s" },
361         { 0,    NULL }
362 };
363
364 static const value_string q933_l1_stop_bits_vals[] = {
365         { 0x20, "1" },
366         { 0x40, "1.5" },
367         { 0x60, "2" },
368         { 0,    NULL }
369 };
370
371 static const value_string q933_l1_data_bits_vals[] = {
372         { 0x08, "5" },
373         { 0x10, "7" },
374         { 0x18, "8" },
375         { 0,    NULL }
376 };
377
378 static const value_string q933_l1_parity_vals[] = {
379         { 0x00, "Odd" },
380         { 0x02, "Even" },
381         { 0x03, "None" },
382         { 0x04, "Forced to 0" },
383         { 0x05, "Forced to 1" },
384         { 0,    NULL }
385 };
386
387 #define Q933_UIL2_USER_SPEC     0x10
388
389 static const value_string q933_uil2_vals[] = {
390         { 0x01,                 "Basic mode ISO 1745" },
391         { 0x06,                 "X.25, link level" },
392         { 0x07,                 "X.25 multilink" },
393         { 0x08,                 "T.71 Extended LAPB" },
394         { 0x09,                 "HDLC ARM" },
395         { 0x0A,                 "HDLC NRM" },
396         { 0x0B,                 "HDLC ABM" },
397         { 0x0C,                 "ISO 8802/2 LLC" },
398         { 0x0D,                 "X.75 Single Link Procedure" },
399         { 0x0E,                 "Q.922" },
400         { 0x0F,                 "Core aspects of Q.922" },
401         { Q933_UIL2_USER_SPEC,  "User-specified" },
402         { 0x11,                 "ISO 7776 DTE-DTE operation" },
403         { 0,                    NULL }
404 };
405
406 static const value_string q933_address_inclusion_vals[] = {
407         { 0x01,                 "Address included" },
408         { 0x02,                 "Encapsulation of logical control frame" },
409         { 0,                    NULL }
410 };
411
412 static const value_string q933_mode_vals[] = {
413         { 0x20, "Normal mode" },
414         { 0x40, "Extended mode" },
415         { 0,    NULL }
416 };
417
418 #define Q933_UIL3_X25_PL        0x06
419 #define Q933_UIL3_ISO_8208      0x07    /* X.25-based */
420 #define Q933_UIL3_X223          0x08    /* X.25-based */
421 #define Q933_UIL3_TR_9577       0x0B
422 #define Q933_UIL3_USER_SPEC     0x10
423
424 static const value_string q933_uil3_vals[] = {
425         { Q933_UIL3_X25_PL,     "X.25, packet layer" },
426         { Q933_UIL3_ISO_8208,   "ISO/IEC 8208" },
427         { Q933_UIL3_X223,       "X.223/ISO 8878" },
428         { 0x09,                 "ISO/IEC 8473" },
429         { 0x0A,                 "T.70" },
430         { Q933_UIL3_TR_9577,    "ISO/IEC TR 9577" },
431         { Q933_UIL3_USER_SPEC,  "User-specified" },
432         { 0,                    NULL }
433 };
434
435 static void
436 dissect_q933_protocol_discriminator(tvbuff_t *tvb, int offset, proto_tree *tree)
437 {
438         unsigned int discriminator = tvb_get_guint8(tvb, offset);
439
440         if (discriminator == NLPID_Q_933) {
441                 proto_tree_add_uint_format_value(tree, hf_q933_discriminator,
442                          tvb, offset, 1, discriminator,
443                          "Q.933");
444         } else if (discriminator == NLPID_Q_2931) {
445                 proto_tree_add_uint_format_value(tree, hf_q933_discriminator,
446                          tvb, offset, 1, discriminator,
447                          "Q.2931");
448         } else if ((discriminator >= 16 && discriminator < 63)
449             || ((discriminator >= 80) && (discriminator < 254))) {
450                 proto_tree_add_uint_format_value(tree, hf_q933_discriminator,
451                     tvb, offset, 1, discriminator,
452                     "Network layer or layer 3 protocol (0x%02X)",
453                     discriminator);
454         } else if (discriminator >= 64 && discriminator <= 79) {
455                 proto_tree_add_uint_format_value(tree, hf_q933_discriminator,
456                     tvb, offset, 1, discriminator,
457                     "National use (0x%02X)",
458                     discriminator);
459         } else {
460                 proto_tree_add_uint_format_value(tree, hf_q933_discriminator,
461                     tvb, offset, 1, discriminator,
462                     "Reserved (0x%02X)",
463                     discriminator);
464         }
465 }
466
467 static void
468 dissect_q933_bearer_capability_ie(tvbuff_t *tvb, int offset, int len,
469     proto_tree *tree)
470 {
471         guint8 octet;
472         guint8 coding_standard;
473         guint8 modem_type;
474         guint8 uil2_protocol;
475         guint8 uil3_protocol;
476         guint8 add_l3_info;
477
478         if (len == 0)
479                 return;
480         octet = tvb_get_guint8(tvb, offset);
481         coding_standard = octet & 0x60;
482         if (coding_standard != Q933_ITU_STANDARDIZED_CODING) {
483                 /*
484                  * We don't know how the bearer capability is encoded,
485                  * so just dump it as data and be done with it.
486                  */
487                 proto_tree_add_text(tree, tvb, offset,
488                     len, "Data: %s",
489                     tvb_bytes_to_ep_str(tvb, offset, len));
490                 proto_tree_add_uint(tree, hf_q933_coding_standard, tvb, offset, 1, octet);
491                 proto_tree_add_boolean(tree, hf_q933_extension_ind, tvb, offset, 1, octet);
492                 return;
493         }
494         proto_tree_add_uint(tree, hf_q933_information_transfer_capability, tvb, offset, 1, octet);
495         proto_tree_add_uint(tree, hf_q933_coding_standard, tvb, offset, 1, octet);
496         proto_tree_add_boolean(tree, hf_q933_extension_ind, tvb, offset, 1, octet);
497         offset += 1;
498         len -= 1;
499
500         /*
501          * XXX - only in Low-layer compatibility information element.
502          */
503         if (!(octet & Q933_IE_VL_EXTENSION)) {
504                 if (len == 0)
505                         return;
506                 octet = tvb_get_guint8(tvb, offset);
507                 proto_tree_add_text(tree, tvb, offset, 1,
508                     "Out-band negotiation %spossible",
509                     (octet & 0x40) ? "" : "not ");
510                 offset += 1;
511                 len -= 1;
512         }
513
514         if (len == 0)
515                 return;
516         octet = tvb_get_guint8(tvb, offset);
517         proto_tree_add_uint(tree, hf_q933_transfer_mode, tvb, offset, 1, octet);
518         proto_tree_add_boolean(tree, hf_q933_extension_ind, tvb, offset, 1, octet);
519         offset += 1;
520         len -= 1;
521
522         if (len == 0)
523                 return;
524         octet = tvb_get_guint8(tvb, offset);
525         if ((octet & 0x60) == 0x20) {
526                 /*
527                  * Layer 1 information.
528                  */
529                 proto_tree_add_uint(tree, hf_q933_uil1, tvb, offset, 1, octet);
530                 proto_tree_add_boolean(tree, hf_q933_extension_ind, tvb, offset, 1, octet);
531                 offset += 1;
532                 len -= 1;
533
534                 if (octet & Q933_IE_VL_EXTENSION)
535                         goto l1_done;
536                 if (len == 0)
537                         return;
538                 octet = tvb_get_guint8(tvb, offset);
539                 proto_tree_add_text(tree, tvb, offset, 1,
540                     "Layer 1 is %s",
541                     (octet & 0x40) ? "Asynchronous" : "Synchronous");
542                 proto_tree_add_text(tree, tvb, offset, 1,
543                     "User rate: %s",
544                     val_to_str(octet & 0x1F, q933_l1_user_rate_vals,
545                       "Unknown (0x%02X)"));
546                 offset += 1;
547                 len -= 1;
548
549                 if (octet & Q933_IE_VL_EXTENSION)
550                         goto l1_done;
551                 if (len == 0)
552                         return;
553                 octet = tvb_get_guint8(tvb, offset);
554                 proto_tree_add_text(tree, tvb, offset, 1,
555                     "Rate adaption header %sincluded",
556                     (octet & 0x40) ? "" : "not ");
557                 proto_tree_add_text(tree, tvb, offset, 1,
558                     "Multiple frame establishment %ssupported",
559                     (octet & 0x20) ? "" : "not ");
560                 proto_tree_add_text(tree, tvb, offset, 1,
561                     "%s mode of operation",
562                     (octet & 0x10) ? "Protocol sensitive" : "Bit transparent");
563                 offset += 1;
564                 len -= 1;
565
566                 if (octet & Q933_IE_VL_EXTENSION)
567                         goto l1_done;
568                 if (len == 0)
569                         return;
570                 octet = tvb_get_guint8(tvb, offset);
571                 proto_tree_add_text(tree, tvb, offset, 1,
572                     "Stop bits: %s",
573                       val_to_str(octet & 0x60, q933_l1_stop_bits_vals,
574                        "Unknown (0x%X)"));
575                 proto_tree_add_text(tree, tvb, offset, 1,
576                     "Data bits: %s",
577                       val_to_str(octet & 0x18, q933_l1_data_bits_vals,
578                        "Unknown (0x%X)"));
579                 proto_tree_add_text(tree, tvb, offset, 1,
580                     "Parity: %s",
581                       val_to_str(octet & 0x07, q933_l1_parity_vals,
582                        "Unknown (0x%X)"));
583                 offset += 1;
584                 len -= 1;
585
586                 if (octet & Q933_IE_VL_EXTENSION)
587                         goto l1_done;
588                 if (len == 0)
589                         return;
590                 octet = tvb_get_guint8(tvb, offset);
591                 proto_tree_add_text(tree, tvb, offset, 1,
592                     "%s duplex",
593                     (octet & 0x40) ? "Full" : "Half");
594                 modem_type = octet & 0x3F;
595                 proto_tree_add_text(tree, tvb, offset, 1,
596                     "Modem type: Network-specific rules 0x%02X", modem_type);
597                 offset += 1;
598                 len -= 1;
599         }
600 l1_done:
601         ;
602
603         if (len == 0)
604                 return;
605         octet = tvb_get_guint8(tvb, offset);
606         if ((octet & 0x60) == 0x40) {
607                 /*
608                  * Layer 2 information.
609                  */
610                 uil2_protocol = octet & 0x1F;
611                 proto_tree_add_text(tree, tvb, offset, 1,
612                     "User information layer 2 protocol: %s",
613                     val_to_str(uil2_protocol, q933_uil2_vals,
614                       "Unknown (0x%02X)"));
615                 offset += 1;
616                 len -= 1;
617
618                 /*
619                  * XXX - only in Low-layer compatibility information element.
620                  */
621                 if (octet & Q933_IE_VL_EXTENSION)
622                         goto l2_done;
623                 if (len == 0)
624                         return;
625                 octet = tvb_get_guint8(tvb, offset);
626                 if (uil2_protocol == Q933_UIL2_USER_SPEC) {
627                         proto_tree_add_text(tree, tvb, offset, 1,
628                             "User-specified layer 2 protocol information: 0x%02X",
629                             octet & 0x7F);
630                 } else {
631                         proto_tree_add_text(tree, tvb, offset, 1,
632                             "Address inclusion: %s",
633                             val_to_str(octet & 0x03, q933_address_inclusion_vals,
634                               "Unknown (0x%02X)"));
635                 }
636                 offset += 1;
637                 len -= 1;
638         }
639 l2_done:
640         ;
641
642         if (len == 0)
643                 return;
644         octet = tvb_get_guint8(tvb, offset);
645         if ((octet & 0x60) == 0x60) {
646                 /*
647                  * Layer 3 information.
648                  */
649                 uil3_protocol = octet & 0x1F;
650                 proto_tree_add_text(tree, tvb, offset, 1,
651                     "User information layer 3 protocol: %s",
652                     val_to_str(uil3_protocol, q933_uil3_vals,
653                       "Unknown (0x%02X)"));
654                 offset += 1;
655                 len -= 1;
656
657
658                 /*
659                  * XXX - only in Low-layer compatibility information element.
660                  */
661                 if (octet & Q933_IE_VL_EXTENSION)
662                         goto l3_done;
663                 if (len == 0)
664                         return;
665                 octet = tvb_get_guint8(tvb, offset);
666                 switch (uil3_protocol) {
667
668                 case Q933_UIL3_X25_PL:
669                 case Q933_UIL3_ISO_8208:
670                 case Q933_UIL3_X223:
671                         proto_tree_add_text(tree, tvb, offset, 1,
672                             "Mode: %s",
673                             val_to_str(octet & 0x60, q933_mode_vals,
674                               "Unknown (0x%02X)"));
675                         offset += 1;
676                         len -= 1;
677
678                         if (octet & Q933_IE_VL_EXTENSION)
679                                 goto l3_done;
680                         if (len == 0)
681                                 return;
682                         octet = tvb_get_guint8(tvb, offset);
683                         proto_tree_add_text(tree, tvb, offset, 1,
684                             "Default packet size: %u", octet & 0x0F);
685                         offset += 1;
686                         len -= 1;
687
688                         if (octet & Q933_IE_VL_EXTENSION)
689                                 goto l3_done;
690                         if (len == 0)
691                                 return;
692                         octet = tvb_get_guint8(tvb, offset);
693                         proto_tree_add_text(tree, tvb, offset, 1,
694                             "Packet window size: %u", octet & 0x7F);
695                         /*offset += 1;*/
696                         /*len -= 1;*/
697                         break;
698
699                 case Q933_UIL3_USER_SPEC:
700                         proto_tree_add_text(tree, tvb, offset, 1,
701                             "Default packet size: %u octets",
702                             1 << (octet & 0x0F));
703                         /*offset += 1;*/
704                         /*len -= 1;*/
705                         break;
706
707                 case Q933_UIL3_TR_9577:
708                         add_l3_info = (octet & 0x0F) << 4;
709                         if (octet & Q933_IE_VL_EXTENSION)
710                                 goto l3_done;
711 #if 0 /* XXX: len is always >0 at this point; is field always 2 bytes (if not Q933_IE_VL_EXTENSION) ? */
712                         if (len == 0)
713                                 return;
714 #endif
715                         octet = tvb_get_guint8(tvb, offset + 1);
716                         add_l3_info |= (octet & 0x0F);
717                         proto_tree_add_text(tree, tvb, offset, 2,
718                             "Additional layer 3 protocol information: %s",
719                             val_to_str(add_l3_info, nlpid_vals,
720                               "Unknown (0x%02X)"));
721                         /*offset += 2;*/
722                         /*len -= 2;*/
723                         break;
724                 }
725         }
726 l3_done:
727         ;
728 }
729
730 /*
731  * Dissect a Cause information element.
732  */
733
734
735 const value_string q933_cause_location_vals[] = {
736         { 0x00, "User (U)" },
737         { 0x01, "Private network serving the local user (LPN)" },
738         { 0x02, "Public network serving the local user (LN)" },
739         { 0x03, "Transit network (TN)" },
740         { 0x04, "Public network serving the remote user (RLN)" },
741         { 0x05, "Private network serving the remote user (RPN)" },
742         { 0x07, "International network (INTL)" },
743         { 0x0A, "Network beyond interworking point (BI)" },
744         { 0,    NULL }
745 };
746
747 static const value_string q933_cause_recommendation_vals[] = {
748         { 0x00, "Q.933" },
749         { 0x03, "X.21" },
750         { 0x04, "X.25" },
751         { 0x05, "Q.1031/Q.1051" },
752         { 0,    NULL }
753 };
754
755 /*
756  * Cause codes for Cause.
757  */
758 #define Q933_CAUSE_UNALLOC_NUMBER       0x01
759 #define Q933_CAUSE_NO_ROUTE_TO_DEST     0x03
760 #define Q933_CAUSE_CALL_REJECTED        0x15
761 #define Q933_CAUSE_NUMBER_CHANGED       0x16
762 #define Q933_CAUSE_ACCESS_INFO_DISC     0x2B
763 #define Q933_CAUSE_QOS_UNAVAILABLE      0x31
764 #define Q933_CAUSE_CHAN_NONEXISTENT     0x52
765 #define Q933_CAUSE_INCOMPATIBLE_DEST    0x58
766 #define Q933_CAUSE_MAND_IE_MISSING      0x60
767 #define Q933_CAUSE_MT_NONEX_OR_UNIMPL   0x61
768 #define Q933_CAUSE_IE_NONEX_OR_UNIMPL   0x63
769 #define Q933_CAUSE_INVALID_IE_CONTENTS  0x64
770 #define Q933_CAUSE_MSG_INCOMPAT_W_CS    0x65
771 #define Q933_CAUSE_REC_TIMER_EXP        0x66
772
773 const value_string q933_cause_code_vals[] = {
774         { 0x00,                         "Valid cause code not yet received" },
775         { Q933_CAUSE_UNALLOC_NUMBER,    "Unallocated (unassigned) number" },
776         { 0x02,                         "No route to specified transit network" },
777         { Q933_CAUSE_NO_ROUTE_TO_DEST,  "No route to destination" },
778         { 0x04,                         "Send special information tone" },
779         { 0x05,                         "Misdialled trunk prefix" },
780         { 0x06,                         "Channel unacceptable" },
781         { 0x07,                         "Call awarded and being delivered in an established channel" },
782         { 0x08,                         "Prefix 0 dialed but not allowed" },
783                                         /* Q.850 - "Preemption" */
784         { 0x09,                         "Prefix 1 dialed but not allowed" },
785                                         /* Q.850 - "Preemption - circuit reserved for reuse" */
786         { 0x0A,                         "Prefix 1 dialed but not required" },
787         { 0x0B,                         "More digits received than allowed, call is proceeding" },
788         { 0x0E,                         "QoR: ported number" },
789         { 0x10,                         "Normal call clearing" },
790         { 0x11,                         "User busy" },
791         { 0x12,                         "No user responding" },
792         { 0x13,                         "No answer from user (user alerted)" },
793         { 0x14,                         "Subscriber absent" },
794         { Q933_CAUSE_CALL_REJECTED,     "Call rejected" },
795         { Q933_CAUSE_NUMBER_CHANGED,    "Number changed" },
796         { 0x17,                         "Reverse charging rejected" },
797                                         /* Q.850 - "Redirection to new destination" */
798         { 0x18,                         "Call suspended" },
799                                         /* Q.850 Amendment 1 - "Call rejected due to feature at the destination" */
800         { 0x19,                         "Call resumed" },
801                                         /* Q.850 - "Exchange routing error */
802         { 0x1A,                         "Non-selected user clearing" },
803         { 0x1B,                         "Destination out of order" },
804         { 0x1C,                         "Invalid number format (incomplete number)" },
805         { 0x1D,                         "Facility rejected" },
806         { 0x1E,                         "Response to STATUS ENQUIRY" },
807         { 0x1F,                         "Normal unspecified" },
808         { 0x21,                         "Circuit out of order" },
809         { 0x22,                         "No circuit/channel available" },
810         { 0x23,                         "Destination unattainable" },
811         { 0x25,                         "Degraded service" },
812         { 0x26,                         "Network out of order" },
813         { 0x27,                         "Transit delay range cannot be achieved" },
814                                         /* Q.850 - "Permanent frame mode connection out of service" */
815         { 0x28,                         "Throughput range cannot be achieved" },
816                                         /* Q.850 - "Permanent frame mode connection operational" */
817         { 0x29,                         "Temporary failure" },
818         { 0x2A,                         "Switching equipment congestion" },
819         { Q933_CAUSE_ACCESS_INFO_DISC,  "Access information discarded" },
820         { 0x2C,                         "Requested circuit/channel not available" },
821         { 0x2D,                         "Pre-empted" },
822         { 0x2E,                         "Precedence call blocked" },
823         { 0x2F,                         "Resources unavailable, unspecified" },
824         { Q933_CAUSE_QOS_UNAVAILABLE,   "Quality of service unavailable" },
825         { 0x32,                         "Requested facility not subscribed" },
826         { 0x33,                         "Reverse charging not allowed" },
827         { 0x34,                         "Outgoing calls barred" },
828         { 0x35,                         "Outgoing calls barred within CUG" },
829         { 0x36,                         "Incoming calls barred" },
830         { 0x37,                         "Incoming calls barred within CUG" },
831         { 0x38,                         "Call waiting not subscribed" },
832         { 0x39,                         "Bearer capability not authorized" },
833         { 0x3A,                         "Bearer capability not presently available" },
834         { 0x3E,                         "Inconsistency in designated outgoing access information and subscriber class" },
835         { 0x3F,                         "Service or option not available, unspecified" },
836         { 0x41,                         "Bearer capability not implemented" },
837         { 0x42,                         "Channel type not implemented" },
838         { 0x43,                         "Transit network selection not implemented" },
839         { 0x44,                         "Message not implemented" },
840         { 0x45,                         "Requested facility not implemented" },
841         { 0x46,                         "Only restricted digital information bearer capability is available" },
842         { 0x4F,                         "Service or option not implemented, unspecified" },
843         { 0x51,                         "Invalid call reference value" },
844         { Q933_CAUSE_CHAN_NONEXISTENT,  "Identified channel does not exist" },
845         { 0x53,                         "Call identity does not exist for suspended call" },
846         { 0x54,                         "Call identity in use" },
847         { 0x55,                         "No call suspended" },
848         { 0x56,                         "Call having the requested call identity has been cleared" },
849         { 0x57,                         "Called user not member of CUG" },
850         { Q933_CAUSE_INCOMPATIBLE_DEST, "Incompatible destination" },
851         { 0x59,                         "Non-existent abbreviated address entry" },
852         { 0x5A,                         "Destination address missing, and direct call not subscribed" },
853                                         /* Q.850 - "Non-existent CUG" */
854         { 0x5B,                         "Invalid transit network selection (national use)" },
855         { 0x5C,                         "Invalid facility parameter" },
856         { 0x5D,                         "Mandatory information element is missing" },
857         { 0x5F,                         "Invalid message, unspecified" },
858         { Q933_CAUSE_MAND_IE_MISSING,   "Mandatory information element is missing" },
859         { Q933_CAUSE_MT_NONEX_OR_UNIMPL,"Message type non-existent or not implemented" },
860         { 0x62,                         "Message not compatible with call state or message type non-existent or not implemented" },
861         { Q933_CAUSE_IE_NONEX_OR_UNIMPL,"Information element non-existent or not implemented" },
862         { Q933_CAUSE_INVALID_IE_CONTENTS,"Invalid information element contents" },
863         { Q933_CAUSE_MSG_INCOMPAT_W_CS, "Message not compatible with call state" },
864         { Q933_CAUSE_REC_TIMER_EXP,     "Recovery on timer expiry" },
865         { 0x67,                         "Parameter non-existent or not implemented - passed on" },
866         { 0x6E,                         "Message with unrecognized parameter discarded" },
867         { 0x6F,                         "Protocol error, unspecified" },
868         { 0x7F,                         "Internetworking, unspecified" },
869         { 0,                            NULL }
870 };
871
872 static const value_string q933_cause_condition_vals[] = {
873         { 0x00, "Unknown" },
874         { 0x01, "Permanent" },
875         { 0x02, "Transient" },
876         { 0x00, NULL }
877 };
878
879 #define Q933_REJ_USER_SPECIFIC          0x00
880 #define Q933_REJ_IE_MISSING             0x04
881 #define Q933_REJ_IE_INSUFFICIENT        0x08
882
883 static const value_string q933_rejection_reason_vals[] = {
884         { 0x00, "User specific" },
885         { 0x04, "Information element missing" },
886         { 0x08, "Information element contents are not sufficient" },
887         { 0x00, NULL }
888 };
889
890 static void
891 dissect_q933_cause_ie(tvbuff_t *tvb, int offset, int len,
892     proto_tree *tree, int hf_cause_value)
893 {
894         guint8 octet;
895         guint8 cause_value;
896         guint8 coding_standard;
897         guint8 rejection_reason;
898
899         if (len == 0)
900                 return;
901         octet = tvb_get_guint8(tvb, offset);
902         coding_standard = octet & 0x60;
903         if (coding_standard != Q933_ITU_STANDARDIZED_CODING) {
904                 /*
905                  * We don't know how the cause is encoded,
906                  * so just dump it as data and be done with it.
907                  */
908                 proto_tree_add_uint(tree, hf_q933_coding_standard, tvb, offset, 1, octet);
909                 proto_tree_add_text(tree, tvb, offset,
910                     len, "Data: %s",
911                     tvb_bytes_to_ep_str(tvb, offset, len));
912                 return;
913         }
914         proto_tree_add_uint(tree, hf_q933_cause_location, tvb, offset, 1, octet);
915         proto_tree_add_uint(tree, hf_q933_coding_standard, tvb, offset, 1, octet);
916         proto_tree_add_boolean(tree, hf_q933_extension_ind, tvb, offset, 1, octet);
917         offset += 1;
918         len -= 1;
919
920         if (!(octet & Q933_IE_VL_EXTENSION)) {
921                 if (len == 0)
922                         return;
923                 octet = tvb_get_guint8(tvb, offset);
924                 proto_tree_add_text(tree, tvb, offset, 1,
925                     "Recommendation: %s",
926                     val_to_str(octet & 0x7F, q933_cause_recommendation_vals,
927                       "Unknown (0x%02X)"));
928                 proto_tree_add_boolean(tree, hf_q933_extension_ind, tvb, offset, 1, octet);
929                 offset += 1;
930                 len -= 1;
931         }
932
933         if (len == 0)
934                 return;
935         octet = tvb_get_guint8(tvb, offset);
936         cause_value = octet & 0x7F;
937         proto_tree_add_uint(tree, hf_cause_value, tvb, offset, 1, cause_value);
938         proto_tree_add_boolean(tree, hf_q933_extension_ind, tvb, offset, 1, octet);
939         offset += 1;
940         len -= 1;
941
942         if (len == 0)
943                 return;
944         switch (cause_value) {
945
946         case Q933_CAUSE_UNALLOC_NUMBER:
947         case Q933_CAUSE_NO_ROUTE_TO_DEST:
948         case Q933_CAUSE_QOS_UNAVAILABLE:
949                 octet = tvb_get_guint8(tvb, offset);
950                 proto_tree_add_text(tree, tvb, offset, 1,
951                     "Network service: %s",
952                     (octet & 0x80) ? "User" : "Provider");
953                 proto_tree_add_text(tree, tvb, offset, 1,
954                     "%s",
955                     (octet & 0x40) ? "Abnormal" : "Normal");
956                 proto_tree_add_text(tree, tvb, offset, 1,
957                     "Condition: %s",
958                     val_to_str(octet & 0x03, q933_cause_condition_vals,
959                       "Unknown (0x%X)"));
960                 break;
961
962         case Q933_CAUSE_CALL_REJECTED:
963                 rejection_reason = octet & 0x7C;
964                 proto_tree_add_text(tree, tvb, offset, 1,
965                     "Rejection reason: %s",
966                     val_to_str(octet & 0x7C, q933_rejection_reason_vals,
967                       "Unknown (0x%X)"));
968                 proto_tree_add_text(tree, tvb, offset, 1,
969                     "Condition: %s",
970                     val_to_str(octet & 0x03, q933_cause_condition_vals,
971                       "Unknown (0x%X)"));
972                 offset += 1;
973                 len -= 1;
974
975                 if (len == 0)
976                         return;
977                 switch (rejection_reason) {
978
979                 case Q933_REJ_USER_SPECIFIC:
980                         proto_tree_add_text(tree, tvb, offset, len,
981                             "User specific diagnostic: %s",
982                             tvb_bytes_to_ep_str(tvb, offset, len));
983                         break;
984
985                 case Q933_REJ_IE_MISSING:
986                         proto_tree_add_text(tree, tvb, offset, 1,
987                             "Missing information element: %s",
988                             val_to_str(tvb_get_guint8(tvb, offset), q933_info_element_vals0,
989                               "Unknown (0x%02X)"));
990                         break;
991
992                 case Q933_REJ_IE_INSUFFICIENT:
993                         proto_tree_add_text(tree, tvb, offset, 1,
994                             "Insufficient information element: %s",
995                             val_to_str(tvb_get_guint8(tvb, offset), q933_info_element_vals0,
996                               "Unknown (0x%02X)"));
997                         break;
998
999                 default:
1000                         proto_tree_add_text(tree, tvb, offset, len,
1001                             "Diagnostic: %s",
1002                             tvb_bytes_to_ep_str(tvb, offset, len));
1003                         break;
1004                 }
1005                 break;
1006
1007         case Q933_CAUSE_ACCESS_INFO_DISC:
1008         case Q933_CAUSE_INCOMPATIBLE_DEST:
1009         case Q933_CAUSE_MAND_IE_MISSING:
1010         case Q933_CAUSE_IE_NONEX_OR_UNIMPL:
1011         case Q933_CAUSE_INVALID_IE_CONTENTS:
1012                 do {
1013                         proto_tree_add_text(tree, tvb, offset, 1,
1014                             "Information element: %s",
1015                             val_to_str(tvb_get_guint8(tvb, offset), q933_info_element_vals0,
1016                               "Unknown (0x%02X)"));
1017                         offset += 1;
1018                         len -= 1;
1019                 } while (len != 0);
1020                 break;
1021
1022         case Q933_CAUSE_MT_NONEX_OR_UNIMPL:
1023         case Q933_CAUSE_MSG_INCOMPAT_W_CS:
1024                 proto_tree_add_text(tree, tvb, offset, 1,
1025                     "Message type: %s",
1026                     val_to_str(tvb_get_guint8(tvb, offset), q933_message_type_vals,
1027                       "Unknown (0x%02X)"));
1028                 break;
1029
1030         case Q933_CAUSE_REC_TIMER_EXP:
1031                 if (len < 3)
1032                         return;
1033                 proto_tree_add_text(tree, tvb, offset, 3,
1034                     "Timer: %.3s", tvb_get_string_enc(wmem_packet_scope(), tvb, offset, 3, ENC_ASCII));
1035                 break;
1036
1037         default:
1038                 proto_tree_add_text(tree, tvb, offset, len,
1039                     "Diagnostics: %s",
1040                     tvb_bytes_to_ep_str(tvb, offset, len));
1041         }
1042 }
1043
1044 /*
1045  * Dissect a Call state information element.
1046  */
1047 static const value_string q933_call_state_vals[] = {
1048         { 0x00, "Null" },
1049         { 0x01, "Call initiated" },
1050         { 0x02, "Overlap sending" },
1051         { 0x03, "Outgoing call proceeding" },
1052         { 0x04, "Call delivered" },
1053         { 0x06, "Call present" },
1054         { 0x07, "Call received" },
1055         { 0x08, "Connect request" },
1056         { 0x09, "Incoming call proceeding" },
1057         { 0x0A, "Active" },
1058         { 0x0B, "Disconnect request" },
1059         { 0x0C, "Disconnect indication" },
1060         { 0x0F, "Suspend request" },
1061         { 0x12, "Resume request" },
1062         { 0x13, "Release request" },
1063         { 0x16, "Call abort"},
1064         { 0x19, "Overlap receiving" },
1065         { 0x3D, "Restart request" },
1066         { 0x3E, "Restart" },
1067         { 0,    NULL }
1068 };
1069
1070 static void
1071 dissect_q933_call_state_ie(tvbuff_t *tvb, int offset, int len,
1072     proto_tree *tree)
1073 {
1074         guint8 octet;
1075         guint8 coding_standard;
1076
1077         if (len == 0)
1078                 return;
1079         octet = tvb_get_guint8(tvb, offset);
1080         coding_standard = octet & 0x60;
1081         proto_tree_add_uint(tree, hf_q933_coding_standard, tvb, offset, 1, octet);
1082         if (coding_standard != Q933_ITU_STANDARDIZED_CODING) {
1083                 /*
1084                  * We don't know how the call state is encoded,
1085                  * so just dump it as data and be done with it.
1086                  */
1087                 proto_tree_add_text(tree, tvb, offset,
1088                     len, "Data: %s",
1089                     tvb_bytes_to_ep_str(tvb, offset, len));
1090                 return;
1091         }
1092         proto_tree_add_text(tree, tvb, offset, 1,
1093             "Call state: %s",
1094             val_to_str(octet & 0x3F, q933_call_state_vals,
1095               "Unknown (0x%02X)"));
1096 }
1097
1098 /*
1099  * Dissect a Report Type information element.
1100  */
1101 #define Q933_IE_REPORT_TYPE_FULL_STATUS 0x00
1102 #define Q933_IE_REPORT_TYPE_LINK_VERIFY 0x01
1103 #define Q933_IE_REPORT_TYPE_ASYNC_PVC_STATUS 0x02
1104
1105 static const value_string q933_report_type_vals[] = {
1106         { Q933_IE_REPORT_TYPE_FULL_STATUS, "Full Status" },
1107         { Q933_IE_REPORT_TYPE_LINK_VERIFY, "Link verify" },
1108         { Q933_IE_REPORT_TYPE_ASYNC_PVC_STATUS, "Async PVC Status" },
1109         { 0,    NULL }
1110 };
1111
1112 static void
1113 dissect_q933_report_type_ie(tvbuff_t *tvb, int offset, int len,
1114     proto_tree *tree)
1115 {
1116         guint8 report_type;
1117
1118         if (len == 0)
1119                 return;
1120
1121         report_type = tvb_get_guint8(tvb, offset);
1122         proto_tree_add_uint(tree, hf_q933_report_type, tvb, offset, 1, report_type);
1123 }
1124
1125 /*
1126  * Dissect a Link Integrity Verification information element.
1127  */
1128 static void
1129 dissect_q933_link_integrity_verf_ie(tvbuff_t *tvb, int offset, int len,
1130     proto_tree *tree)
1131 {
1132         guint8 txseq,rxseq;
1133
1134         if (len < 2)
1135                 return;
1136
1137         txseq = tvb_get_guint8(tvb, offset);
1138         rxseq = tvb_get_guint8(tvb, offset+1);
1139
1140         proto_tree_add_uint(tree, hf_q933_link_verf_txseq, tvb, offset, 1, txseq);
1141         proto_tree_add_uint(tree, hf_q933_link_verf_rxseq, tvb, offset+1, 1, rxseq);
1142
1143 }
1144
1145 /*
1146  * Dissect a PVC status information element.
1147  */
1148 static const value_string q933_pvc_status_vals[] = {
1149     {0x00, "Inactive"},
1150     {0x02, "Active"},
1151     {0x08, "New"},
1152     {0x0a, "New, Active"},
1153     {0, NULL}
1154 };
1155
1156 static void
1157 dissect_q933_pvc_status_ie(tvbuff_t *tvb, int offset, int len,
1158     proto_tree *tree)
1159 {
1160         guint32 dlci;
1161         guint8 dlci_status,dlci_len=2;
1162
1163         if (len < 3)
1164                 return;
1165
1166         dlci = ((tvb_get_guint8(tvb, offset) & 0x3F) << 4) |
1167             ((tvb_get_guint8(tvb, offset+1) & 0x78) >> 3);
1168
1169         /* first determine the DLCI field length */
1170         if (len == 4) {
1171             dlci = (dlci << 6) | ((tvb_get_guint8(tvb, offset+2) & 0x7E) >> 1);
1172             dlci_len++;
1173         } else if (len == 5) {
1174             dlci = (dlci << 13) | (tvb_get_guint8(tvb, offset+3) & 0x7F) |
1175                 ((tvb_get_guint8(tvb, offset+4) & 0x7E) >> 1);
1176             dlci_len+=2;
1177         }
1178         dlci_status=tvb_get_guint8(tvb, offset+dlci_len)&0x0a;
1179
1180         proto_tree_add_text(tree, tvb, offset, dlci_len, "DLCI: %u", dlci);
1181         proto_tree_add_text(tree, tvb, offset+dlci_len, 1, "Status: %s",
1182                             val_to_str_const(dlci_status, q933_pvc_status_vals, "Unknown"));
1183 }
1184
1185 /*
1186  * Dissect a Channel identification information element.
1187  */
1188 #define Q933_INTERFACE_IDENTIFIED       0x40
1189 #define Q933_NOT_BASIC_CHANNEL          0x20
1190
1191 static const value_string q933_basic_channel_selection_vals[] = {
1192         { 0x00, "No channel" },
1193         { 0x01, "B1 channel" },
1194         { 0x02, "B2 channel" },
1195         { 0x03, "Any channel" },
1196         { 0,    NULL }
1197 };
1198
1199 static const value_string q933_not_basic_channel_selection_vals[] = {
1200         { 0x00, "No channel" },
1201         { 0x01, "Channel indicated in following octets" },
1202         { 0x03, "Any channel" },
1203         { 0,    NULL }
1204 };
1205
1206 #define Q933_IS_SLOT_MAP                0x10
1207
1208 static const value_string q933_element_type_vals[] = {
1209         { 0x03, "B-channel units" },
1210         { 0x06, "H0-channel units" },
1211         { 0x08, "H11-channel units" },
1212         { 0x09, "H12-channel units" },
1213         { 0,    NULL }
1214 };
1215
1216 static void
1217 dissect_q933_channel_identification_ie(tvbuff_t *tvb, int offset, int len,
1218     proto_tree *tree)
1219 {
1220         guint8 octet;
1221         int identifier_offset;
1222         int identifier_len;
1223         guint8 coding_standard;
1224
1225         if (len == 0)
1226                 return;
1227         octet = tvb_get_guint8(tvb, offset);
1228         proto_tree_add_text(tree, tvb, offset, 1,
1229             "Interface %s identified",
1230             (octet & Q933_INTERFACE_IDENTIFIED) ? "explicitly" : "implicitly");
1231         proto_tree_add_text(tree, tvb, offset, 1,
1232             "%s interface",
1233             (octet & Q933_NOT_BASIC_CHANNEL) ? "Not basic" : "Basic");
1234         proto_tree_add_text(tree, tvb, offset, 1,
1235             "Indicated channel is %s",
1236             (octet & 0x08) ? "required" : "preferred");
1237         proto_tree_add_text(tree, tvb, offset, 1,
1238             "Indicated channel is %sthe D-channel",
1239             (octet & 0x04) ? "" : "not ");
1240         if (octet & Q933_NOT_BASIC_CHANNEL) {
1241                 proto_tree_add_text(tree, tvb, offset, 1,
1242                     "Channel selection: %s",
1243                     val_to_str(octet & 0x03, q933_not_basic_channel_selection_vals,
1244                       "Unknown (0x%X)"));
1245         } else {
1246                 proto_tree_add_text(tree, tvb, offset, 1,
1247                     "Channel selection: %s",
1248                     val_to_str(octet & 0x03, q933_basic_channel_selection_vals,
1249                       "Unknown (0x%X)"));
1250         }
1251         offset += 1;
1252         len -= 1;
1253
1254         if (octet & Q933_INTERFACE_IDENTIFIED) {
1255                 identifier_offset = offset;
1256                 identifier_len = 0;
1257                 do {
1258                         if (len == 0)
1259                                 break;
1260                         octet = tvb_get_guint8(tvb, offset);
1261                         offset += 1;
1262                         len -= 1;
1263                         identifier_len++;
1264                 } while (!(octet & Q933_IE_VL_EXTENSION));
1265
1266                 /*
1267                  * XXX - do we want to strip off the 8th bit on the
1268                  * last octet of the interface identifier?
1269                  */
1270                 if (identifier_len != 0) {
1271                         proto_tree_add_text(tree, tvb, identifier_offset,
1272                             identifier_len, "Interface identifier: %s",
1273                             tvb_bytes_to_ep_str(tvb, identifier_offset, identifier_len));
1274                 }
1275         }
1276
1277         if (octet & Q933_NOT_BASIC_CHANNEL) {
1278                 if (len == 0)
1279                         return;
1280                 octet = tvb_get_guint8(tvb, offset);
1281                 coding_standard = octet & 0x60;
1282                 proto_tree_add_uint(tree, hf_q933_coding_standard, tvb, offset, 1, octet);
1283                 if (coding_standard != Q933_ITU_STANDARDIZED_CODING) {
1284                         /*
1285                          * We don't know how the channel identifier is
1286                          * encoded, so just dump it as data and be done
1287                          * with it.
1288                          */
1289                         proto_tree_add_text(tree, tvb, offset,
1290                             len, "Data: %s",
1291                             tvb_bytes_to_ep_str(tvb, offset, len));
1292                         return;
1293                 }
1294                 proto_tree_add_text(tree, tvb, offset, 1,
1295                     "Channel is indicated by %s",
1296                     (octet & Q933_IS_SLOT_MAP) ? "slot map" : "number");
1297                 proto_tree_add_text(tree, tvb, offset, 1,
1298                     "%s type: %s",
1299                     (octet & Q933_IS_SLOT_MAP) ? "Map element" : "Channel",
1300                     val_to_str(octet & 0x0F, q933_element_type_vals,
1301                         "Unknown (0x%02X)"));
1302
1303                 /*
1304                  * XXX - dump the channel number or slot map.
1305                  */
1306         }
1307 }
1308
1309 /*
1310  * Dissect a Progress indicator information element.
1311  */
1312 static const value_string q933_progress_description_vals[] = {
1313         { 0x01, "Call is not end-to-end ISDN - progress information available in-band" },
1314         { 0x02, "Destination address is non-ISDN" },
1315         { 0x03, "Origination address is non-ISDN" },
1316         { 0x04, "Call has returned to the ISDN" },
1317         { 0x05, "Interworking has occurred and has resulted in a telecommunications service change" },
1318         { 0x08, "In-band information or an appropriate pattern is now available" },
1319         { 0,    NULL }
1320 };
1321
1322 static void
1323 dissect_q933_progress_indicator_ie(tvbuff_t *tvb, int offset, int len,
1324     proto_tree *tree)
1325 {
1326         guint8 octet;
1327         guint8 coding_standard;
1328
1329         if (len == 0)
1330                 return;
1331         octet = tvb_get_guint8(tvb, offset);
1332         coding_standard = octet & 0x60;
1333         proto_tree_add_uint(tree, hf_q933_coding_standard, tvb, offset, 1, octet);
1334         if (coding_standard != Q933_ITU_STANDARDIZED_CODING) {
1335                 /*
1336                  * We don't know how the progress indicator is encoded,
1337                  * so just dump it as data and be done with it.
1338                  */
1339                 proto_tree_add_text(tree, tvb, offset,
1340                     len, "Data: %s",
1341                     tvb_bytes_to_ep_str(tvb, offset, len));
1342                 return;
1343         }
1344         proto_tree_add_text(tree, tvb, offset, 1,
1345             "Location: %s",
1346             val_to_str(octet & 0x0F, q933_cause_location_vals,
1347               "Unknown (0x%X)"));
1348         offset += 1;
1349         len -= 1;
1350
1351         if (len == 0)
1352                 return;
1353         octet = tvb_get_guint8(tvb, offset);
1354         proto_tree_add_text(tree, tvb, offset, 1,
1355             "Progress description: %s",
1356             val_to_str(octet & 0x7F, q933_progress_description_vals,
1357               "Unknown (0x%02X)"));
1358 }
1359
1360 /*
1361  * Dissect a Network-specific facilities or Transit network selection
1362  * information element.
1363  */
1364 static const value_string q933_netid_type_vals[] = {
1365         { 0x00, "User specified" },
1366         { 0x20, "National network identification" },
1367         { 0x30, "International network identification" },
1368         { 0,    NULL }
1369 };
1370
1371 static const value_string q933_netid_plan_vals[] = {
1372         { 0x00, "Unknown" },
1373         { 0x01, "Carrier Identification Code" },
1374         { 0x03, "X.121 data network identification code" },
1375         { 0,    NULL }
1376 };
1377
1378 static void
1379 dissect_q933_ns_facilities_ie(tvbuff_t *tvb, int offset, int len,
1380     proto_tree *tree)
1381 {
1382         guint8 octet;
1383         int netid_len;
1384
1385         if (len == 0)
1386                 return;
1387         octet = tvb_get_guint8(tvb, offset);
1388         netid_len = octet & 0x7F;
1389         proto_tree_add_text(tree, tvb, offset, 1,
1390             "Network identification length: %u",
1391             netid_len);
1392         offset += 1;
1393         len -= 1;
1394         if (netid_len != 0) {
1395                 if (len == 0)
1396                         return;
1397                 octet = tvb_get_guint8(tvb, offset);
1398                 proto_tree_add_text(tree, tvb, offset, 1,
1399                     "Type of network identification: %s",
1400                     val_to_str(octet & 0x70, q933_netid_type_vals,
1401                       "Unknown (0x%02X)"));
1402                 proto_tree_add_text(tree, tvb, offset, 1,
1403                     "Network identification plan: %s",
1404                     val_to_str(octet & 0x0F, q933_netid_plan_vals,
1405                       "Unknown (0x%02X)"));
1406                 offset += 1;
1407                 len -= 1;
1408                 netid_len--;
1409
1410                 if (len == 0)
1411                         return;
1412                 if (netid_len > len)
1413                         netid_len = len;
1414                 if (netid_len != 0) {
1415                         proto_tree_add_text(tree, tvb, offset, netid_len,
1416                             "Network identification: %s",
1417                             tvb_format_text(tvb, offset, netid_len));
1418                         offset += netid_len;
1419                         len -= netid_len;
1420                 }
1421         }
1422
1423         /*
1424          * Whatever is left is the network-specific facility
1425          * specification.
1426          */
1427          if (len == 0)
1428                 return;
1429         proto_tree_add_text(tree, tvb, offset,
1430             len, "Network-specific facility specification: %s",
1431             tvb_bytes_to_ep_str(tvb, offset, len));
1432 }
1433
1434 static int
1435 dissect_q933_guint16_value(tvbuff_t *tvb, int offset, int len,
1436     proto_tree *tree, const char *label)
1437 {
1438         guint8 octet;
1439         guint16 value;
1440         int value_len;
1441
1442         value_len = 0;
1443
1444         octet = tvb_get_guint8(tvb, offset);
1445         if (octet & Q933_IE_VL_EXTENSION) {
1446                 /*
1447                  * Only one octet long - error.
1448                  */
1449                 goto bad_length;
1450         }
1451         value = (octet & 0x3) << 14;
1452         offset += 1;
1453         len -= 1;
1454         value_len++;
1455
1456         if (len == 0) {
1457                 /*
1458                  * We've reached the end of the information element - error.
1459                  */
1460                 goto past_end;
1461         }
1462         octet = tvb_get_guint8(tvb, offset);
1463         if (octet & Q933_IE_VL_EXTENSION) {
1464                 /*
1465                  * Only two octets long - error.
1466                  */
1467                 goto bad_length;
1468         }
1469         value |= (octet & 0x7F) << 7;
1470         offset += 1;
1471         len -= 1;
1472         value_len++;
1473
1474         if (len == 0) {
1475                 /*
1476                  * We've reached the end of the information element - error.
1477                  */
1478                 goto past_end;
1479         }
1480         octet = tvb_get_guint8(tvb, offset);
1481         if (!(octet & Q933_IE_VL_EXTENSION)) {
1482                 /*
1483                  * More than three octets long - error.
1484                  */
1485                 goto bad_length;
1486         }
1487         value |= (octet & 0x7F);
1488         offset += 1;
1489         /*len -= 1;*/
1490         value_len++;
1491
1492         proto_tree_add_text(tree, tvb, offset, value_len, "%s: %u ms", label,
1493             value);
1494         return value_len;
1495
1496 past_end:
1497         proto_tree_add_text(tree, tvb, offset, len,
1498             "%s goes past end of information element", label);
1499         return -1;
1500
1501 bad_length:
1502         proto_tree_add_text(tree, tvb, offset, len, "%s isn't 3 octets long",
1503             label);
1504         return -1;
1505 }
1506
1507 /*
1508  * Dissect an End-to-end transit delay information element.
1509  */
1510 static void
1511 dissect_q933_e2e_transit_delay_ie(tvbuff_t *tvb, int offset, int len,
1512     proto_tree *tree)
1513 {
1514         int value_len;
1515
1516         if (len == 0)
1517                 return;
1518         value_len = dissect_q933_guint16_value(tvb, offset, len, tree,
1519             "Cumulative transit delay");
1520         if (value_len < 0)
1521                 return; /* error */
1522         offset += value_len;
1523         len -= value_len;
1524
1525         if (len == 0)
1526                 return;
1527         value_len = dissect_q933_guint16_value(tvb, offset, len, tree,
1528             "Requested end-to-end transit delay");
1529         if (value_len < 0)
1530                 return; /* error */
1531         offset += value_len;
1532         len -= value_len;
1533
1534         if (len == 0)
1535                 return;
1536         /*value_len = */dissect_q933_guint16_value(tvb, offset, len, tree,
1537             "Maximum end-to-end transit delay");
1538 }
1539
1540 /*
1541  * Dissect a Transit delay selection and indication information element.
1542  */
1543 static void
1544 dissect_q933_td_selection_and_int_ie(tvbuff_t *tvb, int offset, int len,
1545     proto_tree *tree)
1546 {
1547         if (len == 0)
1548                 return;
1549         dissect_q933_guint16_value(tvb, offset, len, tree,
1550             "Transit delay");
1551 }
1552
1553 static void
1554 dissect_q933_pl_binary_parameters_ie(tvbuff_t *tvb, int offset, int len,
1555     proto_tree *tree)
1556 {
1557         guint8 octet;
1558
1559         if (len == 0)
1560                 return;
1561         octet = tvb_get_guint8(tvb, offset);
1562         proto_tree_add_text(tree, tvb, offset, 1,
1563             "%s",
1564             (octet & 0x04) ? "No request/request denied" :
1565                              "Request indicated/request accepted");
1566         proto_tree_add_text(tree, tvb, offset, 1,
1567             "%s confirmation",
1568             (octet & 0x02) ? "Link-by-link" : "End-to-end");
1569 }
1570
1571 /*
1572  * Dissect a Reverse charging indication information element.
1573  */
1574 static const value_string q933_reverse_charging_indication_vals[] = {
1575         { 0x01, "Reverse charging requested" },
1576         { 0,    NULL }
1577 };
1578
1579 static void
1580 dissect_q933_reverse_charge_ind_ie(tvbuff_t *tvb, int offset, int len,
1581     proto_tree *tree)
1582 {
1583         if (len == 0)
1584                 return;
1585         proto_tree_add_text(tree, tvb, offset, 1,
1586             "Reverse charging indication: %s",
1587             val_to_str(tvb_get_guint8(tvb, offset) & 0x07,
1588               q933_reverse_charging_indication_vals, "Unknown (0x%02X)"));
1589 }
1590
1591 /*
1592  * Dissect a (phone) number information element.
1593  */
1594 static const value_string q933_number_type_vals[] = {
1595         { 0x0, "Unknown" },
1596         { 0x1, "International number" },
1597         { 0x2, "National number" },
1598         { 0x3, "Network specific number" },
1599         { 0x4, "Subscriber number" },
1600         { 0x6, "Abbreviated number" },
1601         { 0,    NULL }
1602 };
1603
1604 static const value_string q933_numbering_plan_vals[] = {
1605         { 0x00, "Unknown" },
1606         { 0x01, "E.164 ISDN/telephony numbering" },
1607         { 0x03, "X.121 data numbering" },
1608         { 0x04, "F.69 Telex numbering" },
1609         { 0x08, "National standard numbering" },
1610         { 0x09, "Private numbering" },
1611         { 0,    NULL }
1612 };
1613
1614 static const value_string q933_presentation_indicator_vals[] = {
1615         { 0x00, "Presentation allowed" },
1616         { 0x01, "Presentation restricted" },
1617         { 0x02, "Number not available due to interworking" },
1618         { 0,    NULL }
1619 };
1620
1621 static const value_string q933_screening_indicator_vals[] = {
1622         { 0x00, "User-provided, not screened" },
1623         { 0x01, "User-provided, verified and passed" },
1624         { 0x02, "User-provided, verified and failed" },
1625         { 0x03, "Network-provided" },
1626         { 0,    NULL }
1627 };
1628
1629 static const value_string q933_redirection_reason_vals[] = {
1630         { 0x00, "Unknown" },
1631         { 0x01, "Call forwarding busy or called DTE busy" },
1632         { 0x02, "Call forwarding no reply" },
1633         { 0x04, "Call deflection" },
1634         { 0x09, "Called DTE out of order" },
1635         { 0x0A, "Call forwarding by the called DTE" },
1636         { 0x0F, "Call forwarding unconditional or systematic call redirection" },
1637         { 0,    NULL }
1638 };
1639
1640 static void
1641 dissect_q933_number_ie(tvbuff_t *tvb, int offset, int len,
1642     proto_tree *tree, int hfindex)
1643 {
1644         guint8 octet;
1645
1646         if (len == 0)
1647                 return;
1648         octet = tvb_get_guint8(tvb, offset);
1649         proto_tree_add_uint(tree, hf_q933_numbering_plan, tvb, offset, 1, octet);
1650         proto_tree_add_uint(tree, hf_q933_number_type, tvb, offset, 1, octet);
1651         proto_tree_add_boolean(tree, hf_q933_extension_ind, tvb, offset, 1, octet);
1652
1653         offset += 1;
1654         len -= 1;
1655
1656         if (!(octet & Q933_IE_VL_EXTENSION)) {
1657                 if (len == 0)
1658                         return;
1659                 octet = tvb_get_guint8(tvb, offset);
1660                 proto_tree_add_uint(tree, hf_q933_screening_ind, tvb, offset, 1, octet);
1661                 proto_tree_add_uint(tree, hf_q933_presentation_ind, tvb, offset, 1, octet);
1662                 proto_tree_add_boolean(tree, hf_q933_extension_ind, tvb, offset, 1, octet);
1663                 offset += 1;
1664                 len -= 1;
1665         }
1666
1667         /*
1668          * XXX - only in a Redirecting number information element.
1669          */
1670         if (!(octet & Q933_IE_VL_EXTENSION)) {
1671                 if (len == 0)
1672                         return;
1673                 octet = tvb_get_guint8(tvb, offset);
1674                 proto_tree_add_text(tree, tvb, offset, 1,
1675                     "Reason for redirection: %s",
1676                     val_to_str(octet & 0x0F, q933_redirection_reason_vals,
1677                       "Unknown (0x%X)"));
1678                 offset += 1;
1679                 len -= 1;
1680         }
1681
1682         if (len == 0)
1683                 return;
1684         proto_tree_add_item(tree, hfindex, tvb, offset, len, ENC_ASCII|ENC_NA);
1685 }
1686
1687 /*
1688  * Dissect a party subaddress information element.
1689  */
1690 static const value_string q933_subaddress_type_vals[] = {
1691         { 0x00, "X.213/ISO 8348 Add.2 NSAP" },
1692         { 0x20, "User-specified" },
1693         { 0,    NULL }
1694 };
1695
1696 static const value_string q933_odd_even_indicator_vals[] = {
1697         { 0x00, "Even number of address signals" },
1698         { 0x10, "Odd number of address signals" },
1699         { 0,    NULL }
1700 };
1701
1702 static void
1703 dissect_q933_party_subaddr_ie(tvbuff_t *tvb, int offset, int len,
1704     proto_tree *tree)
1705 {
1706         guint8 octet;
1707
1708         if (len == 0)
1709                 return;
1710         octet = tvb_get_guint8(tvb, offset);
1711         proto_tree_add_text(tree, tvb, offset, 1,
1712             "Type of subaddress: %s",
1713             val_to_str(octet & 0x70, q933_subaddress_type_vals,
1714               "Unknown (0x%02X)"));
1715         proto_tree_add_text(tree, tvb, offset, 1,
1716             "Odd/even indicator: %s",
1717             val_to_str(octet & 0x10, q933_odd_even_indicator_vals,
1718               "Unknown (0x%02X)"));
1719         offset += 1;
1720         len -= 1;
1721
1722         if (len == 0)
1723                 return;
1724         proto_tree_add_text(tree, tvb, offset, len, "Subaddress: %s",
1725             tvb_bytes_to_ep_str(tvb, offset, len));
1726 }
1727
1728 /*
1729  * Dissect a High-layer compatibility information element.
1730  */
1731 #define Q933_AUDIOVISUAL        0x60
1732 static const value_string q933_high_layer_characteristics_vals[] = {
1733         { 0x01,             "Telephony" },
1734         { 0x04,             "F.182 Facsimile Group 2/3" },
1735         { 0x21,             "F.184 Facsimile Group 4 Class I" },
1736         { 0x24,             "F.230 Teletex, basic and mixed mode, and F.184 Facsimile Group 4, Classes II and III" },
1737         { 0x28,             "F.220 Teletex, basic and processable mode" },
1738         { 0x31,             "F.200 Teletex, basic mode" },
1739         { 0x32,             "F.300 and T.102 syntax-based Videotex" },
1740         { 0x33,             "F.300 and T.101 international Videotex interworking" },
1741         { 0x35,             "F.60 Telex" },
1742         { 0x38,             "X.400 Message Handling Systems" },
1743         { 0x41,             "X.200 OSI application" },
1744         { 0x42,             "FTAM application" },
1745         { 0x5E,             "Reserved for maintenance" },
1746         { 0x5F,             "Reserved for management" },
1747         { Q933_AUDIOVISUAL, "F.720/F.821 and F.731 Profile 1a videotelephony" },
1748         { 0x61,             "F.702 and F.731 Profile 1b videoconferencing" },
1749         { 0x62,             "F.702 and F.731 audiographic conferencing" },
1750         { 0,                NULL }
1751 };
1752
1753 static const value_string q933_audiovisual_characteristics_vals[] = {
1754         { 0x01, "Capability set of initial channel of H.221" },
1755         { 0x02, "Capability set of subsequent channel of H.221" },
1756         { 0x21, "Capability set of initial channel of an active 3.1kHz audio or speech call" },
1757         { 0x00, NULL }
1758 };
1759
1760 static void
1761 dissect_q933_high_layer_compat_ie(tvbuff_t *tvb, int offset, int len,
1762     proto_tree *tree)
1763 {
1764         guint8 octet;
1765         guint8 coding_standard;
1766         guint8 characteristics;
1767
1768         if (len == 0)
1769                 return;
1770         octet = tvb_get_guint8(tvb, offset);
1771         coding_standard = octet & 0x60;
1772         proto_tree_add_uint(tree, hf_q933_coding_standard, tvb, offset, 1, octet);
1773         offset += 1;
1774         len -= 1;
1775         if (coding_standard != Q933_ITU_STANDARDIZED_CODING) {
1776                 /*
1777                  * We don't know how the call state is encoded,
1778                  * so just dump it as data and be done with it.
1779                  */
1780                 proto_tree_add_text(tree, tvb, offset,
1781                     len, "Data: %s",
1782                     tvb_bytes_to_ep_str(tvb, offset, len));
1783                 return;
1784         }
1785
1786         if (len == 0)
1787                 return;
1788         octet = tvb_get_guint8(tvb, offset);
1789         characteristics = octet & 0x7F;
1790         proto_tree_add_text(tree, tvb, offset, 1,
1791             "High layer characteristics identification: %s",
1792             val_to_str(characteristics, q933_high_layer_characteristics_vals,
1793              "Unknown (0x%02X)"));
1794         offset += 1;
1795         len -= 1;
1796
1797         if (!(octet & Q933_IE_VL_EXTENSION)) {
1798                 if (len == 0)
1799                         return;
1800                 octet = tvb_get_guint8(tvb, offset);
1801                 if (characteristics == Q933_AUDIOVISUAL) {
1802                         proto_tree_add_text(tree, tvb, offset, 1,
1803                             "Extended audiovisual characteristics identification: %s",
1804                             val_to_str(octet & 0x7F,
1805                               q933_audiovisual_characteristics_vals,
1806                               "Unknown (0x%02X)"));
1807                 } else {
1808                         proto_tree_add_text(tree, tvb, offset, 1,
1809                             "Extended high layer characteristics identification: %s",
1810                             val_to_str(octet & 0x7F,
1811                               q933_high_layer_characteristics_vals,
1812                               "Unknown (0x%02X)"));
1813                 }
1814         }
1815 }
1816
1817
1818 /*
1819  * Dissect a User-user information element.
1820  */
1821 #define Q933_PROTOCOL_DISCRIMINATOR_IA5         0x04
1822 #define Q933_PROTOCOL_DISCRIMINATOR_ASN1        0x05
1823
1824 static const value_string q933_protocol_discriminator_vals[] = {
1825         { 0x00,                                 "User-specific protocol" },
1826         { 0x01,                                 "OSI high layer protocols" },
1827         { 0x02,                                 "X.244" },
1828         { Q933_PROTOCOL_DISCRIMINATOR_IA5,      "IA5 characters" },
1829         { Q933_PROTOCOL_DISCRIMINATOR_ASN1,     "X.208 and X.209 coded user information" },
1830         { 0x07,                                 "V.120 rate adaption" },
1831         { 0x08,                                 "Q.933/I.451 user-network call control messages" },
1832         { 0,                                    NULL }
1833 };
1834
1835 static void
1836 dissect_q933_user_user_ie(tvbuff_t *tvb, int offset, int len,
1837     proto_tree *tree)
1838 {
1839         guint8 octet;
1840
1841         if (len == 0)
1842                 return;
1843         octet = tvb_get_guint8(tvb, offset);
1844         proto_tree_add_text(tree, tvb, offset, 1,
1845             "Protocol discriminator: %s",
1846             val_to_str(octet, q933_protocol_discriminator_vals,
1847             "Unknown (0x%02x)"));
1848         offset += 1;
1849         len -= 1;
1850
1851         if (len == 0)
1852                 return;
1853         switch (octet) {
1854
1855         case Q933_PROTOCOL_DISCRIMINATOR_IA5:
1856                 proto_tree_add_text(tree, tvb, offset, len, "User information: %s",
1857                     tvb_format_text(tvb, offset, len));
1858                 break;
1859
1860         default:
1861                 proto_tree_add_text(tree, tvb, offset, len, "User information: %s",
1862                     tvb_bytes_to_ep_str(tvb, offset, len));
1863                 break;
1864         }
1865 }
1866
1867 /*
1868  * Dissect information elements consisting of ASCII^H^H^H^H^HIA5 text.
1869  */
1870 static void
1871 dissect_q933_ia5_ie(tvbuff_t *tvb, int offset, int len, proto_tree *tree,
1872     const char *label)
1873 {
1874         if (len != 0) {
1875                 proto_tree_add_text(tree, tvb, offset, len, "%s: %s", label,
1876                     tvb_format_text(tvb, offset, len));
1877         }
1878 }
1879
1880 static const value_string q933_codeset_vals[] = {
1881         { 0x00, "Q.933 information elements" },
1882         { 0x04, "Information elements for ISO/IEC use" },
1883         { 0x05, "Information elements for national use" },
1884         { 0x06, "Information elements specific to the local network" },
1885         { 0x07, "User-specific information elements" },
1886         { 0x00, NULL },
1887 };
1888
1889 static void
1890 dissect_q933(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1891 {
1892         int             offset = 0;
1893         proto_tree      *q933_tree = NULL;
1894         proto_item      *ti;
1895         proto_tree      *ie_tree = NULL;
1896         guint8          call_ref_len;
1897         guint8          call_ref[15];
1898         guint8          message_type;
1899         guint8          info_element;
1900         guint16         info_element_len;
1901         int             codeset, locked_codeset;
1902         gboolean        non_locking_shift;
1903
1904         col_set_str(pinfo->cinfo, COL_PROTOCOL, "Q.933");
1905
1906         if (tree) {
1907                 ti = proto_tree_add_item(tree, proto_q933, tvb, offset, -1,
1908                     ENC_NA);
1909                 q933_tree = proto_item_add_subtree(ti, ett_q933);
1910
1911                 dissect_q933_protocol_discriminator(tvb, offset, q933_tree);
1912         }
1913         offset += 1;
1914         call_ref_len = tvb_get_guint8(tvb, offset) & 0xF;       /* XXX - do as a bit field? */
1915         if (q933_tree != NULL)
1916                 proto_tree_add_uint(q933_tree, hf_q933_call_ref_len, tvb, offset, 1, call_ref_len);
1917         offset += 1;
1918         if (call_ref_len != 0) {
1919                 tvb_memcpy(tvb, call_ref, offset, call_ref_len);
1920                 if (q933_tree != NULL) {
1921                         proto_tree_add_boolean(q933_tree, hf_q933_call_ref_flag,
1922                             tvb, offset, 1, (call_ref[0] & 0x80) != 0);
1923                         call_ref[0] &= 0x7F;
1924                         proto_tree_add_bytes(q933_tree, hf_q933_call_ref,
1925                             tvb, offset, call_ref_len, call_ref);
1926                 }
1927                 offset += call_ref_len;
1928         }
1929         message_type = tvb_get_guint8(tvb, offset);
1930         col_add_str(pinfo->cinfo, COL_INFO,
1931                     val_to_str(message_type, q933_message_type_vals,
1932                       "Unknown message type (0x%02X)"));
1933
1934         proto_tree_add_uint(q933_tree, hf_q933_message_type, tvb, offset, 1, message_type);
1935         offset += 1;
1936
1937         /*
1938          * And now for the information elements....
1939          */
1940         codeset = locked_codeset = 0;   /* start out in codeset 0 */
1941         while (tvb_reported_length_remaining(tvb, offset) > 0) {
1942                 info_element = tvb_get_guint8(tvb, offset);
1943
1944                  /* Check for the codeset shift */
1945                 if ((info_element & Q933_IE_SO_MASK) &&
1946                     ((info_element & Q933_IE_SO_IDENTIFIER_MASK) == Q933_IE_SHIFT)) {
1947                         non_locking_shift = info_element & Q933_IE_SHIFT_NON_LOCKING;
1948                         codeset = info_element & Q933_IE_SHIFT_CODESET;
1949                         if (!non_locking_shift)
1950                                 locked_codeset = codeset;
1951                         if (q933_tree != NULL) {
1952                                 proto_tree_add_text(q933_tree, tvb, offset, 1,
1953                                     "%s shift to codeset %u: %s",
1954                                     (non_locking_shift ? "Non-locking" : "Locking"),
1955                                     codeset,
1956                                     val_to_str(codeset, q933_codeset_vals,
1957                                       "Unknown (0x%02X)"));
1958                         }
1959                         offset += 1;
1960                         continue;
1961                 }
1962
1963                 /*
1964                  * Check for the single-octet IEs.
1965                  */
1966                 if (info_element & Q933_IE_SO_MASK) {
1967                         switch ((codeset << 8) | (info_element & Q933_IE_SO_IDENTIFIER_MASK)) {
1968
1969                         case CS0 | Q933_IE_REPEAT_INDICATOR:
1970                                 if (q933_tree != NULL) {
1971                                         proto_tree_add_text(q933_tree, tvb, offset, 1,
1972                                             "Repeat indicator: %s",
1973                                             val_to_str(info_element & Q933_IE_SO_IE_MASK,
1974                                           q933_repeat_indication_vals,
1975                                               "Unknown (0x%X)"));
1976                                 }
1977                                 break;
1978
1979                         default:
1980                                 if (q933_tree != NULL) {
1981                                         proto_tree_add_text(q933_tree, tvb, offset, 1,
1982                                             "Unknown information element (0x%02X)",
1983                                             info_element);
1984                                 }
1985                                 break;
1986                         }
1987                         offset += 1;
1988                         codeset = locked_codeset;
1989                         continue;
1990                 }
1991
1992                 /*
1993                  * Variable-length IE.
1994                  */
1995                 info_element_len = tvb_get_guint8(tvb, offset + 1);
1996                 if (q933_tree != NULL) {
1997                         ti = proto_tree_add_text(q933_tree, tvb, offset,
1998                             1+1+info_element_len, "%s",
1999                             val_to_str(info_element, q933_info_element_vals[codeset],
2000                               "Unknown information element (0x%02X)"));
2001                                 ie_tree = proto_item_add_subtree(ti, ett_q933_ie);
2002                         proto_tree_add_text(ie_tree, tvb, offset, 1,
2003                             "Information element: %s",
2004                             val_to_str(info_element, q933_info_element_vals[codeset],
2005                               "Unknown (0x%02X)"));
2006                         proto_tree_add_text(ie_tree, tvb, offset + 1, 1,
2007                             "Length: %u", info_element_len);
2008
2009                         switch ((codeset << 8) | info_element) {
2010
2011                         case CS0 | Q933_IE_SEGMENTED_MESSAGE:
2012                                 dissect_q933_segmented_message_ie(tvb,
2013                                     offset + 2, info_element_len,
2014                                     ie_tree);
2015                                 break;
2016
2017                         case CS0 | Q933_IE_BEARER_CAPABILITY:
2018                         case CS0 | Q933_IE_LOW_LAYER_COMPAT:
2019                                 dissect_q933_bearer_capability_ie(tvb,
2020                                     offset + 2, info_element_len,
2021                                     ie_tree);
2022                                 break;
2023
2024                         case CS0 | Q933_IE_CAUSE:
2025                                 dissect_q933_cause_ie(tvb,
2026                                     offset + 2, info_element_len,
2027                                     ie_tree,
2028                                     hf_q933_cause_value);
2029                                 break;
2030
2031                         case CS0 | Q933_IE_CALL_STATE:
2032                                 dissect_q933_call_state_ie(tvb,
2033                                     offset + 2, info_element_len,
2034                                     ie_tree);
2035                                 break;
2036
2037                         case CS0 | Q933_IE_CHANNEL_IDENTIFICATION:
2038                                 dissect_q933_channel_identification_ie(
2039                                     tvb, offset + 2, info_element_len,
2040                                     ie_tree);
2041                                 break;
2042
2043                         case CS0 | Q933_IE_PROGRESS_INDICATOR:
2044                                 dissect_q933_progress_indicator_ie(tvb,
2045                                     offset + 2, info_element_len,
2046                                     ie_tree);
2047                                 break;
2048
2049                         case CS0 | Q933_IE_NETWORK_SPECIFIC_FACIL:
2050                         case CS0 | Q933_IE_TRANSIT_NETWORK_SEL:
2051                                 dissect_q933_ns_facilities_ie(tvb,
2052                                     offset + 2, info_element_len,
2053                                     ie_tree);
2054                                 break;
2055
2056                         case CS0 | Q933_IE_DISPLAY:
2057                                 dissect_q933_ia5_ie(tvb, offset + 2,
2058                                     info_element_len, ie_tree,
2059                                     "Display information");
2060                                 break;
2061
2062                         case CS0 | Q933_IE_E2E_TRANSIT_DELAY:
2063                                 dissect_q933_e2e_transit_delay_ie(tvb,
2064                                     offset + 2, info_element_len,
2065                                     ie_tree);
2066                                 break;
2067
2068                         case CS0 | Q933_IE_TD_SELECTION_AND_INT:
2069                                 dissect_q933_td_selection_and_int_ie(
2070                                     tvb, offset + 2, info_element_len,
2071                                     ie_tree);
2072                                 break;
2073
2074                         case CS0 | Q933_IE_PL_BINARY_PARAMETERS:
2075                                 dissect_q933_pl_binary_parameters_ie(
2076                                     tvb, offset + 2, info_element_len,
2077                                     ie_tree);
2078                                 break;
2079
2080                         case CS0 | Q933_IE_REVERSE_CHARGE_IND:
2081                                 dissect_q933_reverse_charge_ind_ie(tvb,
2082                                     offset + 2, info_element_len,
2083                                     ie_tree);
2084                                 break;
2085
2086                         case CS0 | Q933_IE_CALLING_PARTY_NUMBER:
2087                                 dissect_q933_number_ie(tvb,
2088                                     offset + 2, info_element_len,
2089                                     ie_tree,
2090                                     hf_q933_calling_party_number);
2091                                 break;
2092
2093                         case CS0 | Q933_IE_CONNECTED_NUMBER:
2094                                 dissect_q933_number_ie(tvb,
2095                                     offset + 2, info_element_len,
2096                                     ie_tree,
2097                                     hf_q933_connected_number);
2098                                 break;
2099
2100                         case CS0 | Q933_IE_CALLED_PARTY_NUMBER:
2101                                 dissect_q933_number_ie(tvb,
2102                                     offset + 2, info_element_len,
2103                                     ie_tree,
2104                                     hf_q933_called_party_number);
2105                                 break;
2106
2107                         case CS0 | Q933_IE_CALLING_PARTY_SUBADDR:
2108                         case CS0 | Q933_IE_CALLED_PARTY_SUBADDR:
2109                                 dissect_q933_party_subaddr_ie(tvb,
2110                                     offset + 2, info_element_len,
2111                                     ie_tree);
2112                                 break;
2113
2114                         case CS0 | Q933_IE_HIGH_LAYER_COMPAT:
2115                                 dissect_q933_high_layer_compat_ie(tvb,
2116                                     offset + 2, info_element_len,
2117                                     ie_tree);
2118                                 break;
2119
2120                         case CS0 | Q933_IE_USER_USER:
2121                                 dissect_q933_user_user_ie(tvb,
2122                                     offset + 2, info_element_len,
2123                                     ie_tree);
2124                                 break;
2125
2126
2127                         case CS0 | Q933_IE_REPORT_TYPE:
2128                         case CS5 | Q933_IE_REPORT_TYPE:
2129                         case CS5 | Q933_IE_ANSI_REPORT_TYPE:
2130                                 dissect_q933_report_type_ie(tvb,
2131                                     offset + 2, info_element_len,
2132                                     ie_tree);
2133                                 break;
2134
2135                         case CS5 | Q933_IE_LINK_INTEGRITY_VERF:
2136                         case CS5 | Q933_IE_ANSI_LINK_INTEGRITY_VERF:
2137                                 dissect_q933_link_integrity_verf_ie(tvb,
2138                                     offset + 2, info_element_len,
2139                                     ie_tree);
2140                                 break;
2141
2142                         case CS5 | Q933_IE_PVC_STATUS:
2143                         case CS5 | Q933_IE_ANSI_PVC_STATUS:
2144                                 dissect_q933_pvc_status_ie(tvb,
2145                                     offset + 2, info_element_len,
2146                                     ie_tree);
2147                                 break;
2148
2149                         default:
2150                                 proto_tree_add_text(ie_tree, tvb,
2151                                     offset + 2, info_element_len,
2152                                     "Data: %s",
2153                                     tvb_bytes_to_ep_str(tvb, offset + 2,
2154                                           info_element_len));
2155                                 break;
2156                         }
2157                 }
2158                 offset += 1 + 1 + info_element_len;
2159                 codeset = locked_codeset;
2160         }
2161 }
2162
2163 void
2164 proto_register_q933(void)
2165 {
2166         static hf_register_info hf[] = {
2167                 { &hf_q933_discriminator,
2168                   { "Protocol discriminator", "q933.disc", FT_UINT8, BASE_HEX, NULL, 0x0,
2169                         NULL, HFILL }},
2170
2171                 { &hf_q933_call_ref_flag,
2172                   { "Call reference flag", "q933.call_ref_flag", FT_BOOLEAN, BASE_NONE, TFS(&tfs_call_ref_flag), 0x0,
2173                         NULL, HFILL }},
2174
2175                 { &hf_q933_call_ref,
2176                   { "Call reference value", "q933.call_ref", FT_BYTES, BASE_NONE, NULL, 0x0,
2177                         NULL, HFILL }},
2178
2179
2180                 { &hf_q933_coding_standard,
2181                   { "Coding standard", "q933.coding_standard", FT_UINT8, BASE_HEX,
2182                          VALS(q933_coding_standard_vals), 0x60,NULL, HFILL }},
2183
2184                 { &hf_q933_information_transfer_capability,
2185                   { "Information transfer capability", "q933.information_transfer_capability", FT_UINT8, BASE_HEX,
2186                          VALS(q933_information_transfer_capability_vals), 0x1f,NULL, HFILL }},
2187
2188                 { &hf_q933_transfer_mode,
2189                   { "Transfer mode", "q933.transfer_mode", FT_UINT8, BASE_HEX,
2190                          VALS(q933_transfer_mode_vals), 0x60,NULL, HFILL }},
2191
2192                 { &hf_q933_uil1,
2193                   { "User information layer 1 protocol", "q933.uil1", FT_UINT8, BASE_HEX,
2194                          VALS(q933_uil1_vals), 0x1f,NULL, HFILL }},
2195
2196                 { &hf_q933_call_ref_len,
2197                   { "Call reference value length", "q933.call_ref_len", FT_UINT8, BASE_DEC, NULL, 0x0,
2198                         NULL, HFILL }},
2199
2200                 { &hf_q933_message_type,
2201                   { "Message type", "q933.message_type", FT_UINT8, BASE_HEX, VALS(q933_message_type_vals), 0x0,
2202                         NULL, HFILL }},
2203
2204                 { &hf_q933_cause_location,
2205                   { "Cause location", "q933.cause_location", FT_UINT8, BASE_DEC, VALS(q933_cause_location_vals), 0x0f,
2206                         NULL, HFILL }},
2207
2208                 { &hf_q933_cause_value,
2209                   { "Cause value", "q933.cause_value", FT_UINT8, BASE_DEC, VALS(q933_cause_code_vals), 0x7f,
2210                         NULL, HFILL }},
2211
2212                 { &hf_q933_number_type,
2213                   { "Number type", "q933.number_type", FT_UINT8, BASE_HEX, VALS(q933_number_type_vals), 0x70,
2214                         NULL, HFILL }},
2215
2216                 { &hf_q933_numbering_plan,
2217                   { "numbering plan", "q933.numbering_plan", FT_UINT8, BASE_HEX, VALS(q933_numbering_plan_vals), 0x0f,
2218                         NULL, HFILL }},
2219
2220                 { &hf_q933_screening_ind,
2221                   { "Screening indicator", "q933.screening_ind", FT_UINT8, BASE_HEX, VALS(q933_screening_indicator_vals), 0x03,
2222                         NULL, HFILL }},
2223
2224                 { &hf_q933_presentation_ind,
2225                   { "Presentation indicator", "q933.presentation_ind", FT_UINT8, BASE_HEX, VALS(q933_presentation_indicator_vals), 0x60,
2226                         NULL, HFILL }},
2227
2228                 { &hf_q933_extension_ind,
2229                   { "Extension indicator",  "q933.extension_ind",
2230                         FT_BOOLEAN, 8, TFS(&q933_extension_ind_value), 0x80,
2231                         NULL, HFILL }},
2232
2233                 { &hf_q933_calling_party_number,
2234                   { "Calling party number digits", "q933.calling_party_number.digits", FT_STRING, BASE_NONE, NULL, 0x0,
2235                         NULL, HFILL }},
2236
2237                 { &hf_q933_called_party_number,
2238                   { "Called party number digits", "q933.called_party_number.digits", FT_STRING, BASE_NONE, NULL, 0x0,
2239                         NULL, HFILL }},
2240
2241                 { &hf_q933_connected_number,
2242                   { "Connected party number digits", "q933.connected_number.digits", FT_STRING, BASE_NONE, NULL, 0x0,
2243                         NULL, HFILL }},
2244
2245 #if 0
2246                 { &hf_q933_redirecting_number,
2247                   { "Redirecting party number digits", "q933.redirecting_number.digits", FT_STRING, BASE_NONE, NULL, 0x0,
2248                         NULL, HFILL }},
2249 #endif
2250                 { &hf_q933_report_type,
2251                   { "Report type", "q933.report_type", FT_UINT8, BASE_DEC, VALS(q933_report_type_vals), 0x0,
2252                         NULL, HFILL }},
2253                 { &hf_q933_link_verf_txseq,
2254                   { "TX Sequence", "q933.link_verification.txseq", FT_UINT8, BASE_DEC, NULL, 0x0,
2255                         NULL, HFILL }},
2256                 { &hf_q933_link_verf_rxseq,
2257                   { "RX Sequence", "q933.link_verification.rxseq", FT_UINT8, BASE_DEC, NULL, 0x0,
2258                         NULL, HFILL }},
2259
2260         };
2261         static gint *ett[] = {
2262                 &ett_q933,
2263                 &ett_q933_ie,
2264         };
2265
2266         proto_q933 = proto_register_protocol("Q.933", "Q.933", "q933");
2267         proto_register_field_array (proto_q933, hf, array_length(hf));
2268         proto_register_subtree_array(ett, array_length(ett));
2269
2270         register_dissector("q933", dissect_q933, proto_q933);
2271 }
2272
2273 void
2274 proto_reg_handoff_q933(void)
2275 {
2276         dissector_handle_t q933_handle;
2277
2278         q933_handle = find_dissector("q933");
2279         dissector_add_uint("fr.osinl", NLPID_Q_933, q933_handle);
2280 }