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