Fix some "format not a string literal and no format arguments" warnings.
[obnox/wireshark/wip.git] / epan / dissectors / packet-gsm_a_dtap.c
1 /* packet-gsm_a_dtap.c
2  * Routines for GSM A Interface DTAP dissection - A.K.A. GSM layer 3
3  * NOTE: it actually includes RR messages, which are (generally) not carried
4  * over the A interface on DTAP, but are part of the same Layer 3 protocol set
5  *
6  * Copyright 2003, Michael Lum <mlum [AT] telostech.com>
7  * In association with Telos Technology Inc.
8  *
9  *
10  * Added the GPRS Mobility Managment Protocol and
11  * the GPRS Session Managment Protocol
12  *   Copyright 2004, Rene Pilz <rene.pilz [AT] ftw.com>
13  *   In association with Telecommunications Research Center
14  *   Vienna (ftw.)Betriebs-GmbH within the Project Metawin.
15  *
16  * Added Dissection of Radio Resource Management Information Elements
17  * and othere enhancements and fixes.
18  * Copyright 2005 - 2006, Anders Broman [AT] ericsson.com
19  * Small bugfixes, mainly in Qos and TFT by Nils Ljungberg and Stefan Boman [AT] ericsson.com
20  *
21  * Title                3GPP                    Other
22  *
23  *   Reference [3]
24  *   Mobile radio interface Layer 3 specification;
25  *   Core network protocols;
26  *   Stage 3
27  *   (3GPP TS 24.008 version 4.7.0 Release 4)
28  *   (ETSI TS 124 008 V6.8.0 (2005-03))
29  *
30  *   Reference [4]
31  *   Mobile radio interface layer 3 specification;
32  *   Radio Resource Control Protocol
33  *   (GSM 04.18 version 8.4.1 Release 1999)
34  *   (3GPP TS 04.18 version 8.26.0 Release 1999)
35  *
36  *   Reference [5]
37  *   Point-to-Point (PP) Short Message Service (SMS)
38  *   support on mobile radio interface
39  *   (3GPP TS 24.011 version 4.1.1 Release 4)
40  *
41  *   Reference [6]
42  *   Mobile radio Layer 3 supplementary service specification;
43  *   Formats and coding
44  *   (3GPP TS 24.080 version 4.3.0 Release 4)
45  *
46  *   Reference [7]
47  *   Mobile radio interface Layer 3 specification;
48  *   Core network protocols;
49  *   Stage 3
50  *   (3GPP TS 24.008 version 5.9.0 Release 5)
51  *
52  *   Reference [8]
53  *   Mobile radio interface Layer 3 specification;
54  *   Core network protocols;
55  *   Stage 3
56  *   (3GPP TS 24.008 version 6.7.0 Release 6)
57  *       (3GPP TS 24.008 version 6.8.0 Release 6)
58  *
59  * $Id$
60  *
61  * Wireshark - Network traffic analyzer
62  * By Gerald Combs <gerald@wireshark.org>
63  * Copyright 1998 Gerald Combs
64  *
65  * This program is free software; you can redistribute it and/or
66  * modify it under the terms of the GNU General Public License
67  * as published by the Free Software Foundation; either version 2
68  * of the License, or (at your option) any later version.
69  *
70  * This program is distributed in the hope that it will be useful,
71  * but WITHOUT ANY WARRANTY; without even the implied warranty of
72  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
73  * GNU General Public License for more details.
74  *
75  * You should have received a copy of the GNU General Public License
76  * along with this program; if not, write to the Free Software
77  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
78  */
79
80 #ifdef HAVE_CONFIG_H
81 # include "config.h"
82 #endif
83
84 #include <stdio.h>
85 #include <stdlib.h>
86
87 #include <string.h>
88
89 #include <epan/packet.h>
90 #include <epan/prefs.h>
91 #include <epan/tap.h>
92 #include <epan/emem.h>
93 #include <epan/asn1.h>
94
95 #include "packet-bssap.h"
96 #include "packet-sccp.h"
97 #include "packet-ber.h"
98 #include "packet-q931.h"
99 #include "packet-gsm_a_common.h"
100 #include "packet-ipv6.h"
101 #include "packet-e212.h"
102 #include "packet-ppp.h"
103
104 /* PROTOTYPES/FORWARDS */
105
106 const value_string gsm_a_dtap_msg_mm_strings[] = {
107         { 0x01, "IMSI Detach Indication" },
108         { 0x02, "Location Updating Accept" },
109         { 0x04, "Location Updating Reject" },
110         { 0x08, "Location Updating Request" },
111         { 0x11, "Authentication Reject" },
112         { 0x12, "Authentication Request" },
113         { 0x14, "Authentication Response" },
114         { 0x1c, "Authentication Failure" },
115         { 0x18, "Identity Request" },
116         { 0x19, "Identity Response" },
117         { 0x1a, "TMSI Reallocation Command" },
118         { 0x1b, "TMSI Reallocation Complete" },
119         { 0x21, "CM Service Accept" },
120         { 0x22, "CM Service Reject" },
121         { 0x23, "CM Service Abort" },
122         { 0x24, "CM Service Request" },
123         { 0x25, "CM Service Prompt" },
124         { 0x26, "Reserved: was allocated in earlier phases of the protocol" },
125         { 0x28, "CM Re-establishment Request" },
126         { 0x29, "Abort" },
127         { 0x30, "MM Null" },
128         { 0x31, "MM Status" },
129         { 0x32, "MM Information" },
130         { 0, NULL }
131 };
132
133 const value_string gsm_a_dtap_msg_cc_strings[] = {
134         { 0x01, "Alerting" },
135         { 0x08, "Call Confirmed" },
136         { 0x02, "Call Proceeding" },
137         { 0x07, "Connect" },
138         { 0x0f, "Connect Acknowledge" },
139         { 0x0e, "Emergency Setup" },
140         { 0x03, "Progress" },
141         { 0x04, "CC-Establishment" },
142         { 0x06, "CC-Establishment Confirmed" },
143         { 0x0b, "Recall" },
144         { 0x09, "Start CC" },
145         { 0x05, "Setup" },
146         { 0x17, "Modify" },
147         { 0x1f, "Modify Complete" },
148         { 0x13, "Modify Reject" },
149         { 0x10, "User Information" },
150         { 0x18, "Hold" },
151         { 0x19, "Hold Acknowledge" },
152         { 0x1a, "Hold Reject" },
153         { 0x1c, "Retrieve" },
154         { 0x1d, "Retrieve Acknowledge" },
155         { 0x1e, "Retrieve Reject" },
156         { 0x25, "Disconnect" },
157         { 0x2d, "Release" },
158         { 0x2a, "Release Complete" },
159         { 0x39, "Congestion Control" },
160         { 0x3e, "Notify" },
161         { 0x3d, "Status" },
162         { 0x34, "Status Enquiry" },
163         { 0x35, "Start DTMF" },
164         { 0x31, "Stop DTMF" },
165         { 0x32, "Stop DTMF Acknowledge" },
166         { 0x36, "Start DTMF Acknowledge" },
167         { 0x37, "Start DTMF Reject" },
168         { 0x3a, "Facility" },
169         { 0, NULL }
170 };
171
172 const value_string gsm_a_dtap_msg_sms_strings[] = {
173         { 0x01, "CP-DATA" },
174         { 0x04, "CP-ACK" },
175         { 0x10, "CP-ERROR" },
176         { 0, NULL }
177 };
178
179 const value_string gsm_a_dtap_msg_ss_strings[] = {
180         { 0x2a, "Release Complete" },
181         { 0x3a, "Facility" },
182         { 0x3b, "Register" },
183         { 0, NULL }
184 };
185
186 const value_string gsm_a_dtap_msg_tp_strings[] = {
187         { 0x00, "Close TCH Loop Cmd" },
188         { 0x01, "Close TCH Loop Ack" },
189         { 0x06, "Open Loop Cmd" },
190         { 0x0c, "Act EMMI Cmd" },
191         { 0x0d, "Act EMMI Ack" },
192         { 0x10, "Deact EMMI" },
193         { 0x14, "Test Interface" },
194         { 0x20, "Close Multi-slot Loop Cmd" },
195         { 0x21, "Close Multi-slot Loop Ack" },
196         { 0x22, "Open Multi-slot Loop Cmd" },
197         { 0x23, "Open Multi-slot Loop Ack" },
198         { 0x24, "GPRS Test Mode Cmd" },
199         { 0x25, "EGPRS Start Radio Block Loopback Cmd" },
200         { 0x40, "Close UE Test Loop" },
201         { 0x41, "Close UE Test Loop Complete" },
202         { 0x42, "Open UE Test Loop" },
203         { 0x43, "Open UE Test Loop Complete" },
204         { 0x44, "Activate RB Test Mode" },
205         { 0x45, "Activate RB Test Mode Complete" },
206         { 0x46, "Deactivate RB Test Mode" },
207         { 0x47, "Deactivate RB Test Mode Complete" },
208         { 0x48, "Reset UE Positioning Stored Information" },
209         { 0x49, "UE Test Loop Mode 3 RLC SDU Counter Request" },
210         { 0x4A, "UE Test Loop Mode 3 RLC SDU Counter Response" },
211         { 0, NULL }
212 };
213
214 const value_string gsm_dtap_elem_strings[] = {
215         /* Mobility Management Information Elements 10.5.3 */
216         { 0x00, "Authentication Parameter RAND" },
217         { 0x00, "Authentication Parameter AUTN (UMTS authentication challenge only)" },
218         { 0x00, "Authentication Response Parameter" },
219         { 0x00, "Authentication Response Parameter (extension) (UMTS authentication challenge only)" },
220         { 0x00, "Authentication Failure Parameter (UMTS authentication challenge only)" },
221         { 0x00, "CM Service Type" },
222         { 0x00, "Identity Type" },
223         { 0x00, "Location Updating Type" },
224         { 0x00, "Network Name" },
225         { 0x00, "Reject Cause" },
226         { 0x00, "Follow-on Proceed" },
227         { 0x00, "Time Zone" },
228         { 0x00, "Time Zone and Time" },
229         { 0x00, "CTS Permission" },
230         { 0x00, "LSA Identifier" },
231         { 0x00, "Daylight Saving Time" },
232         { 0x00, "Emergency Number List" },
233         /* Call Control Information Elements 10.5.4 */
234         { 0x00, "Auxiliary States" },                                   /* 10.5.4.4 Auxiliary states */
235         { 0x00, "Bearer Capability" },                                  /* 10.5.4.4a Backup bearer capability */
236         { 0x00, "Call Control Capabilities" },
237         { 0x00, "Call State" },
238         { 0x00, "Called Party BCD Number" },
239         { 0x00, "Called Party Subaddress" },
240         { 0x00, "Calling Party BCD Number" },
241         { 0x00, "Calling Party Subaddress" },
242         { 0x00, "Cause" },
243         { 0x00, "CLIR Suppression" },
244         { 0x00, "CLIR Invocation" },
245         { 0x00, "Congestion Level" },
246         { 0x00, "Connected Number" },
247         { 0x00, "Connected Subaddress" },
248         { 0x00, "Facility" },
249         { 0x00, "High Layer Compatibility" },
250         { 0x00, "Keypad Facility" },
251         { 0x00, "Low Layer Compatibility" },
252         { 0x00, "More Data" },
253         { 0x00, "Notification Indicator" },
254         { 0x00, "Progress Indicator" },
255         { 0x00, "Recall type $(CCBS)$" },
256         { 0x00, "Redirecting Party BCD Number" },
257         { 0x00, "Redirecting Party Subaddress" },
258         { 0x00, "Repeat Indicator" },
259         { 0x00, "Reverse Call Setup Direction" },
260         { 0x00, "SETUP Container $(CCBS)$" },
261         { 0x00, "Signal" },
262         { 0x00, "SS Version Indicator" },
263         { 0x00, "User-user" },
264         { 0x00, "Alerting Pattern $(NIA)$" },                   /* 10.5.4.26 Alerting Pattern $(NIA)$ */
265         { 0x00, "Allowed Actions $(CCBS)$" },
266         { 0x00, "Stream Identifier" },
267         { 0x00, "Network Call Control Capabilities" },
268         { 0x00, "Cause of No CLI" },
269         { 0x00, "Immediate Modification Indicator" },   /* 10.5.4.30 Cause of No CLI */
270         /* 10.5.4.31 Void */
271         { 0x00, "Supported Codec List" },                               /* 10.5.4.32 Supported codec list */
272         { 0x00, "Service Category" },                                   /* 10.5.4.33 Service category */
273         /* 10.5.4.34 Redial */
274         /* 10.5.4.35 Network-initiated Service Upgrade indicator */
275         /* Short Message Service Information Elements [5] 8.1.4 */
276         { 0x00, "CP-User Data" },
277         { 0x00, "CP-Cause" },
278         /* Short Message Service Information Elements [5] 8.2 */
279         { 0x00, "RP-Message Reference" },
280         { 0x00, "RP-Origination Address" },
281         { 0x00, "RP-Destination Address" },
282         { 0x00, "RP-User Data" },
283         { 0x00, "RP-Cause" },
284         /* Tests procedures information elements 3GPP TS 44.014 6.4.0 and 3GPP TS 34.109 6.4.0 */
285         { 0x00, "Close TCH Loop Cmd Sub-channel"},
286         { 0x00, "Open Loop Cmd Ack"},
287         { 0x00, "Close Multi-slot Loop Cmd Loop type"},
288         { 0x00, "Close Multi-slot Loop Ack Result"},
289         { 0x00, "Test Interface Tested device"},
290         { 0x00, "GPRS Test Mode Cmd PDU description"},
291         { 0x00, "GPRS Test Mode Cmd Mode flag"},
292         { 0x00, "EGPRS Start Radio Block Loopback Cmd Mode flag"},
293         { 0x00, "Close UE Test Loop Mode"},
294         { 0x00, "UE Positioning Technology"},
295         { 0x00, "RLC SDU Counter Value"},
296         { 0, NULL }
297 };
298
299 const gchar *gsm_a_pd_str[] = {
300         "Group Call Control",
301         "Broadcast Call Control",
302         "Reserved: was allocated in earlier phases of the protocol",
303         "Call Control; call related SS messages",
304         "GPRS Transparent Transport Protocol (GTTP)",
305         "Mobility Management messages",
306         "Radio Resources Management messages",
307         "Unknown",
308         "GPRS Mobility Management messages",
309         "SMS messages",
310         "GPRS Session Management messages",
311         "Non call related SS messages",
312         "Location Services",
313         "Unknown",
314         "Reserved for extension of the PD to one octet length",
315         "Special conformance testing functions"
316 };
317 /* L3 Protocol discriminator values according to TS 24 007 (6.4.0)  */
318 const value_string protocol_discriminator_vals[] = {
319         {0x0,           "Group call control"},
320         {0x1,           "Broadcast call control"},
321         {0x2,           "Reserved: was allocated in earlier phases of the protocol"},
322         {0x3,           "Call Control; call related SS messages"},
323         {0x4,           "GPRS Transparent Transport Protocol (GTTP)"},
324         {0x5,           "Mobility Management messages"},
325         {0x6,           "Radio Resources Management messages"},
326         {0x7,           "Unknown"},
327         {0x8,           "GPRS mobility management messages"},
328         {0x9,           "SMS messages"},
329         {0xa,           "GPRS session management messages"},
330         {0xb,           "Non call related SS messages"},
331         {0xc,           "Location services specified in 3GPP TS 44.071 [8a]"},
332         {0xd,           "Unknown"},
333         {0xe,           "Reserved for extension of the PD to one octet length "},
334         {0xf,           "Special conformance testing functions"},
335         { 0,    NULL }
336 };
337
338 const value_string gsm_a_pd_short_str_vals[] = {
339         {0x0,           "GCC"},                         /* Group Call Control */
340         {0x1,           "BCC"},                         /* Broadcast Call Control */
341         {0x2,           "Reserved"},            /* : was allocated in earlier phases of the protocol */
342         {0x3,           "CC"},                          /* Call Control; call related SS messages */
343         {0x4,           "GTTP"},                        /* GPRS Transparent Transport Protocol (GTTP) */
344         {0x5,           "MM"},                          /* Mobility Management messages */
345         {0x6,           "RR"},                          /* Radio Resources Management messages */
346         {0x7,           "Unknown"},
347         {0x8,           "GMM"},                         /* GPRS Mobility Management messages */
348         {0x9,           "SMS"},
349         {0xa,           "SM"},                          /* GPRS Session Management messages */
350         {0xb,           "SS"},
351         {0xc,           "LS"},                          /* Location Services */
352         {0xd,           "Unknown"},
353         {0xe,           "Reserved"},            /*  for extension of the PD to one octet length  */
354         {0xf,           "TP"},          /*  for tests procedures described in 3GPP TS 44.014 6.4.0 and 3GPP TS 34.109 6.4.0.*/
355         { 0,    NULL }
356 };
357
358
359 #define DTAP_PD_MASK            0x0f
360 #define DTAP_SKIP_MASK          0xf0
361 #define DTAP_TI_MASK            DTAP_SKIP_MASK
362 #define DTAP_TIE_PRES_MASK      0x07                    /* after TI shifted to right */
363 #define DTAP_TIE_MASK           0x7f
364
365 #define DTAP_MM_IEI_MASK        0x3f
366 #define DTAP_CC_IEI_MASK        0x3f
367 #define DTAP_SMS_IEI_MASK       0xff
368 #define DTAP_SS_IEI_MASK        0x3f
369 #define DTAP_TP_IEI_MASK  0xff
370
371 /* Initialize the protocol and registered fields */
372 static int proto_a_dtap = -1;
373
374 static int hf_gsm_a_dtap_msg_mm_type = -1;
375 static int hf_gsm_a_dtap_msg_cc_type = -1;
376 static int hf_gsm_a_seq_no = -1;
377 static int hf_gsm_a_dtap_msg_sms_type = -1;
378 static int hf_gsm_a_dtap_msg_ss_type = -1;
379 static int hf_gsm_a_dtap_msg_tp_type = -1;
380 int hf_gsm_a_dtap_elem_id = -1;
381 static int hf_gsm_a_cld_party_bcd_num = -1;
382 static int hf_gsm_a_clg_party_bcd_num = -1;
383 static int hf_gsm_a_dtap_cause = -1;
384
385 int hf_gsm_a_extension = -1;
386 static int hf_gsm_a_type_of_number = -1;
387 static int hf_gsm_a_numbering_plan_id = -1;
388
389 static int hf_gsm_a_lsa_id = -1;
390
391 /* Initialize the subtree pointers */
392 static gint ett_dtap_msg = -1;
393 static gint ett_dtap_oct_1 = -1;
394 static gint ett_cm_srvc_type = -1;
395 static gint ett_gsm_enc_info = -1;
396 static gint ett_bc_oct_3 = -1;
397 static gint ett_bc_oct_3a = -1;
398 static gint ett_bc_oct_4 = -1;
399 static gint ett_bc_oct_5 = -1;
400 static gint ett_bc_oct_5a = -1;
401 static gint ett_bc_oct_5b = -1;
402 static gint ett_bc_oct_6 = -1;
403 static gint ett_bc_oct_6a = -1;
404 static gint ett_bc_oct_6b = -1;
405 static gint ett_bc_oct_6c = -1;
406 static gint ett_bc_oct_6d = -1;
407 static gint ett_bc_oct_6e = -1;
408 static gint ett_bc_oct_6f = -1;
409 static gint ett_bc_oct_6g = -1;
410 static gint ett_bc_oct_7 = -1;
411
412 static char a_bigbuf[1024];
413
414 static dissector_handle_t data_handle;
415 static dissector_handle_t gsm_map_handle;
416 static dissector_handle_t rp_handle;
417
418 packet_info *gsm_a_dtap_pinfo;
419 static proto_tree *g_tree;
420
421 /*
422  * this should be set on a per message basis, if possible
423  */
424 static gint is_uplink;
425
426 #define NUM_GSM_DTAP_ELEM (sizeof(gsm_dtap_elem_strings)/sizeof(value_string))
427 gint ett_gsm_dtap_elem[NUM_GSM_DTAP_ELEM];
428
429 static dgt_set_t Dgt_mbcd = {
430         {
431   /*  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e */
432          '0','1','2','3','4','5','6','7','8','9','*','#','a','b','c'
433         }
434 };
435
436 /*
437  * [3] 10.5.3.1
438  */
439 static guint8
440 de_auth_param_rand(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
441 {
442         guint32 curr_offset;
443
444         len = len;
445         curr_offset = offset;
446
447 /*
448  * 16 octets == 128 bits
449  */
450 #define AUTH_PARAM_RAND_LEN     16
451
452         proto_tree_add_text(tree,
453                 tvb, curr_offset, AUTH_PARAM_RAND_LEN,
454                 "RAND value: %s",
455                 tvb_bytes_to_str(tvb, curr_offset, AUTH_PARAM_RAND_LEN));
456
457         curr_offset += AUTH_PARAM_RAND_LEN;
458
459         /* no length check possible */
460
461         return(curr_offset - offset);
462 }
463
464 /*
465  * [3] 10.5.3.1.1
466  */
467 static guint8
468 de_auth_param_autn(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
469 {
470         guint32 curr_offset;
471
472         curr_offset = offset;
473
474         proto_tree_add_text(tree,
475                 tvb, curr_offset, len,
476                 "AUTN value: %s",
477                 tvb_bytes_to_str(tvb, curr_offset, len));
478
479         curr_offset += len;
480
481         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
482
483         return(curr_offset - offset);
484 }
485
486 /*
487  * [3] 10.5.3.2
488  */
489 static guint8
490 de_auth_resp_param(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
491 {
492         guint32 curr_offset;
493
494         len = len;
495         curr_offset = offset;
496
497 /*
498  * 4 octets == 32 bits
499  */
500 #define AUTH_PARAM_SRES_LEN     4
501
502         proto_tree_add_text(tree,
503                 tvb, curr_offset, AUTH_PARAM_SRES_LEN,
504                 "SRES value: %s",
505                 tvb_bytes_to_str(tvb, curr_offset, AUTH_PARAM_SRES_LEN));
506
507         curr_offset += AUTH_PARAM_SRES_LEN;
508
509         /* no length check possible */
510
511         return(curr_offset - offset);
512 }
513
514 /*
515  * [3] 10.5.3.2.1
516  */
517 static guint8
518 de_auth_resp_param_ext(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
519 {
520         guint32 curr_offset;
521
522         curr_offset = offset;
523
524         proto_tree_add_text(tree,
525                 tvb, curr_offset, len,
526                 "XRES value: %s",
527                 tvb_bytes_to_str(tvb, curr_offset, len));
528
529         curr_offset += len;
530
531         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
532
533         return(curr_offset - offset);
534 }
535
536 /*
537  * [3] 10.5.3.2.2
538  */
539 static guint8
540 de_auth_fail_param(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
541 {
542         guint32 curr_offset;
543
544         curr_offset = offset;
545
546         proto_tree_add_text(tree,
547                 tvb, curr_offset, len,
548                 "AUTS value: %s",
549                 tvb_bytes_to_str(tvb, curr_offset, len));
550
551         curr_offset += len;
552
553         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
554
555         return(curr_offset - offset);
556 }
557
558 /*
559  * [3] 10.5.3.5a
560  */
561 static guint8
562 de_network_name(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
563 {
564         guint8  oct;
565         guint32 curr_offset;
566         const gchar *str;
567
568         curr_offset = offset;
569
570         oct = tvb_get_guint8(tvb, curr_offset);
571
572         proto_tree_add_item(tree, hf_gsm_a_extension, tvb, curr_offset, 1, FALSE);
573
574         switch ((oct & 0x70) >> 4)
575         {
576         case 0x00: str = "Cell Broadcast data coding scheme, GSM default alphabet, language unspecified, defined in 3GPP TS 03.38"; break;
577         case 0x01: str = "UCS2 (16 bit)"; break;
578         default:
579                 str = "Reserved";
580         break;
581         }
582
583         other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
584         proto_tree_add_text(tree,
585                 tvb, curr_offset, 1,
586                 "%s :  Coding Scheme: %s",
587                 a_bigbuf,
588                 str);
589
590         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
591         proto_tree_add_text(tree,
592                 tvb, curr_offset, 1,
593                 "%s :  Add CI: The MS should %s",
594                 a_bigbuf,
595                 (oct & 0x08) ?
596                         "add the letters for the Country's Initials and a separator (e.g. a space) to the text string" :
597                         "The MS should not add the letters for the Country's Initials to the text string");
598
599         switch (oct & 0x07)
600         {
601         case 1: str = "bit 8 is spare and set to '0' in octet n"; break;
602         case 2: str = "bits 7 and 8 are spare and set to '0' in octet n"; break;
603         case 3: str = "bits 6 to 8(inclusive) are spare and set to '0' in octet n"; break;
604         case 4: str = "bits 5 to 8(inclusive) are spare and set to '0' in octet n"; break;
605         case 5: str = "bits 4 to 8(inclusive) are spare and set to '0' in octet n"; break;
606         case 6: str = "bits 3 to 8(inclusive) are spare and set to '0' in octet n"; break;
607         case 7: str = "bits 2 to 8(inclusive) are spare and set to '0' in octet n"; break;
608         default:
609                 str = "this field carries no information about the number of spare bits in octet n";
610         break;
611         }
612
613         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
614         proto_tree_add_text(tree,
615                 tvb, curr_offset, 1,
616                 "%s :  Number of spare bits in last octet: %s",
617                 a_bigbuf,
618                 str);
619
620         curr_offset++;
621
622         NO_MORE_DATA_CHECK(len);
623
624         proto_tree_add_text(tree,
625                 tvb, curr_offset, len - 1,
626                 "Text string encoded according to Coding Scheme");
627
628         curr_offset += len - 1;
629
630         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
631
632         return(curr_offset - offset);
633 }
634
635 /* 3GPP TS 24.008
636  * [3] 10.5.3.6 Reject cause
637  */
638 guint8
639 de_rej_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
640 {
641         guint8  oct;
642         guint32 curr_offset;
643         const gchar *str;
644
645         curr_offset = offset;
646
647         oct = tvb_get_guint8(tvb, curr_offset);
648
649         switch (oct)
650         {
651         case 0x02: str = "IMSI unknown in HLR"; break;
652         case 0x03: str = "Illegal MS"; break;
653         case 0x04: str = "IMSI unknown in VLR"; break;
654         case 0x05: str = "IMEI not accepted"; break;
655         case 0x06: str = "Illegal ME"; break;
656         case 0x0b: str = "PLMN not allowed"; break;
657         case 0x0c: str = "Location Area not allowed"; break;
658         case 0x0d: str = "Roaming not allowed in this location area"; break;
659         case 0x0f: str = "No Suitable Cells In Location Area"; break;
660         case 0x11: str = "Network failure"; break;
661         case 0x14: str = "MAC failure"; break;
662         case 0x15: str = "Synch failure"; break;
663         case 0x16: str = "Congestion"; break;
664         case 0x17: str = "GSM authentication unacceptable"; break;
665         case 0x20: str = "Service option not supported"; break;
666         case 0x21: str = "Requested service option not subscribed"; break;
667         case 0x22: str = "Service option temporarily out of order"; break;
668         case 0x26: str = "Call cannot be identified"; break;
669         case 0x5f: str = "Semantically incorrect message"; break;
670         case 0x60: str = "Invalid mandatory information"; break;
671         case 0x61: str = "Message type non-existent or not implemented"; break;
672         case 0x62: str = "Message type not compatible with the protocol state"; break;
673         case 0x63: str = "Information element non-existent or not implemented"; break;
674         case 0x64: str = "Conditional IE error"; break;
675         case 0x65: str = "Message not compatible with the protocol state"; break;
676         case 0x6f: str = "Protocol error, unspecified"; break;
677         default:
678                 switch (is_uplink)
679                 {
680                 case IS_UPLINK_FALSE:
681                         str = "Service option temporarily out of order";
682                         break;
683                 default:
684                         str = "Protocol error, unspecified";
685                         break;
686                 }
687                 break;
688         }
689
690         proto_tree_add_text(tree,
691                 tvb, curr_offset, 1,
692                 "Reject Cause value: 0x%02x (%u) %s",
693                 oct,
694                 oct,
695                 str);
696
697         curr_offset++;
698
699         /* no length check possible */
700
701         return(curr_offset - offset);
702 }
703
704 /*
705  * [3] 10.5.3.8
706  */
707 static guint8
708 de_time_zone(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
709 {
710         guint8  oct;
711         guint32 curr_offset;
712         char sign;
713
714         curr_offset = offset;
715
716         /* 3GPP TS 23.040 version 6.6.0 Release 6
717          * 9.2.3.11 TP-Service-Centre-Time-Stamp (TP-SCTS)
718          * :
719          * The Time Zone indicates the difference, expressed in quarters of an hour,
720          * between the local time and GMT. In the first of the two semi-octets,
721          * the first bit (bit 3 of the seventh octet of the TP-Service-Centre-Time-Stamp field)
722          * represents the algebraic sign of this difference (0: positive, 1: negative).
723          */
724
725         oct = tvb_get_guint8(tvb, curr_offset);
726         sign = (oct & 0x08)?'-':'+';
727         oct = (oct >> 4) + (oct & 0x07) * 10;
728
729         proto_tree_add_text(tree,
730                 tvb, offset, 1,
731                 "Timezone: GMT %c %d hours %d minutes",
732                 sign, oct / 4, oct % 4 * 15);
733         curr_offset++;
734
735         /* no length check possible */
736
737         return(curr_offset - offset);
738 }
739
740 /*
741  * [3] 10.5.3.9
742  */
743 static guint8
744 de_time_zone_time(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
745 {
746         guint8  oct, oct2, oct3;
747         guint32 curr_offset;
748         char sign;
749
750         curr_offset = offset;
751
752         oct = tvb_get_guint8(tvb, curr_offset);
753         oct2 = tvb_get_guint8(tvb, curr_offset+1);
754         oct3 = tvb_get_guint8(tvb, curr_offset+2);
755
756         proto_tree_add_text(tree,
757                 tvb, curr_offset, 3,
758                 "Year %u%u, Month %u%u, Day %u%u",
759                 oct & 0x0f,
760                 (oct & 0xf0) >> 4,
761                 oct2 & 0x0f,
762                 (oct2 & 0xf0) >> 4,
763                 oct3 & 0x0f,
764                 (oct3 & 0xf0) >> 4);
765
766         curr_offset += 3;
767
768         oct = tvb_get_guint8(tvb, curr_offset);
769         oct2 = tvb_get_guint8(tvb, curr_offset+1);
770         oct3 = tvb_get_guint8(tvb, curr_offset+2);
771
772         proto_tree_add_text(tree,
773                 tvb, curr_offset, 3,
774                 "Hour %u%u, Minutes %u%u, Seconds %u%u",
775                 oct & 0x0f,
776                 (oct & 0xf0) >> 4,
777                 oct2 & 0x0f,
778                 (oct2 & 0xf0) >> 4,
779                 oct3 & 0x0f,
780                 (oct3 & 0xf0) >> 4);
781
782         curr_offset += 3;
783
784         /* 3GPP TS 23.040 version 6.6.0 Release 6
785          * 9.2.3.11 TP-Service-Centre-Time-Stamp (TP-SCTS)
786          * :
787          * The Time Zone indicates the difference, expressed in quarters of an hour,
788          * between the local time and GMT. In the first of the two semi-octets,
789          * the first bit (bit 3 of the seventh octet of the TP-Service-Centre-Time-Stamp field)
790          * represents the algebraic sign of this difference (0: positive, 1: negative).
791          */
792
793         oct = tvb_get_guint8(tvb, curr_offset);
794         sign = (oct & 0x08)?'-':'+';
795         oct = (oct >> 4) + (oct & 0x07) * 10;
796
797         proto_tree_add_text(tree,
798                 tvb, offset, 1,
799                 "Timezone: GMT %c %d hours %d minutes",
800                 sign, oct / 4, oct % 4 * 15);
801
802         curr_offset++;
803
804         /* no length check possible */
805
806         return(curr_offset - offset);
807 }
808
809 /*
810  * [3] 10.5.3.11 3GPP TS 24.008 version 6.8.0 Release 6
811  */
812 static guint8
813 de_lsa_id(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
814 {
815         guint32 curr_offset;
816
817         curr_offset = offset;
818
819         if (len == 0){
820                 proto_tree_add_text(tree,tvb, curr_offset, len,"LSA ID not included");
821         }else{
822                 proto_tree_add_item(tree, hf_gsm_a_lsa_id, tvb, curr_offset, 3, FALSE);
823         }
824
825         curr_offset += len;
826
827         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
828
829         return(curr_offset - offset);
830 }
831
832 /*
833  * [3] 10.5.3.12
834  */
835 static guint8
836 de_day_saving_time(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
837 {
838         guint8  oct;
839         guint32 curr_offset;
840         const gchar *str;
841
842         curr_offset = offset;
843
844         oct = tvb_get_guint8(tvb, curr_offset);
845
846         other_decode_bitfield_value(a_bigbuf, oct, 0xfc, 8);
847         proto_tree_add_text(tree,
848                 tvb, curr_offset, 1,
849                 "%s :  Spare",
850                 a_bigbuf);
851
852         switch (oct & 0x03)
853         {
854         case 0: str = "No adjustment for Daylight Saving Time"; break;
855         case 1: str = "+1 hour adjustment for Daylight Saving Time"; break;
856         case 2: str = "+2 hours adjustment for Daylight Saving Time"; break;
857         default:
858                 str = "Reserved";
859                 break;
860         }
861
862         other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
863         proto_tree_add_text(tree,
864                 tvb, curr_offset, 1,
865                 "%s :  %s",
866                 a_bigbuf,
867                 str);
868
869         curr_offset++;
870
871         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
872
873         return(curr_offset - offset);
874 }
875
876 /*
877  * [3] 10.5.4.4
878  */
879 static guint8
880 de_aux_states(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
881 {
882         guint8  oct;
883         guint32 curr_offset;
884         const gchar *str;
885
886         curr_offset = offset;
887
888         oct = tvb_get_guint8(tvb, curr_offset);
889
890         proto_tree_add_item(tree, hf_gsm_a_extension, tvb, curr_offset, 1, FALSE);
891
892         other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
893         proto_tree_add_text(tree,
894                 tvb, curr_offset, 1,
895                 "%s :  Spare",
896                 a_bigbuf);
897
898         switch ((oct & 0x0c) >> 2)
899         {
900         case 0: str = "Idle"; break;
901         case 1: str = "Hold request"; break;
902         case 2: str = "Call held"; break;
903         default:
904                 str = "Retrieve request";
905                 break;
906         }
907
908         other_decode_bitfield_value(a_bigbuf, oct, 0x0c, 8);
909         proto_tree_add_text(tree,
910                 tvb, curr_offset, 1,
911                 "%s :  Hold auxiliary state: %s",
912                 a_bigbuf,
913                 str);
914
915         switch (oct & 0x03)
916         {
917         case 0: str = "Idle"; break;
918         case 1: str = "MPTY request"; break;
919         case 2: str = "Call in MPTY"; break;
920         default:
921                 str = "Split request";
922                 break;
923         }
924
925         other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
926         proto_tree_add_text(tree,
927                 tvb, curr_offset, 1,
928                 "%s :  Multi party auxiliary state: %s",
929                 a_bigbuf,
930                 str);
931
932         curr_offset++;
933
934         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
935
936         return(curr_offset - offset);
937 }
938
939 /*
940  * [3] 10.5.4.5
941  */
942 guint8
943 de_bearer_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
944 {
945         guint8  oct;
946         guint8  itc;
947         gboolean        extended;
948         guint32 curr_offset;
949         guint32 saved_offset;
950         proto_tree      *subtree;
951         proto_item      *item;
952         const gchar *str;
953
954 #define DE_BC_ITC_SPEECH        0x00
955 #define DE_BC_ITC_UDI           0x01
956 #define DE_BC_ITC_EX_PLMN       0x02
957 #define DE_BC_ITC_FASC_G3       0x03
958 #define DE_BC_ITC_OTHER_ITC     0x05
959 #define DE_BC_ITC_RSVD_NET      0x07
960
961         curr_offset = offset;
962
963         oct = tvb_get_guint8(tvb, curr_offset);
964
965         /* octet 3 */
966
967         /*
968          * warning, bearer cap uses extended values that
969          * are reversed from other parameters!
970          */
971     item =
972         proto_tree_add_text(tree,
973             tvb, curr_offset, 1,
974             "Octet 3");
975     subtree = proto_item_add_subtree(item, ett_bc_oct_3);
976
977         extended = (oct & 0x80) ? FALSE : TRUE;
978         itc = oct & 0x07;
979
980         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
981     proto_tree_add_text(subtree,
982                 tvb, curr_offset, 1,
983                 "%s :  Extension: %s",
984                 a_bigbuf,
985                 extended ? "extended" : "not extended");
986
987         switch (is_uplink)
988         {
989         case IS_UPLINK_FALSE:
990                 str = "Spare";
991                 break;
992
993         case IS_UPLINK_TRUE:
994                 /*
995                  * depends on Information transfer capability
996                  */
997                 switch (itc)
998                 {
999                 case DE_BC_ITC_SPEECH:
1000                         if (extended)
1001                         {
1002                                 switch ((oct & 0x60) >> 5)
1003                                 {
1004                                 case 1: str = "MS supports at least full rate speech version 1 but does not support half rate speech version 1"; break;
1005                                 case 2: str = "MS supports at least full rate speech version 1 and half rate speech version 1. MS has a greater preference for half rate speech version 1 than for full rate speech version 1"; break;
1006                                 case 3: str = "MS supports at least full rate speech version 1 and half rate speech version 1. MS has a greater preference for full rate speech version 1 than for half rate speech version 1"; break;
1007                                 default:
1008                                         str = "Reserved";
1009                                         break;
1010                                 }
1011                         }
1012                         else
1013                         {
1014                                 switch ((oct & 0x60) >> 5)
1015                                 {
1016                                 case 1: str = "Full rate support only MS/fullrate speech version 1 supported"; break;
1017                                 case 2: str = "Dual rate support MS/half rate speech version 1 preferred, full rate speech version 1 also supported"; break;
1018                                 case 3: str = "Dual rate support MS/full rate speech version 1 preferred, half rate speech version 1 also supported"; break;
1019                                 default:
1020                                         str = "Reserved";
1021                                         break;
1022                                 }
1023                         }
1024                         break;
1025
1026                 default:
1027                         switch ((oct & 0x60) >> 5)
1028                         {
1029                         case 1: str = "Full rate support only MS"; break;
1030                         case 2: str = "Dual rate support MS/half rate preferred"; break;
1031                         case 3: str = "Dual rate support MS/full rate preferred"; break;
1032                         default:
1033                                 str = "Reserved";
1034                                 break;
1035                         }
1036                         break;
1037                 }
1038                 break;
1039
1040                 default:
1041                         str = "(dissect problem)";
1042                         break;
1043                 }
1044
1045         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
1046     proto_tree_add_text(subtree,
1047         tvb, curr_offset, 1,
1048         "%s :  Radio channel requirement: %s",
1049         a_bigbuf,
1050         str);
1051
1052         other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
1053     proto_tree_add_text(subtree,
1054                 tvb, curr_offset, 1,
1055                 "%s :  Coding standard: %s",
1056                 a_bigbuf,
1057                 (oct & 0x10) ? "reserved" : "GSM standardized coding");
1058
1059         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
1060     proto_tree_add_text(subtree,
1061                 tvb, curr_offset, 1,
1062                 "%s :  Transfer mode: %s",
1063                 a_bigbuf,
1064                 (oct & 0x08) ? "packet" : "circuit");
1065
1066         switch (itc)
1067         {
1068         case DE_BC_ITC_SPEECH: str = "Speech"; break;
1069         case DE_BC_ITC_UDI: str = "Unrestricted digital information"; break;
1070         case DE_BC_ITC_EX_PLMN: str = "3.1 kHz audio, ex PLMN"; break;
1071         case DE_BC_ITC_FASC_G3: str = "Facsimile group 3"; break;
1072         case DE_BC_ITC_OTHER_ITC: str = "Other ITC (See Octet 5a)"; break;
1073         case DE_BC_ITC_RSVD_NET: str = "Reserved, to be used in the network"; break;
1074         default:
1075                 str = "Reserved";
1076                 break;
1077         }
1078
1079         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
1080     proto_tree_add_text(subtree,
1081                 tvb, curr_offset, 1,
1082                 "%s :  Information transfer capability: %s",
1083                 a_bigbuf,
1084                 str);
1085
1086         if (add_string)
1087                 g_snprintf(add_string, string_len, " - (%s)", str);
1088
1089         curr_offset++;
1090
1091         NO_MORE_DATA_CHECK(len);
1092
1093         switch (itc)
1094         {
1095         case DE_BC_ITC_SPEECH:
1096                 /* octets 3a */
1097
1098                 item =
1099                         proto_tree_add_text(tree,
1100                         tvb, curr_offset, -1,
1101                         "Octets 3a - Speech Versions");
1102
1103                 subtree = proto_item_add_subtree(item, ett_bc_oct_3a);
1104
1105                 saved_offset = curr_offset;
1106
1107                 do
1108                 {
1109                         oct = tvb_get_guint8(tvb, curr_offset);
1110
1111                         extended = (oct & 0x80) ? FALSE : TRUE;
1112
1113                         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1114                         proto_tree_add_text(subtree,
1115                                 tvb, curr_offset, 1,
1116                                 "%s :  Extension: %s",
1117                                 a_bigbuf,
1118                                 extended ? "extended" : "not extended");
1119
1120                         other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
1121                         proto_tree_add_text(subtree,
1122                                 tvb, curr_offset, 1,
1123                                 "%s :  Coding: octet used for %s",
1124                                 a_bigbuf,
1125                                 (oct & 0x40) ? "other extension of octet 3" :
1126                                 "extension of information transfer capability");
1127
1128                         other_decode_bitfield_value(a_bigbuf, oct, 0x30, 8);
1129                         proto_tree_add_text(subtree,
1130                                 tvb, curr_offset, 1,
1131                                 "%s :  Spare",
1132                                 a_bigbuf);
1133
1134                         switch (oct & 0x0f)
1135                         {
1136                         case 0: str = "GSM full rate speech version 1"; break;
1137                         case 2: str = "GSM full rate speech version 2"; break;
1138                         case 4: str = "GSM full rate speech version 3"; break;
1139                         case 1: str = "GSM half rate speech version 1"; break;
1140                         case 5: str = "GSM half rate speech version 3"; break;
1141                         default:
1142                                 str = "Speech version TBD";
1143                                 break;
1144                         }
1145
1146                         other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
1147                         proto_tree_add_text(subtree,
1148                                 tvb, curr_offset, 1,
1149                                 "%s :  Speech version indication: %s",
1150                                 a_bigbuf,
1151                                 str);
1152
1153                         curr_offset++;
1154                 }
1155                 while (extended &&
1156                         ((len - (curr_offset - offset)) > 0));
1157
1158                 proto_item_set_len(item, curr_offset - saved_offset);
1159                 break;
1160
1161                 default:
1162                 /* octet 4 */
1163
1164                 item =
1165                         proto_tree_add_text(tree,
1166                                 tvb, curr_offset, 1,
1167                                 "Octet 4");
1168
1169                 subtree = proto_item_add_subtree(item, ett_bc_oct_4);
1170
1171                 oct = tvb_get_guint8(tvb, curr_offset);
1172
1173                 extended = (oct & 0x80) ? FALSE : TRUE;
1174
1175                 other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1176                 proto_tree_add_text(subtree,
1177                         tvb, curr_offset, 1,
1178                         "%s :  Extension: %s",
1179                         a_bigbuf,
1180                         extended ? "extended" : "not extended");
1181
1182                 other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
1183                 proto_tree_add_text(subtree,
1184                         tvb, curr_offset, 1,
1185                         "%s :  Compression: data compression %s%s",
1186                         a_bigbuf,
1187                         (oct & 0x40) ? "" : "not ",
1188                         is_uplink ? "allowed" : "possible");
1189
1190                 switch ((oct & 0x30) >> 4)
1191                 {
1192                 case 0x00: str = "Service data unit integrity"; break;
1193                 case 0x03: str = "Unstructured"; break;
1194                 default:
1195                         str = "Reserved";
1196                         break;
1197                 }
1198
1199                 other_decode_bitfield_value(a_bigbuf, oct, 0x30, 8);
1200                 proto_tree_add_text(subtree,
1201                         tvb, curr_offset, 1,
1202                         "%s :  Structure: %s",
1203                         a_bigbuf,
1204                         str);
1205
1206                 other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
1207                 proto_tree_add_text(subtree,
1208                         tvb, curr_offset, 1,
1209                         "%s :  Duplex mode: %s",
1210                         a_bigbuf,
1211                         (oct & 0x08) ? "Full" : "Half");
1212
1213                 other_decode_bitfield_value(a_bigbuf, oct, 0x04, 8);
1214                 proto_tree_add_text(subtree,
1215                         tvb, curr_offset, 1,
1216                         "%s :  Configuration: %s",
1217                         a_bigbuf,
1218                         (oct & 0x04) ? "Reserved" : "Point-to-point");
1219
1220                 other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
1221                 proto_tree_add_text(subtree,
1222                         tvb, curr_offset, 1,
1223                         "%s :  NIRR: %s",
1224                         a_bigbuf,
1225                         (oct & 0x02) ?
1226                         "Data up to and including 4.8 kb/s, full rate, non-transparent, 6 kb/s radio interface rate is requested" :
1227                         "No meaning is associated with this value");
1228
1229                 other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
1230                 proto_tree_add_text(subtree,
1231                         tvb, curr_offset, 1,
1232                         "%s :  Establishment: %s",
1233                         a_bigbuf,
1234                         (oct & 0x01) ? "Reserved" : "Demand");
1235
1236                 curr_offset++;
1237
1238         NO_MORE_DATA_CHECK(len);
1239
1240         /* octet 5 */
1241
1242         item =
1243                 proto_tree_add_text(tree,
1244                 tvb, curr_offset, 1,
1245                 "Octet 5");
1246
1247         subtree = proto_item_add_subtree(item, ett_bc_oct_5);
1248
1249         oct = tvb_get_guint8(tvb, curr_offset);
1250
1251         extended = (oct & 0x80) ? FALSE : TRUE;
1252
1253         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1254         proto_tree_add_text(subtree,
1255                 tvb, curr_offset, 1,
1256                 "%s :  Extension: %s",
1257                 a_bigbuf,
1258                 extended ? "extended" : "not extended");
1259
1260         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
1261         proto_tree_add_text(subtree,
1262                 tvb, curr_offset, 1,
1263                 "%s :  Access Identity: %s",
1264                 a_bigbuf,
1265                 (oct & 0x60) ? "Reserved" : "Octet identifier");
1266
1267         switch ((oct & 0x18) >> 3)
1268         {
1269         case 0x00: str = "No rate adaption"; break;
1270         case 0x01: str = "V.110, I.460/X.30 rate adaptation"; break;
1271         case 0x02: str = "ITU-T X.31 flag stuffing"; break;
1272         default:
1273                 str = "Other rate adaption (see octet 5a)";
1274                 break;
1275         }
1276
1277         other_decode_bitfield_value(a_bigbuf, oct, 0x18, 8);
1278         proto_tree_add_text(subtree,
1279                 tvb, curr_offset, 1,
1280                 "%s :  Rate Adaption: %s",
1281                 a_bigbuf,
1282                 str);
1283
1284         switch (oct & 0x07)
1285         {
1286         case 0x01: str = "I.440/450"; break;
1287         case 0x02: str = "Reserved: was allocated in earlier phases of the protocol"; break;
1288         case 0x03: str = "Reserved: was allocated in earlier phases of the protocol"; break;
1289         case 0x04: str = "Reserved: was allocated in earlier phases of the protocol"; break;
1290         case 0x05: str = "Reserved: was allocated in earlier phases of the protocol"; break;
1291         case 0x06: str = "Reserved: was allocated in earlier phases of the protocol"; break;
1292         default:
1293                 str = "Reserved";
1294                 break;
1295         }
1296
1297         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
1298         proto_tree_add_text(subtree,
1299                 tvb, curr_offset, 1,
1300                 "%s :  Signalling Access Protocol: %s",
1301                 a_bigbuf,
1302                 str);
1303
1304         curr_offset++;
1305
1306         NO_MORE_DATA_CHECK(len);
1307
1308         if (!extended) goto bc_octet_6;
1309
1310         /* octet 5a */
1311
1312         item =
1313                 proto_tree_add_text(tree,
1314                 tvb, curr_offset, 1,
1315                 "Octet 5a");
1316
1317         subtree = proto_item_add_subtree(item, ett_bc_oct_5a);
1318
1319         oct = tvb_get_guint8(tvb, curr_offset);
1320
1321         extended = (oct & 0x80) ? FALSE : TRUE;
1322
1323         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1324         proto_tree_add_text(subtree,
1325                 tvb, curr_offset, 1,
1326                 "%s :  Extension: %s",
1327                 a_bigbuf,
1328                 extended ? "extended" : "not extended");
1329
1330         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
1331         proto_tree_add_text(subtree,
1332                 tvb, curr_offset, 1,
1333                 "%s :  Other ITC: %s",
1334                 a_bigbuf,
1335                 (oct & 0x60) ? "Reserved" : "Restricted digital information");
1336
1337         switch ((oct & 0x18) >> 3)
1338         {
1339         case 0x00: str = "V.120"; break;
1340         case 0x01: str = "H.223 & H.245"; break;
1341         case 0x02: str = "PIAFS"; break;
1342         default:
1343                 str = "Reserved";
1344                 break;
1345         }
1346
1347         other_decode_bitfield_value(a_bigbuf, oct, 0x18, 8);
1348         proto_tree_add_text(subtree,
1349                 tvb, curr_offset, 1,
1350                 "%s :  Other Rate Adaption: %s",
1351                 a_bigbuf,
1352                 str);
1353
1354         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
1355         proto_tree_add_text(subtree,
1356                 tvb, curr_offset, 1,
1357                 "%s :  Spare",
1358                 a_bigbuf);
1359
1360         curr_offset++;
1361
1362         NO_MORE_DATA_CHECK(len);
1363
1364         if (!extended) goto bc_octet_6;
1365
1366         /* octet 5b */
1367
1368         item =
1369                 proto_tree_add_text(tree,
1370                 tvb, curr_offset, 1,
1371                 "Octet 5b");
1372
1373         subtree = proto_item_add_subtree(item, ett_bc_oct_5b);
1374
1375         oct = tvb_get_guint8(tvb, curr_offset);
1376
1377         extended = (oct & 0x80) ? FALSE : TRUE;
1378
1379         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1380         proto_tree_add_text(subtree,
1381                 tvb, curr_offset, 1,
1382                 "%s :  Extension: %s",
1383                 a_bigbuf,
1384                 extended ? "extended" : "not extended");
1385
1386         other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
1387         proto_tree_add_text(subtree,
1388                 tvb, curr_offset, 1,
1389                 "%s :  Rate Adaption Header: %sincluded",
1390                 a_bigbuf,
1391                 (oct & 0x40) ? "" : "not ");
1392
1393         other_decode_bitfield_value(a_bigbuf, oct, 0x20, 8);
1394         proto_tree_add_text(subtree,
1395                 tvb, curr_offset, 1,
1396                 "%s :  Multiple frame establishment support in data link: %s",
1397                 a_bigbuf,
1398                 (oct & 0x20) ? "Supported" : "Not supported, only UI frames allowed");
1399
1400         other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
1401         proto_tree_add_text(subtree,
1402                 tvb, curr_offset, 1,
1403                 "%s :  Mode of operation: %s",
1404                 a_bigbuf,
1405                 (oct & 0x10) ? "Protocol sensitive" : "Bit transparent");
1406
1407         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
1408         proto_tree_add_text(subtree,
1409                 tvb, curr_offset, 1,
1410                 "%s :  Logical link identifier negotiation: %s",
1411                 a_bigbuf,
1412                 (oct & 0x08) ? "Full protocol negotiation" : "Default, LLI=256 only");
1413
1414         other_decode_bitfield_value(a_bigbuf, oct, 0x04, 8);
1415         proto_tree_add_text(subtree,
1416                 tvb, curr_offset, 1,
1417                 "%s :  Assignor/Assignee: Message originator is '%s'",
1418                 a_bigbuf,
1419                 (oct & 0x04) ? "assignor only" : "default assignee");
1420
1421         other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
1422         proto_tree_add_text(subtree,
1423                 tvb, curr_offset, 1,
1424                 "%s :  In band/Out of band negotiation: Negotiation is done %s",
1425                 a_bigbuf,
1426                 (oct & 0x02) ?
1427                 "with USER INFORMATION messages on a temporary signalling connection" :
1428                 "in-band using logical link zero");
1429
1430         other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
1431         proto_tree_add_text(subtree,
1432                 tvb, curr_offset, 1,
1433                 "%s :  Spare",
1434                 a_bigbuf);
1435
1436         curr_offset++;
1437
1438         NO_MORE_DATA_CHECK(len);
1439
1440 bc_octet_6:
1441
1442         /* octet 6 */
1443
1444         item =
1445                 proto_tree_add_text(tree,
1446                 tvb, curr_offset, 1,
1447                 "Octet 6");
1448
1449         subtree = proto_item_add_subtree(item, ett_bc_oct_6);
1450
1451         oct = tvb_get_guint8(tvb, curr_offset);
1452
1453         extended = (oct & 0x80) ? FALSE : TRUE;
1454
1455         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1456         proto_tree_add_text(subtree,
1457                 tvb, curr_offset, 1,
1458                 "%s :  Extension: %s",
1459                 a_bigbuf,
1460                 extended ? "extended" : "not extended");
1461
1462         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
1463         proto_tree_add_text(subtree,
1464                 tvb, curr_offset, 1,
1465                 "%s :  Layer 1 Identity: %s",
1466                 a_bigbuf,
1467                 ((oct & 0x60) == 0x20) ? "Octet identifier" : "Reserved");
1468
1469         other_decode_bitfield_value(a_bigbuf, oct, 0x1e, 8);
1470         proto_tree_add_text(subtree,
1471                 tvb, curr_offset, 1,
1472                 "%s :  User information layer 1 protocol: %s",
1473                 a_bigbuf,
1474                 (oct & 0x1e) ? "Reserved" : "Default layer 1 protocol");
1475
1476         other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
1477         proto_tree_add_text(subtree,
1478                 tvb, curr_offset, 1,
1479                 "%s :  Synchronous/asynchronous: %s",
1480                 a_bigbuf,
1481                 (oct & 0x01) ? "Asynchronous" : "Synchronous");
1482
1483         curr_offset++;
1484
1485         NO_MORE_DATA_CHECK(len);
1486
1487         if (!extended) goto bc_octet_7;
1488
1489         /* octet 6a */
1490
1491         item =
1492                 proto_tree_add_text(tree,
1493                 tvb, curr_offset, 1,
1494                 "Octet 6a");
1495
1496         subtree = proto_item_add_subtree(item, ett_bc_oct_6a);
1497
1498         oct = tvb_get_guint8(tvb, curr_offset);
1499
1500         extended = (oct & 0x80) ? FALSE : TRUE;
1501
1502         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1503         proto_tree_add_text(subtree,
1504                 tvb, curr_offset, 1,
1505                 "%s :  Extension: %s",
1506                 a_bigbuf,
1507                 extended ? "extended" : "not extended");
1508
1509         other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
1510         proto_tree_add_text(subtree,
1511                 tvb, curr_offset, 1,
1512                 "%s :  Number of Stop Bits: %s",
1513                 a_bigbuf,
1514                 (oct & 0x40) ? "2" : "1");
1515
1516         other_decode_bitfield_value(a_bigbuf, oct, 0x20, 8);
1517         proto_tree_add_text(subtree,
1518                 tvb, curr_offset, 1,
1519                 "%s :  Negotiation: %s",
1520                 a_bigbuf,
1521                 (oct & 0x20) ? "Reserved" : "In-band negotiation not possible");
1522
1523         other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
1524         proto_tree_add_text(subtree,
1525                 tvb, curr_offset, 1,
1526                 "%s :  Number of data bits excluding parity bit if present: %s",
1527                 a_bigbuf,
1528                 (oct & 0x10) ? "8" : "7");
1529
1530         switch (oct & 0x0f)
1531         {
1532         case 0x01: str = "0.3 kbit/s Recommendation X.1 and V.110"; break;
1533         case 0x02: str = "1.2 kbit/s Recommendation X.1 and V.110"; break;
1534         case 0x03: str = "2.4 kbit/s Recommendation X.1 and V.110"; break;
1535         case 0x04: str = "4.8 kbit/s Recommendation X.1 and V.110"; break;
1536         case 0x05: str = "9.6 kbit/s Recommendation X.1 and V.110"; break;
1537         case 0x06: str = "12.0 kbit/s transparent (non compliance with X.1 and V.110)"; break;
1538         case 0x07: str = "Reserved: was allocated in earlier phases of the protocol"; break;
1539         default:
1540                 str = "Reserved";
1541                 break;
1542         }
1543
1544         other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
1545         proto_tree_add_text(subtree,
1546                 tvb, curr_offset, 1,
1547                 "%s :  User rate: %s",
1548                 a_bigbuf,
1549                 str);
1550
1551         curr_offset++;
1552
1553         NO_MORE_DATA_CHECK(len);
1554
1555         if (!extended) goto bc_octet_7;
1556
1557         /* octet 6b */
1558
1559         item =
1560                 proto_tree_add_text(tree,
1561                 tvb, curr_offset, 1,
1562                 "Octet 6b");
1563
1564         subtree = proto_item_add_subtree(item, ett_bc_oct_6b);
1565
1566         oct = tvb_get_guint8(tvb, curr_offset);
1567
1568         extended = (oct & 0x80) ? FALSE : TRUE;
1569
1570         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1571         proto_tree_add_text(subtree,
1572                 tvb, curr_offset, 1,
1573                 "%s :  Extension: %s",
1574                 a_bigbuf,
1575                 extended ? "extended" : "not extended");
1576
1577         switch ((oct & 0x60) >> 5)
1578         {
1579         case 0x02: str = "8 kbit/s"; break;
1580         case 0x03: str = "16 kbit/s"; break;
1581         default:
1582                 str = "Reserved";
1583                 break;
1584         }
1585
1586         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
1587         proto_tree_add_text(subtree,
1588                 tvb, curr_offset, 1,
1589                 "%s :  V.110/X.30 rate adaptation Intermediate rate: %s",
1590                 a_bigbuf,
1591                 str);
1592
1593         other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
1594         proto_tree_add_text(subtree,
1595                 tvb, curr_offset, 1,
1596                 "%s :  Network independent clock (NIC) on transmission (Tx): %s to send data with network independent clock",
1597                 a_bigbuf,
1598                 (oct & 0x10) ? "requires" : "does not require");
1599
1600         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
1601         proto_tree_add_text(subtree,
1602                 tvb, curr_offset, 1,
1603                 "%s :  Network independent clock (NIC) on reception (Rx): %s accept data with network independent clock",
1604                 a_bigbuf,
1605                 (oct & 0x08) ? "can" : "cannot");
1606
1607         switch (oct & 0x07)
1608         {
1609         case 0x00: str = "Odd"; break;
1610         case 0x02: str = "Even"; break;
1611         case 0x03: str = "None"; break;
1612         case 0x04: str = "Forced to 0"; break;
1613         case 0x05: str = "Forced to 1"; break;
1614         default:
1615                 str = "Reserved";
1616                 break;
1617         }
1618
1619         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
1620         proto_tree_add_text(subtree,
1621                 tvb, curr_offset, 1,
1622                 "%s :  Parity information: %s",
1623                 a_bigbuf,
1624                 str);
1625
1626         curr_offset++;
1627
1628         NO_MORE_DATA_CHECK(len);
1629
1630         if (!extended) goto bc_octet_7;
1631
1632         /* octet 6c */
1633
1634         item =
1635                 proto_tree_add_text(tree,
1636                 tvb, curr_offset, 1,
1637                 "Octet 6c");
1638
1639         subtree = proto_item_add_subtree(item, ett_bc_oct_6c);
1640
1641         oct = tvb_get_guint8(tvb, curr_offset);
1642
1643         extended = (oct & 0x80) ? FALSE : TRUE;
1644
1645         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1646         proto_tree_add_text(subtree,
1647                 tvb, curr_offset, 1,
1648                 "%s :  Extension: %s",
1649                 a_bigbuf,
1650                 extended ? "extended" : "not extended");
1651
1652         switch ((oct & 0x60) >> 5)
1653         {
1654         case 0x01: str = "Non transparent (RLP)"; break;
1655         case 0x02: str = "Both, transparent preferred"; break;
1656         case 0x03: str = "Both, non transparent preferred"; break;
1657         default:
1658                 str = "Transparent";
1659                 break;
1660         }
1661
1662         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
1663         proto_tree_add_text(subtree,
1664                 tvb, curr_offset, 1,
1665                 "%s :  Connection element: %s",
1666                 a_bigbuf,
1667                 str);
1668
1669         switch (oct & 0x1f)
1670         {
1671         case 0x00: str = "None"; break;
1672         case 0x01: str = "V.21"; break;
1673         case 0x02: str = "V.22"; break;
1674         case 0x03: str = "V.22 bis"; break;
1675         case 0x04: str = "Reserved: was allocated in earlier phases of the protocol"; break;
1676         case 0x05: str = "V.26 ter"; break;
1677         case 0x06: str = "V.32"; break;
1678         case 0x07: str = "Modem for undefined interface"; break;
1679         case 0x08: str = "Autobauding type 1"; break;
1680         default:
1681                 str = "Reserved";
1682                 break;
1683         }
1684
1685         other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
1686         proto_tree_add_text(subtree,
1687                 tvb, curr_offset, 1,
1688                 "%s :  Modem type: %s",
1689                 a_bigbuf,
1690                 str);
1691
1692         curr_offset++;
1693
1694         NO_MORE_DATA_CHECK(len);
1695
1696         if (!extended) goto bc_octet_7;
1697
1698         /* octet 6d */
1699
1700         item =
1701                 proto_tree_add_text(tree,
1702                 tvb, curr_offset, 1,
1703                 "Octet 6d");
1704
1705         subtree = proto_item_add_subtree(item, ett_bc_oct_6d);
1706
1707         oct = tvb_get_guint8(tvb, curr_offset);
1708
1709         extended = (oct & 0x80) ? FALSE : TRUE;
1710
1711         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1712         proto_tree_add_text(subtree,
1713                 tvb, curr_offset, 1,
1714                 "%s :  Extension: %s",
1715                 a_bigbuf,
1716                 extended ? "extended" : "not extended");
1717
1718         switch ((oct & 0x60) >> 5)
1719         {
1720         case 0x00: str = "No other modem type specified in this field"; break;
1721         case 0x02: str = "V.34"; break;
1722         default:
1723                 str = "Reserved";
1724                 break;
1725         }
1726
1727         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
1728         proto_tree_add_text(subtree,
1729                 tvb, curr_offset, 1,
1730                 "%s :  Other modem type: %s",
1731                 a_bigbuf,
1732                 str);
1733
1734         switch (oct & 0x1f)
1735         {
1736         case 0x00: str = "Fixed network user rate not applicable/No meaning is associated with this value"; break;
1737         case 0x01: str = "9.6 kbit/s Recommendation X.1 and V.110"; break;
1738         case 0x02: str = "14.4 kbit/s Recommendation X.1 and V.110"; break;
1739         case 0x03: str = "19.2 kbit/s Recommendation X.1 and V.110"; break;
1740         case 0x04: str = "28.8 kbit/s Recommendation X.1 and V.110"; break;
1741         case 0x05: str = "38.4 kbit/s Recommendation X.1 and V.110"; break;
1742         case 0x06: str = "48.0 kbit/s Recommendation X.1 and V.110(synch)"; break;
1743         case 0x07: str = "56.0 kbit/s Recommendation X.1 and V.110(synch) /bit transparent"; break;
1744         case 0x08: str = "64.0 kbit/s bit transparent"; break;
1745         case 0x09: str = "33.6 kbit/s bit transparent"; break;
1746         case 0x0a: str = "32.0 kbit/s Recommendation I.460"; break;
1747         case 0x0b: str = "31.2 kbit/s Recommendation V.34"; break;
1748         default:
1749                 str = "Reserved";
1750                 break;
1751         }
1752
1753         other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
1754         proto_tree_add_text(subtree,
1755                 tvb, curr_offset, 1,
1756                 "%s :  Fixed network user rate: %s",
1757                 a_bigbuf,
1758                 str);
1759
1760         curr_offset++;
1761
1762         NO_MORE_DATA_CHECK(len);
1763
1764         if (!extended) goto bc_octet_7;
1765
1766         /* octet 6e */
1767
1768         item =
1769                 proto_tree_add_text(tree,
1770                 tvb, curr_offset, 1,
1771                 "Octet 6e");
1772
1773         subtree = proto_item_add_subtree(item, ett_bc_oct_6e);
1774
1775         oct = tvb_get_guint8(tvb, curr_offset);
1776
1777         extended = (oct & 0x80) ? FALSE : TRUE;
1778
1779         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1780         proto_tree_add_text(subtree,
1781                 tvb, curr_offset, 1,
1782                 "%s :  Extension: %s",
1783                 a_bigbuf,
1784                 extended ? "extended" : "not extended");
1785
1786         if (is_uplink == IS_UPLINK_TRUE)
1787         {
1788                 other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
1789                 proto_tree_add_text(subtree,
1790                 tvb, curr_offset, 1,
1791                 "%s :  Acceptable channel codings: TCH/F14.4 %sacceptable",
1792                 a_bigbuf,
1793                 (oct & 0x40) ? "" : "not ");
1794
1795                 other_decode_bitfield_value(a_bigbuf, oct, 0x20, 8);
1796                 proto_tree_add_text(subtree,
1797                 tvb, curr_offset, 1,
1798                 "%s :  Acceptable channel codings: Spare",
1799                 a_bigbuf);
1800
1801                 other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
1802                 proto_tree_add_text(subtree,
1803                 tvb, curr_offset, 1,
1804                 "%s :  Acceptable channel codings: TCH/F9.6 %sacceptable",
1805                 a_bigbuf,
1806                 (oct & 0x10) ? "" : "not ");
1807
1808                 other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
1809                 proto_tree_add_text(subtree,
1810                 tvb, curr_offset, 1,
1811                 "%s :  Acceptable channel codings: TCH/F4.8 %sacceptable",
1812                 a_bigbuf,
1813                 (oct & 0x08) ? "" : "not ");
1814
1815                 other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
1816                 proto_tree_add_text(subtree,
1817                 tvb, curr_offset, 1,
1818                 "%s :  Maximum number of traffic channels: %u TCH",
1819                 a_bigbuf,
1820                 (oct & 0x07) + 1);
1821         }
1822         else
1823         {
1824                 other_decode_bitfield_value(a_bigbuf, oct, 0x78, 8);
1825                 proto_tree_add_text(subtree,
1826                 tvb, curr_offset, 1,
1827                 "%s :  Acceptable channel codings: Spare",
1828                 a_bigbuf);
1829
1830                 other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
1831                 proto_tree_add_text(subtree,
1832                 tvb, curr_offset, 1,
1833                 "%s :  Maximum number of traffic channels: Spare",
1834                 a_bigbuf);
1835         }
1836
1837         curr_offset++;
1838
1839         NO_MORE_DATA_CHECK(len);
1840
1841         if (!extended) goto bc_octet_7;
1842
1843         /* octet 6f */
1844
1845         item =
1846                 proto_tree_add_text(tree,
1847                 tvb, curr_offset, 1,
1848                 "Octet 6f");
1849
1850         subtree = proto_item_add_subtree(item, ett_bc_oct_6f);
1851
1852         oct = tvb_get_guint8(tvb, curr_offset);
1853
1854         extended = (oct & 0x80) ? FALSE : TRUE;
1855
1856         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1857         proto_tree_add_text(subtree,
1858                 tvb, curr_offset, 1,
1859                 "%s :  Extension: %s",
1860                 a_bigbuf,
1861                 extended ? "extended" : "not extended");
1862
1863         switch ((oct & 0x70) >> 4)
1864         {
1865         case 0x00: str = "not allowed/required/applicable"; break;
1866         case 0x01: str = "up to 1 TCH/F allowed/may be requested"; break;
1867         case 0x02: str = "up to 2 TCH/F allowed/may be requested"; break;
1868         case 0x03: str = "up to 3 TCH/F allowed/may be requested"; break;
1869         case 0x04: str = "up to 4 TCH/F allowed/may be requested"; break;
1870         default:
1871                 str = "up to 4 TCH/F may be requested";
1872                 break;
1873         }
1874
1875         other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
1876         proto_tree_add_text(subtree,
1877                 tvb, curr_offset, 1,
1878                 "%s :  UIMI, User initiated modification indication: %s",
1879                 a_bigbuf,
1880                 str);
1881
1882         if (is_uplink == IS_UPLINK_TRUE)
1883         {
1884                 switch (oct & 0x0f)
1885                 {
1886                 case 0x00: str = "Air interface user rate not applicable/No meaning associated with this value"; break;
1887                 case 0x01: str = "9.6 kbit/s"; break;
1888                 case 0x02: str = "14.4 kbit/s"; break;
1889                 case 0x03: str = "19.2 kbit/s"; break;
1890                 case 0x05: str = "28.8 kbit/s"; break;
1891                 case 0x06: str = "38.4 kbit/s"; break;
1892                 case 0x07: str = "43.2 kbit/s"; break;
1893                 case 0x08: str = "57.6 kbit/s"; break;
1894                 case 0x09: str = "interpreted by the network as 38.4 kbit/s in this version of the protocol"; break;
1895                 case 0x0a: str = "interpreted by the network as 38.4 kbit/s in this version of the protocol"; break;
1896                 case 0x0b: str = "interpreted by the network as 38.4 kbit/s in this version of the protocol"; break;
1897                 case 0x0c: str = "interpreted by the network as 38.4 kbit/s in this version of the protocol"; break;
1898                 default:
1899                 str = "Reserved";
1900                 break;
1901                 }
1902
1903                 other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
1904                 proto_tree_add_text(subtree,
1905                 tvb, curr_offset, 1,
1906                 "%s :  Wanted air interface user rate: %s",
1907                 a_bigbuf,
1908                 str);
1909         }
1910         else
1911         {
1912                 other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
1913                 proto_tree_add_text(subtree,
1914                 tvb, curr_offset, 1,
1915                 "%s :  Wanted air interface user rate: Spare",
1916                 a_bigbuf);
1917         }
1918
1919         curr_offset++;
1920
1921         NO_MORE_DATA_CHECK(len);
1922
1923         if (!extended) goto bc_octet_7;
1924
1925         /* octet 6g */
1926
1927         item =
1928                 proto_tree_add_text(tree,
1929                 tvb, curr_offset, 1,
1930                 "Octet 6g");
1931
1932         subtree = proto_item_add_subtree(item, ett_bc_oct_6g);
1933
1934         oct = tvb_get_guint8(tvb, curr_offset);
1935
1936         extended = (oct & 0x80) ? FALSE : TRUE;
1937
1938         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1939         proto_tree_add_text(subtree,
1940                 tvb, curr_offset, 1,
1941                 "%s :  Extension: %s",
1942                 a_bigbuf,
1943                 extended ? "extended" : "not extended");
1944
1945         if (is_uplink == IS_UPLINK_TRUE)
1946         {
1947                 other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
1948                 proto_tree_add_text(subtree,
1949                 tvb, curr_offset, 1,
1950                 "%s :  Acceptable channel codings extended: TCH/F28.8 %sacceptable",
1951                 a_bigbuf,
1952                 (oct & 0x40) ? "" : "not ");
1953
1954                 other_decode_bitfield_value(a_bigbuf, oct, 0x20, 8);
1955                 proto_tree_add_text(subtree,
1956                 tvb, curr_offset, 1,
1957                 "%s :  Acceptable channel codings extended: TCH/F32.0 %sacceptable",
1958                 a_bigbuf,
1959                 (oct & 0x20) ? "" : "not ");
1960
1961                 other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
1962                 proto_tree_add_text(subtree,
1963                 tvb, curr_offset, 1,
1964                 "%s :  Acceptable channel codings extended: TCH/F43.2 %sacceptable",
1965                 a_bigbuf,
1966                 (oct & 0x10) ? "" : "not ");
1967
1968                 other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
1969                 proto_tree_add_text(subtree,
1970                 tvb, curr_offset, 1,
1971                 "%s :  Acceptable channel codings extended: TCH/F43.2 %sacceptable",
1972                 a_bigbuf,
1973                 (oct & 0x10) ? "" : "not ");
1974
1975                 switch ((oct & 0x0c) >> 2)
1976                 {
1977                 case 0: str = "Channel coding symmetry preferred"; break;
1978                 case 2: str = "Downlink biased channel coding asymmetry is preferred"; break;
1979                 case 1: str = "Uplink biased channel coding asymmetry is preferred"; break;
1980                 default:
1981                 str = "Unused, treat as Channel coding symmetry preferred";
1982                 break;
1983                 }
1984
1985                 other_decode_bitfield_value(a_bigbuf, oct, 0x0c, 8);
1986                 proto_tree_add_text(subtree,
1987                 tvb, curr_offset, 1,
1988                 "%s :  Channel Coding Asymmetry Indication: %s",
1989                 a_bigbuf,
1990                 str);
1991         }
1992         else
1993         {
1994                 other_decode_bitfield_value(a_bigbuf, oct, 0x7c, 8);
1995                 proto_tree_add_text(subtree,
1996                 tvb, curr_offset, 1,
1997                 "%s :  EDGE Channel Codings: Spare",
1998                 a_bigbuf);
1999         }
2000
2001         other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
2002         proto_tree_add_text(subtree,
2003                 tvb, curr_offset, 1,
2004                 "%s :  Spare",
2005                 a_bigbuf);
2006
2007         curr_offset++;
2008
2009         NO_MORE_DATA_CHECK(len);
2010
2011 bc_octet_7:
2012         /* octet 7 */
2013
2014         item =
2015                 proto_tree_add_text(tree,
2016                 tvb, curr_offset, 1,
2017                 "Octet 7");
2018
2019         subtree = proto_item_add_subtree(item, ett_bc_oct_7);
2020                 extended = (oct & 0x80) ? FALSE : TRUE;
2021                 oct = tvb_get_guint8(tvb, curr_offset);
2022                 other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
2023         proto_tree_add_text(subtree,
2024                 tvb, curr_offset, 1,
2025                 "%s :  Extension: %s",
2026                 a_bigbuf,
2027                 extended ? "extended" : "not extended");
2028
2029         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
2030         proto_tree_add_text(subtree,
2031                 tvb, curr_offset, 1,
2032                 "%s :  Layer 2 Identity: %s",
2033                 a_bigbuf,
2034                 ((oct & 0x60) == 0x40) ? "Octet identifier" : "Reserved");
2035
2036         switch (oct & 0x1f)
2037         {
2038         case 0x06: str = "Reserved: was allocated in earlier phases of the protocol"; break;
2039         case 0x08: str = "ISO 6429, codeset 0 (DC1/DC3)"; break;
2040         case 0x09: str = "Reserved: was allocated but never used in earlier phases of the protocol"; break;
2041         case 0x0a: str = "Videotex profile 1"; break;
2042         case 0x0c: str = "COPnoFlCt (Character oriented Protocol with no Flow Control mechanism)"; break;
2043         case 0x0d: str = "Reserved: was allocated in earlier phases of the protocol"; break;
2044         default:
2045                 str = "Reserved";
2046                 break;
2047         }
2048
2049         other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
2050         proto_tree_add_text(subtree,
2051                 tvb, curr_offset, 1,
2052                 "%s :  User information layer 2 protocol: %s",
2053                 a_bigbuf,
2054                 str);
2055         break;
2056         }
2057
2058         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2059
2060         return(curr_offset - offset);
2061 }
2062
2063 /*
2064  * [3] 10.5.4.5a
2065  */
2066 guint8
2067 de_bearer_cap_uplink(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
2068 {
2069         is_uplink = IS_UPLINK_TRUE;
2070         return de_bearer_cap(tvb, tree, offset, len, add_string, string_len);
2071
2072 }
2073
2074
2075 static guint8
2076 de_cc_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2077 {
2078         guint8  oct;
2079         guint32 curr_offset;
2080
2081         curr_offset = offset;
2082
2083         oct = tvb_get_guint8(tvb, curr_offset);
2084
2085         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2086
2087         switch ((oct & 0xf0) >> 4)
2088         {
2089         case 0:
2090         proto_tree_add_text(tree,
2091                 tvb, curr_offset, 1,
2092                 "%s :  Maximum number of supported bearers: 1",
2093                 a_bigbuf);
2094         break;
2095
2096         default:
2097         proto_tree_add_text(tree,
2098                 tvb, curr_offset, 1,
2099                 "%s :  Maximum number of supported bearers: %u",
2100                 a_bigbuf,
2101                 (oct & 0xf0) >> 4);
2102         break;
2103         }
2104
2105         other_decode_bitfield_value(a_bigbuf, oct, 0x0c, 8);
2106         proto_tree_add_text(tree,
2107                 tvb, curr_offset, 1,
2108                 "%s :  Spare",
2109                 a_bigbuf);
2110
2111         other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
2112                 proto_tree_add_text(tree,
2113                 tvb, curr_offset, 1,
2114                 "%s :  PCP: the mobile station %s the Prolonged Clearing Procedure",
2115                 a_bigbuf,
2116                 (oct & 0x02) ? "supports" : "does not support");
2117
2118         other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
2119         proto_tree_add_text(tree,
2120                 tvb, curr_offset, 1,
2121                 "%s :  DTMF: %s",
2122                 a_bigbuf,
2123                 (oct & 0x01) ?
2124                         "the mobile station supports DTMF as specified in subclause 5.5.7 of TS 24.008" :
2125                         "reserved for earlier versions of the protocol");
2126
2127         curr_offset++;
2128
2129         NO_MORE_DATA_CHECK(len);
2130
2131         oct = tvb_get_guint8(tvb, curr_offset);
2132
2133         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2134         proto_tree_add_text(tree,
2135                 tvb, curr_offset, 1,
2136                 "%s :  Spare",
2137                 a_bigbuf);
2138
2139         other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
2140         proto_tree_add_text(tree,
2141                 tvb, curr_offset, 1,
2142                 "%s :  Maximum number of speech bearers: %u",
2143                 a_bigbuf,
2144                 oct & 0x0f);
2145
2146         curr_offset++;
2147
2148         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2149
2150         return(curr_offset - offset);
2151 }
2152
2153 /*
2154  * [3] 10.5.4.6
2155  */
2156 static guint8
2157 de_call_state(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2158 {
2159         guint8  oct;
2160         guint32 curr_offset;
2161         proto_tree      *subtree;
2162         proto_item      *item;
2163         const gchar *str;
2164
2165         curr_offset = offset;
2166
2167         oct = tvb_get_guint8(tvb, curr_offset);
2168
2169         item =
2170         proto_tree_add_text(tree,
2171                 tvb, curr_offset, 1, "%s",
2172                 gsm_dtap_elem_strings[DE_CALL_STATE].strptr);
2173
2174         subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CALL_STATE]);
2175
2176         switch ((oct & 0xc0) >> 6)
2177         {
2178         case 0: str = "Coding as specified in ITU-T Rec. Q.931"; break;
2179         case 1: str = "Reserved for other international standards"; break;
2180         case 2: str = "National standard"; break;
2181         default:
2182                 str = "Standard defined for the GSM PLMNS";
2183                 break;
2184         }
2185
2186         other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
2187         proto_tree_add_text(subtree,
2188                 tvb, curr_offset, 1,
2189                 "%s :  Coding standard: %s",
2190                 a_bigbuf,
2191                 str);
2192
2193         switch (oct & 0x3f)
2194         {
2195         case 0x00: str = "UO - null                                 NO - null"; break;
2196         case 0x02: str = "U0.1- MM connection pending               N0.1- MM connection pending"; break;
2197         case 0x22: str = "U0.2- CC prompt present                   N0.2- CC connection pending"; break;
2198         case 0x23: str = "U0.3- Wait for network information        N0.3- Network answer pending"; break;
2199         case 0x24: str = "U0.4- CC-Establishment present            N0.4- CC-Establishment present"; break;
2200         case 0x25: str = "U0.5- CC-Establishment confirmed          N0.5- CC-Establishment confirmed"; break;
2201         case 0x26: str = "U0.6- Recall present                      N0.6- Recall present"; break;
2202         case 0x01: str = "U1 - call initiated                       N1 - call initiated"; break;
2203         case 0x03: str = "U3 - mobile originating call proceeding   N3 - mobile originating call proceeding"; break;
2204         case 0x04: str = "U4 - call delivered                       N4 - call delivered"; break;
2205         case 0x06: str = "U6 - call present                         N6 - call present"; break;
2206         case 0x07: str = "U7 - call received                        N7 - call received"; break;
2207         case 0x08: str = "U8 - connect request                      N8 - connect request"; break;
2208         case 0x09: str = "U9 - mobile terminating call confirmed    N9 - mobile terminating call confirmed"; break;
2209         case 0x0a: str = "U10- active                               N10- active"; break;
2210         case 0x0b: str = "U11- disconnect request"; break;
2211         case 0x0c: str = "U12- disconnect indication                N12-disconnect indication"; break;
2212         case 0x13: str = "U19- release request                      N19- release request"; break;
2213         case 0x1a: str = "U26- mobile originating modify            N26- mobile originating modify"; break;
2214         case 0x1b: str = "U27- mobile terminating modify            N27- mobile terminating modify"; break;
2215         case 0x1c: str = "                                          N28- connect indication"; break;
2216         default:
2217                 str = "Unknown";
2218                 break;
2219         }
2220
2221         other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
2222         proto_tree_add_text(subtree,
2223                 tvb, curr_offset, 1,
2224                 "%s :  Call state value: %s",
2225                 a_bigbuf,
2226                 str);
2227
2228         curr_offset++;
2229
2230         /* no length check possible */
2231
2232         return(curr_offset - offset);
2233 }
2234
2235 static const true_false_string gsm_a_extension_value = {
2236         "No Extension",
2237         "Extension"
2238 };
2239
2240 const value_string gsm_a_type_of_number_values[] = {
2241         { 0x00, "unknown" },
2242         { 0x01, "International Number" },
2243         { 0x02, "National number" },
2244         { 0x03, "Network Specific Number" },
2245         { 0x04, "Dedicated access, short code" },
2246         { 0x05, "Reserved" },
2247         { 0x06, "Reserved" },
2248         { 0x07, "Reserved for extension" },
2249         { 0, NULL }
2250 };
2251
2252 const value_string gsm_a_numbering_plan_id_values[] = {
2253         { 0x00, "unknown" },
2254         { 0x01, "ISDN/Telephony Numbering (Rec ITU-T E.164)" },
2255         { 0x02, "spare" },
2256         { 0x03, "Data Numbering (ITU-T Rec. X.121)" },
2257         { 0x04, "Telex Numbering (ITU-T Rec. F.69)" },
2258         { 0x08, "National Numbering" },
2259         { 0x09, "Private Numbering" },
2260         { 0x0d, "reserved for CTS (see 3GPP TS 44.056 [91])" },
2261         { 0x0f, "Reserved for extension" },
2262         { 0, NULL }
2263 };
2264
2265 /*
2266  * [3] 10.5.4.7
2267  */
2268 guint8
2269 de_cld_party_bcd_num(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
2270 {
2271         guint8  *poctets;
2272         guint32 curr_offset;
2273
2274         curr_offset = offset;
2275
2276         proto_tree_add_item(tree, hf_gsm_a_extension, tvb, curr_offset, 1, FALSE);
2277         proto_tree_add_item(tree, hf_gsm_a_type_of_number , tvb, curr_offset, 1, FALSE);
2278         proto_tree_add_item(tree, hf_gsm_a_numbering_plan_id , tvb, curr_offset, 1, FALSE);
2279
2280         curr_offset++;
2281
2282         NO_MORE_DATA_CHECK(len);
2283
2284         poctets = tvb_get_ephemeral_string(tvb, curr_offset, len - (curr_offset - offset));
2285
2286         my_dgt_tbcd_unpack(a_bigbuf, poctets, len - (curr_offset - offset),
2287                 &Dgt_mbcd);
2288
2289         proto_tree_add_string_format(tree, hf_gsm_a_cld_party_bcd_num,
2290                 tvb, curr_offset, len - (curr_offset - offset),
2291                 a_bigbuf,
2292                 "BCD Digits: %s",
2293                 a_bigbuf);
2294
2295         if (sccp_assoc && ! sccp_assoc->called_party) {
2296                 sccp_assoc->called_party = se_strdup(a_bigbuf);
2297         }
2298
2299         curr_offset += len - (curr_offset - offset);
2300
2301         if (add_string)
2302                 g_snprintf(add_string, string_len, " - (%s)", a_bigbuf);
2303
2304         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2305
2306         return(curr_offset - offset);
2307 }
2308
2309 /*
2310  * [3] 10.5.4.8
2311  */
2312 static guint8
2313 de_cld_party_sub_addr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2314 {
2315         guint8  oct;
2316         guint32 curr_offset;
2317         const gchar *str;
2318
2319         curr_offset = offset;
2320
2321         oct = tvb_get_guint8(tvb, curr_offset);
2322
2323         proto_tree_add_item(tree, hf_gsm_a_extension, tvb, curr_offset, 1, FALSE);
2324
2325         switch ((oct & 0x70) >> 4)
2326         {
2327         case 0: str = "NSAP (X.213/ISO 8348 AD2)"; break;
2328         case 2: str = "User specified"; break;
2329         default:
2330                 str = "Reserved";
2331                 break;
2332         }
2333
2334         other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
2335         proto_tree_add_text(tree,
2336                 tvb, curr_offset, 1,
2337                 "%s :  Type of subaddress: %s",
2338                 a_bigbuf,
2339                 str);
2340
2341         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
2342         proto_tree_add_text(tree,
2343                 tvb, curr_offset, 1,
2344                 "%s :  Odd/Even indicator: %s",
2345                 a_bigbuf,
2346                 (oct & 0x08) ?
2347                         "odd number of address signals" : "even number of address signals");
2348
2349         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
2350         proto_tree_add_text(tree,
2351                 tvb, curr_offset, 1,
2352                 "%s :  Spare",
2353                 a_bigbuf);
2354
2355         curr_offset++;
2356
2357         NO_MORE_DATA_CHECK(len);
2358
2359         proto_tree_add_text(tree,
2360                 tvb, curr_offset, len - (curr_offset - offset),
2361                 "Subaddress information");
2362
2363         curr_offset += len - (curr_offset - offset);
2364
2365         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2366
2367         return(curr_offset - offset);
2368 }
2369
2370 /* 3GPP TS 24.008
2371  * [3] 10.5.4.9
2372  */
2373 static guint8
2374 de_clg_party_bcd_num(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
2375 {
2376         guint8  oct;
2377         guint8  *poctets;
2378         guint32 curr_offset;
2379         const gchar *str;
2380
2381         curr_offset = offset;
2382
2383         proto_tree_add_item(tree, hf_gsm_a_extension, tvb, curr_offset, 1, FALSE);
2384         proto_tree_add_item(tree, hf_gsm_a_type_of_number , tvb, curr_offset, 1, FALSE);
2385         proto_tree_add_item(tree, hf_gsm_a_numbering_plan_id , tvb, curr_offset, 1, FALSE);
2386
2387         curr_offset++;
2388
2389         oct = tvb_get_guint8(tvb, curr_offset);
2390
2391         proto_tree_add_item(tree, hf_gsm_a_extension, tvb, curr_offset, 1, FALSE);
2392
2393         switch ((oct & 0x60) >> 5)
2394         {
2395         case 0: str = "Presentation allowed"; break;
2396         case 1: str = "Presentation restricted"; break;
2397         case 2: str = "Number not available due to interworking"; break;
2398         default:
2399                 str = "Reserved";
2400                 break;
2401         }
2402
2403         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
2404         proto_tree_add_text(tree,
2405                 tvb, curr_offset, 1,
2406                 "%s :  Presentation indicator: %s",
2407                 a_bigbuf,
2408                 str);
2409
2410         other_decode_bitfield_value(a_bigbuf, oct, 0x1c, 8);
2411         proto_tree_add_text(tree,
2412                 tvb, curr_offset, 1,
2413                 "%s :  Spare",
2414                 a_bigbuf);
2415
2416         switch (oct & 0x03)
2417         {
2418         case 0: str = "User-provided, not screened"; break;
2419         case 1: str = "User-provided, verified and passed"; break;
2420         case 2: str = "User-provided, verified and failed"; break;
2421         default:
2422                 str = "Network provided";
2423                 break;
2424         }
2425
2426         other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
2427         proto_tree_add_text(tree,
2428                 tvb, curr_offset, 1,
2429                 "%s :  Screening indicator: %s",
2430                 a_bigbuf,
2431                 str);
2432
2433         curr_offset++;
2434
2435         NO_MORE_DATA_CHECK(len);
2436
2437         poctets = tvb_get_ephemeral_string(tvb, curr_offset, len - (curr_offset - offset));
2438
2439         my_dgt_tbcd_unpack(a_bigbuf, poctets, len - (curr_offset - offset),
2440                 &Dgt_mbcd);
2441
2442         proto_tree_add_string_format(tree, hf_gsm_a_clg_party_bcd_num,
2443                 tvb, curr_offset, len - (curr_offset - offset),
2444                 a_bigbuf,
2445                 "BCD Digits: %s",
2446                 a_bigbuf);
2447
2448         curr_offset += len - (curr_offset - offset);
2449
2450         if (add_string)
2451         g_snprintf(add_string, string_len, " - (%s)", a_bigbuf);
2452
2453         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2454
2455         return(curr_offset - offset);
2456 }
2457
2458 /*
2459  * [3] 10.5.4.10
2460  */
2461 static guint8
2462 de_clg_party_sub_addr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2463 {
2464         guint8  oct;
2465         guint32 curr_offset;
2466         const gchar *str;
2467
2468         curr_offset = offset;
2469
2470         oct = tvb_get_guint8(tvb, curr_offset);
2471
2472         proto_tree_add_item(tree, hf_gsm_a_extension, tvb, curr_offset, 1, FALSE);
2473
2474         switch ((oct & 0x70) >> 4)
2475         {
2476         case 0: str = "NSAP (X.213/ISO 8348 AD2)"; break;
2477         case 2: str = "User specified"; break;
2478         default:
2479                 str = "Reserved";
2480                 break;
2481         }
2482
2483         other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
2484         proto_tree_add_text(tree,
2485                 tvb, curr_offset, 1,
2486                 "%s :  Type of subaddress: %s",
2487                 a_bigbuf,
2488                 str);
2489
2490         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
2491         proto_tree_add_text(tree,
2492                 tvb, curr_offset, 1,
2493                 "%s :  Odd/Even indicator: %s",
2494                 a_bigbuf,
2495                 (oct & 0x08) ?
2496                         "odd number of address signals" : "even number of address signals");
2497
2498         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
2499         proto_tree_add_text(tree,
2500                 tvb, curr_offset, 1,
2501                 "%s :  Spare",
2502                 a_bigbuf);
2503
2504         curr_offset++;
2505
2506         NO_MORE_DATA_CHECK(len);
2507
2508         proto_tree_add_text(tree,
2509                 tvb, curr_offset, len - (curr_offset - offset),
2510                 "Subaddress information");
2511
2512         curr_offset += len - (curr_offset - offset);
2513
2514         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2515
2516         return(curr_offset - offset);
2517 }
2518
2519 /*
2520  * [3] 10.5.4.11
2521  */
2522 static guint8
2523 de_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
2524 {
2525         guint8  oct;
2526         guint8  cause;
2527         guint32 curr_offset;
2528         const gchar *str;
2529
2530         curr_offset = offset;
2531
2532         oct = tvb_get_guint8(tvb, curr_offset);
2533
2534         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
2535         proto_tree_add_text(tree,
2536                 tvb, curr_offset, 1,
2537                 "%s :  Extension: %s",
2538                 a_bigbuf,
2539                 (oct & 0x80) ? "not extended" : "extended");
2540
2541         switch ((oct & 0x60) >> 5)
2542         {
2543         case 0: str = "Coding as specified in ITU-T Rec. Q.931"; break;
2544         case 1: str = "Reserved for other international standards"; break;
2545         case 2: str = "National standard"; break;
2546         default:
2547                 str = "Standard defined for the GSM PLMNS";
2548                 break;
2549         }
2550
2551         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
2552         proto_tree_add_text(tree,
2553         tvb, curr_offset, 1,
2554         "%s :  Coding standard: %s",
2555         a_bigbuf,
2556         str);
2557
2558         other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
2559         proto_tree_add_text(tree,
2560         tvb, curr_offset, 1,
2561         "%s :  Spare",
2562         a_bigbuf);
2563
2564         switch (oct & 0x0f)
2565         {
2566         case 0: str = "User"; break;
2567         case 1: str = "Private network serving the local user"; break;
2568         case 2: str = "Public network serving the local user"; break;
2569         case 3: str = "Transit network"; break;
2570         case 4: str = "Public network serving the remote user"; break;
2571         case 5: str = "Private network serving the remote user"; break;
2572         case 7: str = "International network"; break;
2573         case 10: str = "Network beyond interworking point"; break;
2574         default:
2575                 str = "Reserved";
2576                 break;
2577         }
2578
2579         other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
2580         proto_tree_add_text(tree,
2581                 tvb, curr_offset, 1,
2582                 "%s :  Location: %s",
2583                 a_bigbuf,
2584                 str);
2585
2586         curr_offset++;
2587
2588         oct = tvb_get_guint8(tvb, curr_offset);
2589
2590         if (!(oct & 0x80))
2591         {
2592         proto_tree_add_item(tree, hf_gsm_a_extension, tvb, curr_offset, 1, FALSE);
2593
2594         other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
2595         proto_tree_add_text(tree,
2596                 tvb, curr_offset, 1,
2597                 "%s :  Recommendation",
2598                 a_bigbuf);
2599
2600         curr_offset++;
2601
2602         oct = tvb_get_guint8(tvb, curr_offset);
2603         }
2604
2605         proto_tree_add_item(tree, hf_gsm_a_extension, tvb, curr_offset, 1, FALSE);
2606
2607         cause = oct & 0x7f;
2608         switch (cause)
2609         {
2610         case 1: str = "Unassigned (unallocated) number"; break;
2611         case 3: str = "No route to destination"; break;
2612         case 6: str = "Channel unacceptable"; break;
2613         case 8: str = "Operator determined barring"; break;
2614         case 16: str = "Normal call clearing"; break;
2615         case 17: str = "User busy"; break;
2616         case 18: str = "No user responding"; break;
2617         case 19: str = "User alerting, no answer"; break;
2618         case 21: str = "Call rejected"; break;
2619         case 22: str = "Number changed"; break;
2620         case 25: str = "Pre-emption"; break;
2621         case 26: str = "Non selected user clearing"; break;
2622         case 27: str = "Destination out of order"; break;
2623         case 28: str = "Invalid number format (incomplete number)"; break;
2624         case 29: str = "Facility rejected"; break;
2625         case 30: str = "Response to STATUS ENQUIRY"; break;
2626         case 31: str = "Normal, unspecified"; break;
2627         case 34: str = "No circuit/channel available"; break;
2628         case 38: str = "Network out of order"; break;
2629         case 41: str = "Temporary failure"; break;
2630         case 42: str = "Switching equipment congestion"; break;
2631         case 43: str = "Access information discarded"; break;
2632         case 44: str = "requested circuit/channel not available"; break;
2633         case 47: str = "Resources unavailable, unspecified"; break;
2634         case 49: str = "Quality of service unavailable"; break;
2635         case 50: str = "Requested facility not subscribed"; break;
2636         case 55: str = "Incoming calls barred within the CUG"; break;
2637         case 57: str = "Bearer capability not authorized"; break;
2638         case 58: str = "Bearer capability not presently available"; break;
2639         case 63: str = "Service or option not available, unspecified"; break;
2640         case 65: str = "Bearer service not implemented"; break;
2641         case 68: str = "ACM equal to or greater than ACMmax"; break;
2642         case 69: str = "Requested facility not implemented"; break;
2643         case 70: str = "Only restricted digital information bearer capability is available"; break;
2644         case 79: str = "Service or option not implemented, unspecified"; break;
2645         case 81: str = "Invalid transaction identifier value"; break;
2646         case 87: str = "User not member of CUG"; break;
2647         case 88: str = "Incompatible destination"; break;
2648         case 91: str = "Invalid transit network selection"; break;
2649         case 95: str = "Semantically incorrect message"; break;
2650         case 96: str = "Invalid mandatory information"; break;
2651         case 97: str = "Message type non-existent or not implemented"; break;
2652         case 98: str = "Message type not compatible with protocol state"; break;
2653         case 99: str = "Information element non-existent or not implemented"; break;
2654         case 100: str = "Conditional IE error"; break;
2655         case 101: str = "Message not compatible with protocol state"; break;
2656         case 102: str = "Recovery on timer expiry"; break;
2657         case 111: str = "Protocol error, unspecified"; break;
2658         case 127: str = "Interworking, unspecified"; break;
2659         default:
2660                 if (cause <= 31) { str = "Treat as Normal, unspecified"; }
2661                 else if ((cause >= 32) && (cause <= 47)) { str = "Treat as Resources unavailable, unspecified"; }
2662                 else if ((cause >= 48) && (cause <= 63)) { str = "Treat as Service or option not available, unspecified"; }
2663                 else if ((cause >= 64) && (cause <= 79)) { str = "Treat as Service or option not implemented, unspecified"; }
2664                 else if ((cause >= 80) && (cause <= 95)) { str = "Treat as Semantically incorrect message"; }
2665                 else if ((cause >= 96) && (cause <= 111)) { str = "Treat as Protocol error, unspecified"; }
2666                 else if ((cause >= 112) && (cause <= 127)) { str = "Treat as Interworking, unspecified"; }
2667                 break;
2668         }
2669
2670         other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
2671         proto_tree_add_uint_format(tree, hf_gsm_a_dtap_cause,
2672                 tvb, curr_offset, 1, cause,
2673                 "%s :  Cause: (%u) %s",
2674                 a_bigbuf,
2675                 cause,
2676                 str);
2677
2678         curr_offset++;
2679
2680         if (add_string)
2681                 g_snprintf(add_string, string_len, " - (%u) %s", cause, str);
2682
2683         NO_MORE_DATA_CHECK(len);
2684
2685         proto_tree_add_text(tree,
2686                 tvb, curr_offset, len - (curr_offset - offset),
2687                 "Diagnostics");
2688
2689         curr_offset += len - (curr_offset - offset);
2690
2691         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2692
2693         return(curr_offset - offset);
2694 }
2695
2696 /*
2697  * 10.5.4.18 Low layer compatibility
2698  */
2699 static guint8
2700 de_llc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2701 {
2702         guint32 curr_offset;
2703
2704         curr_offset = offset;
2705
2706         dissect_q931_bearer_capability_ie(tvb, offset, len, tree);
2707
2708         curr_offset = curr_offset + len;
2709         return(curr_offset - offset);
2710 }
2711
2712 /*
2713  * [6] 3.6
2714  */
2715
2716
2717 static guint8
2718 de_facility(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint fac_len, gchar *add_string _U_, int string_len _U_)
2719 {
2720         guint   saved_offset;
2721         gint8 class;
2722         gboolean pc;
2723         gboolean ind = FALSE;
2724         guint32 component_len = 0;
2725         guint32 header_end_offset;
2726         guint32 header_len;
2727         asn1_ctx_t asn1_ctx;
2728         tvbuff_t *SS_tvb = NULL;
2729         void *save_private_data;
2730         static gint comp_type_tag;
2731
2732         asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, gsm_a_dtap_pinfo);
2733
2734         save_private_data= gsm_a_dtap_pinfo->private_data;
2735         saved_offset = offset;
2736         gsm_a_dtap_pinfo->private_data = NULL;
2737         while ( fac_len > (offset - saved_offset)){
2738
2739                 /* Get the length of the component there can be more than one component in a facility message */
2740
2741                 header_end_offset = get_ber_identifier(tvb, offset, &class, &pc, &comp_type_tag);
2742                 header_end_offset = get_ber_length(tvb, header_end_offset, &component_len, &ind);
2743                 if (ind){
2744                         proto_tree_add_text(tree, tvb, offset+1, 1,
2745                                 "Indefinte length, ignoring component");
2746                         return (fac_len);
2747                 }
2748                 header_len = header_end_offset - offset;
2749                 component_len = header_len + component_len;
2750                 /*
2751                 dissect_ROS_Component(FALSE, tvb, offset, &asn1_ctx, tree, hf_ROS_component);
2752                 TODO Call gsm map here
2753                 */
2754                 SS_tvb = tvb_new_subset(tvb, offset, component_len, component_len);
2755                 call_dissector(gsm_map_handle, SS_tvb, gsm_a_dtap_pinfo, tree);
2756                 offset = offset + component_len;
2757         }
2758         gsm_a_dtap_pinfo->private_data = save_private_data;
2759         return(fac_len);
2760 }
2761
2762 /*
2763  * [3] 10.5.4.17
2764  */
2765 static guint8
2766 de_keypad_facility(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string, int string_len)
2767 {
2768         guint8  oct;
2769         guint32 curr_offset;
2770
2771         curr_offset = offset;
2772
2773         oct = tvb_get_guint8(tvb, curr_offset);
2774
2775         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
2776         proto_tree_add_text(tree,
2777                 tvb, curr_offset, 1,
2778                 "%s :  Spare",
2779                 a_bigbuf);
2780
2781         other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
2782         proto_tree_add_text(tree,
2783                 tvb, curr_offset, 1,
2784                 "%s :  Keypad information: %c",
2785                 a_bigbuf,
2786                 oct & 0x7f);
2787
2788         curr_offset++;
2789
2790         if (add_string)
2791                 g_snprintf(add_string, string_len, " - %c", oct & 0x7f);
2792
2793         /* no length check possible */
2794
2795         return(curr_offset - offset);
2796 }
2797
2798 /*
2799  * [3] 10.5.4.21
2800  */
2801 static guint8
2802 de_prog_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string, int string_len)
2803 {
2804         guint8  oct;
2805         guint32 curr_offset;
2806         const gchar *str;
2807
2808         curr_offset = offset;
2809
2810         oct = tvb_get_guint8(tvb, curr_offset);
2811
2812         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
2813         proto_tree_add_text(tree,
2814                 tvb, curr_offset, 1,
2815                 "%s :  Extension: %s",
2816                 a_bigbuf,
2817                 (oct & 0x80) ? "extended" : "not extended");
2818
2819         switch ((oct & 0x60) >> 5)
2820         {
2821         case 0: str = "Coding as specified in ITU-T Rec. Q.931"; break;
2822         case 1: str = "Reserved for other international standards"; break;
2823         case 2: str = "National standard"; break;
2824         default:
2825                 str = "Standard defined for the GSM PLMNS";
2826                 break;
2827         }
2828
2829         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
2830         proto_tree_add_text(tree,
2831                 tvb, curr_offset, 1,
2832                 "%s :  Coding standard: %s",
2833                 a_bigbuf,
2834                 str);
2835
2836         other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
2837         proto_tree_add_text(tree,
2838                 tvb, curr_offset, 1,
2839                 "%s :  Spare",
2840                 a_bigbuf);
2841
2842         switch (oct & 0x0f)
2843         {
2844         case 0: str = "User"; break;
2845         case 1: str = "Private network serving the local user"; break;
2846         case 2: str = "Public network serving the local user"; break;
2847         case 4: str = "Public network serving the remote user"; break;
2848         case 5: str = "Private network serving the remote user"; break;
2849         case 10: str = "Network beyond interworking point"; break;
2850         default:
2851                 str = "Reserved";
2852                 break;
2853         }
2854
2855         other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
2856         proto_tree_add_text(tree,
2857                 tvb, curr_offset, 1,
2858                 "%s :  Location: %s",
2859                 a_bigbuf,
2860                 str);
2861
2862         curr_offset++;
2863
2864         oct = tvb_get_guint8(tvb, curr_offset);
2865
2866         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
2867         proto_tree_add_text(tree,
2868                 tvb, curr_offset, 1,
2869                 "%s :  Extension: %s",
2870                 a_bigbuf,
2871                 (oct & 0x80) ? "extended" : "not extended");
2872
2873         switch (oct & 0x7f)
2874         {
2875         case 1: str = "Call is not end-to-end PLMN/ISDN, further call progress information may be available in-band"; break;
2876         case 2: str = "Destination address in non-PLMN/ISDN"; break;
2877         case 3: str = "Origination address in non-PLMN/ISDN"; break;
2878         case 4: str = "Call has returned to the PLMN/ISDN"; break;
2879         case 8: str = "In-band information or appropriate pattern now available"; break;
2880         case 32: str = "Call is end-to-end PLMN/ISDN"; break;
2881         case 64: str = "Queueing"; break;
2882         default:
2883                 str = "Unspecific";
2884                 break;
2885         }
2886
2887         other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
2888         proto_tree_add_text(tree,
2889                 tvb, curr_offset, 1,
2890                 "%s :  Progress Description: %s (%d)",
2891                 a_bigbuf,
2892                 str,
2893                 oct & 0x7f);
2894
2895         if (add_string)
2896                 g_snprintf(add_string, string_len, " - %d", oct & 0x7f);
2897
2898         curr_offset++;
2899
2900         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2901
2902         return(curr_offset - offset);
2903 }
2904
2905 /*
2906  * [3] 10.5.4.22
2907  */
2908 static guint8
2909 de_repeat_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2910 {
2911         guint8  oct;
2912         guint32 curr_offset;
2913         const gchar *str;
2914
2915         curr_offset = offset;
2916
2917         oct = tvb_get_guint8(tvb, curr_offset);
2918
2919         switch (oct & 0x0f)
2920         {
2921         case 1: str = "Circular for successive selection 'mode 1 alternate mode 2'"; break;
2922         case 2: str = "Support of fallback mode 1 preferred, mode 2 selected if setup of mode 1 fails"; break;
2923         case 3: str = "Reserved: was allocated in earlier phases of the protocol"; break;
2924         default:
2925                 str = "Reserved";
2926                 break;
2927         }
2928
2929         other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
2930         proto_tree_add_text(tree,
2931                 tvb, curr_offset, 1,
2932                 "%s :  %s",
2933                 a_bigbuf,
2934                 str);
2935
2936         curr_offset++;
2937
2938         /* no length check possible */
2939
2940         return(curr_offset - offset);
2941 }
2942
2943 /*
2944  * [6] 3.7.2
2945  */
2946 static guint8
2947 de_ss_ver_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2948 {
2949         guint8  oct;
2950         guint32 curr_offset;
2951         const gchar *str;
2952
2953         curr_offset = offset;
2954
2955         oct = tvb_get_guint8(tvb, curr_offset);
2956
2957         switch (oct)
2958         {
2959         case 0: str = "Phase 2 service, ellipsis notation, and phase 2 error handling is supported"; break;
2960         case 1: str = "SS-Protocol version 3 is supported, and phase 2 error handling is supported"; break;
2961         default:
2962                 str = "Reserved";
2963                 break;
2964         }
2965
2966         proto_tree_add_text(tree,
2967                 tvb, curr_offset, 1,
2968                 "%s",
2969                 str);
2970
2971         curr_offset++;
2972
2973         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2974
2975         return(curr_offset - offset);
2976 }
2977
2978 /*
2979  * [5] 8.1.4.1 3GPP TS 24.011 version 6.1.0 Release 6
2980  */
2981 static guint8
2982 de_cp_user_data(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2983 {
2984         guint32 curr_offset;
2985         tvbuff_t        *rp_tvb;
2986
2987         curr_offset = offset;
2988
2989         proto_tree_add_text(tree, tvb, curr_offset, len,
2990                 "RPDU (not displayed)");
2991
2992         /*
2993          * dissect the embedded RP message
2994          */
2995         rp_tvb = tvb_new_subset(tvb, curr_offset, len, len);
2996
2997         call_dissector(rp_handle, rp_tvb, gsm_a_dtap_pinfo, g_tree);
2998
2999         curr_offset += len;
3000
3001         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3002
3003         return(curr_offset - offset);
3004 }
3005
3006 /*
3007  * [5] 8.1.4.2
3008  */
3009 static guint8
3010 de_cp_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string, int string_len)
3011 {
3012         guint8  oct;
3013         guint32 curr_offset;
3014         const gchar *str;
3015
3016         curr_offset = offset;
3017
3018         oct = tvb_get_guint8(tvb, curr_offset);
3019
3020         switch (oct)
3021         {
3022         case 17: str = "Network failure"; break;
3023         case 22: str = "Congestion"; break;
3024         case 81: str = "Invalid Transaction Identifier value"; break;
3025         case 95: str = "Semantically incorrect message"; break;
3026         case 96: str = "Invalid mandatory information"; break;
3027         case 97: str = "Message type non-existent or not implemented"; break;
3028         case 98: str = "Message not compatible with the short message protocol state"; break;
3029         case 99: str = "Information element non-existent or not implemented"; break;
3030         case 111: str = "Protocol error, unspecified"; break;
3031         default:
3032                 str = "Reserved, treat as Protocol error, unspecified";
3033                 break;
3034         }
3035
3036         proto_tree_add_text(tree,
3037                 tvb, curr_offset, 1,
3038                 "Cause: (%u) %s",
3039                 oct,
3040                 str);
3041
3042         curr_offset++;
3043
3044         if (add_string)
3045                 g_snprintf(add_string, string_len, " - (%u) %s", oct, str);
3046
3047         /* no length check possible */
3048
3049         return(curr_offset - offset);
3050 }
3051
3052 static guint8
3053 de_tp_sub_channel(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3054 {
3055         guint32 curr_offset;
3056         guchar  oct;
3057         const gchar     *str;
3058
3059         curr_offset = offset;
3060
3061         oct = tvb_get_guint8(tvb, curr_offset) & 0x3f;
3062         if ((oct & 0x38) == 0x38)
3063                 str = "I";
3064         else if ((oct & 0x38) == 0x18)
3065                 str = "F";
3066         else if ((oct & 0x38) == 0x10)
3067                 str = "E";
3068         else if ((oct & 0x38) == 0x08)
3069                 str = "D";
3070         else if ((oct & 0x3c) == 0x04)
3071                 str = "C";
3072         else if ((oct & 0x3e) == 0x02)
3073                 str = "B";
3074         else if ((oct & 0x3e) == 0x00)
3075                 str = "A";
3076         else
3077                 str = "unknown";
3078
3079         proto_tree_add_text(tree,
3080                 tvb, curr_offset, 1,
3081                 "Test Loop %s",str);
3082
3083         if (oct & 0x01)
3084                 proto_tree_add_text(tree,
3085                         tvb, curr_offset, 1,
3086                         "Only one TCH active or sub-channel 0 of two half rate channels is to be looped");
3087         else
3088                 proto_tree_add_text(tree,
3089                         tvb, curr_offset, 1,
3090                         "Sub-channel 1 of two half rate channels is to be looped");
3091
3092         curr_offset+= 1;
3093
3094         return(curr_offset - offset);
3095 }
3096
3097 static guint8
3098 de_tp_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3099 {
3100         guint32 curr_offset;
3101         guchar  oct;
3102
3103         curr_offset = offset;
3104
3105         oct = tvb_get_guint8(tvb, curr_offset);
3106
3107         if ((oct & 0xF0) == 0x80)
3108                 proto_tree_add_text(tree,tvb, curr_offset, 1, "Acknowledgment element: %d",oct&0x01);
3109         else
3110                 proto_tree_add_text(tree,tvb, curr_offset, 1, "No acknowledgment element present");
3111
3112         curr_offset+= 1;
3113
3114         return(curr_offset - offset);
3115 }
3116
3117 static guint8
3118 de_tp_loop_type(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3119 {
3120         guint32 curr_offset;
3121         guchar  oct;
3122
3123         curr_offset = offset;
3124
3125         oct = tvb_get_guint8(tvb, curr_offset);
3126
3127         switch (oct & 0x03)
3128         {
3129                 case 0x00:
3130                         proto_tree_add_text(tree, tvb, curr_offset, 1, "Channel coding not needed. The Burst-by-Burst loop is activated, type G");
3131                         break;
3132                 case 0x01:
3133                         proto_tree_add_text(tree, tvb, curr_offset, 1, "Channel coding needed. Frame erasure is to be signalled, type H");
3134                         break;
3135                 default:
3136                         proto_tree_add_text(tree, tvb, curr_offset, 1, "Channel coding reserved (%d)",oct & 0x03);
3137                         break;
3138         }
3139
3140         switch (oct & 0x1c)
3141         {
3142                 case 0x00:
3143                         proto_tree_add_text(tree, tvb, curr_offset, 1, "Multi-slot mechanism 1");
3144                         proto_tree_add_text(tree, tvb, curr_offset, 1, "Timeslot number %d",(oct & 0xe0)>>5);
3145                         break;
3146                 case 0x04:
3147                         proto_tree_add_text(tree, tvb, curr_offset, 1, "Multi-slot mechanism 2");
3148                         break;
3149                 default:
3150                         proto_tree_add_text(tree, tvb, curr_offset, 1, "Loop mechanism reserved (%d)",(oct & 0x1c)>>2);
3151                         break;
3152         }
3153
3154         curr_offset+= 1;
3155
3156         return(curr_offset - offset);
3157 }
3158
3159 static guint8
3160 de_tp_loop_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3161 {
3162         guint32 curr_offset;
3163         guchar  oct;
3164
3165         curr_offset = offset;
3166
3167         oct = tvb_get_guint8(tvb, curr_offset);
3168
3169         switch (oct & 0x30)
3170         {
3171                 case 0x00:
3172                         proto_tree_add_text(tree, tvb, curr_offset, 1, "Channel coding not needed. The Burst-by-Burst loop is activated, type G");
3173                         break;
3174                 case 0x10:
3175                         proto_tree_add_text(tree, tvb, curr_offset, 1, "Channel coding needed. Frame erasure is to be signalled, type H");
3176                         break;
3177                 default:
3178                         proto_tree_add_text(tree, tvb, curr_offset, 1, "Channel coding reserved (%d)",(oct & 0x30)>>4);
3179                         break;
3180         }
3181
3182         switch (oct & 0x0e)
3183         {
3184                 case 0x00:
3185                         proto_tree_add_text(tree, tvb, curr_offset, 1, "Multi-slot mechanism 1");
3186                         break;
3187                 case 0x02:
3188                         proto_tree_add_text(tree, tvb, curr_offset, 1, "Multi-slot mechanism 2");
3189                         break;
3190                 default:
3191                         proto_tree_add_text(tree, tvb, curr_offset, 1, "Loop mechanism reserved (%d)",(oct & 0x0e)>>1);
3192                         break;
3193         }
3194
3195         if (oct & 0x01)
3196                 proto_tree_add_text(tree, tvb, curr_offset, 1, "Multi-slot TCH loop was not closed due to error");
3197         else
3198                 proto_tree_add_text(tree, tvb, curr_offset, 1, "Multi-slot TCH loop was closed successfully");
3199
3200         curr_offset+= 1;
3201
3202         return(curr_offset - offset);
3203 }
3204
3205 static guint8
3206 de_tp_tested_device(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3207 {
3208         guint32 curr_offset;
3209         guchar  oct;
3210
3211         curr_offset = offset;
3212
3213         oct = tvb_get_guint8(tvb, curr_offset);
3214
3215         switch (oct)
3216         {
3217                 case 0:
3218                         proto_tree_add_text(tree, tvb, curr_offset, 1, "Normal operation (no tested device via DAI)");
3219                         break;
3220                 case 1:
3221                         proto_tree_add_text(tree, tvb, curr_offset, 1, "Test of speech decoder / DTX functions (downlink)");
3222                         break;
3223                 case 2:
3224                         proto_tree_add_text(tree, tvb, curr_offset, 1, "Test of speech encoder / DTX functions (uplink)");
3225                         break;
3226                 case 4:
3227                         proto_tree_add_text(tree, tvb, curr_offset, 1, "Test of acoustic devices and A/D & D/A");
3228                         break;
3229                 default:
3230                         proto_tree_add_text(tree, tvb, curr_offset, 1, "Tested device reserved (%d)",oct);
3231                         break;
3232         }
3233
3234         curr_offset+= 1;
3235
3236         return(curr_offset - offset);
3237 }
3238
3239 static guint8
3240 de_tp_pdu_description(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3241 {
3242         guint32 curr_offset;
3243         guint16 value;
3244
3245         curr_offset = offset;
3246
3247         value = tvb_get_ntohs(tvb, curr_offset);
3248         curr_offset += 2;
3249
3250         if (value & 0x8000)
3251         {
3252                 if ((value & 0xfff) == 0)
3253                         proto_tree_add_text(tree, tvb, curr_offset, 1, "Infinite number of PDUs to be transmitted in the TBF");
3254                 else
3255                         proto_tree_add_text(tree, tvb, curr_offset, 1, "%d PDUs to be transmitted in the TBF",value & 0xfff);
3256         }
3257         else
3258                 proto_tree_add_text(tree, tvb, curr_offset, 1, "PDU description reserved");
3259
3260         return(curr_offset - offset);
3261 }
3262
3263 static guint8
3264 de_tp_mode_flag(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3265 {
3266         guint32 curr_offset;
3267         guchar  oct;
3268
3269         curr_offset = offset;
3270
3271         oct = tvb_get_guint8(tvb, curr_offset);
3272
3273         if (oct & 0x01)
3274                 proto_tree_add_text(tree, tvb, curr_offset, 1, "MS shall select the loop back option");
3275         else
3276                 proto_tree_add_text(tree, tvb, curr_offset, 1, "MS shall itself generate the pseudorandom data");
3277
3278         proto_tree_add_text(tree, tvb, curr_offset, 1, "Downlink Timeslot Offset: timeslot number %d",(oct & 0x0e)>>1);
3279
3280         curr_offset+= 1;
3281
3282         return(curr_offset - offset);
3283 }
3284
3285 static guint8
3286 de_tp_egprs_mode_flag(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3287 {
3288         guint32 curr_offset;
3289         guchar  oct;
3290
3291         curr_offset = offset;
3292
3293         oct = tvb_get_guint8(tvb, curr_offset);
3294
3295         if (oct & 0x01)
3296                 proto_tree_add_text(tree, tvb, curr_offset, 1, "MS loops back blocks on the uplink using GMSK modulation only");
3297         else
3298                 proto_tree_add_text(tree, tvb, curr_offset, 1, "MS loops back blocks on the uplink using either GMSK or 8-PSK modulation following the detected received modulation");
3299
3300         proto_tree_add_text(tree, tvb, curr_offset, 1, "Downlink Timeslot Offset: timeslot number %d",(oct & 0x0e)>>1);
3301
3302         curr_offset+= 1;
3303
3304         return(curr_offset - offset);
3305 }
3306
3307 static guint8
3308 de_tp_ue_test_loop_mode(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3309 {
3310         guint32 curr_offset;
3311         guchar  oct;
3312         guint8  lb_setup_length,i,j;
3313         guint16 value;
3314
3315         curr_offset = offset;
3316
3317         oct = tvb_get_guint8(tvb, curr_offset);
3318         curr_offset+= 1;
3319
3320         switch (oct & 0x03)
3321         {
3322                 case 0:
3323                 {
3324                         proto_tree_add_text(tree, tvb, curr_offset, 1, "UE test loop mode 1 loop back (loopback of RLC SDUs or PDCP SDUs)");
3325                         lb_setup_length = tvb_get_guint8(tvb, curr_offset);
3326                         curr_offset += 1;
3327                         for (i=0,j=0; (i<lb_setup_length) && (j<4); i+=3,j++)
3328                         {
3329                                 proto_tree_add_text(tree, tvb, curr_offset, 1, "LB setup RB IE %d",j+1);
3330                                 value = tvb_get_ntohs(tvb, curr_offset);
3331                                 curr_offset += 2;
3332                                 proto_tree_add_text(tree, tvb, curr_offset, 1, "Uplink RLC SDU size is %d bits",value);
3333                                 oct = tvb_get_guint8(tvb, curr_offset);
3334                                 curr_offset+= 1;
3335                                 proto_tree_add_text(tree, tvb, curr_offset, 1, "Radio Bearer %d",oct & 0x1f);
3336                         }
3337                         break;
3338                 }
3339                 case 1:
3340                         proto_tree_add_text(tree, tvb, curr_offset, 1, "UE test loop mode 2 loop back (loopback of transport block data and CRC bits)");
3341                         break;
3342                 case 2:
3343                         proto_tree_add_text(tree, tvb, curr_offset, 1, "UE test loop mode 3 RLC SDU counting (counting of received RLC SDUs)");
3344                         oct = tvb_get_guint8(tvb, curr_offset);
3345                         curr_offset+= 1;
3346                         proto_tree_add_text(tree, tvb, curr_offset, 1, "MBMS short transmission identity %d",(oct & 0x1f)+1);
3347                         break;
3348                 default:
3349                         proto_tree_add_text(tree, tvb, curr_offset, 1, "UE test loop mode reserved (%d)",oct & 0x03);
3350                         break;
3351         }
3352
3353         return(curr_offset - offset);
3354 }
3355
3356 static guint8
3357 de_tp_ue_positioning_technology(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3358 {
3359         guint32 curr_offset;
3360         guchar  oct;
3361
3362         curr_offset = offset;
3363
3364         oct = tvb_get_guint8(tvb, curr_offset);
3365
3366         switch (oct)
3367         {
3368                 case 0:
3369                         proto_tree_add_text(tree, tvb, curr_offset, 1, "AGPS");
3370                         break;
3371                 default:
3372                         proto_tree_add_text(tree, tvb, curr_offset, 1, "UE positioning technology reserved (%d)",oct);
3373                         break;
3374         }
3375
3376         curr_offset+= 1;
3377
3378         return(curr_offset - offset);
3379 }
3380
3381 static guint8
3382 de_tp_rlc_sdu_counter_value(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3383 {
3384         guint32 curr_offset;
3385         guint32 value;
3386
3387         curr_offset = offset;
3388
3389         value = tvb_get_ntohl(tvb, curr_offset);
3390         curr_offset+= 4;
3391
3392         proto_tree_add_text(tree, tvb, curr_offset, 1, "UE received RLC SDU counter value %d",value);
3393
3394         return(curr_offset - offset);
3395 }
3396
3397 guint8 (*dtap_elem_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len) = {
3398         /* Mobility Management Information Elements 10.5.3 */
3399         de_auth_param_rand,     /* Authentication Parameter RAND */
3400         de_auth_param_autn,     /* Authentication Parameter AUTN (UMTS authentication challenge only) */
3401         de_auth_resp_param,     /* Authentication Response Parameter */
3402         de_auth_resp_param_ext, /* Authentication Response Parameter (extension) (UMTS authentication challenge only) */
3403         de_auth_fail_param,     /* Authentication Failure Parameter (UMTS authentication challenge only) */
3404         NULL /* handled inline */,      /* CM Service Type */
3405         NULL /* handled inline */,      /* Identity Type */
3406         NULL /* handled inline */,      /* Location Updating Type */
3407         de_network_name,        /* Network Name */
3408         de_rej_cause,   /* Reject Cause */
3409         NULL /* no associated data */,  /* Follow-on Proceed */
3410         de_time_zone,   /* Time Zone */
3411         de_time_zone_time,      /* Time Zone and Time */
3412         NULL /* no associated data */,  /* CTS Permission */
3413         de_lsa_id,      /* LSA Identifier */
3414         de_day_saving_time,     /* Daylight Saving Time */
3415         NULL, /* Emergency Number List */
3416         /* Call Control Information Elements 10.5.4 */
3417         de_aux_states,  /* Auxiliary States */
3418         de_bearer_cap,  /* Bearer Capability */
3419         de_cc_cap,      /* Call Control Capabilities */
3420         de_call_state,  /* Call State */
3421         de_cld_party_bcd_num,   /* Called Party BCD Number */
3422         de_cld_party_sub_addr,  /* Called Party Subaddress */
3423         de_clg_party_bcd_num,   /* Calling Party BCD Number */
3424         de_clg_party_sub_addr,  /* Calling Party Subaddress */
3425         de_cause,       /* Cause */
3426         NULL /* no associated data */,  /* CLIR Suppression */
3427         NULL /* no associated data */,  /* CLIR Invocation */
3428         NULL /* handled inline */,      /* Congestion Level */
3429         NULL,   /* Connected Number */
3430         NULL,   /* Connected Subaddress */
3431         de_facility,    /* Facility */
3432         NULL,   /* High Layer Compatibility */
3433         de_keypad_facility,     /* Keypad Facility */
3434         de_llc,                                                 /* 10.5.4.18 Low layer compatibility */
3435         NULL,   /* More Data */
3436         NULL,   /* Notification Indicator */
3437         de_prog_ind,    /* Progress Indicator */
3438         NULL,   /* Recall type $(CCBS)$ */
3439         NULL,   /* Redirecting Party BCD Number */
3440         NULL,   /* Redirecting Party Subaddress */
3441         de_repeat_ind,  /* Repeat Indicator */
3442         NULL /* no associated data */,  /* Reverse Call Setup Direction */
3443         NULL,   /* SETUP Container $(CCBS)$ */
3444         NULL,   /* Signal */
3445         de_ss_ver_ind,  /* SS Version Indicator */
3446         NULL,   /* User-user */
3447         NULL,   /* Alerting Pattern $(NIA)$ */
3448         NULL,   /* Allowed Actions $(CCBS)$ */
3449         NULL,   /* Stream Identifier */
3450         NULL,   /* Network Call Control Capabilities */
3451         NULL,   /* Cause of No CLI */
3452         NULL,   /* Immediate Modification Indicator */
3453         NULL,   /* Supported Codec List */
3454         NULL,   /* Service Category */
3455         /* Short Message Service Information Elements [5] 8.1.4 */
3456         de_cp_user_data,        /* CP-User Data */
3457         de_cp_cause,    /* CP-Cause */
3458         /* Tests procedures information elements 3GPP TS 44.014 6.4.0 and 3GPP TS 34.109 6.4.0 */
3459         de_tp_sub_channel,      /* Close TCH Loop Cmd Sub-channel */
3460         de_tp_ack,      /* Open Loop Cmd Ack */
3461         de_tp_loop_type,                        /* Close Multi-slot Loop Cmd Loop type */
3462         de_tp_loop_ack,                 /* Close Multi-slot Loop Ack Result */
3463         de_tp_tested_device,                    /* Test Interface Tested device */
3464         de_tp_pdu_description,                  /* GPRS Test Mode Cmd PDU description */
3465         de_tp_mode_flag,                        /* GPRS Test Mode Cmd Mode flag */
3466         de_tp_egprs_mode_flag,                  /* EGPRS Start Radio Block Loopback Cmd Mode flag */
3467         de_tp_ue_test_loop_mode,                        /* Close UE Test Loop Mode */
3468         de_tp_ue_positioning_technology,                        /* UE Positioning Technology */
3469         de_tp_rlc_sdu_counter_value,                    /* RLC SDU Counter Value */
3470         NULL,   /* NONE */
3471 };
3472
3473 /* MESSAGE FUNCTIONS */
3474
3475 /*
3476  * [4] 9.2.2
3477  */
3478 static void
3479 dtap_mm_auth_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
3480 {
3481         guint32 curr_offset;
3482         guint32 consumed;
3483         guint   curr_len;
3484         guint8  oct;
3485         proto_tree      *subtree;
3486         proto_item      *item;
3487
3488         curr_offset = offset;
3489         curr_len = len;
3490
3491         is_uplink = IS_UPLINK_FALSE;
3492
3493         /*
3494          * special dissection for Cipher Key Sequence Number
3495          */
3496         oct = tvb_get_guint8(tvb, curr_offset);
3497
3498         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
3499         proto_tree_add_text(tree,
3500                 tvb, curr_offset, 1,
3501                 "%s :  Spare",
3502                 a_bigbuf);
3503
3504         item =
3505         proto_tree_add_text(tree,
3506                 tvb, curr_offset, 1, "%s",
3507                 gsm_common_elem_strings[DE_CIPH_KEY_SEQ_NUM].strptr);
3508
3509         subtree = proto_item_add_subtree(item, ett_gsm_common_elem[DE_CIPH_KEY_SEQ_NUM]);
3510
3511         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
3512         proto_tree_add_text(subtree,
3513                 tvb, curr_offset, 1,
3514                 "%s :  Spare",
3515                 a_bigbuf);
3516
3517         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
3518
3519         switch (oct & 0x07)
3520         {
3521         case 0x07:
3522                 proto_tree_add_text(subtree,
3523                         tvb, curr_offset, 1,
3524                         "%s :  Ciphering Key Sequence Number: No key is available",
3525                         a_bigbuf);
3526                 break;
3527
3528         default:
3529                 proto_tree_add_text(subtree,
3530                         tvb, curr_offset, 1,
3531                         "%s :  Ciphering Key Sequence Number: %u",
3532                         a_bigbuf,
3533                         oct & 0x07);
3534                 break;
3535         }
3536
3537         curr_offset++;
3538         curr_len--;
3539
3540         if (curr_len <= 0) return;
3541
3542         ELEM_MAND_V(GSM_A_PDU_TYPE_DTAP, DE_AUTH_PARAM_RAND);
3543
3544         ELEM_OPT_TLV(0x20, GSM_A_PDU_TYPE_DTAP, DE_AUTH_PARAM_AUTN, "");
3545
3546         EXTRANEOUS_DATA_CHECK(curr_len, 0);
3547 }
3548
3549 /*
3550  * [4] 9.2.3
3551  */
3552 static void
3553 dtap_mm_auth_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
3554 {
3555         guint32 curr_offset;
3556         guint32 consumed;
3557         guint   curr_len;
3558
3559         curr_offset = offset;
3560         curr_len = len;
3561
3562         is_uplink = IS_UPLINK_TRUE;
3563
3564         ELEM_MAND_V(GSM_A_PDU_TYPE_DTAP, DE_AUTH_RESP_PARAM);
3565
3566         ELEM_OPT_TLV(0x21, GSM_A_PDU_TYPE_DTAP, DE_AUTH_RESP_PARAM_EXT, "");
3567
3568         EXTRANEOUS_DATA_CHECK(curr_len, 0);
3569 }
3570
3571 /*
3572  * [4] 9.2.3a
3573  */
3574 static void
3575 dtap_mm_auth_fail(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
3576 {
3577         guint32 curr_offset;
3578         guint32 consumed;
3579         guint   curr_len;
3580
3581         curr_offset = offset;
3582         curr_len = len;
3583
3584         is_uplink = IS_UPLINK_TRUE;
3585
3586         ELEM_MAND_V(GSM_A_PDU_TYPE_DTAP, DE_REJ_CAUSE);
3587
3588         ELEM_OPT_TLV(0x22, GSM_A_PDU_TYPE_DTAP, DE_AUTH_FAIL_PARAM, "");
3589
3590         EXTRANEOUS_DATA_CHECK(curr_len, 0);
3591 }
3592
3593 /*
3594  * [3] 9.2.4
3595  */
3596 static void
3597 dtap_mm_cm_reestab_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
3598 {
3599         guint32 curr_offset;
3600         guint32 consumed;
3601         guint   curr_len;
3602         guint8  oct;
3603         proto_tree      *subtree;
3604         proto_item      *item;
3605
3606         curr_offset = offset;
3607         curr_len = len;
3608
3609         is_uplink = IS_UPLINK_TRUE;
3610
3611         /*
3612          * special dissection for Cipher Key Sequence Number
3613          */
3614         oct = tvb_get_guint8(tvb, curr_offset);
3615
3616         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
3617         proto_tree_add_text(tree,
3618                 tvb, curr_offset, 1,
3619                 "%s :  Spare",
3620                 a_bigbuf);
3621
3622         item =
3623         proto_tree_add_text(tree,
3624                 tvb, curr_offset, 1, "%s",
3625                 gsm_common_elem_strings[DE_CIPH_KEY_SEQ_NUM].strptr);
3626
3627         subtree = proto_item_add_subtree(item, ett_gsm_common_elem[DE_CIPH_KEY_SEQ_NUM]);
3628
3629         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
3630         proto_tree_add_text(subtree,
3631                 tvb, curr_offset, 1,
3632                 "%s :  Spare",
3633                 a_bigbuf);
3634
3635         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
3636
3637         switch (oct & 0x07)
3638         {
3639         case 0x07:
3640                 proto_tree_add_text(subtree,
3641                         tvb, curr_offset, 1,
3642                         "%s :  Ciphering Key Sequence Number: No key is available",
3643                         a_bigbuf);
3644                 break;
3645
3646         default:
3647                 proto_tree_add_text(subtree,
3648                         tvb, curr_offset, 1,
3649                         "%s :  Ciphering Key Sequence Number: %u",
3650                         a_bigbuf,
3651                         oct & 0x07);
3652                 break;
3653         }
3654
3655         curr_offset++;
3656         curr_len--;
3657
3658         if (curr_len <= 0) return;
3659
3660         ELEM_MAND_LV(GSM_A_PDU_TYPE_COMMON, DE_MS_CM_2, "");
3661
3662         ELEM_MAND_LV(GSM_A_PDU_TYPE_COMMON, DE_MID, "");
3663
3664         ELEM_OPT_TV(0x13, GSM_A_PDU_TYPE_COMMON, DE_LAI, "");
3665
3666         EXTRANEOUS_DATA_CHECK(curr_len, 0);
3667 }
3668
3669 /*
3670  * [3] 9.2.5a
3671  */
3672 static void
3673 dtap_mm_cm_srvc_prompt(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
3674 {
3675         guint32 curr_offset;
3676         guint32 consumed;
3677         guint   curr_len;
3678
3679         curr_offset = offset;
3680         curr_len = len;
3681
3682         is_uplink = IS_UPLINK_FALSE;
3683
3684         ELEM_MAND_V(GSM_A_PDU_TYPE_COMMON, DE_PD_SAPI);
3685
3686         EXTRANEOUS_DATA_CHECK(curr_len, 0);
3687 }
3688
3689 /*
3690  * [4] 9.2.6
3691  */
3692 static void
3693 dtap_mm_cm_srvc_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
3694 {
3695         guint32 curr_offset;
3696         guint32 consumed;
3697         guint   curr_len;
3698
3699         curr_offset = offset;
3700         curr_len = len;
3701
3702         is_uplink = IS_UPLINK_FALSE;
3703
3704         ELEM_MAND_V(GSM_A_PDU_TYPE_DTAP, DE_REJ_CAUSE);
3705
3706         EXTRANEOUS_DATA_CHECK(curr_len, 0);
3707 }
3708
3709 /*
3710  * [4] 9.2.8
3711  */
3712 static void
3713 dtap_mm_abort(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
3714 {
3715         guint32 curr_offset;
3716         guint32 consumed;
3717         guint   curr_len;
3718
3719         curr_offset = offset;
3720         curr_len = len;
3721
3722         is_uplink = IS_UPLINK_FALSE;
3723
3724         ELEM_MAND_V(GSM_A_PDU_TYPE_DTAP, DE_REJ_CAUSE);
3725
3726         EXTRANEOUS_DATA_CHECK(curr_len, 0);
3727 }
3728
3729 /*
3730  * [3] 9.2.9
3731  */
3732 static void
3733 dtap_mm_cm_srvc_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
3734 {
3735         guint32 curr_offset;
3736         guint32 consumed;
3737         guint   curr_len;
3738         guint8  oct;
3739         proto_tree      *subtree;
3740         proto_item      *item;
3741         const gchar *str;
3742
3743         curr_offset = offset;
3744         curr_len = len;
3745
3746         is_uplink = IS_UPLINK_TRUE;
3747
3748         /*
3749          * special dissection for CM Service Type
3750          */
3751         oct = tvb_get_guint8(tvb, curr_offset);
3752
3753         item =
3754         proto_tree_add_text(tree,
3755                 tvb, curr_offset, 1, "%s",
3756                 gsm_common_elem_strings[DE_CIPH_KEY_SEQ_NUM].strptr);
3757
3758         subtree = proto_item_add_subtree(item, ett_gsm_common_elem[DE_CIPH_KEY_SEQ_NUM]);
3759
3760         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
3761         proto_tree_add_text(subtree,
3762                 tvb, curr_offset, 1,
3763                 "%s :  Spare",
3764                 a_bigbuf);
3765
3766         other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
3767
3768         switch ((oct & 0x70) >> 4)
3769         {
3770         case 0x07:
3771                 proto_tree_add_text(subtree,
3772                         tvb, curr_offset, 1,
3773                         "%s :  Ciphering Key Sequence Number: No key is available",
3774                         a_bigbuf);
3775                 break;
3776
3777         default:
3778                 proto_tree_add_text(subtree,
3779                         tvb, curr_offset, 1,
3780                         "%s :  Ciphering Key Sequence Number: %u",
3781                         a_bigbuf,
3782                         (oct & 0x70) >> 4);
3783                 break;
3784         }
3785
3786         item =
3787         proto_tree_add_text(tree,
3788                 tvb, curr_offset, 1, "%s",
3789                 gsm_dtap_elem_strings[DE_CM_SRVC_TYPE].strptr);
3790
3791         subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CM_SRVC_TYPE]);
3792
3793         switch (oct & 0x0f)
3794         {
3795         case 0x01: str = "Mobile originating call establishment or packet mode connection establishment"; break;
3796         case 0x02: str = "Emergency call establishment"; break;
3797         case 0x04: str = "Short message service"; break;
3798         case 0x08: str = "Supplementary service activation"; break;
3799         case 0x09: str = "Voice group call establishment"; break;
3800         case 0x0a: str = "Voice broadcast call establishment"; break;
3801         case 0x0b: str = "Location Services"; break;
3802         default:
3803                 str = "Reserved";
3804                 break;
3805         }
3806
3807         other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
3808         proto_tree_add_text(subtree,
3809                 tvb, curr_offset, 1,
3810                 "%s :  Service Type: (%u) %s",
3811                 a_bigbuf,
3812                 oct & 0x0f,
3813                 str);
3814
3815         curr_offset++;
3816         curr_len--;
3817
3818         if (curr_len <= 0) return;
3819
3820         ELEM_MAND_LV(GSM_A_PDU_TYPE_COMMON, DE_MS_CM_2, "");
3821
3822         ELEM_MAND_LV(GSM_A_PDU_TYPE_COMMON, DE_MID, "");
3823
3824         ELEM_OPT_TV_SHORT(0x80, GSM_A_PDU_TYPE_COMMON, DE_PRIO, "");
3825
3826         EXTRANEOUS_DATA_CHECK(curr_len, 0);
3827 }
3828
3829 /*
3830  * [3] 9.2.10
3831  */
3832 static void
3833 dtap_mm_id_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
3834 {
3835         guint8  oct;
3836         guint32 curr_offset;
3837         guint   curr_len;
3838         proto_tree      *subtree;
3839         proto_item      *item;
3840         const gchar *str;
3841
3842         curr_offset = offset;
3843         curr_len = len;
3844
3845         is_uplink = IS_UPLINK_FALSE;
3846
3847         /*
3848          * special dissection for Identity Type
3849          */
3850         oct = tvb_get_guint8(tvb, curr_offset);
3851
3852         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
3853         proto_tree_add_text(tree,
3854                 tvb, curr_offset, 1,
3855                 "%s :  Spare",
3856                 a_bigbuf);
3857
3858         item =
3859         proto_tree_add_text(tree,
3860                 tvb, curr_offset, 1, "%s",
3861                 gsm_dtap_elem_strings[DE_ID_TYPE].strptr);
3862
3863         subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_ID_TYPE]);
3864
3865         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
3866         proto_tree_add_text(subtree,
3867                 tvb, curr_offset, 1,
3868                 "%s :  Spare",
3869                 a_bigbuf);
3870
3871         switch (oct & 0x07)
3872         {
3873         case 1: str = "IMSI"; break;
3874         case 2: str = "IMEI"; break;
3875         case 3: str = "IMEISV"; break;
3876         case 4: str = "TMSI"; break;
3877         default:
3878                 str = "Reserved";
3879                 break;
3880         }
3881
3882         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
3883         proto_tree_add_text(subtree,
3884                 tvb, curr_offset, 1,
3885                 "%s :  Type of identity: %s",
3886                 a_bigbuf,
3887                 str);
3888
3889         curr_offset++;
3890         curr_len--;
3891
3892         EXTRANEOUS_DATA_CHECK(curr_len, 0);
3893 }
3894
3895 /*
3896  * [3] 9.2.11
3897  */
3898 static void
3899 dtap_mm_id_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
3900 {
3901         guint32 curr_offset;
3902         guint32 consumed;
3903         guint   curr_len;
3904
3905         curr_offset = offset;
3906         curr_len = len;
3907
3908         is_uplink = IS_UPLINK_TRUE;
3909
3910         ELEM_MAND_LV(GSM_A_PDU_TYPE_COMMON, DE_MID, "");
3911
3912         EXTRANEOUS_DATA_CHECK(curr_len, 0);
3913 }
3914
3915 /*
3916  * [3] 9.2.12
3917  */
3918 static void
3919 dtap_mm_imsi_det_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
3920 {
3921         guint32 curr_offset;
3922         guint32 consumed;
3923         guint   curr_len;
3924
3925         curr_offset = offset;
3926         curr_len = len;
3927
3928         is_uplink = IS_UPLINK_TRUE;
3929
3930         ELEM_MAND_V(GSM_A_PDU_TYPE_COMMON, DE_MS_CM_1);
3931
3932         ELEM_MAND_LV(GSM_A_PDU_TYPE_COMMON, DE_MID, "");
3933
3934         EXTRANEOUS_DATA_CHECK(curr_len, 0);
3935 }
3936
3937 /*
3938  * [3] 9.2.13
3939  */
3940 static void
3941 dtap_mm_loc_upd_acc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
3942 {
3943         guint32 curr_offset;
3944         guint32 consumed;
3945         guint   curr_len;
3946
3947         curr_offset = offset;
3948         curr_len = len;
3949
3950         is_uplink = IS_UPLINK_FALSE;
3951
3952         ELEM_MAND_V(GSM_A_PDU_TYPE_COMMON, DE_LAI);
3953
3954         ELEM_OPT_TLV(0x17, GSM_A_PDU_TYPE_COMMON, DE_MID, "");
3955
3956         ELEM_OPT_T(0xa1, GSM_A_PDU_TYPE_DTAP, DE_FOP, "");
3957
3958         ELEM_OPT_T(0xa2, GSM_A_PDU_TYPE_DTAP, DE_CTS_PERM, "");
3959
3960         ELEM_OPT_TLV(0x4a, GSM_A_PDU_TYPE_COMMON, DE_PLMN_LIST, " Equivalent");
3961
3962         EXTRANEOUS_DATA_CHECK(curr_len, 0);
3963 }
3964
3965 /*
3966  * [3] 9.2.14
3967  */
3968 static void
3969 dtap_mm_loc_upd_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
3970 {
3971         guint32 curr_offset;
3972         guint32 consumed;
3973         guint   curr_len;
3974
3975         curr_offset = offset;
3976         curr_len = len;
3977
3978         is_uplink = IS_UPLINK_FALSE;
3979
3980         ELEM_MAND_V(GSM_A_PDU_TYPE_DTAP, DE_REJ_CAUSE);
3981
3982         EXTRANEOUS_DATA_CHECK(curr_len, 0);
3983 }
3984
3985 /*
3986  * [3] 9.2.15
3987  */
3988 static void
3989 dtap_mm_loc_upd_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
3990 {
3991         guint32 curr_offset;
3992         guint32 consumed;
3993         guint   curr_len;
3994         guint8  oct;
3995         proto_tree      *subtree;
3996         proto_item      *item;
3997         const gchar *str;
3998
3999         curr_offset = offset;
4000         curr_len = len;
4001
4002         is_uplink = IS_UPLINK_TRUE;
4003
4004         /*
4005          * special dissection for Location Updating Type
4006          */
4007         oct = tvb_get_guint8(tvb, curr_offset);
4008
4009         item =
4010         proto_tree_add_text(tree,
4011                 tvb, curr_offset, 1, "%s",
4012                 gsm_common_elem_strings[DE_CIPH_KEY_SEQ_NUM].strptr);
4013
4014         subtree = proto_item_add_subtree(item, ett_gsm_common_elem[DE_CIPH_KEY_SEQ_NUM]);
4015
4016         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
4017         proto_tree_add_text(subtree,
4018                 tvb, curr_offset, 1,
4019                 "%s :  Spare",
4020                 a_bigbuf);
4021
4022         other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
4023
4024         switch ((oct & 0x70) >> 4)
4025         {
4026         case 0x07:
4027                 proto_tree_add_text(subtree,
4028                         tvb, curr_offset, 1,
4029                         "%s :  Ciphering Key Sequence Number: No key is available",
4030                         a_bigbuf);
4031                 break;
4032
4033         default:
4034                 proto_tree_add_text(subtree,
4035                         tvb, curr_offset, 1,
4036                         "%s :  Ciphering Key Sequence Number: %u",
4037                         a_bigbuf,
4038                         (oct & 0x70) >> 4);
4039                 break;
4040         }
4041
4042         item =
4043         proto_tree_add_text(tree,
4044                 tvb, curr_offset, 1, "%s",
4045                 gsm_dtap_elem_strings[DE_LOC_UPD_TYPE].strptr);
4046
4047         subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_LOC_UPD_TYPE]);
4048
4049         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
4050         proto_tree_add_text(subtree,
4051                 tvb, curr_offset, 1,
4052                 "%s :  Follow-On Request (FOR): %s",
4053                 a_bigbuf,
4054                 (oct & 0x08) ? "Follow-on request pending" : "No follow-on request pending");
4055
4056         other_decode_bitfield_value(a_bigbuf, oct, 0x04, 8);
4057         proto_tree_add_text(subtree,
4058                 tvb, curr_offset, 1,
4059                 "%s :  Spare",
4060                 a_bigbuf);
4061
4062         switch (oct & 0x03)
4063         {
4064         case 0: str = "Normal"; break;
4065         case 1: str = "Periodic"; break;
4066         case 2: str = "IMSI attach"; break;
4067         default:
4068                 str = "Reserved";
4069                 break;
4070         }
4071
4072         other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
4073         proto_tree_add_text(subtree,
4074                 tvb, curr_offset, 1,
4075                 "%s :  Updating Type: %s",
4076                 a_bigbuf,
4077                 str);
4078
4079         proto_item_append_text(item, " - %s", str);
4080
4081         curr_offset++;
4082         curr_len--;
4083
4084         if (curr_len <= 0) return;
4085
4086         ELEM_MAND_V(GSM_A_PDU_TYPE_COMMON, DE_LAI);
4087
4088         ELEM_MAND_V(GSM_A_PDU_TYPE_COMMON, DE_MS_CM_1);
4089
4090         ELEM_MAND_LV(GSM_A_PDU_TYPE_COMMON, DE_MID, "");
4091
4092         ELEM_OPT_TLV(0x33, GSM_A_PDU_TYPE_COMMON, DE_MS_CM_2, "");
4093
4094         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4095 }
4096
4097
4098 /*
4099  * [4] 9.2.15a
4100  */
4101 void
4102 dtap_mm_mm_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4103 {
4104         guint32 curr_offset;
4105         guint32 consumed;
4106         guint   curr_len;
4107
4108         curr_offset = offset;
4109         curr_len = len;
4110
4111         is_uplink = IS_UPLINK_TRUE;
4112
4113         ELEM_OPT_TLV(0x43, GSM_A_PDU_TYPE_DTAP, DE_NETWORK_NAME, " - Full Name");
4114
4115         ELEM_OPT_TLV(0x45, GSM_A_PDU_TYPE_DTAP, DE_NETWORK_NAME, " - Short Name");
4116
4117         ELEM_OPT_TV(0x46, GSM_A_PDU_TYPE_DTAP, DE_TIME_ZONE, " - Local");
4118
4119         ELEM_OPT_TV(0x47, GSM_A_PDU_TYPE_DTAP, DE_TIME_ZONE_TIME, " - Universal Time and Local Time Zone");
4120
4121         ELEM_OPT_TLV(0x48, GSM_A_PDU_TYPE_DTAP, DE_LSA_ID, "");
4122
4123         ELEM_OPT_TLV(0x49, GSM_A_PDU_TYPE_DTAP, DE_DAY_SAVING_TIME, "");
4124
4125         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4126 }
4127
4128 /*
4129  * [4] 9.2.16
4130  */
4131 static void
4132 dtap_mm_mm_status(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4133 {
4134         guint32 curr_offset;
4135         guint32 consumed;
4136         guint   curr_len;
4137
4138         curr_offset = offset;
4139         curr_len = len;
4140
4141         is_uplink = IS_UPLINK_TRUE;
4142
4143         ELEM_MAND_V(GSM_A_PDU_TYPE_DTAP, DE_REJ_CAUSE);
4144
4145         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4146 }
4147
4148 /*
4149  * [3] 9.2.17
4150  */
4151 static void
4152 dtap_mm_tmsi_realloc_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4153 {
4154         guint32 curr_offset;
4155         guint32 consumed;
4156         guint   curr_len;
4157
4158         curr_offset = offset;
4159         curr_len = len;
4160
4161         is_uplink = IS_UPLINK_FALSE;
4162
4163         ELEM_MAND_V(GSM_A_PDU_TYPE_COMMON, DE_LAI);
4164
4165         ELEM_MAND_LV(GSM_A_PDU_TYPE_COMMON, DE_MID, "");
4166
4167         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4168 }
4169
4170 /*
4171  * [4] 9.3.1
4172  */
4173 static void
4174 dtap_cc_alerting(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4175 {
4176         guint32 curr_offset;
4177         guint32 consumed;
4178         guint   curr_len;
4179
4180         curr_offset = offset;
4181         curr_len = len;
4182
4183         is_uplink = IS_UPLINK_TRUE;
4184
4185         ELEM_OPT_TLV(0x1c, GSM_A_PDU_TYPE_DTAP, DE_FACILITY, "");
4186
4187         ELEM_OPT_TLV(0x1e, GSM_A_PDU_TYPE_DTAP, DE_PROG_IND, "");
4188
4189         ELEM_OPT_TLV(0x7e, GSM_A_PDU_TYPE_DTAP, DE_USER_USER, "");
4190
4191         /* uplink only */
4192
4193         ELEM_OPT_TLV(0x7f, GSM_A_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
4194
4195         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4196 }
4197
4198 /*
4199  * [4] 9.3.2
4200  */
4201 static void
4202 dtap_cc_call_conf(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4203 {
4204         guint32 curr_offset;
4205         guint32 consumed;
4206         guint   curr_len;
4207
4208         curr_offset = offset;
4209         curr_len = len;
4210
4211         is_uplink = IS_UPLINK_TRUE;
4212
4213         ELEM_OPT_TV_SHORT(0xd0, GSM_A_PDU_TYPE_DTAP, DE_REPEAT_IND, " BC repeat indicator");
4214
4215         ELEM_OPT_TLV(0x04, GSM_A_PDU_TYPE_DTAP, DE_BEARER_CAP, " 1");
4216
4217         ELEM_OPT_TLV(0x04, GSM_A_PDU_TYPE_DTAP, DE_BEARER_CAP, " 2");
4218
4219         ELEM_OPT_TLV(0x08, GSM_A_PDU_TYPE_DTAP, DE_CAUSE, "");
4220
4221         ELEM_OPT_TLV(0x15, GSM_A_PDU_TYPE_DTAP, DE_CC_CAP, "");
4222
4223         ELEM_OPT_TLV(0x2d, GSM_A_PDU_TYPE_DTAP, DE_SI, "");
4224
4225         ELEM_OPT_TLV(0x40, GSM_A_PDU_TYPE_DTAP, DE_SUP_CODEC_LIST, "");
4226
4227         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4228 }
4229
4230 /*
4231  * [4] 9.3.3
4232  */
4233 static void
4234 dtap_cc_call_proceed(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4235 {
4236         guint32 curr_offset;
4237         guint32 consumed;
4238         guint   curr_len;
4239
4240         curr_offset = offset;
4241         curr_len = len;
4242
4243         is_uplink = IS_UPLINK_FALSE;
4244
4245         ELEM_OPT_TV_SHORT(0xd0, GSM_A_PDU_TYPE_DTAP, DE_REPEAT_IND, " BC repeat indicator");
4246
4247         ELEM_OPT_TLV(0x04, GSM_A_PDU_TYPE_DTAP, DE_BEARER_CAP, " 1");
4248
4249         ELEM_OPT_TLV(0x04, GSM_A_PDU_TYPE_DTAP, DE_BEARER_CAP, " 2");
4250
4251         ELEM_OPT_TLV(0x1c, GSM_A_PDU_TYPE_DTAP, DE_FACILITY, "");
4252
4253         ELEM_OPT_TLV(0x1e, GSM_A_PDU_TYPE_DTAP, DE_PROG_IND, "");
4254
4255         ELEM_OPT_TV_SHORT(0x80, GSM_A_PDU_TYPE_COMMON, DE_PRIO, "");
4256
4257         ELEM_OPT_TLV(0x2f, GSM_A_PDU_TYPE_DTAP, DE_NET_CC_CAP, "");
4258
4259         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4260 }
4261
4262 /*
4263  * [4] 9.3.4
4264  */
4265 static void
4266 dtap_cc_congestion_control(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4267 {
4268         guint32 curr_offset;
4269         guint32 consumed;
4270         guint   curr_len;
4271         guint8  oct;
4272         proto_tree      *subtree;
4273         proto_item      *item;
4274         const gchar *str;
4275
4276         curr_offset = offset;
4277         curr_len = len;
4278
4279         is_uplink = IS_UPLINK_FALSE;
4280
4281         /*
4282          * special dissection for Congestion Level
4283          */
4284         oct = tvb_get_guint8(tvb, curr_offset);
4285
4286         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
4287         proto_tree_add_text(tree,
4288                 tvb, curr_offset, 1,
4289                 "%s :  Spare",
4290                 a_bigbuf);
4291
4292         item =
4293                 proto_tree_add_text(tree,
4294                         tvb, curr_offset, 1, "%s",
4295                         gsm_dtap_elem_strings[DE_CONGESTION].strptr);
4296
4297         subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CONGESTION]);
4298
4299         switch (oct & 0x0f)
4300         {
4301         case 0: str = "Receiver ready"; break;
4302         case 15: str = "Receiver not ready"; break;
4303         default:
4304                 str = "Reserved";
4305                 break;
4306         }
4307
4308         other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
4309         proto_tree_add_text(subtree,
4310                 tvb, curr_offset, 1,
4311                 "%s :  Congestion level: %s",
4312                 a_bigbuf,
4313                 str);
4314
4315         curr_offset++;
4316         curr_len--;
4317
4318         if (curr_len <= 0) return;
4319
4320         ELEM_OPT_TLV(0x08, GSM_A_PDU_TYPE_DTAP, DE_CAUSE, "");
4321
4322         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4323 }
4324
4325 /*
4326  * [4] 9.3.5
4327  */
4328 static void
4329 dtap_cc_connect(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4330 {
4331         guint32 curr_offset;
4332         guint32 consumed;
4333         guint   curr_len;
4334
4335         curr_offset = offset;
4336         curr_len = len;
4337
4338         is_uplink = IS_UPLINK_TRUE;
4339
4340         ELEM_OPT_TLV(0x1c, GSM_A_PDU_TYPE_DTAP, DE_FACILITY, "");
4341
4342         ELEM_OPT_TLV(0x1e, GSM_A_PDU_TYPE_DTAP, DE_PROG_IND, "");
4343
4344         ELEM_OPT_TLV(0x4c, GSM_A_PDU_TYPE_DTAP, DE_CONN_NUM, "");
4345
4346         ELEM_OPT_TLV(0x4d, GSM_A_PDU_TYPE_DTAP, DE_CONN_SUB_ADDR, "");
4347
4348         ELEM_OPT_TLV(0x7e, GSM_A_PDU_TYPE_DTAP, DE_USER_USER, "");
4349
4350         /* uplink only */
4351
4352         ELEM_OPT_TLV(0x7f, GSM_A_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
4353
4354         ELEM_OPT_TLV(0x2d, GSM_A_PDU_TYPE_DTAP, DE_SI, "");
4355
4356         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4357 }
4358
4359 /*
4360  * [4] 9.3.7
4361  */
4362 static void
4363 dtap_cc_disconnect(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4364 {
4365         guint32 curr_offset;
4366         guint32 consumed;
4367         guint   curr_len;
4368
4369         curr_offset = offset;
4370         curr_len = len;
4371
4372         is_uplink = IS_UPLINK_TRUE;
4373
4374         ELEM_MAND_LV(GSM_A_PDU_TYPE_DTAP, DE_CAUSE, "");
4375
4376         ELEM_OPT_TLV(0x1c, GSM_A_PDU_TYPE_DTAP, DE_FACILITY, "");
4377
4378         ELEM_OPT_TLV(0x1e, GSM_A_PDU_TYPE_DTAP, DE_PROG_IND, "");
4379
4380         ELEM_OPT_TLV(0x7e, GSM_A_PDU_TYPE_DTAP, DE_USER_USER, "");
4381
4382         ELEM_OPT_TLV(0x7b, GSM_A_PDU_TYPE_DTAP, DE_ALLOWED_ACTIONS, "");
4383
4384         /* uplink only */
4385
4386         ELEM_OPT_TLV(0x7f, GSM_A_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
4387
4388         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4389 }
4390
4391 /*
4392  * [4] 9.3.8
4393  */
4394 static void
4395 dtap_cc_emerg_setup(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4396 {
4397         guint32 curr_offset;
4398         guint32 consumed;
4399         guint   curr_len;
4400
4401         curr_offset = offset;
4402         curr_len = len;
4403
4404         is_uplink = IS_UPLINK_TRUE;
4405
4406         ELEM_OPT_TLV(0x04, GSM_A_PDU_TYPE_DTAP, DE_BEARER_CAP, "");
4407
4408         ELEM_OPT_TLV(0x2d, GSM_A_PDU_TYPE_DTAP, DE_SI, "");
4409
4410         ELEM_OPT_TLV(0x40, GSM_A_PDU_TYPE_DTAP, DE_SUP_CODEC_LIST, "");
4411
4412         ELEM_OPT_TLV(0x2e, GSM_A_PDU_TYPE_DTAP, DE_SRVC_CAT, " Emergency");
4413
4414         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4415 }
4416
4417 /*
4418  * [4] 9.3.9
4419  */
4420 static void
4421 dtap_cc_facility(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4422 {
4423         guint32 curr_offset;
4424         guint32 consumed;
4425         guint   curr_len;
4426
4427         curr_offset = offset;
4428         curr_len = len;
4429
4430         is_uplink = IS_UPLINK_TRUE;
4431
4432         ELEM_MAND_LV(GSM_A_PDU_TYPE_DTAP, DE_FACILITY, "");
4433
4434         /* uplink only */
4435
4436         ELEM_OPT_TLV(0x7f, GSM_A_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
4437
4438         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4439 }
4440
4441 /*
4442  * [4] 9.3.12
4443  */
4444 static void
4445 dtap_cc_hold_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4446 {
4447         guint32 curr_offset;
4448         guint32 consumed;
4449         guint   curr_len;
4450
4451         curr_offset = offset;
4452         curr_len = len;
4453
4454         is_uplink = IS_UPLINK_FALSE;
4455
4456         ELEM_MAND_LV(GSM_A_PDU_TYPE_DTAP, DE_CAUSE, "");
4457
4458         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4459 }
4460
4461 /*
4462  * [4] 9.3.13
4463  */
4464 static void
4465 dtap_cc_modify(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4466 {
4467         guint32 curr_offset;
4468         guint32 consumed;
4469         guint   curr_len;
4470
4471         curr_offset = offset;
4472         curr_len = len;
4473
4474         is_uplink = IS_UPLINK_TRUE;
4475
4476         ELEM_MAND_LV(GSM_A_PDU_TYPE_DTAP, DE_BEARER_CAP, "");
4477
4478         ELEM_OPT_TLV(0x7c, GSM_A_PDU_TYPE_DTAP, DE_LLC, "");
4479
4480         ELEM_OPT_TLV(0x7d, GSM_A_PDU_TYPE_DTAP, DE_HLC, "");
4481
4482         ELEM_OPT_T(0xa3, GSM_A_PDU_TYPE_DTAP, DE_REV_CALL_SETUP_DIR, "");
4483
4484         ELEM_OPT_T(0xa4, GSM_A_PDU_TYPE_DTAP, DE_IMM_MOD_IND, "");
4485
4486         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4487 }
4488
4489 /*
4490  * [4] 9.3.14
4491  */
4492 static void
4493 dtap_cc_modify_complete(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4494 {
4495         guint32 curr_offset;
4496         guint32 consumed;
4497         guint   curr_len;
4498
4499         curr_offset = offset;
4500         curr_len = len;
4501
4502         is_uplink = IS_UPLINK_TRUE;
4503
4504         ELEM_MAND_LV(GSM_A_PDU_TYPE_DTAP, DE_BEARER_CAP, "");
4505
4506         ELEM_OPT_TLV(0x7c, GSM_A_PDU_TYPE_DTAP, DE_LLC, "");
4507
4508         ELEM_OPT_TLV(0x7d, GSM_A_PDU_TYPE_DTAP, DE_HLC, "");
4509
4510         ELEM_OPT_T(0xa3, GSM_A_PDU_TYPE_DTAP, DE_REV_CALL_SETUP_DIR, "");
4511
4512         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4513 }
4514
4515 /*
4516  * [4] 9.3.15
4517  */
4518 static void
4519 dtap_cc_modify_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4520 {
4521         guint32 curr_offset;
4522         guint32 consumed;
4523         guint   curr_len;
4524
4525         curr_offset = offset;
4526         curr_len = len;
4527
4528         is_uplink = IS_UPLINK_FALSE;
4529
4530         ELEM_MAND_LV(GSM_A_PDU_TYPE_DTAP, DE_BEARER_CAP, "");
4531
4532         ELEM_MAND_LV(GSM_A_PDU_TYPE_DTAP, DE_CAUSE, "");
4533
4534         ELEM_OPT_TLV(0x7c, GSM_A_PDU_TYPE_DTAP, DE_LLC, "");
4535
4536         ELEM_OPT_TLV(0x7d, GSM_A_PDU_TYPE_DTAP, DE_HLC, "");
4537
4538         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4539 }
4540
4541 /*
4542  * [4] 9.3.16
4543  */
4544 static void
4545 dtap_cc_notify(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4546 {
4547         guint32 curr_offset;
4548         guint32 consumed;
4549         guint   curr_len;
4550
4551         curr_offset = offset;
4552         curr_len = len;
4553
4554         is_uplink = IS_UPLINK_FALSE;
4555
4556         ELEM_MAND_V(GSM_A_PDU_TYPE_DTAP, DE_NOT_IND);
4557
4558         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4559 }
4560
4561 /*
4562  * [4] 9.3.17
4563  */
4564 static void
4565 dtap_cc_progress(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4566 {
4567         guint32 curr_offset;
4568         guint32 consumed;
4569         guint   curr_len;
4570
4571         curr_offset = offset;
4572         curr_len = len;
4573
4574         is_uplink = IS_UPLINK_FALSE;
4575
4576         ELEM_MAND_LV(GSM_A_PDU_TYPE_DTAP, DE_PROG_IND, "");
4577
4578         ELEM_OPT_TLV(0x7e, GSM_A_PDU_TYPE_DTAP, DE_USER_USER, "");
4579
4580         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4581 }
4582
4583 /*
4584  * [4] 9.3.17a
4585  */
4586 static void
4587 dtap_cc_cc_est(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4588 {
4589         guint32 curr_offset;
4590         guint32 consumed;
4591         guint   curr_len;
4592
4593         curr_offset = offset;
4594         curr_len = len;
4595
4596         is_uplink = IS_UPLINK_FALSE;
4597
4598         ELEM_MAND_LV(GSM_A_PDU_TYPE_DTAP, DE_SETUP_CONTAINER, "");
4599
4600         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4601 }
4602
4603 /*
4604  * [4] 9.3.17b
4605  */
4606 static void
4607 dtap_cc_cc_est_conf(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4608 {
4609         guint32 curr_offset;
4610         guint32 consumed;
4611         guint   curr_len;
4612
4613         curr_offset = offset;
4614         curr_len = len;
4615
4616         is_uplink = IS_UPLINK_TRUE;
4617
4618         ELEM_OPT_TV_SHORT(0xd0, GSM_A_PDU_TYPE_DTAP, DE_REPEAT_IND, " Repeat indicator");
4619
4620         ELEM_MAND_TLV(0x04, GSM_A_PDU_TYPE_DTAP, DE_BEARER_CAP, " 1");
4621
4622         ELEM_OPT_TLV(0x04, GSM_A_PDU_TYPE_DTAP, DE_BEARER_CAP, " 2");
4623
4624         ELEM_OPT_TLV(0x08, GSM_A_PDU_TYPE_DTAP, DE_CAUSE, "");
4625
4626         ELEM_OPT_TLV(0x40, GSM_A_PDU_TYPE_DTAP, DE_SUP_CODEC_LIST, "");
4627
4628         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4629 }
4630
4631 /*
4632  * [4] 9.3.18
4633  */
4634 static void
4635 dtap_cc_release(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4636 {
4637         guint32 curr_offset;
4638         guint32 consumed;
4639         guint   curr_len;
4640
4641         curr_offset = offset;
4642         curr_len = len;
4643
4644         is_uplink = IS_UPLINK_TRUE;
4645
4646         ELEM_OPT_TLV(0x08, GSM_A_PDU_TYPE_DTAP, DE_CAUSE, "");
4647
4648         ELEM_OPT_TLV(0x08, GSM_A_PDU_TYPE_DTAP, DE_CAUSE, " 2");
4649
4650         ELEM_OPT_TLV(0x1c, GSM_A_PDU_TYPE_DTAP, DE_FACILITY, "");
4651
4652         ELEM_OPT_TLV(0x7e, GSM_A_PDU_TYPE_DTAP, DE_USER_USER, "");
4653
4654         /* uplink only */
4655
4656         ELEM_OPT_TLV(0x7f, GSM_A_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
4657
4658         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4659 }
4660
4661 /*
4662  * [4] 9.3.18a
4663  */
4664 static void
4665 dtap_cc_recall(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4666 {
4667         guint32 curr_offset;
4668         guint32 consumed;
4669         guint   curr_len;
4670
4671         curr_offset = offset;
4672         curr_len = len;
4673
4674         is_uplink = IS_UPLINK_FALSE;
4675
4676         ELEM_MAND_V(GSM_A_PDU_TYPE_DTAP, DE_RECALL_TYPE);
4677
4678         ELEM_MAND_LV(GSM_A_PDU_TYPE_DTAP, DE_FACILITY, "");
4679
4680         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4681 }
4682
4683 /*
4684  * [4] 9.3.19
4685  */
4686 static void
4687 dtap_cc_release_complete(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4688 {
4689         guint32 curr_offset;
4690         guint32 consumed;
4691         guint   curr_len;
4692
4693         curr_offset = offset;
4694         curr_len = len;
4695
4696         is_uplink = IS_UPLINK_FALSE;
4697
4698         ELEM_OPT_TLV(0x08, GSM_A_PDU_TYPE_DTAP, DE_CAUSE, "");
4699
4700         ELEM_OPT_TLV(0x1c, GSM_A_PDU_TYPE_DTAP, DE_FACILITY, "");
4701
4702         ELEM_OPT_TLV(0x7e, GSM_A_PDU_TYPE_DTAP, DE_USER_USER, "");
4703
4704         /* uplink only */
4705
4706         ELEM_OPT_TLV(0x7f, GSM_A_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
4707
4708         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4709 }
4710
4711 /*
4712  * [4] 9.3.22
4713  */
4714 static void
4715 dtap_cc_retrieve_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4716 {
4717         guint32 curr_offset;
4718         guint32 consumed;
4719         guint   curr_len;
4720
4721         curr_offset = offset;
4722         curr_len = len;
4723
4724         is_uplink = IS_UPLINK_FALSE;
4725
4726         ELEM_MAND_LV(GSM_A_PDU_TYPE_DTAP, DE_CAUSE, "");
4727
4728         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4729 }
4730
4731 /*
4732  * [4] 9.3.23
4733  * 3GPP TS 24.008 version 7.5.0 Release 7
4734  */
4735 static void
4736 dtap_cc_setup(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4737 {
4738         guint32 curr_offset;
4739         guint32 consumed;
4740         guint   curr_len;
4741
4742         curr_offset = offset;
4743         curr_len = len;
4744
4745         is_uplink = IS_UPLINK_TRUE;
4746
4747         ELEM_OPT_TV_SHORT(0xd0, GSM_A_PDU_TYPE_DTAP, DE_REPEAT_IND, " BC repeat indicator");
4748
4749         ELEM_OPT_TLV(0x04, GSM_A_PDU_TYPE_DTAP, DE_BEARER_CAP, " 1");
4750
4751         ELEM_OPT_TLV(0x04, GSM_A_PDU_TYPE_DTAP, DE_BEARER_CAP, " 2");
4752
4753         ELEM_OPT_TLV(0x1c, GSM_A_PDU_TYPE_DTAP, DE_FACILITY, "");
4754
4755         ELEM_OPT_TLV(0x1e, GSM_A_PDU_TYPE_DTAP, DE_PROG_IND, "");
4756
4757         ELEM_OPT_TV(0x34, GSM_A_PDU_TYPE_DTAP, DE_SIGNAL, "");
4758
4759         ELEM_OPT_TLV(0x5c, GSM_A_PDU_TYPE_DTAP, DE_CLG_PARTY_BCD_NUM, "");
4760
4761         ELEM_OPT_TLV(0x5d, GSM_A_PDU_TYPE_DTAP, DE_CLG_PARTY_SUB_ADDR, "");
4762
4763         ELEM_OPT_TLV(0x5e, GSM_A_PDU_TYPE_DTAP, DE_CLD_PARTY_BCD_NUM, "");
4764
4765         ELEM_OPT_TLV(0x6d, GSM_A_PDU_TYPE_DTAP, DE_CLD_PARTY_SUB_ADDR, "");
4766
4767         ELEM_OPT_TLV(0x74, GSM_A_PDU_TYPE_DTAP, DE_RED_PARTY_BCD_NUM, "");
4768
4769         ELEM_OPT_TLV(0x75, GSM_A_PDU_TYPE_DTAP, DE_RED_PARTY_SUB_ADDR, "");
4770
4771         ELEM_OPT_TV_SHORT(0xd0, GSM_A_PDU_TYPE_DTAP, DE_REPEAT_IND, " LLC repeat indicator");
4772
4773         ELEM_OPT_TLV(0x7c, GSM_A_PDU_TYPE_DTAP, DE_LLC, " 1");
4774
4775         ELEM_OPT_TLV(0x7c, GSM_A_PDU_TYPE_DTAP, DE_LLC, " 2");
4776
4777         ELEM_OPT_TV_SHORT(0xd0, GSM_A_PDU_TYPE_DTAP, DE_REPEAT_IND, " HLC repeat indicator");
4778
4779         ELEM_OPT_TLV(0x7d, GSM_A_PDU_TYPE_DTAP, DE_HLC, " 1");
4780
4781         ELEM_OPT_TLV(0x7d, GSM_A_PDU_TYPE_DTAP, DE_HLC, " 2");
4782
4783         ELEM_OPT_TLV(0x7e, GSM_A_PDU_TYPE_DTAP, DE_USER_USER, "");
4784
4785         /* downlink only */
4786
4787         ELEM_OPT_TV_SHORT(0x80, GSM_A_PDU_TYPE_COMMON, DE_PRIO, "");
4788
4789         ELEM_OPT_TLV(0x19, GSM_A_PDU_TYPE_DTAP, DE_ALERT_PATTERN, "");
4790
4791         ELEM_OPT_TLV(0x2f, GSM_A_PDU_TYPE_DTAP, DE_NET_CC_CAP, "");
4792
4793         ELEM_OPT_TLV(0x3a, GSM_A_PDU_TYPE_DTAP, DE_CAUSE_NO_CLI, "");
4794
4795         /* Backup bearer capability O TLV 3-15 10.5.4.4a */
4796         ELEM_OPT_TLV(0x41, GSM_A_PDU_TYPE_DTAP, DE_BEARER_CAP, "");
4797
4798         /* uplink only */
4799
4800         ELEM_OPT_TLV(0x7f, GSM_A_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
4801
4802         ELEM_OPT_T(0xa1, GSM_A_PDU_TYPE_DTAP, DE_CLIR_SUP, "");
4803
4804         ELEM_OPT_T(0xa2, GSM_A_PDU_TYPE_DTAP, DE_CLIR_INV, "");
4805
4806         ELEM_OPT_TLV(0x15, GSM_A_PDU_TYPE_DTAP, DE_CC_CAP, "");
4807
4808         ELEM_OPT_TLV(0x1d, GSM_A_PDU_TYPE_DTAP, DE_FACILITY, " $(CCBS)$ (advanced recall alignment)");
4809
4810         ELEM_OPT_TLV(0x1b, GSM_A_PDU_TYPE_DTAP, DE_FACILITY, " (recall alignment Not essential) $(CCBS)$");
4811
4812         ELEM_OPT_TLV(0x2d, GSM_A_PDU_TYPE_DTAP, DE_SI, "");
4813
4814         ELEM_OPT_TLV(0x40, GSM_A_PDU_TYPE_DTAP, DE_SUP_CODEC_LIST, "");
4815
4816         /*A3 Redial Redial O T 1 10.5.4.34
4817          * TODO add this element
4818          * ELEM_OPT_T(0xA3, GSM_A_PDU_TYPE_DTAP, DE_REDIAL, "");
4819          */
4820
4821         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4822 }
4823
4824 /*
4825  * [4] 9.3.23a
4826  */
4827 static void
4828 dtap_cc_start_cc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4829 {
4830         guint32 curr_offset;
4831         guint32 consumed;
4832         guint   curr_len;
4833
4834         curr_offset = offset;
4835         curr_len = len;
4836
4837         is_uplink = IS_UPLINK_FALSE;
4838
4839         ELEM_OPT_TLV(0x15, GSM_A_PDU_TYPE_DTAP, DE_CC_CAP, "");
4840
4841         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4842 }
4843
4844 /*
4845  * [4] 9.3.24
4846  */
4847 static void
4848 dtap_cc_start_dtmf(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4849 {
4850         guint32 curr_offset;
4851         guint32 consumed;
4852         guint   curr_len;
4853
4854         curr_offset = offset;
4855         curr_len = len;
4856
4857         is_uplink = IS_UPLINK_TRUE;
4858
4859         ELEM_MAND_TV(0x2c, GSM_A_PDU_TYPE_DTAP, DE_KEYPAD_FACILITY, "");
4860
4861         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4862 }
4863
4864 /*
4865  * [4] 9.3.25
4866  */
4867 static void
4868 dtap_cc_start_dtmf_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4869 {
4870         guint32 curr_offset;
4871         guint32 consumed;
4872         guint   curr_len;
4873
4874         curr_offset = offset;
4875         curr_len = len;
4876
4877         is_uplink = IS_UPLINK_FALSE;
4878
4879         ELEM_MAND_TV(0x2c, GSM_A_PDU_TYPE_DTAP, DE_KEYPAD_FACILITY, "");
4880
4881         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4882 }
4883
4884 /*
4885  * [4] 9.3.26
4886  */
4887 static void
4888 dtap_cc_start_dtmf_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4889 {
4890         guint32 curr_offset;
4891         guint32 consumed;
4892         guint   curr_len;
4893
4894         curr_offset = offset;
4895         curr_len = len;
4896
4897         is_uplink = IS_UPLINK_FALSE;
4898
4899         ELEM_MAND_LV(GSM_A_PDU_TYPE_DTAP, DE_CAUSE, "");
4900
4901         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4902 }
4903
4904 /*
4905  * [4] 9.3.27
4906  */
4907 static void
4908 dtap_cc_status(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4909 {
4910         guint32 curr_offset;
4911         guint32 consumed;
4912         guint   curr_len;
4913
4914         curr_offset = offset;
4915         curr_len = len;
4916
4917         is_uplink = IS_UPLINK_FALSE;
4918
4919         ELEM_MAND_LV(GSM_A_PDU_TYPE_DTAP, DE_CAUSE, "");
4920
4921         ELEM_MAND_V(GSM_A_PDU_TYPE_DTAP, DE_CALL_STATE);
4922
4923         ELEM_OPT_TLV(0x24, GSM_A_PDU_TYPE_DTAP, DE_AUX_STATES, "");
4924
4925         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4926 }
4927
4928 /*
4929  * [4] 9.3.31
4930  */
4931 static void
4932 dtap_cc_user_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4933 {
4934         guint32 curr_offset;
4935         guint32 consumed;
4936         guint   curr_len;
4937
4938         curr_offset = offset;
4939         curr_len = len;
4940
4941         is_uplink = IS_UPLINK_TRUE;
4942
4943         ELEM_MAND_LV(GSM_A_PDU_TYPE_DTAP, DE_USER_USER, "");
4944
4945         ELEM_OPT_T(0xa0, GSM_A_PDU_TYPE_DTAP, DE_MORE_DATA, "");
4946
4947         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4948 }
4949
4950 /*
4951  * [6] 2.4.2
4952  */
4953 static void
4954 dtap_ss_register(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4955 {
4956         guint32 curr_offset;
4957         guint32 consumed;
4958         guint   curr_len;
4959
4960         curr_offset = offset;
4961         curr_len = len;
4962
4963         is_uplink = IS_UPLINK_TRUE;
4964
4965         ELEM_MAND_TLV(0x1c, GSM_A_PDU_TYPE_DTAP, DE_FACILITY, "");
4966
4967         ELEM_OPT_TLV(0x7f, GSM_A_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
4968
4969         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4970 }
4971
4972 /*
4973  * [5] 7.2.1
4974  */
4975 static void
4976 dtap_sms_cp_data(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4977 {
4978         guint32 curr_offset;
4979         guint32 consumed;
4980         guint   curr_len;
4981
4982         curr_offset = offset;
4983         curr_len = len;
4984
4985         is_uplink = IS_UPLINK_TRUE;
4986
4987         ELEM_MAND_LV(GSM_A_PDU_TYPE_DTAP, DE_CP_USER_DATA, "");
4988
4989         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4990 }
4991
4992 /*
4993  * [5] 7.2.3
4994  */
4995 static void
4996 dtap_sms_cp_error(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4997 {
4998         guint32 curr_offset;
4999         guint32 consumed;
5000         guint   curr_len;
5001
5002         curr_offset = offset;
5003         curr_len = len;
5004
5005         is_uplink = IS_UPLINK_TRUE;
5006
5007         ELEM_MAND_V(GSM_A_PDU_TYPE_DTAP, DE_CP_CAUSE);
5008
5009         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5010 }
5011
5012 static void
5013 dtap_tp_close_tch_loop_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5014 {
5015         guint32 curr_offset;
5016         guint32 consumed;
5017         guint   curr_len;
5018
5019         curr_len = len;
5020         curr_offset = offset;
5021
5022         ELEM_MAND_V(GSM_A_PDU_TYPE_DTAP, DE_TP_SUB_CHANNEL );
5023
5024         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5025 }
5026
5027 static void
5028 dtap_tp_open_loop_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5029 {
5030         guint32 curr_offset;
5031         guint32 consumed;
5032         guint   curr_len;
5033
5034         curr_len = len;
5035         curr_offset = offset;
5036
5037         if (curr_len)
5038                 ELEM_MAND_V(GSM_A_PDU_TYPE_DTAP, DE_TP_ACK );
5039
5040         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5041 }
5042
5043 static void
5044 dtap_tp_multi_slot_loop_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5045 {
5046         guint32 curr_offset;
5047         guint32 consumed;
5048         guint   curr_len;
5049
5050         curr_len = len;
5051         curr_offset = offset;
5052
5053         ELEM_MAND_V(GSM_A_PDU_TYPE_DTAP, DE_TP_LOOP_TYPE );
5054
5055         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5056 }
5057
5058 static void
5059 dtap_tp_multi_slot_loop_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5060 {
5061         guint32 curr_offset;
5062         guint32 consumed;
5063         guint   curr_len;
5064
5065         curr_len = len;
5066         curr_offset = offset;
5067
5068         ELEM_MAND_V(GSM_A_PDU_TYPE_DTAP, DE_TP_LOOP_ACK );
5069
5070         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5071 }
5072
5073 static void
5074 dtap_tp_test_interface(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5075 {
5076         guint32 curr_offset;
5077         guint32 consumed;
5078         guint   curr_len;
5079
5080         curr_len = len;
5081         curr_offset = offset;
5082
5083         ELEM_MAND_V(GSM_A_PDU_TYPE_DTAP, DE_TP_TESTED_DEVICE );
5084
5085         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5086 }
5087
5088 static void
5089 dtap_tp_gprs_test_mode_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5090 {
5091         guint32 curr_offset;
5092         guint32 consumed;
5093         guint   curr_len;
5094
5095         curr_len = len;
5096         curr_offset = offset;
5097
5098         ELEM_MAND_V(GSM_A_PDU_TYPE_DTAP, DE_TP_PDU_DESCRIPTION );
5099
5100         ELEM_MAND_V(GSM_A_PDU_TYPE_DTAP, DE_TP_MODE_FLAG );
5101
5102         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5103 }
5104
5105 static void
5106 dtap_tp_egprs_start_radio_block_loopback_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5107 {
5108         guint32 curr_offset;
5109         guint32 consumed;
5110         guint   curr_len;
5111
5112         curr_len = len;
5113         curr_offset = offset;
5114
5115         ELEM_MAND_V(GSM_A_PDU_TYPE_DTAP, DE_TP_EGPRS_MODE_FLAG );
5116
5117         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5118 }
5119
5120 static void
5121 dtap_tp_close_ue_test_loop(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5122 {
5123         guint32 curr_offset;
5124         guint32 consumed;
5125         guint   curr_len;
5126
5127         curr_len = len;
5128         curr_offset = offset;
5129
5130         ELEM_MAND_V(GSM_A_PDU_TYPE_DTAP, DE_TP_UE_TEST_LOOP_MODE );
5131
5132         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5133 }
5134
5135 static void
5136 dtap_tp_reset_ue_positioning_ue_stored_information(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5137 {
5138         guint32 curr_offset;
5139         guint32 consumed;
5140         guint   curr_len;
5141
5142         curr_len = len;
5143         curr_offset = offset;
5144
5145         ELEM_MAND_V(GSM_A_PDU_TYPE_DTAP, DE_TP_UE_POSITIONING_TECHNOLOGY );
5146
5147         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5148 }
5149
5150 static void
5151 dtap_tp_ue_test_loop_mode_3_rlc_sdu_counter_response(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5152 {
5153         guint32 curr_offset;
5154         guint32 consumed;
5155         guint   curr_len;
5156
5157         curr_len = len;
5158         curr_offset = offset;
5159
5160         ELEM_MAND_V(GSM_A_PDU_TYPE_DTAP, DE_TP_RLC_SDU_COUNTER_VALUE );
5161
5162         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5163 }
5164
5165 #define NUM_GSM_DTAP_MSG_MM (sizeof(gsm_a_dtap_msg_mm_strings)/sizeof(value_string))
5166 static gint ett_gsm_dtap_msg_mm[NUM_GSM_DTAP_MSG_MM];
5167 static void (*dtap_msg_mm_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
5168         dtap_mm_imsi_det_ind,   /* IMSI Detach Indication */
5169         dtap_mm_loc_upd_acc,    /* Location Updating Accept */
5170         dtap_mm_loc_upd_rej,    /* Location Updating Reject */
5171         dtap_mm_loc_upd_req,    /* Location Updating Request */
5172         NULL /* no associated data */,  /* Authentication Reject */
5173         dtap_mm_auth_req,       /* Authentication Request */
5174         dtap_mm_auth_resp,      /* Authentication Response */
5175         dtap_mm_auth_fail,      /* Authentication Failure */
5176         dtap_mm_id_req, /* Identity Request */
5177         dtap_mm_id_resp,        /* Identity Response */
5178         dtap_mm_tmsi_realloc_cmd,       /* TMSI Reallocation Command */
5179         NULL /* no associated data */,  /* TMSI Reallocation Complete */
5180         NULL /* no associated data */,  /* CM Service Accept */
5181         dtap_mm_cm_srvc_rej,    /* CM Service Reject */
5182         NULL /* no associated data */,  /* CM Service Abort */
5183         dtap_mm_cm_srvc_req,    /* CM Service Request */
5184         dtap_mm_cm_srvc_prompt, /* CM Service Prompt */
5185         NULL,   /* Reserved: was allocated in earlier phases of the protocol */
5186         dtap_mm_cm_reestab_req, /* CM Re-establishment Request */
5187         dtap_mm_abort,  /* Abort */
5188         NULL /* no associated data */,  /* MM Null */
5189         dtap_mm_mm_status,      /* MM Status */
5190         dtap_mm_mm_info,        /* MM Information */
5191         NULL,   /* NONE */
5192 };
5193
5194 #define NUM_GSM_DTAP_MSG_CC (sizeof(gsm_a_dtap_msg_cc_strings)/sizeof(value_string))
5195 static gint ett_gsm_dtap_msg_cc[NUM_GSM_DTAP_MSG_CC];
5196 static void (*dtap_msg_cc_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
5197         dtap_cc_alerting,       /* Alerting */
5198         dtap_cc_call_conf,      /* Call Confirmed */
5199         dtap_cc_call_proceed,   /* Call Proceeding */
5200         dtap_cc_connect,        /* Connect */
5201         NULL /* no associated data */,  /* Connect Acknowledge */
5202         dtap_cc_emerg_setup,    /* Emergency Setup */
5203         dtap_cc_progress,       /* Progress */
5204         dtap_cc_cc_est, /* CC-Establishment */
5205         dtap_cc_cc_est_conf,    /* CC-Establishment Confirmed */
5206         dtap_cc_recall, /* Recall */
5207         dtap_cc_start_cc,       /* Start CC */
5208         dtap_cc_setup,  /* Setup */
5209         dtap_cc_modify, /* Modify */
5210         dtap_cc_modify_complete,        /* Modify Complete */
5211         dtap_cc_modify_rej,     /* Modify Reject */
5212         dtap_cc_user_info,      /* User Information */
5213         NULL /* no associated data */,  /* Hold */
5214         NULL /* no associated data */,  /* Hold Acknowledge */
5215         dtap_cc_hold_rej,       /* Hold Reject */
5216         NULL /* no associated data */,  /* Retrieve */
5217         NULL /* no associated data */,  /* Retrieve Acknowledge */
5218         dtap_cc_retrieve_rej,   /* Retrieve Reject */
5219         dtap_cc_disconnect,     /* Disconnect */
5220         dtap_cc_release,        /* Release */
5221         dtap_cc_release_complete,       /* Release Complete */
5222         dtap_cc_congestion_control,     /* Congestion Control */
5223         dtap_cc_notify, /* Notify */
5224         dtap_cc_status, /* Status */
5225         NULL /* no associated data */,  /* Status Enquiry */
5226         dtap_cc_start_dtmf,     /* Start DTMF */
5227         NULL /* no associated data */,  /* Stop DTMF */
5228         NULL /* no associated data */,  /* Stop DTMF Acknowledge */
5229         dtap_cc_start_dtmf_ack, /* Start DTMF Acknowledge */
5230         dtap_cc_start_dtmf_rej, /* Start DTMF Reject */
5231         dtap_cc_facility,       /* Facility */
5232         NULL,   /* NONE */
5233 };
5234
5235 #define NUM_GSM_DTAP_MSG_SMS (sizeof(gsm_a_dtap_msg_sms_strings)/sizeof(value_string))
5236 static gint ett_gsm_dtap_msg_sms[NUM_GSM_DTAP_MSG_SMS];
5237 static void (*dtap_msg_sms_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
5238         dtap_sms_cp_data,       /* CP-DATA */
5239         NULL /* no associated data */,  /* CP-ACK */
5240         dtap_sms_cp_error,      /* CP-ERROR */
5241         NULL,   /* NONE */
5242 };
5243
5244 #define NUM_GSM_DTAP_MSG_SS (sizeof(gsm_a_dtap_msg_ss_strings)/sizeof(value_string))
5245 static gint ett_gsm_dtap_msg_ss[NUM_GSM_DTAP_MSG_SS];
5246 static void (*dtap_msg_ss_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
5247         dtap_cc_release_complete,       /* Release Complete */
5248         dtap_cc_facility,       /* Facility */
5249         dtap_ss_register,       /* Register */
5250         NULL,   /* NONE */
5251 };
5252
5253 #define NUM_GSM_DTAP_MSG_TP (sizeof(gsm_a_dtap_msg_tp_strings)/sizeof(value_string))
5254 static gint ett_gsm_dtap_msg_tp[NUM_GSM_DTAP_MSG_TP];
5255 static void (*dtap_msg_tp_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
5256         dtap_tp_close_tch_loop_cmd,     /* CLOSE TCH LOOP CMD */
5257         NULL,   /* CLOSE TCH LOOP ACK */
5258         dtap_tp_open_loop_cmd,  /* OPEN LOOP CMD */
5259         NULL,   /* ACT EMMI CMD */
5260         NULL,   /* ACT EMMI ACK */
5261         NULL,   /* DEACT EMMI */
5262         dtap_tp_test_interface, /* Test Interface */
5263         dtap_tp_multi_slot_loop_cmd,    /* CLOSE Multi-slot LOOP CMD */
5264         dtap_tp_multi_slot_loop_ack,    /* CLOSE Multi-slot LOOP ACK */
5265         NULL,   /* OPEN Multi-slot LOOP CMD */
5266         NULL,   /* OPEN Multi-slot LOOP ACK */
5267         dtap_tp_gprs_test_mode_cmd,     /* GPRS TEST MODE CMD */
5268         dtap_tp_egprs_start_radio_block_loopback_cmd,   /* EGPRS START RADIO BLOCK LOOPBACK CMD */
5269         dtap_tp_close_ue_test_loop,     /* CLOSE UE TEST LOOP */
5270         NULL,   /* CLOSE UE TEST LOOP COMPLETE */
5271         NULL,   /* OPEN UE TEST LOOP */
5272         NULL,   /* OPEN UE TEST LOOP COMPLETE */
5273         NULL,   /* ACTIVATE RB TEST MODE */
5274         NULL,   /* ACTIVATE RB TEST MODE COMPLETE */
5275         NULL,   /* DEACTIVATE RB TEST MODE */
5276         NULL,   /* DEACTIVATE RB TEST MODE COMPLETE */
5277         dtap_tp_reset_ue_positioning_ue_stored_information,     /* RESET UE POSITIONING STORED INFORMATION */
5278         NULL,   /* UE Test Loop Mode 3 RLC SDU Counter Request */
5279         dtap_tp_ue_test_loop_mode_3_rlc_sdu_counter_response,   /* UE Test Loop Mode 3 RLC SDU Counter Response */
5280         NULL,   /* NONE */
5281 };
5282
5283 /* GENERIC DISSECTOR FUNCTIONS */
5284
5285 static void
5286 dissect_dtap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
5287 {
5288         static gsm_a_tap_rec_t  tap_rec[4];
5289         static gsm_a_tap_rec_t  *tap_p;
5290         static guint                    tap_current=0;
5291         void                    (*msg_fcn)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len);
5292         guint8                  oct;
5293         guint8                  pd;
5294         guint32                 offset;
5295         guint32                 len;
5296         guint32                 oct_1, oct_2;
5297         gint                    idx;
5298         proto_item                      *dtap_item = NULL;
5299         proto_tree                      *dtap_tree = NULL;
5300         proto_item                      *oct_1_item = NULL;
5301         proto_tree                      *pd_tree = NULL;
5302         const gchar                     *msg_str;
5303         gint                    ett_tree;
5304         gint                    ti;
5305         int                             hf_idx;
5306         gboolean                        nsd;
5307
5308
5309         len = tvb_length(tvb);
5310
5311         if (len < 2)
5312         {
5313                 /*
5314                  * too short to be DTAP
5315                  */
5316                 call_dissector(data_handle, tvb, pinfo, tree);
5317                 return;
5318         }
5319
5320         if (check_col(pinfo->cinfo, COL_INFO))
5321         {
5322                 col_append_str(pinfo->cinfo, COL_INFO, "(DTAP) ");
5323         }
5324
5325         /*
5326          * set tap record pointer
5327          */
5328         tap_current++;
5329         if (tap_current >= 4)
5330         {
5331                 tap_current = 0;
5332         }
5333         tap_p = &tap_rec[tap_current];
5334
5335
5336         offset = 0;
5337         oct_2 = 0;
5338
5339         gsm_a_dtap_pinfo = pinfo;
5340         g_tree = tree;
5341
5342         /*
5343          * get protocol discriminator
5344          */
5345         oct_1 = tvb_get_guint8(tvb, offset++);
5346
5347         if ((((oct_1 & DTAP_TI_MASK) >> 4) & DTAP_TIE_PRES_MASK) == DTAP_TIE_PRES_MASK)
5348         {
5349                 /*
5350                  * eventhough we don't know if a TI should be in the message yet
5351                  * we rely on the TI/SKIP indicator to be 0 to avoid taking this
5352                  * octet
5353                  */
5354                 oct_2 = tvb_get_guint8(tvb, offset++);
5355         }
5356
5357         oct = tvb_get_guint8(tvb, offset);
5358
5359         pd = oct_1 & DTAP_PD_MASK;
5360         ti = -1;
5361         msg_str = NULL;
5362         ett_tree = -1;
5363         hf_idx = -1;
5364         msg_fcn = NULL;
5365         nsd = FALSE;
5366         if (check_col(pinfo->cinfo, COL_INFO))
5367         {
5368                 col_append_fstr(pinfo->cinfo, COL_INFO, "(%s) ",val_to_str(pd,gsm_a_pd_short_str_vals,"unknown"));
5369         }
5370
5371         /*
5372          * octet 1
5373          */
5374         switch (pd)
5375         {
5376         case 3:
5377                 msg_str = match_strval_idx((guint32) (oct & DTAP_CC_IEI_MASK), gsm_a_dtap_msg_cc_strings, &idx);
5378                 ett_tree = ett_gsm_dtap_msg_cc[idx];
5379                 hf_idx = hf_gsm_a_dtap_msg_cc_type;
5380                 msg_fcn = dtap_msg_cc_fcn[idx];
5381                 ti = (oct_1 & DTAP_TI_MASK) >> 4;
5382                 nsd = TRUE;
5383                 break;
5384
5385         case 5:
5386                 msg_str = match_strval_idx((guint32) (oct & DTAP_MM_IEI_MASK), gsm_a_dtap_msg_mm_strings, &idx);
5387                 ett_tree = ett_gsm_dtap_msg_mm[idx];
5388                 hf_idx = hf_gsm_a_dtap_msg_mm_type;
5389                 msg_fcn = dtap_msg_mm_fcn[idx];
5390                 nsd = TRUE;
5391                 break;
5392
5393         case 6:
5394                 get_rr_msg_params(oct, &msg_str, &ett_tree, &hf_idx, &msg_fcn);
5395                 break;
5396
5397         case 8:
5398                 get_gmm_msg_params(oct, &msg_str, &ett_tree, &hf_idx, &msg_fcn);
5399                 break;
5400
5401         case 9:
5402                 msg_str = match_strval_idx((guint32) (oct & DTAP_SMS_IEI_MASK), gsm_a_dtap_msg_sms_strings, &idx);
5403                 ett_tree = ett_gsm_dtap_msg_sms[idx];
5404                 hf_idx = hf_gsm_a_dtap_msg_sms_type;
5405                 msg_fcn = dtap_msg_sms_fcn[idx];
5406                 ti = (oct_1 & DTAP_TI_MASK) >> 4;
5407                 break;
5408
5409         case 10:
5410                 get_sm_msg_params(oct, &msg_str, &ett_tree, &hf_idx, &msg_fcn);
5411                 ti = (oct_1 & DTAP_TI_MASK) >> 4;
5412                 break;
5413
5414         case 11:
5415                 msg_str = match_strval_idx((guint32) (oct & DTAP_SS_IEI_MASK), gsm_a_dtap_msg_ss_strings, &idx);
5416                 ett_tree = ett_gsm_dtap_msg_ss[idx];
5417                 hf_idx = hf_gsm_a_dtap_msg_ss_type;
5418                 msg_fcn = dtap_msg_ss_fcn[idx];
5419                 ti = (oct_1 & DTAP_TI_MASK) >> 4;
5420                 nsd = TRUE;
5421                 break;
5422
5423         case 15:
5424                 msg_str = match_strval_idx((guint32) (oct & DTAP_TP_IEI_MASK), gsm_a_dtap_msg_tp_strings, &idx);
5425                 ett_tree = ett_gsm_dtap_msg_tp[idx];
5426                 hf_idx = hf_gsm_a_dtap_msg_tp_type;
5427                 msg_fcn = dtap_msg_tp_fcn[idx];
5428                 ti = (oct_1 & DTAP_TI_MASK) >> 4;
5429                 nsd = TRUE;
5430                 break;
5431
5432         default:
5433                 /* XXX - hf_idx is still -1! this is a bug in the implementation, and I don't know how to fix it so simple return here */
5434                 return;
5435         }
5436
5437         sccp_msg = pinfo->sccp_info;
5438
5439         if (sccp_msg && sccp_msg->data.co.assoc) {
5440                 sccp_assoc = sccp_msg->data.co.assoc;
5441         } else {
5442                 sccp_assoc = NULL;
5443                 sccp_msg = NULL;
5444         }
5445
5446         /*
5447          * create the protocol tree
5448          */
5449         if (msg_str == NULL)
5450         {
5451                 dtap_item =
5452                         proto_tree_add_protocol_format(tree, proto_a_dtap, tvb, 0, len,
5453                         "GSM A-I/F DTAP - Unknown DTAP Message Type (0x%02x)",
5454                         oct);
5455
5456                 dtap_tree = proto_item_add_subtree(dtap_item, ett_dtap_msg);
5457
5458                 if (sccp_msg && !sccp_msg->data.co.label) {
5459                         sccp_msg->data.co.label = se_strdup_printf("DTAP (0x%02x)",oct);
5460                 }
5461
5462
5463         }
5464         else
5465         {
5466                 dtap_item =
5467                         proto_tree_add_protocol_format(tree, proto_a_dtap, tvb, 0, -1,
5468                                 "GSM A-I/F DTAP - %s",
5469                                 msg_str);
5470
5471                 dtap_tree = proto_item_add_subtree(dtap_item, ett_tree);
5472
5473                 if (sccp_msg && !sccp_msg->data.co.label) {
5474                         sccp_msg->data.co.label = se_strdup(msg_str);
5475                 }
5476
5477                 if (check_col(pinfo->cinfo, COL_INFO))
5478                 {
5479                         col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", msg_str);
5480                 }
5481         }
5482
5483         oct_1_item =
5484         proto_tree_add_text(dtap_tree,
5485                 tvb, 0, 1,
5486                 "Protocol Discriminator: %s",
5487                 val_to_str(pd, protocol_discriminator_vals, "Unknown (%u)"));
5488
5489         pd_tree = proto_item_add_subtree(oct_1_item, ett_dtap_oct_1);
5490
5491         if (ti == -1)
5492         {
5493                 proto_tree_add_item(pd_tree, hf_gsm_a_skip_ind, tvb, 0, 1, FALSE);
5494         }
5495         else
5496         {
5497                 other_decode_bitfield_value(a_bigbuf, oct_1, 0x80, 8);
5498                 proto_tree_add_text(pd_tree,
5499                         tvb, 0, 1,
5500                         "%s :  TI flag: %s",
5501                         a_bigbuf,
5502                         ((oct_1 & 0x80) ?  "allocated by receiver" : "allocated by sender"));
5503
5504                 if ((ti & DTAP_TIE_PRES_MASK) == DTAP_TIE_PRES_MASK)
5505                 {
5506                         /* ti is extended to next octet */
5507
5508                         other_decode_bitfield_value(a_bigbuf, oct_1, 0x70, 8);
5509                         proto_tree_add_text(pd_tree,
5510                                 tvb, 0, 1,
5511                                 "%s :  TIO: The TI value is given by the TIE in octet 2",
5512                                 a_bigbuf);
5513                 }
5514                 else
5515                 {
5516                         other_decode_bitfield_value(a_bigbuf, oct_1, 0x70, 8);
5517                         proto_tree_add_text(pd_tree,
5518                                 tvb, 0, 1,
5519                                 "%s :  TIO: %u",
5520                                 a_bigbuf,
5521                                 ti & DTAP_TIE_PRES_MASK);
5522                 }
5523         }
5524
5525         proto_tree_add_item(pd_tree, hf_gsm_a_L3_protocol_discriminator, tvb, 0, 1, FALSE);
5526
5527         if ((ti != -1) &&
5528                 (ti & DTAP_TIE_PRES_MASK) == DTAP_TIE_PRES_MASK)
5529         {
5530                 proto_tree_add_item(tree, hf_gsm_a_extension, tvb, 1, 1, FALSE);
5531
5532                 other_decode_bitfield_value(a_bigbuf, oct_2, DTAP_TIE_MASK, 8);
5533                 proto_tree_add_text(pd_tree,
5534                         tvb, 1, 1,
5535                         "%s :  TIE: %u",
5536                         a_bigbuf,
5537                         oct_2 & DTAP_TIE_MASK);
5538         }
5539
5540         /*
5541          * N(SD)
5542          */
5543         if ((pinfo->p2p_dir == P2P_DIR_RECV) &&
5544                 nsd)
5545         {
5546                 /* XXX */
5547         }
5548         /* In case of Mobility Management and Call Control and Call related SS messages
5549          * bit 7 and 8 is sequence number
5550          */
5551         if((pd==5)||(pd==3)){
5552                 proto_tree_add_item(dtap_tree, hf_gsm_a_seq_no, tvb, offset, 1, FALSE);
5553         }
5554         /*
5555          * add DTAP message name
5556          */
5557         proto_tree_add_item(dtap_tree, hf_idx, tvb, offset, 1, FALSE);
5558         offset++;
5559
5560         tap_p->pdu_type = GSM_A_PDU_TYPE_DTAP;
5561         tap_p->message_type = (nsd ? (oct & 0x3f) : oct);
5562         tap_p->protocol_disc = pd;
5563
5564         tap_queue_packet(gsm_a_tap, pinfo, tap_p);
5565
5566         if (msg_str == NULL) return;
5567
5568         if ((len - offset) <= 0) return;
5569
5570         /*
5571          * decode elements
5572          */
5573         if (msg_fcn == NULL)
5574         {
5575                 proto_tree_add_text(dtap_tree,
5576                         tvb, offset, len - offset,
5577                         "Message Elements");
5578         }
5579         else
5580         {
5581                 (*msg_fcn)(tvb, dtap_tree, offset, len - offset);
5582         }
5583 }
5584
5585
5586 /* Register the protocol with Wireshark */
5587 void
5588 proto_register_gsm_a_dtap(void)
5589 {
5590         guint           i;
5591         guint           last_offset;
5592
5593         /* Setup list of header fields */
5594
5595         static hf_register_info hf[] =
5596         {
5597         { &hf_gsm_a_seq_no,
5598                 { "Sequence number", "gsm_a.dtap_seq_no",
5599                 FT_UINT8, BASE_DEC, NULL, 0xc0,
5600                 "", HFILL }
5601         },
5602         { &hf_gsm_a_dtap_msg_mm_type,
5603                 { "DTAP Mobility Management Message Type", "gsm_a.dtap_msg_mm_type",
5604                 FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_mm_strings), 0x3f,
5605                 "", HFILL }
5606         },
5607         { &hf_gsm_a_dtap_msg_cc_type,
5608                 { "DTAP Call Control Message Type", "gsm_a.dtap_msg_cc_type",
5609                 FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_cc_strings), 0x3f,
5610                 "", HFILL }
5611         },
5612         { &hf_gsm_a_dtap_msg_sms_type,
5613                 { "DTAP Short Message Service Message Type", "gsm_a.dtap_msg_sms_type",
5614                 FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_sms_strings), 0x0,
5615                 "", HFILL }
5616         },
5617         { &hf_gsm_a_dtap_msg_ss_type,
5618                 { "DTAP Non call Supplementary Service Message Type", "gsm_a.dtap_msg_ss_type",
5619                 FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_ss_strings), 0x0,
5620                 "", HFILL }
5621         },
5622         { &hf_gsm_a_dtap_msg_tp_type,
5623                 { "DTAP Tests Procedures Message Type", "gsm_a.dtap_msg_tp_type",
5624                 FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_tp_strings), 0x0,
5625                 "", HFILL }
5626         },
5627         { &hf_gsm_a_dtap_elem_id,
5628                 { "Element ID", "gsm_a_dtap.elem_id",
5629                 FT_UINT8, BASE_DEC, NULL, 0,
5630                 "", HFILL }
5631         },
5632         { &hf_gsm_a_cld_party_bcd_num,
5633                 { "Called Party BCD Number", "gsm_a.cld_party_bcd_num",
5634                 FT_STRING, BASE_DEC, 0, 0,
5635                 "", HFILL }
5636         },
5637         { &hf_gsm_a_clg_party_bcd_num,
5638                 { "Calling Party BCD Number", "gsm_a.clg_party_bcd_num",
5639                 FT_STRING, BASE_DEC, 0, 0,
5640                 "", HFILL }
5641         },
5642         { &hf_gsm_a_dtap_cause,
5643                 { "DTAP Cause", "gsm_a_dtap.cause",
5644                 FT_UINT8, BASE_HEX, 0, 0x0,
5645                 "", HFILL }
5646         },
5647         { &hf_gsm_a_extension,
5648                 { "Extension", "gsm_a.extension",
5649                 FT_BOOLEAN, 8, TFS(&gsm_a_extension_value), 0x80,
5650                 "Extension", HFILL }
5651         },
5652         { &hf_gsm_a_type_of_number,
5653                 { "Type of number", "gsm_a.type_of_number",
5654                 FT_UINT8, BASE_HEX, VALS(gsm_a_type_of_number_values), 0x70,
5655                 "Type of number", HFILL }
5656         },
5657         { &hf_gsm_a_numbering_plan_id,
5658                 { "Numbering plan identification", "gsm_a.numbering_plan_id",
5659                 FT_UINT8, BASE_HEX, VALS(gsm_a_numbering_plan_id_values), 0x0f,
5660                 "Numbering plan identification", HFILL }
5661         },
5662         { &hf_gsm_a_lsa_id,
5663                 { "LSA Identifier", "gsm_a.lsa_id",
5664                 FT_UINT24, BASE_HEX, NULL, 0x0,
5665                 "LSA Identifier", HFILL }
5666         },
5667         };
5668
5669         /* Setup protocol subtree array */
5670 #define NUM_INDIVIDUAL_ELEMS    19
5671         static gint *ett[NUM_INDIVIDUAL_ELEMS +
5672                         NUM_GSM_DTAP_MSG_MM + NUM_GSM_DTAP_MSG_CC +
5673                         NUM_GSM_DTAP_MSG_SMS + NUM_GSM_DTAP_MSG_SS + NUM_GSM_DTAP_MSG_TP +
5674                         NUM_GSM_DTAP_ELEM];
5675
5676         ett[0] = &ett_dtap_msg;
5677         ett[1] = &ett_dtap_oct_1;
5678         ett[2] = &ett_cm_srvc_type;
5679         ett[3] = &ett_gsm_enc_info;
5680     ett[4] = &ett_bc_oct_3;
5681     ett[5] = &ett_bc_oct_3a;
5682     ett[6] = &ett_bc_oct_4;
5683     ett[7] = &ett_bc_oct_5;
5684     ett[8] = &ett_bc_oct_5a;
5685     ett[9] = &ett_bc_oct_5b;
5686     ett[10] = &ett_bc_oct_6;
5687     ett[11] = &ett_bc_oct_6a;
5688     ett[12] = &ett_bc_oct_6b;
5689     ett[13] = &ett_bc_oct_6c;
5690     ett[14] = &ett_bc_oct_6d;
5691     ett[15] = &ett_bc_oct_6e;
5692     ett[16] = &ett_bc_oct_6f;
5693     ett[17] = &ett_bc_oct_6g;
5694     ett[18] = &ett_bc_oct_7;
5695
5696         last_offset = NUM_INDIVIDUAL_ELEMS;
5697
5698         for (i=0; i < NUM_GSM_DTAP_MSG_MM; i++, last_offset++)
5699         {
5700                 ett_gsm_dtap_msg_mm[i] = -1;
5701                 ett[last_offset] = &ett_gsm_dtap_msg_mm[i];
5702         }
5703
5704         for (i=0; i < NUM_GSM_DTAP_MSG_CC; i++, last_offset++)
5705         {
5706                 ett_gsm_dtap_msg_cc[i] = -1;
5707                 ett[last_offset] = &ett_gsm_dtap_msg_cc[i];
5708         }
5709
5710         for (i=0; i < NUM_GSM_DTAP_MSG_SMS; i++, last_offset++)
5711         {
5712                 ett_gsm_dtap_msg_sms[i] = -1;
5713                 ett[last_offset] = &ett_gsm_dtap_msg_sms[i];
5714         }
5715
5716         for (i=0; i < NUM_GSM_DTAP_MSG_SS; i++, last_offset++)
5717         {
5718                 ett_gsm_dtap_msg_ss[i] = -1;
5719                 ett[last_offset] = &ett_gsm_dtap_msg_ss[i];
5720         }
5721
5722         for (i=0; i < NUM_GSM_DTAP_MSG_TP; i++, last_offset++)
5723         {
5724                 ett_gsm_dtap_msg_tp[i] = -1;
5725                 ett[last_offset] = &ett_gsm_dtap_msg_tp[i];
5726         }
5727
5728         for (i=0; i < NUM_GSM_DTAP_ELEM; i++, last_offset++)
5729         {
5730                 ett_gsm_dtap_elem[i] = -1;
5731                 ett[last_offset] = &ett_gsm_dtap_elem[i];
5732         }
5733
5734         /* Register the protocol name and description */
5735
5736         proto_a_dtap =
5737                 proto_register_protocol("GSM A-I/F DTAP", "GSM DTAP", "gsm_a_dtap");
5738
5739         proto_register_field_array(proto_a_dtap, hf, array_length(hf));
5740
5741         proto_register_subtree_array(ett, array_length(ett));
5742
5743         /* subdissector code */
5744         register_dissector("gsm_a_dtap", dissect_dtap, proto_a_dtap);
5745 }
5746
5747 void
5748 proto_reg_handoff_gsm_a_dtap(void)
5749 {
5750         dissector_handle_t dtap_handle;
5751
5752         dtap_handle = find_dissector("gsm_a_dtap");
5753         dissector_add("bssap.pdu_type", BSSAP_PDU_TYPE_DTAP, dtap_handle);
5754         dissector_add("ranap.nas_pdu", BSSAP_PDU_TYPE_DTAP, dtap_handle);
5755         dissector_add("llcgprs.sapi", 1 , dtap_handle); /* GPRS Mobility Management */
5756         dissector_add("llcgprs.sapi", 7 , dtap_handle); /* SMS */
5757
5758         data_handle = find_dissector("data");
5759         gsm_map_handle = find_dissector("gsm_map");
5760         rp_handle = find_dissector("gsm_a_rp");
5761 }