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