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