change the signature that asn2wrs generates for functions to marm all parameters...
[obnox/wireshark/wip.git] / epan / dissectors / packet-gsm_a.c
1 /* packet-gsm_a.c
2  * Routines for GSM A Interface (BSSMAP/DTAP) dissection
3  *
4  * Copyright 2003, Michael Lum <mlum [AT] telostech.com>
5  * In association with Telos Technology Inc.
6  *
7  *
8  * Added the GPRS Mobility Managment Protocol and 
9  * the GPRS Session Managment Protocol
10  *   Copyright 2004, Rene Pilz <rene.pilz [AT] ftw.com>
11  *   In association with Telecommunications Research Center 
12  *   Vienna (ftw.)Betriebs-GmbH within the Project Metawin.
13  *
14  * Added Dissection of Radio Resource Management Information Elements
15  * and othere enhancements and fixes.
16  * Copyright 2005 - 2006, Anders Broman [AT] ericsson.com
17  * Small bugfixes, mainly in Qos and TFT by Nils Ljungberg and Stefan Boman [AT] ericsson.com
18  *
19  * Title                3GPP                    Other
20  *
21  *   Reference [1]
22  *   Mobile radio interface signalling layer 3;
23  *   General Aspects
24  *   (3GPP TS 24.007 version 3.9.0 Release 1999)
25  *
26  *   Reference [2]
27  *   Mobile-services Switching Centre - Base Station System
28  *   (MSC - BSS) interface;
29  *   Layer 3 specification
30  *   (GSM 08.08 version 7.7.0 Release 1998)     TS 100 590 v7.7.0
31  *
32  *   Reference [3]
33  *   Mobile radio interface Layer 3 specification;
34  *   Core network protocols;
35  *   Stage 3
36  *   (3GPP TS 24.008 version 4.7.0 Release 4)
37  *   (ETSI TS 124 008 V6.8.0 (2005-03))
38  *
39  *   Reference [4]
40  *   Mobile radio interface layer 3 specification;
41  *   Radio Resource Control Protocol
42  *   (GSM 04.18 version 8.4.1 Release 1999)
43  *   (3GPP TS 04.18 version 8.26.0 Release 1999)
44  *
45  *   Reference [5]
46  *   Point-to-Point (PP) Short Message Service (SMS)
47  *   support on mobile radio interface
48  *   (3GPP TS 24.011 version 4.1.1 Release 4)
49  *
50  *   Reference [6]
51  *   Mobile radio Layer 3 supplementary service specification;
52  *   Formats and coding
53  *   (3GPP TS 24.080 version 4.3.0 Release 4)
54  *
55  *   Reference [7]
56  *   Mobile radio interface Layer 3 specification;
57  *   Core network protocols;
58  *   Stage 3
59  *   (3GPP TS 24.008 version 5.9.0 Release 5)
60  *
61  *   Reference [8]
62  *   Mobile radio interface Layer 3 specification;
63  *   Core network protocols;
64  *   Stage 3
65  *   (3GPP TS 24.008 version 6.7.0 Release 6)
66  *       (3GPP TS 24.008 version 6.8.0 Release 6)
67  *
68  * $Id$
69  *
70  * Wireshark - Network traffic analyzer
71  * By Gerald Combs <gerald@wireshark.org>
72  * Copyright 1998 Gerald Combs
73  *
74  * This program is free software; you can redistribute it and/or
75  * modify it under the terms of the GNU General Public License
76  * as published by the Free Software Foundation; either version 2
77  * of the License, or (at your option) any later version.
78  *
79  * This program is distributed in the hope that it will be useful,
80  * but WITHOUT ANY WARRANTY; without even the implied warranty of
81  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
82  * GNU General Public License for more details.
83  *
84  * You should have received a copy of the GNU General Public License
85  * along with this program; if not, write to the Free Software
86  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
87  */
88
89 #ifdef HAVE_CONFIG_H
90 # include "config.h"
91 #endif
92
93 #include <stdio.h>
94 #include <stdlib.h>
95
96 #include <string.h>
97
98 #include <epan/packet.h>
99 #include <epan/prefs.h>
100 #include <epan/tap.h>
101 #include <epan/emem.h>
102
103 #include "packet-bssap.h"
104 #include "packet-gsm_ss.h"
105 #include "packet-ber.h"
106 #include "packet-q931.h"
107 #include "packet-gsm_a.h"
108 #include "packet-ipv6.h"
109 #include "packet-sccp.h"
110
111 #include "packet-ppp.h"
112
113 /* PROTOTYPES/FORWARDS */
114
115 const value_string gsm_a_bssmap_msg_strings[] = {
116     { 0x01,     "Assignment Request" },
117     { 0x02,     "Assignment Complete" },
118     { 0x03,     "Assignment Failure" },
119     { 0x10,     "Handover Request" },
120     { 0x11,     "Handover Required" },
121     { 0x12,     "Handover Request Acknowledge" },
122     { 0x13,     "Handover Command" },
123     { 0x14,     "Handover Complete" },
124     { 0x15,     "Handover Succeeded" },
125     { 0x16,     "Handover Failure" },
126     { 0x17,     "Handover Performed" },
127     { 0x18,     "Handover Candidate Enquire" },
128     { 0x19,     "Handover Candidate Response" },
129     { 0x1a,     "Handover Required Reject" },
130     { 0x1b,     "Handover Detect" },
131     { 0x20,     "Clear Command" },
132     { 0x21,     "Clear Complete" },
133     { 0x22,     "Clear Request" },
134     { 0x23,     "Reserved" },
135     { 0x24,     "Reserved" },
136     { 0x25,     "SAPI 'n' Reject" },
137     { 0x26,     "Confusion" },
138     { 0x28,     "Suspend" },
139     { 0x29,     "Resume" },
140     { 0x2a,     "Connection Oriented Information" },
141     { 0x2b,     "Perform Location Request" },
142     { 0x2c,     "LSA Information" },
143     { 0x2d,     "Perform Location Response" },
144     { 0x2e,     "Perform Location Abort" },
145     { 0x2f,     "Common Id" },
146     { 0x30,     "Reset" },
147     { 0x31,     "Reset Acknowledge" },
148     { 0x32,     "Overload" },
149     { 0x33,     "Reserved" },
150     { 0x34,     "Reset Circuit" },
151     { 0x35,     "Reset Circuit Acknowledge" },
152     { 0x36,     "MSC Invoke Trace" },
153     { 0x37,     "BSS Invoke Trace" },
154     { 0x3a,     "Connectionless Information" },
155     { 0x40,     "Block" },
156     { 0x41,     "Blocking Acknowledge" },
157     { 0x42,     "Unblock" },
158     { 0x43,     "Unblocking Acknowledge" },
159     { 0x44,     "Circuit Group Block" },
160     { 0x45,     "Circuit Group Blocking Acknowledge" },
161     { 0x46,     "Circuit Group Unblock" },
162     { 0x47,     "Circuit Group Unblocking Acknowledge" },
163     { 0x48,     "Unequipped Circuit" },
164     { 0x4e,     "Change Circuit" },
165     { 0x4f,     "Change Circuit Acknowledge" },
166     { 0x50,     "Resource Request" },
167     { 0x51,     "Resource Indication" },
168     { 0x52,     "Paging" },
169     { 0x53,     "Cipher Mode Command" },
170     { 0x54,     "Classmark Update" },
171     { 0x55,     "Cipher Mode Complete" },
172     { 0x56,     "Queuing Indication" },
173     { 0x57,     "Complete Layer 3 Information" },
174     { 0x58,     "Classmark Request" },
175     { 0x59,     "Cipher Mode Reject" },
176     { 0x5a,     "Load Indication" },
177     { 0x04,     "VGCS/VBS Setup" },
178     { 0x05,     "VGCS/VBS Setup Ack" },
179     { 0x06,     "VGCS/VBS Setup Refuse" },
180     { 0x07,     "VGCS/VBS Assignment Request" },
181     { 0x1c,     "VGCS/VBS Assignment Result" },
182     { 0x1d,     "VGCS/VBS Assignment Failure" },
183     { 0x1e,     "VGCS/VBS Queuing Indication" },
184     { 0x1f,     "Uplink Request" },
185     { 0x27,     "Uplink Request Acknowledge" },
186     { 0x49,     "Uplink Request Confirmation" },
187     { 0x4a,     "Uplink Release Indication" },
188     { 0x4b,     "Uplink Reject Command" },
189     { 0x4c,     "Uplink Release Command" },
190     { 0x4d,     "Uplink Seized Command" },
191     { 0, NULL },
192 };
193
194 const value_string gsm_a_dtap_msg_mm_strings[] = {
195     { 0x01,     "IMSI Detach Indication" },
196     { 0x02,     "Location Updating Accept" },
197     { 0x04,     "Location Updating Reject" },
198     { 0x08,     "Location Updating Request" },
199     { 0x11,     "Authentication Reject" },
200     { 0x12,     "Authentication Request" },
201     { 0x14,     "Authentication Response" },
202     { 0x1c,     "Authentication Failure" },
203     { 0x18,     "Identity Request" },
204     { 0x19,     "Identity Response" },
205     { 0x1a,     "TMSI Reallocation Command" },
206     { 0x1b,     "TMSI Reallocation Complete" },
207     { 0x21,     "CM Service Accept" },
208     { 0x22,     "CM Service Reject" },
209     { 0x23,     "CM Service Abort" },
210     { 0x24,     "CM Service Request" },
211     { 0x25,     "CM Service Prompt" },
212     { 0x26,     "Reserved: was allocated in earlier phases of the protocol" },
213     { 0x28,     "CM Re-establishment Request" },
214     { 0x29,     "Abort" },
215     { 0x30,     "MM Null" },
216     { 0x31,     "MM Status" },
217     { 0x32,     "MM Information" },
218     { 0, NULL },
219 };
220
221 const value_string gsm_a_dtap_msg_rr_strings[] = {
222     { 0x3c,     "RR Initialisation Request" },
223     { 0x3b,     "Additional Assignment" },
224     { 0x3f,     "Immediate Assignment" },
225     { 0x39,     "Immediate Assignment Extended" },
226     { 0x3a,     "Immediate Assignment Reject" },
227
228     { 0x48,     "DTM Assignment Failure" },
229     { 0x49,     "DTM Reject" },
230     { 0x4a,     "DTM Request" },
231     { 0x4b,     "Main DCCH Assignment Command" },
232     { 0x4c,     "Packet Assignment Command" },
233
234     { 0x35,     "Ciphering Mode Command" },
235     { 0x32,     "Ciphering Mode Complete" },
236
237     { 0x30,     "Configuration Change Command" },
238     { 0x31,     "Configuration Change Ack." },
239     { 0x33,     "Configuration Change Reject" },
240
241     { 0x2e,     "Assignment Command" },
242     { 0x29,     "Assignment Complete" },
243     { 0x2f,     "Assignment Failure" },
244     { 0x2b,     "Handover Command" },
245     { 0x2c,     "Handover Complete" },
246     { 0x28,     "Handover Failure" },
247     { 0x2d,     "Physical Information" },
248     { 0x4d,     "DTM Assignment Command" },
249
250     { 0x08,     "RR-cell Change Order" },
251     { 0x23,     "PDCH Assignment Command" },
252
253     { 0x0d,     "Channel Release" },
254     { 0x0a,     "Partial Release" },
255     { 0x0f,     "Partial Release Complete" },
256
257     { 0x21,     "Paging Request Type 1" },
258     { 0x22,     "Paging Request Type 2" },
259     { 0x24,     "Paging Request Type 3" },
260     { 0x27,     "Paging Response" },
261     { 0x20,     "Notification/NCH" },
262     { 0x25,     "Reserved" },
263     { 0x26,     "Notification/Response" },
264
265     { 0x0b,     "Reserved" },
266
267 /*      ETSI TS 101 503 V8.5.0 Seems to give Other def for this Messages???
268     { 0xc0,     "Utran Classmark Change" }, CONFLICTS WITH Handover To UTRAN Command 
269     { 0xc1,     "UE RAB Preconfiguration" },
270     { 0xc2,     "cdma2000 Classmark Change" },*/
271
272         /* ETSI TS 101 503 V8.5.0 */
273     { 0x60,     "Utran Classmark Change" },  
274     { 0x61,     "UE RAB Preconfiguration" },
275     { 0x62,     "cdma2000 Classmark Change" },
276     { 0x63,     "Inter System to UTRAN Handover Command" },
277     { 0x64,     "Inter System to cdma2000 Handover Command" },
278     { 0x18,     "System Information Type 8" },
279     { 0x19,     "System Information Type 1" },
280     { 0x1a,     "System Information Type 2" },
281     { 0x1b,     "System Information Type 3" },
282     { 0x1c,     "System Information Type 4" },
283     { 0x1d,     "System Information Type 5" },
284     { 0x1e,     "System Information Type 6" },
285     { 0x1f,     "System Information Type 7" },
286
287     { 0x02,     "System Information Type 2bis" },
288     { 0x03,     "System Information Type 2ter" },
289     { 0x07,     "System Information Type 2quater" },
290     { 0x05,     "System Information Type 5bis" },
291     { 0x06,     "System Information Type 5ter" },
292     { 0x04,     "System Information Type 9" },
293     { 0x00,     "System Information Type 13" },
294
295     { 0x3d,     "System Information Type 16" },
296     { 0x3e,     "System Information Type 17" },
297
298     { 0x40,     "System Information Type 18" },
299     { 0x41,     "System Information Type 19" },
300     { 0x42,     "System Information Type 20" },
301
302     { 0x10,     "Channel Mode Modify" },
303     { 0x12,     "RR Status" },
304     { 0x17,     "Channel Mode Modify Acknowledge" },
305     { 0x14,     "Frequency Redefinition" },
306     { 0x15,     "Measurement Report" },
307     { 0x16,     "Classmark Change" },
308     { 0x13,     "Classmark Enquiry" },
309     { 0x36,     "Extended Measurement Report" },
310     { 0x37,     "Extended Measurement Order" },
311     { 0x34,     "GPRS Suspension Request" },
312
313     { 0x09,     "VGCS Uplink Grant" },
314     { 0x0e,     "Uplink Release" },
315     { 0x0c,     "Reserved" },
316     { 0x2a,     "Uplink Busy" },
317     { 0x11,     "Talker Indication" },
318
319     { 0xc0,     "UTRAN Classmark Change/Handover To UTRAN Command" },   /* spec conflict */
320
321     { 0x38,     "Application Information" },
322
323     { 0, NULL },
324 };
325
326 const value_string gsm_a_dtap_msg_cc_strings[] = {
327     { 0x01,     "Alerting" },
328     { 0x08,     "Call Confirmed" },
329     { 0x02,     "Call Proceeding" },
330     { 0x07,     "Connect" },
331     { 0x0f,     "Connect Acknowledge" },
332     { 0x0e,     "Emergency Setup" },
333     { 0x03,     "Progress" },
334     { 0x04,     "CC-Establishment" },
335     { 0x06,     "CC-Establishment Confirmed" },
336     { 0x0b,     "Recall" },
337     { 0x09,     "Start CC" },
338     { 0x05,     "Setup" },
339     { 0x17,     "Modify" },
340     { 0x1f,     "Modify Complete" },
341     { 0x13,     "Modify Reject" },
342     { 0x10,     "User Information" },
343     { 0x18,     "Hold" },
344     { 0x19,     "Hold Acknowledge" },
345     { 0x1a,     "Hold Reject" },
346     { 0x1c,     "Retrieve" },
347     { 0x1d,     "Retrieve Acknowledge" },
348     { 0x1e,     "Retrieve Reject" },
349     { 0x25,     "Disconnect" },
350     { 0x2d,     "Release" },
351     { 0x2a,     "Release Complete" },
352     { 0x39,     "Congestion Control" },
353     { 0x3e,     "Notify" },
354     { 0x3d,     "Status" },
355     { 0x34,     "Status Enquiry" },
356     { 0x35,     "Start DTMF" },
357     { 0x31,     "Stop DTMF" },
358     { 0x32,     "Stop DTMF Acknowledge" },
359     { 0x36,     "Start DTMF Acknowledge" },
360     { 0x37,     "Start DTMF Reject" },
361     { 0x3a,     "Facility" },
362     { 0, NULL },
363 };
364
365 const value_string gsm_a_dtap_msg_gmm_strings[] = {
366     { 0x01,     "Attach Request" },
367     { 0x02,     "Attach Accept" },
368     { 0x03,     "Attach Complete" },
369     { 0x04,     "Attach Reject" },
370     { 0x05,     "Detach Request" },
371     { 0x06,     "Detach Accept" },
372     { 0x08,     "Routing Area Update Request" },
373     { 0x09,     "Routing Area Update Accept" },
374     { 0x0a,     "Routing Area Update Complete" },
375     { 0x0b,     "Routing Area Update Reject" },
376     { 0x0c,     "Service Request" },
377     { 0x0d,     "Service Accept" },
378     { 0x0e,     "Service Reject" },
379     { 0x10,     "P-TMSI Reallocation Command" },
380     { 0x11,     "P-TMSI Reallocation Complete" },
381     { 0x12,     "Authentication and Ciphering Req" },
382     { 0x13,     "Authentication and Ciphering Resp" },
383     { 0x14,     "Authentication and Ciphering Rej" },
384     { 0x1c,     "Authentication and Ciphering Failure" },
385     { 0x15,     "Identity Request" },
386     { 0x16,     "Identity Response" },
387     { 0x20,     "GMM Status" },
388     { 0x21,     "GMM Information" },
389     { 0, NULL },
390 };
391
392 const value_string gsm_a_dtap_msg_sms_strings[] = {
393     { 0x01,     "CP-DATA" },
394     { 0x04,     "CP-ACK" },
395     { 0x10,     "CP-ERROR" },
396     { 0, NULL },
397 };
398
399 const value_string gsm_a_dtap_msg_sm_strings[] = {
400     { 0x41,     "Activate PDP Context Request" },
401     { 0x42,     "Activate PDP Context Accept" },
402     { 0x43,     "Activate PDP Context Reject" },
403     { 0x44,     "Request PDP Context Activation" },
404     { 0x45,     "Request PDP Context Activation rej." },
405     { 0x46,     "Deactivate PDP Context Request" },
406     { 0x47,     "Deactivate PDP Context Accept" },
407     { 0x48,     "Modify PDP Context Request(Network to MS direction)" },
408     { 0x49,     "Modify PDP Context Accept (MS to network direction)" },
409     { 0x4a,     "Modify PDP Context Request(MS to network direction)" },
410     { 0x4b,     "Modify PDP Context Accept (Network to MS direction)" },
411     { 0x4c,     "Modify PDP Context Reject" },
412     { 0x4d,     "Activate Secondary PDP Context Request" },
413     { 0x4e,     "Activate Secondary PDP Context Accept" },
414     { 0x4f,     "Activate Secondary PDP Context Reject" },
415     { 0x50,     "Reserved: was allocated in earlier phases of the protocol" },
416     { 0x51,     "Reserved: was allocated in earlier phases of the protocol" },
417     { 0x52,     "Reserved: was allocated in earlier phases of the protocol" },
418     { 0x53,     "Reserved: was allocated in earlier phases of the protocol" },
419     { 0x54,     "Reserved: was allocated in earlier phases of the protocol" },
420     { 0x55,     "SM Status" },
421     { 0x56,     "Activate MBMS Context Request" },
422     { 0x57,     "Activate MBMS Context Accept" },
423     { 0x58,     "Activate MBMS Context Reject" },
424     { 0x59,     "Request MBMS Context Activation" },
425     { 0x5a,     "Request MBMS Context Activation Reject" },
426     { 0, NULL },
427 };
428
429 const value_string gsm_a_dtap_msg_ss_strings[] = {
430     { 0x2a,     "Release Complete" },
431     { 0x3a,     "Facility" },
432     { 0x3b,     "Register" },
433     { 0, NULL },
434 };
435
436 static const value_string gsm_rp_msg_strings[] = {
437     { 0x00,     "RP-DATA (MS to Network)" },
438     { 0x01,     "RP-DATA (Network to MS)" },
439     { 0x02,     "RP-ACK (MS to Network)" },
440     { 0x03,     "RP-ACK (Network to MS)" },
441     { 0x04,     "RP-ERROR (MS to Network)" },
442     { 0x05,     "RP-ERROR (Network to MS)" },
443     { 0x06,     "RP-SMMA (MS to Network)" },
444     { 0, NULL },
445 };
446
447 static const value_string gsm_bssmap_elem_strings[] = {
448     { 0x01,     "Circuit Identity Code" },
449     { 0x02,     "Reserved" },
450     { 0x03,     "Resource Available" },
451     { 0x04,     "Cause" },
452     { 0x05,     "Cell Identifier" },
453     { 0x06,     "Priority" },
454     { 0x07,     "Layer 3 Header Information" },
455     { 0x08,     "IMSI" },
456     { 0x09,     "TMSI" },
457     { 0x0a,     "Encryption Information" },
458     { 0x0b,     "Channel Type" },
459     { 0x0c,     "Periodicity" },
460     { 0x0d,     "Extended Resource Indicator" },
461     { 0x0e,     "Number Of MSs" },
462     { 0x0f,     "Reserved" },
463     { 0x10,     "Reserved" },
464     { 0x11,     "Reserved" },
465     { 0x12,     "Classmark Information Type 2" },
466     { 0x13,     "Classmark Information Type 3" },
467     { 0x14,     "Interference Band To Be Used" },
468     { 0x15,     "RR Cause" },
469     { 0x16,     "Reserved" },
470     { 0x17,     "Layer 3 Information" },
471     { 0x18,     "DLCI" },
472     { 0x19,     "Downlink DTX Flag" },
473     { 0x1a,     "Cell Identifier List" },
474     { 0x1b,     "Response Request" },
475     { 0x1c,     "Resource Indication Method" },
476     { 0x1d,     "Classmark Information Type 1" },
477     { 0x1e,     "Circuit Identity Code List" },
478     { 0x1f,     "Diagnostic" },
479     { 0x20,     "Layer 3 Message Contents" },
480     { 0x21,     "Chosen Channel" },
481     { 0x22,     "Total Resource Accessible" },
482     { 0x23,     "Cipher Response Mode" },
483     { 0x24,     "Channel Needed" },
484     { 0x25,     "Trace Type" },
485     { 0x26,     "TriggerID" },
486     { 0x27,     "Trace Reference" },
487     { 0x28,     "TransactionID" },
488     { 0x29,     "Mobile Identity" },
489     { 0x2a,     "OMCID" },
490     { 0x2b,     "Forward Indicator" },
491     { 0x2c,     "Chosen Encryption Algorithm" },
492     { 0x2d,     "Circuit Pool" },
493     { 0x2e,     "Circuit Pool List" },
494     { 0x2f,     "Time Indication" },
495     { 0x30,     "Resource Situation" },
496     { 0x31,     "Current Channel Type 1" },
497     { 0x32,     "Queuing Indicator" },
498     { 0x40,     "Speech Version" },
499     { 0x33,     "Assignment Requirement" },
500     { 0x35,     "Talker Flag" },
501     { 0x36,     "Connection Release Requested" },
502     { 0x37,     "Group Call Reference" },
503     { 0x38,     "eMLPP Priority" },
504     { 0x39,     "Configuration Evolution Indication" },
505     { 0x3a,     "Old BSS to New BSS Information" },
506     { 0x3b,     "LSA Identifier" },
507     { 0x3c,     "LSA Identifier List" },
508     { 0x3d,     "LSA Information" },
509     { 0x3e,     "LCS QoS" },
510     { 0x3f,     "LSA access control suppression" },
511     { 0x43,     "LCS Priority" },
512     { 0x44,     "Location Type" },
513     { 0x45,     "Location Estimate" },
514     { 0x46,     "Positioning Data" },
515     { 0x47,     "LCS Cause" },
516     { 0x48,     "LCS Client Type" },
517     { 0x49,     "APDU" },
518     { 0x4a,     "Network Element Identity" },
519     { 0x4b,     "GPS Assistance Data" },
520     { 0x4c,     "Deciphering Keys" },
521     { 0x4d,     "Return Error Request" },
522     { 0x4e,     "Return Error Cause" },
523     { 0x4f,     "Segmentation" },
524     { 0, NULL },
525 };
526
527 static const value_string gsm_dtap_elem_strings[] = {
528     /* Common Information Elements 10.5.1 */
529     { 0x00,     "Cell Identity" },
530     { 0x00,     "Ciphering Key Sequence Number" },
531     { 0x00,     "Location Area Identification" },
532     { 0x00,     "Mobile Identity" },
533     { 0x00,     "Mobile Station Classmark 1" },
534     { 0x00,     "Mobile Station Classmark 2" },
535     { 0x00,     "Mobile Station Classmark 3" },
536     { 0x00,     "Descriptive group or broadcast call reference" },
537     { 0x00,     "Group Cipher Key Number" },
538     { 0x00,     "PD and SAPI $(CCBS)$" },
539         /* Pos 10 */
540     { 0x00,     "Priority Level" },
541     { 0x00,     "PLMN List" },
542     /* Radio Resource Management Information Elements 10.5.2, most are from 10.5.1 */
543 /*
544  * [3]  10.5.2.1a       BA Range
545  */
546     { 0x00,     "Cell Channel Description" },           /* [3]  10.5.2.1b       */      
547 /* [3]  10.5.2.1c       BA List Pref
548  * [3]  10.5.2.1d       UTRAN Frequency List
549  * [3]  10.5.2.1e       Cell selection indicator after release of all TCH and SDCCH IE
550  */
551         { 0x00, "Cell Description" },                           /* 10.5.2.2  */
552 /*
553  * [3]  10.5.2.3        Cell Options (BCCH)     
554  * [3]  10.5.2.3a       Cell Options (SACCH)
555  * [3]  10.5.2.4        Cell Selection Parameters
556  * [3]  10.5.2.4a       (void) */
557         { 0x00, "Channel Description" },                        /* 10.5.2.5      */
558         { 0x00, "Channel Description 2" },                      /* 10.5.2.5a */
559
560         { 0x00, "Channel Mode" },                                       /* [3]  10.5.2.6 */     
561         { 0x00, "Channel Mode 2" },                                     /* [3]  10.5.2.7 */     
562 /* [3]  10.5.2.7a       UTRAN predefined configuration status information / START-CS / UE CapabilityUTRAN Classmark information element 218
563  * [3]  10.5.2.7b       (void) */
564         { 0x00, "Classmark Enquiry Mask" },                     /* [3]  10.5.2.7c */
565 /* [3]  10.5.2.7d       GERAN Iu Mode Classmark information element */
566         { 0x00, "Channel Needed"},                                      /* [3]  10.5.2.8        */
567  /* [3]  10.5.2.8a      (void) */
568  /* [3]  10.5.2.8b      Channel Request Description 2 */
569                 /* Pos 20 */
570         { 0x00, "Cipher Mode Setting" },                                /* [3]  10.5.2.9        */
571 /* [3]  10.5.2.10       Cipher Response
572  * [3]  10.5.2.11       Control Channel Description
573  * [3]  10.5.2.11a      DTM Information Details */
574         { 0x00, "Dynamic ARFCN Mapping" },                      /* [3]  10.5.2.11b      */
575         { 0x00, "Frequency Channel Sequence" },         /* [3]  10.5.2.12       */
576     { 0x00,     "Frequency List" },                                     /* 10.5.2.13            */
577         { 0x00, "Frequency Short List" },                       /* 10.5.2.14            */
578         { 0x00, "Frequency Short List2" },                      /* 10.5.2.14a           */
579 /* [3]  10.5.2.14b      Group Channel Description
580  * [3]  10.5.2.14c      GPRS Resumption
581  * [3]  10.5.2.14d      GPRS broadcast information
582  * [3]  10.5.2.14e      Enhanced DTM CS Release Indication
583  */
584         { 0x00, "Handover Reference" },                         /* 10.5.2.15 */
585 /*
586  * [3] 10.5.2.16 IA Rest Octets
587  * [3] 10.5.2.17 IAR Rest Octets
588  * [3] 10.5.2.18 IAX Rest Octets
589  * [3] 10.5.2.19 L2 Pseudo Length
590  * [3] 10.5.2.20 Measurement Results
591  * [3] 10.5.2.20a GPRS Measurement Results
592  */
593         { 0x00, "Mobile Allocation" },                          /* [3] 10.5.2.21        */ 
594         { 0x00, "Mobile Time Difference" },                     /* [3] 10.5.2.21a       */
595         { 0x00, "MultiRate configuration" },            /* [3] 10.5.2.21aa      */
596         /* Pos 30 */
597         { 0x00, "Multislot Allocation" },                       /* [3] 10.5.2.21b       */ 
598  /*
599  * [3] 10.5.2.21c NC mode
600  * [3] 10.5.2.22 Neighbour Cell Description
601  * [3] 10.5.2.22a Neighbour Cell Description 2
602  * [3] 10.5.2.22b (void)
603  * [3] 10.5.2.22c NT/N Rest Octets
604  * [3] 10.5.2.23 P1 Rest Octets
605  * [3] 10.5.2.24 P2 Rest Octets
606  * [3] 10.5.2.25 P3 Rest Octets
607  * [3] 10.5.2.25a Packet Channel Description
608  * [3] 10.5.2.25b Dedicated mode or TBF
609  * [3] 10.5.2.25c RR Packet Uplink Assignment
610  * [3] 10.5.2.25d RR Packet Downlink Assignment
611  * [3] 10.5.2.26 Page Mode
612  * [3] 10.5.2.26a (void)
613  * [3] 10.5.2.26b (void)
614  * [3] 10.5.2.26c (void)
615  * [3] 10.5.2.26d (void)
616  * [3] 10.5.2.27 NCC Permitted
617  */
618         { 0x00, "Power Command" },                                      /* 10.5.2.28 */
619         { 0x00, "Power Command and access type" },      /* 10.5.2.28a */
620 /*
621  * [3] 10.5.2.29 RACH Control Parameters
622  * [3] 10.5.2.30 Request Reference
623  */
624     { 0x00,     "RR Cause" },                                           /* 10.5.2.31 */
625         { 0x00, "Synchronization Indication" },         /* 10.5.2.39 */
626 /* [3] 10.5.2.32 SI 1 Rest Octets
627  * [3] 10.5.2.33 SI 2bis Rest Octets 
628  * [3] 10.5.2.33a SI 2ter Rest Octets
629  * [3] 10.5.2.33b SI 2quater Rest Octets
630  * [3] 10.5.2.34 SI 3 Rest Octets
631  * [3] 10.5.2.35 SI 4 Rest Octets
632  * [3] 10.5.2.35a SI 6 Rest Octets
633  * [3] 10.5.2.36 SI 7 Rest Octets
634  * [3] 10.5.2.37 SI 8 Rest Octets
635  * [3] 10.5.2.37a SI 9 Rest Octets
636  * [3] 10.5.2.37b SI 13 Rest Octets
637  * [3] 10.5.2.37c (void)
638  * [3] 10.5.2.37d (void)
639  * [3] 10.5.2.37e SI 16 Rest Octets
640  * [3] 10.5.2.37f SI 17 Rest Octets
641  * [3] 10.5.2.37g SI 19 Rest Octets
642  * [3] 10.5.2.37h SI 18 Rest Octets
643  * [3] 10.5.2.37i SI 20 Rest Octets */
644     { 0x00,     "Starting Time" },                                      /* [3] 10.5.2.38 Starting Time  */
645     { 0x00,     "Timing Advance" },                                     /* [3] 10.5.2.40 Timing Advance */ 
646         { 0x00, "Time Difference" },                            /* [3] 10.5.2.41 Time Difference                                */
647         { 0x00, "TLLI" },                                                       /* [3] 10.5.2.41a TLLI                                                  */
648 /*
649  * [3] 10.5.2.42 TMSI/P-TMSI */
650         { 0x00, "VGCS target mode Indication" },        /* [3] 10.5.2.42a                                                               */ 
651         /* Pos 40 */
652         { 0x00, "VGCS Ciphering Parameters" },          /* [3] 10.5.2.42b                                                               */
653 /* [3] 10.5.2.43 Wait Indication
654  * [3] 10.5.2.44 SI10 rest octets $(ASCI)$
655  * [3] 10.5.2.45 EXTENDED MEASUREMENT RESULTS
656  * [3] 10.5.2.46 Extended Measurement Frequency List */
657         { 0x00, "Suspension Cause" },                           /* [3] 10.5.2.47                                                                */ 
658 /* [3] 10.5.2.48 APDU ID 
659  * [3] 10.5.2.49 APDU Flags
660  * [3] 10.5.2.50 APDU Data
661  * [3] 10.5.2.51 Handover To UTRAN Command
662  * [3] 10.5.2.52 Handover To cdma2000 Command 
663  * [3] 10.5.2.53 (void)
664  * [3] 10.5.2.54 (void)
665  * [3] 10.5.2.55 (void)
666  * [3] 10.5.2.56 3G Target Cell */
667         { 0x00, "Dedicated Service Information" },              /* [3] 10.5.2.59        */
668
669
670     /* Mobility Management Information Elements 10.5.3 */
671     { 0x00,     "Authentication Parameter RAND" },
672     { 0x00,     "Authentication Parameter AUTN (UMTS authentication challenge only)" },
673     { 0x00,     "Authentication Response Parameter" },
674     { 0x00,     "Authentication Response Parameter (extension) (UMTS authentication challenge only)" },
675     { 0x00,     "Authentication Failure Parameter (UMTS authentication challenge only)" },
676     { 0x00,     "CM Service Type" },
677     { 0x00,     "Identity Type" },
678         /* Pos 50 */
679     { 0x00,     "Location Updating Type" },
680     { 0x00,     "Network Name" },
681     { 0x00,     "Reject Cause" },
682     { 0x00,     "Follow-on Proceed" },
683     { 0x00,     "Time Zone" },
684     { 0x00,     "Time Zone and Time" },
685     { 0x00,     "CTS Permission" },
686     { 0x00,     "LSA Identifier" },
687     { 0x00,     "Daylight Saving Time" },
688     { 0x00, "Emergency Number List" },
689     /* Call Control Information Elements 10.5.4 */
690         /* Pos 60 */
691     { 0x00,     "Auxiliary States" },                                   /* 10.5.4.4 Auxiliary states */
692     { 0x00,     "Bearer Capability" },                                  /* 10.5.4.4a Backup bearer capability */
693     { 0x00,     "Call Control Capabilities" },
694     { 0x00,     "Call State" },
695     { 0x00,     "Called Party BCD Number" },
696     { 0x00,     "Called Party Subaddress" },
697     { 0x00,     "Calling Party BCD Number" },
698     { 0x00,     "Calling Party Subaddress" },
699     { 0x00,     "Cause" },
700     { 0x00,     "CLIR Suppression" },
701     { 0x00,     "CLIR Invocation" },
702     { 0x00,     "Congestion Level" },
703     { 0x00,     "Connected Number" },
704     { 0x00,     "Connected Subaddress" },
705     { 0x00,     "Facility" },
706     { 0x00,     "High Layer Compatibility" },
707     { 0x00,     "Keypad Facility" },
708     { 0x00,     "Low Layer Compatibility" },
709     { 0x00,     "More Data" },
710     { 0x00,     "Notification Indicator" },
711     { 0x00,     "Progress Indicator" },
712     { 0x00,     "Recall type $(CCBS)$" },
713     { 0x00,     "Redirecting Party BCD Number" },
714     { 0x00,     "Redirecting Party Subaddress" },
715     { 0x00,     "Repeat Indicator" },
716     { 0x00,     "Reverse Call Setup Direction" },
717     { 0x00,     "SETUP Container $(CCBS)$" },
718     { 0x00,     "Signal" },
719     { 0x00,     "SS Version Indicator" },
720     { 0x00,     "User-user" },
721     { 0x00,     "Alerting Pattern $(NIA)$" },                   /* 10.5.4.26 Alerting Pattern $(NIA)$ */
722     { 0x00,     "Allowed Actions $(CCBS)$" },
723     { 0x00,     "Stream Identifier" },
724     { 0x00,     "Network Call Control Capabilities" },
725     { 0x00,     "Cause of No CLI" },
726     { 0x00,     "Immediate Modification Indicator" },   /* 10.5.4.30 Cause of No CLI */
727         /* 10.5.4.31 Void */
728     { 0x00,     "Supported Codec List" },                               /* 10.5.4.32 Supported codec list */
729     { 0x00,     "Service Category" },                                   /* 10.5.4.33 Service category */
730         /* 10.5.4.34 Redial */
731         /* 10.5.4.35 Network-initiated Service Upgrade indicator */
732     /* GPRS Mobility Management Information Elements 10.5.5 */
733     { 0x00,     "Attach Result" },
734     { 0x00,     "Attach Type" },
735     { 0x00,     "Cipher Algorithm" },
736     { 0x00,     "TMSI Status" },
737     { 0x00,     "Detach Type" },
738     { 0x00,     "DRX Parameter" },
739     { 0x00,     "Force to Standby" },
740     { 0x00, "Force to Standby" },
741     { 0x00,     "P-TMSI Signature" },
742     { 0x00,     "P-TMSI Signature 2" },
743     { 0x00,     "Identity Type 2" },
744     { 0x00,     "IMEISV Request" },
745     { 0x00,     "Receive N-PDU Numbers List" },
746     { 0x00,     "MS Network Capability" },
747     { 0x00,     "MS Radio Access Capability" },
748     { 0x00,     "GMM Cause" },
749     { 0x00,     "Routing Area Identification" },
750     { 0x00,     "Update Result" },
751     { 0x00, "Update Type" },
752     { 0x00,     "A&C Reference Number" },
753     { 0x00, "A&C Reference Number" },
754     { 0x00,     "Service Type" },
755     { 0x00,     "Cell Notification" },
756     { 0x00, "PS LCS Capability" },
757     { 0x00,     "Network Feature Support" },
758         { 0x00, "Inter RAT information container" },
759     /* Short Message Service Information Elements [5] 8.1.4 */
760     { 0x00,     "CP-User Data" },
761     { 0x00,     "CP-Cause" },
762     /* Short Message Service Information Elements [5] 8.2 */
763     { 0x00,     "RP-Message Reference" },
764     { 0x00,     "RP-Origination Address" },
765     { 0x00,     "RP-Destination Address" },
766     { 0x00,     "RP-User Data" },
767     { 0x00,     "RP-Cause" },
768     /* Session Management Information Elements 10.5.6 */
769     { 0x00,     "Access Point Name" },
770     { 0x00,     "Network Service Access Point Identifier" },
771     { 0x00,     "Protocol Configuration Options" },
772     { 0x00,     "Packet Data Protocol Address" },
773     { 0x00,     "Quality Of Service" },
774     { 0x00,     "SM Cause" },
775     { 0x00,     "Linked TI" },
776     { 0x00,     "LLC Service Access Point Identifier" },
777     { 0x00,     "Tear Down Indicator" },
778     { 0x00,     "Packet Flow Identifier" },
779     { 0x00,     "Traffic Flow Template" },
780     /* GPRS Common Information Elements 10.5.7 */
781     { 0x00,     "PDP Context Status" },
782     { 0x00,     "Radio Priority" },
783     { 0x00,     "GPRS Timer" },
784     { 0x00,     "GPRS Timer 2" },
785     { 0x00, "Radio Priority 2"},
786         { 0x00, "MBMS context status"},
787     { 0x00, "Spare Nibble"},
788     { 0, NULL },
789 };
790
791 const gchar *gsm_a_pd_str[] = {
792     "Group Call Control",
793     "Broadcast Call Control",
794     "Reserved: was allocated in earlier phases of the protocol",
795     "Call Control; call related SS messages",
796     "GPRS Transparent Transport Protocol (GTTP)",
797     "Mobility Management messages",
798     "Radio Resources Management messages",
799     "Unknown",
800     "GPRS Mobility Management messages",
801     "SMS messages",
802     "GPRS Session Management messages",
803     "Non call related SS messages",
804     "Location Services",
805     "Unknown",
806     "Reserved for extension of the PD to one octet length",
807     "Reserved for tests procedures"
808 };
809 /* L3 Protocol discriminator values according to TS 24 007 (6.4.0)  */
810 static const value_string protocol_discriminator_vals[] = {
811         {0x0,           "Group call control"},
812         {0x1,           "Broadcast call control"},
813         {0x2,           "Reserved: was allocated in earlier phases of the protocol"},
814         {0x3,           "Call Control; call related SS messages"},
815         {0x4,           "GPRS Transparent Transport Protocol (GTTP)"},
816         {0x5,           "Mobility Management messages"},
817         {0x6,           "Radio Resources Management messages"},
818         {0x7,           "Unknown"},
819         {0x8,           "GPRS mobility management messages"},
820         {0x9,           "SMS messages"},
821         {0xa,           "GPRS session management messages"},
822         {0xb,           "Non call related SS messages"},
823         {0xc,           "Location services specified in 3GPP TS 44.071 [8a]"},
824         {0xd,           "Unknown"},
825         {0xe,           "Reserved for extension of the PD to one octet length "},
826         {0xf,           "Reserved for tests procedures described in 3GPP TS 44.014 [5a] and 3GPP TS 34.109 [17a]."},
827         { 0,    NULL }
828 };
829
830 static const value_string gsm_a_pd_short_str_vals[] = {
831         {0x0,           "GCC"},                         /* Group Call Control */
832         {0x1,           "BCC"},                         /* Broadcast Call Control */
833         {0x2,           "Reserved"},            /* : was allocated in earlier phases of the protocol */
834         {0x3,           "CC"},                          /* Call Control; call related SS messages */
835         {0x4,           "GTTP"},                        /* GPRS Transparent Transport Protocol (GTTP) */
836         {0x5,           "MM"},                          /* Mobility Management messages */
837         {0x6,           "RR"},                          /* Radio Resources Management messages */
838         {0x7,           "Unknown"},
839         {0x8,           "GMM"},                         /* GPRS Session Management messages */
840         {0x9,           "SMS"},
841         {0xa,           "SM"},                          /* GPRS Session Management messages */
842         {0xb,           "SS"},
843         {0xc,           "LS"},                          /* Location Services */
844         {0xd,           "Unknown"},
845         {0xe,           "Reserved"},            /*  for extension of the PD to one octet length  */
846         {0xf,           "Reserved"},            /*  for tests procedures described in 3GPP TS 44.014 [5a] and 3GPP TS 34.109 [17a].*/
847         { 0,    NULL }
848 };
849 static const value_string bssap_cc_values[] = {
850     { 0x00,             "not further specified" },
851     { 0x80,             "FACCH or SDCCH" },
852     { 0xc0,             "SACCH" },
853     { 0,                NULL } };
854
855 static const value_string bssap_sapi_values[] = {
856     { 0x00,             "RR/MM/CC" },
857     { 0x03,             "SMS" },
858     { 0,                NULL } };
859
860 /* Mobile Station Classmark Value strings
861  */
862
863 /* Mobile Station Classmark  
864  * Revision level 
865  */
866 const value_string gsm_a_msc_rev_vals[] = {
867         { 0,            "Reserved for GSM phase 1"},
868         { 1,            "Used by GSM phase 2 mobile stations"},
869         { 2,            "Used by mobile stations supporting R99 or later versions of the protocol"},
870         { 3,            "Reserved for future use"},
871         { 0,    NULL }
872 };
873
874 /* ES IND (octet 3, bit 5) "Controlled Early Classmark Sending" option implementation */
875 static const value_string ES_IND_vals[] = {
876         { 0,            "Controlled Early Classmark Sending option is not implemented in the MS"},
877         { 1,            "Controlled Early Classmark Sending option is implemented in the MS"},
878         { 0,    NULL }
879 };
880 /* A5/1 algorithm supported (octet 3, bit 4 */
881 static const value_string A5_1_algorithm_sup_vals[] = {
882         { 0,            "encryption algorithm A5/1 available"},
883         { 1,            "encryption algorithm A5/1 not available"},
884         { 0,    NULL }
885 };
886 /* RF Power Capability (Octet 3) */
887 static const value_string RF_power_capability_vals[] = {
888         { 0,            "class 1"},
889         { 1,            "class 2"},
890         { 2,            "class 3"},
891         { 3,            "class 4"},
892         { 4,            "class 5"},
893         { 7,            "RF Power capability is irrelevant in this information element"},
894         { 0,    NULL }
895 };
896 /* PS capability (pseudo-synchronization capability) (octet 4) */
897 static const value_string ps_sup_cap_vals[] = {
898         { 0,            "PS capability not present"},
899         { 1,            "PS capability present"},
900         { 0,    NULL }
901 };
902 /* SS Screening Indicator (octet 4)defined in 3GPP TS 24.080 */
903 static const value_string SS_screening_indicator_vals[] = {
904         { 0,            "Default value of phase 1"},
905         { 1,            "Capability of handling of ellipsis notation and phase 2 error handling "},
906         { 2,            "For future use"},
907         { 3,            "For future use"},
908         { 0,    NULL }
909 };
910 /* SM capability (MT SMS pt to pt capability) (octet 4)*/
911 static const value_string SM_capability_vals[] = {
912         { 0,            "Mobile station does not support mobile terminated point to point SMS"},
913         { 1,            "Mobile station supports mobile terminated point to point SMS"},
914         { 0,    NULL }
915 };
916 /* VBS notification reception (octet 4) */
917 static const value_string VBS_notification_rec_vals[] = {
918         { 0,            "no VBS capability or no notifications wanted"},
919         { 1,            "VBS capability and notifications wanted"},
920         { 0,    NULL }
921 };
922 /* VGCS notification reception (octet 4) */
923 static const value_string VGCS_notification_rec_vals[] = {
924         { 0,            "no VGCS capability or no notifications wanted"},
925         { 1,            "VGCS capability and notifications wanted"},
926         { 0,    NULL }
927 };
928 /* FC Frequency Capability (octet 4 ) */
929 static const value_string FC_frequency_cap_vals[] = {
930         { 0,            "The MS does not support the E-GSM or R-GSM band"},
931         { 1,            "The MS does support the E-GSM or R-GSM "},
932         { 0,    NULL }
933 };
934 /* CM3 (octet 5, bit 8) */
935 static const value_string CM3_vals[] = {
936         { 0,            "The MS does not support any options that are indicated in CM3"},
937         { 1,            "The MS supports options that are indicated in classmark 3 IE"},
938         { 0,    NULL }
939 };
940 /* LCS VA capability (LCS value added location request notification capability) (octet 5,bit 6) */
941 static const value_string LCS_VA_cap_vals[] = {
942         { 0,            "LCS value added location request notification capability not supported"},
943         { 1,            "LCS value added location request notification capability supported"},
944         { 0,    NULL }
945 };
946 /* UCS2 treatment (octet 5, bit 5) */
947 static const value_string UCS2_treatment_vals[] = {
948         { 0,            "the ME has a preference for the default alphabet"},
949         { 1,            "the ME has no preference between the use of the default alphabet and the use of UCS2"},
950         { 0,    NULL }
951 };
952 /* SoLSA (octet 5, bit 4) */
953 static const value_string SoLSA_vals[] = {
954         { 0,            "The ME does not support SoLSA"},
955         { 1,            "The ME supports SoLSA"},
956         { 0,    NULL }
957 };
958 /* CMSP: CM Service Prompt (octet 5, bit 3) */
959 static const value_string CMSP_vals[] = {
960         { 0,            "Network initiated MO CM connection request not supported"},
961         { 1,            "Network initiated MO CM connection request supported for at least one CM protocol"},
962         { 0,    NULL }
963 };
964 /* A5/3 algorithm supported (octet 5, bit 2) */
965 static const value_string A5_3_algorithm_sup_vals[] = {
966         { 0,            "encryption algorithm A5/3 not available"},
967         { 1,            "encryption algorithm A5/3 available"},
968         { 0,    NULL }
969 };
970
971 /* A5/2 algorithm supported (octet 5, bit 1) */
972 static const value_string A5_2_algorithm_sup_vals[] = {
973         { 0,            "encryption algorithm A5/2 not available"},
974         { 1,            "encryption algorithm A5/2 available"},
975         { 0,    NULL }
976 };
977
978  static const value_string gsm_a_algorithm_identifier_vals[] = {
979         { 0,            "Cipher with algorithm A5/1"},
980         { 1,            "Cipher with algorithm A5/2"},
981         { 2,            "Cipher with algorithm A5/3"},
982         { 3,            "Cipher with algorithm A5/4"},
983         { 4,            "Cipher with algorithm A5/5"},
984         { 5,            "Cipher with algorithm A5/6"},
985         { 6,            "Cipher with algorithm A5/7"},
986         { 7,            "Reserved"},
987         { 0,    NULL }
988 };
989
990  static const value_string mobile_identity_type_vals[] = {
991         { 1,            "IMSI"},
992         { 2,            "IMEI"},
993         { 3,            "IMEISV"},
994         { 4,            "TMSI/P-TMSI"},
995         { 5,            "TMGI and optional MBMS Session Identity"}, /* ETSI TS 124 008 V6.8.0 (2005-03) p326 */
996         { 0,            "No Identity"},
997         { 0,    NULL }
998 };
999
1000 static const value_string oddevenind_vals[] = {
1001         { 0,            "Even number of identity digits"},
1002         { 1,            "Odd number of identity digits"},
1003         { 0,    NULL }
1004 };
1005
1006 /* RR cause value (octet 2) TS 44.018 6.11.0*/
1007 static const value_string gsm_a_rr_RR_cause_vals[] = {
1008         { 0,            "Normal event"},
1009         { 1,            "Abnormal release, unspecified"},
1010         { 2,            "Abnormal release, channel unacceptable"},
1011         { 3,            "Abnormal release, timer expired"},
1012         { 4,            "Abnormal release, no activity on the radio path"},
1013         { 5,            "Preemptive release"},
1014         { 6,            "UTRAN configuration unknown"},
1015         { 8,            "Handover impossible, timing advance out of range"},
1016         { 9,            "Channel mode unacceptable"},
1017         { 10,           "Frequency not implemented"},
1018         { 13,           "Originator or talker leaving group call area"},
1019         { 12,           "Lower layer failure"},
1020         { 0x41,         "Call already cleared"},
1021         { 0x5f,         "Semantically incorrect message"},
1022         { 0x60,         "Invalid mandatory information"},
1023         { 0x61,         "Message type non-existent or not implemented"},
1024         { 0x62,         "Message type not compatible with protocol state"},
1025         { 0x64,         "Conditional IE error"},
1026         { 0x65,         "No cell allocation available"},
1027         { 0x6f,         "Protocol error unspecified"},
1028         { 0,    NULL }
1029 };
1030 /* Cell identification discriminator */
1031 static const value_string gsm_a_rr_cell_id_disc_vals[] = {
1032         { 0,            "The whole Cell Global Identification, CGI, is used to identify the cells."},
1033         { 1,            "Location Area Code, LAC, and Cell Identify, CI, is used to identify the cells."},
1034         { 2,            "Cell Identity, CI, is used to identify the cells."},
1035         { 3,            "No cell is associated with the transaction."},
1036         { 4,            "Location Area Identification, LAI, is used to identify all cells within a Location Area."},
1037         { 5,            "Location Area Code, LAC, is used to identify all cells within a location area."},
1038         { 6,            "All cells on the BSS are identified."},
1039         { 8,            "Intersystem Handover to UTRAN or cdma2000. PLMN-ID, LAC, and RNC-ID, are encoded to identify the target RNC."},
1040         { 9,            "Intersystem Handover to UTRAN or cdma2000. The RNC-ID is coded to identify the target RNC."},
1041         { 10,           "Intersystem Handover to UTRAN or cdma2000. LAC and RNC-ID are encoded to identify the target RNC."},
1042         { 0,    NULL }
1043 };
1044
1045
1046 #define DTAP_PD_MASK            0x0f
1047 #define DTAP_SKIP_MASK          0xf0
1048 #define DTAP_TI_MASK            DTAP_SKIP_MASK
1049 #define DTAP_TIE_PRES_MASK      0x07                    /* after TI shifted to right */
1050 #define DTAP_TIE_MASK           0x7f
1051
1052 #define DTAP_MM_IEI_MASK        0x3f
1053 #define DTAP_RR_IEI_MASK        0xff
1054 #define DTAP_CC_IEI_MASK        0x3f
1055 #define DTAP_GMM_IEI_MASK       0xff
1056 #define DTAP_SMS_IEI_MASK       0xff
1057 #define DTAP_SM_IEI_MASK        0xff
1058 #define DTAP_SS_IEI_MASK        0x3f
1059
1060 /* Initialize the protocol and registered fields */
1061 static int proto_a_bssmap = -1;
1062 static int proto_a_dtap = -1;
1063 static int proto_a_rp = -1;
1064
1065 static int gsm_a_tap = -1;
1066
1067 static int hf_gsm_a_none = -1;
1068 static int hf_gsm_a_bssmap_msg_type = -1;
1069 static int hf_gsm_a_dtap_msg_mm_type = -1;
1070 static int hf_gsm_a_dtap_msg_rr_type = -1;
1071 static int hf_gsm_a_dtap_msg_cc_type = -1;
1072 static int hf_gsm_a_dtap_msg_gmm_type = -1;
1073 static int hf_gsm_a_dtap_msg_sms_type = -1;
1074 static int hf_gsm_a_dtap_msg_sm_type = -1;
1075 static int hf_gsm_a_dtap_msg_ss_type = -1;
1076 static int hf_gsm_a_rp_msg_type = -1;
1077 static int hf_gsm_a_length = -1;
1078 static int hf_gsm_a_bssmap_elem_id = -1;
1079 static int hf_gsm_a_dtap_elem_id = -1;
1080 static int hf_gsm_a_imsi = -1;
1081 static int hf_gsm_a_tmsi = -1;
1082 static int hf_gsm_a_imei = -1;
1083 static int hf_gsm_a_imeisv = -1;
1084 static int hf_gsm_a_cld_party_bcd_num = -1;
1085 static int hf_gsm_a_clg_party_bcd_num = -1;
1086 static int hf_gsm_a_cell_ci = -1;
1087 static int hf_gsm_a_cell_lac = -1;
1088 static int hf_gsm_a_dlci_cc = -1;
1089 static int hf_gsm_a_dlci_spare = -1;
1090 static int hf_gsm_a_dlci_sapi = -1;
1091 static int hf_gsm_a_bssmap_cause = -1;
1092 static int hf_gsm_a_dtap_cause = -1;
1093
1094 static int hf_gsm_a_MSC_rev = -1;
1095 static int hf_gsm_a_ES_IND                      = -1;
1096 static int hf_gsm_a_qos_traffic_cls = -1;
1097 static int hf_gsm_a_qos_del_order = -1;
1098 static int hf_gsm_a_qos_del_of_err_sdu = -1;
1099 static int hf_gsm_a_qos_ber = -1;
1100 static int hf_gsm_a_qos_sdu_err_rat = -1;
1101 static int hf_gsm_a_qos_traff_hdl_pri = -1;
1102 static int hf_gsm_a_A5_1_algorithm_sup = -1;
1103 static int hf_gsm_a_RF_power_capability = -1;
1104 static int hf_gsm_a_ps_sup_cap          = -1;
1105 static int hf_gsm_a_SS_screening_indicator = -1;
1106 static int hf_gsm_a_SM_capability                = -1;
1107 static int hf_gsm_a_VBS_notification_rec = -1;
1108 static int hf_gsm_a_VGCS_notification_rec = -1;
1109 static int hf_gsm_a_FC_frequency_cap    = -1;
1110 static int hf_gsm_a_CM3                         = -1;
1111 static int hf_gsm_a_LCS_VA_cap          = -1;
1112 static int hf_gsm_a_UCS2_treatment      = -1;
1113 static int hf_gsm_a_SoLSA                               = -1;
1114 static int hf_gsm_a_CMSP                                = -1;
1115 static int hf_gsm_a_A5_3_algorithm_sup= -1;
1116 static int hf_gsm_a_A5_2_algorithm_sup = -1;
1117
1118 static int hf_gsm_a_odd_even_ind = -1;
1119 static int hf_gsm_a_mobile_identity_type = -1;
1120 static int hf_gsm_a_L3_protocol_discriminator = -1; 
1121 static int hf_gsm_a_skip_ind = -1; 
1122
1123 static int hf_gsm_a_bcc                         = -1;
1124 static int hf_gsm_a_ncc                         = -1;
1125 static int hf_gsm_a_bcch_arfcn          = -1;
1126 static int hf_gsm_a_rr_ho_ref_val = -1;
1127 static int hf_gsm_a_b7spare = -1;
1128 static int hf_gsm_a_b8spare = -1;
1129 static int hf_gsm_a_rr_pow_cmd_atc = -1;
1130 static int hf_gsm_a_rr_pow_cmd_epc = -1;
1131 static int hf_gsm_a_rr_pow_cmd_fpcepc = -1;
1132 static int hf_gsm_a_rr_pow_cmd_powlev = -1;
1133 static int hf_gsm_a_rr_sync_ind_nci = -1;
1134 static int hf_gsm_a_rr_sync_ind_rot = -1;
1135 static int hf_gsm_a_rr_sync_ind_si = -1;
1136 static int hf_gsm_a_rr_format_id = -1;
1137 static int hf_gsm_a_rr_channel_mode = -1;
1138 static int hf_gsm_a_rr_channel_mode2 = -1;
1139 static int hf_gsm_a_rr_sc = -1;
1140 static int hf_gsm_a_algorithm_id = -1;
1141 static int hf_gsm_a_rr_multirate_speech_ver = -1;
1142 static int hf_gsm_a_rr_NCSB                             = -1;
1143 static int hf_gsm_a_rr_ICMI                             = -1;
1144 static int hf_gsm_a_rr_start_mode               = -1;
1145 static int hf_gsm_a_rr_timing_adv = -1;
1146 static int hf_gsm_a_rr_time_diff = -1;
1147 static int hf_gsm_a_rr_tlli = -1;
1148 static int hf_gsm_a_rr_target_mode = -1;
1149 static int hf_gsm_a_rr_group_cipher_key_number = -1;
1150 static int hf_gsm_a_rr_last_segment = -1;
1151 static int hf_gsm_a_gmm_split_on_ccch = -1;
1152 static int hf_gsm_a_gmm_non_drx_timer = -1;
1153 static int hf_gsm_a_gmm_cn_spec_drs_cycle_len_coef = -1;
1154 static int hf_gsm_a_rr_RR_cause = -1;
1155 static int hf_gsm_a_be_cell_id_disc = -1;
1156 static int hf_gsm_a_be_rnc_id = -1;
1157 static int hf_gsm_a_rr_cm_cng_msg_req = -1;
1158 static int hf_gsm_a_rr_utran_cm_cng_msg_req = -1;
1159 static int hf_gsm_a_rr_cdma200_cm_cng_msg_req = -1;
1160 static int hf_gsm_a_rr_geran_iu_cm_cng_msg_req = -1;
1161 static int hf_gsm_a_rr_chnl_needed_ch1 = -1;
1162 static int hf_gsm_a_rr_chnl_needed_ch2 = -1;
1163 static int hf_gsm_a_rr_suspension_cause = -1;
1164 static int hf_ROS_component = -1;
1165 static int hf_ROS_invoke = -1;                    /* Invoke */
1166 static int hf_ROS_returnResultLast = -1;          /* ReturnResult */
1167 static int hf_ROS_returnError = -1;               /* ReturnError */
1168 static int hf_ROS_reject = -1;                    /* Reject */
1169 static int hf_ROS_invokeID = -1;                  /* InvokeIdType */
1170 static int hf_ROS_linkedID = -1;                  /* InvokeIdType */
1171 static int hf_ROS_opCode = -1;                    /* OPERATION */
1172 static int hf_ROS_parameter = -1;                 /* Parameter */
1173 static int hf_ROS_resultretres = -1;              /* T_resultretres */
1174 static int hf_ROS_errorCode = -1;                 /* ErrorCode */
1175 static int hf_ROS_invokeIDRej = -1;               /* T_invokeIDRej */
1176 static int hf_ROS_derivable = -1;                 /* InvokeIdType */
1177 static int hf_ROS_not_derivable = -1;             /* NULL */
1178 static int hf_ROS_problem = -1;                   /* T_problem */
1179 static int hf_ROS_generalProblem = -1;            /* GeneralProblem */
1180 static int hf_ROS_invokeProblem = -1;             /* InvokeProblem */
1181 static int hf_ROS_returnResultProblem = -1;       /* ReturnResultProblem */
1182 static int hf_ROS_returnErrorProblem = -1;        /* ReturnErrorProblem */
1183 static int hf_ROS_localValue = -1;                /* INTEGER */
1184 static int hf_ROS_globalValue = -1;               /* OBJECT_IDENTIFIER */
1185 static int hf_ROS_nationaler = -1;                /* INTEGER_M32768_32767 */
1186 static int hf_ROS_privateer = -1;                 /* INTEGER */
1187 static int hf_gsm_a_rr_set_of_amr_codec_modes_v1_b8 = -1;
1188 static int hf_gsm_a_rr_set_of_amr_codec_modes_v1_b7 = -1;
1189 static int hf_gsm_a_rr_set_of_amr_codec_modes_v1_b6 = -1;
1190 static int hf_gsm_a_rr_set_of_amr_codec_modes_v1_b5 = -1;
1191 static int hf_gsm_a_rr_set_of_amr_codec_modes_v1_b4 = -1;
1192 static int hf_gsm_a_rr_set_of_amr_codec_modes_v1_b3 = -1;
1193 static int hf_gsm_a_rr_set_of_amr_codec_modes_v1_b2 = -1;
1194 static int hf_gsm_a_rr_set_of_amr_codec_modes_v1_b1 = -1;
1195 static int hf_gsm_a_rr_set_of_amr_codec_modes_v2_b5 = -1;
1196 static int hf_gsm_a_rr_set_of_amr_codec_modes_v2_b4 = -1;
1197 static int hf_gsm_a_rr_set_of_amr_codec_modes_v2_b3 = -1;
1198 static int hf_gsm_a_rr_set_of_amr_codec_modes_v2_b2 = -1;
1199 static int hf_gsm_a_rr_set_of_amr_codec_modes_v2_b1 = -1;
1200
1201 static int hf_gsm_a_extension = -1;
1202 static int hf_gsm_a_type_of_number = -1;
1203 static int hf_gsm_a_numbering_plan_id = -1;
1204
1205 static int hf_gsm_a_ptmsi_sig =-1;
1206 static int hf_gsm_a_ptmsi_sig2 =-1;
1207
1208 static int hf_gsm_a_tft_op_code = -1;
1209 static int hf_gsm_a_tft_e_bit = -1;
1210 static int hf_gsm_a_tft_pkt_flt = -1;
1211 static int hf_gsm_a_tft_ip4_address = -1;
1212 static int hf_gsm_a_tft_ip4_mask = -1;
1213 static int hf_gsm_a_tft_ip6_address = -1;
1214 static int hf_gsm_a_tft_ip6_mask = -1;
1215 static int hf_gsm_a_tft_protocol_header = -1;
1216 static int hf_gsm_a_tft_port = -1;
1217 static int hf_gsm_a_tft_port_low = -1;
1218 static int hf_gsm_a_tft_port_high = -1;
1219 static int hf_gsm_a_tft_security = -1;
1220 static int hf_gsm_a_tft_traffic_mask = -1;
1221 static int hf_gsm_a_tft_flow = -1;
1222
1223 static int hf_gsm_a_apdu_protocol_id = -1;
1224 static int hf_gsm_a_lsa_id = -1;
1225
1226 /* Initialize the subtree pointers */
1227 static gint ett_bssmap_msg = -1;
1228 static gint ett_dtap_msg = -1;
1229 static gint ett_rp_msg = -1;
1230 static gint ett_elems = -1;
1231 static gint ett_elem = -1;
1232 static gint ett_dtap_oct_1 = -1;
1233 static gint ett_cm_srvc_type = -1;
1234 static gint ett_gsm_enc_info = -1;
1235 static gint ett_cell_list = -1;
1236 static gint ett_dlci = -1;
1237 static gint ett_bc_oct_3a = -1;
1238 static gint ett_bc_oct_4 = -1;
1239 static gint ett_bc_oct_5 = -1;
1240 static gint ett_bc_oct_5a = -1;
1241 static gint ett_bc_oct_5b = -1;
1242 static gint ett_bc_oct_6 = -1;
1243 static gint ett_bc_oct_6a = -1;
1244 static gint ett_bc_oct_6b = -1;
1245 static gint ett_bc_oct_6c = -1;
1246 static gint ett_bc_oct_6d = -1;
1247 static gint ett_bc_oct_6e = -1;
1248 static gint ett_bc_oct_6f = -1;
1249 static gint ett_bc_oct_6g = -1;
1250 static gint ett_bc_oct_7 = -1;
1251
1252 static gint ett_tc_component = -1;
1253 static gint ett_tc_invoke_id = -1;
1254 static gint ett_tc_linked_id = -1;
1255 static gint ett_tc_opr_code = -1;
1256 static gint ett_tc_err_code = -1;
1257 static gint ett_tc_prob_code = -1;
1258 static gint ett_tc_sequence = -1;
1259
1260 static gint ett_gmm_drx = -1;
1261 static gint ett_gmm_detach_type = -1;
1262 static gint ett_gmm_attach_type = -1;
1263 static gint ett_gmm_context_stat = -1;
1264 static gint ett_gmm_update_type = -1;
1265 static gint ett_gmm_radio_cap = -1;
1266
1267 static gint ett_ros = -1;
1268 static gint ett_ROS_Component = -1;
1269 static gint ett_ROS_Invoke = -1;
1270 static gint ett_ROS_ReturnResult = -1;
1271 static gint ett_ROS_T_resultretres = -1;
1272 static gint ett_ROS_ReturnError = -1;
1273 static gint ett_ROS_Reject = -1;
1274 static gint ett_ROS_T_invokeIDRej = -1;
1275 static gint ett_ROS_T_problem = -1;
1276 static gint ett_ROS_OPERATION = -1;
1277 static gint ett_ROS_ERROR = -1;
1278 static gint ett_ROS_ErrorCode = -1;
1279
1280 static gint ett_sm_tft = -1;
1281
1282 static char a_bigbuf[1024];
1283
1284 static dissector_handle_t data_handle;
1285 static dissector_handle_t bssmap_handle;
1286 static dissector_handle_t dtap_handle;
1287 static dissector_handle_t rp_handle;
1288 static dissector_table_t sms_dissector_table;   /* SMS TPDU */
1289 static dissector_table_t gprs_sm_pco_subdissector_table; /* GPRS SM PCO PPP Protocols */
1290
1291 static packet_info *g_pinfo;
1292 static proto_tree *g_tree;
1293 static gint comp_type_tag;
1294 static guint32 localValue;
1295
1296 static sccp_msg_info_t* sccp_msg;
1297 static sccp_assoc_info_t* sccp_assoc;
1298
1299 /*
1300  * this should be set on a per message basis, if possible
1301  */
1302 #define IS_UPLINK_FALSE         0
1303 #define IS_UPLINK_TRUE          1
1304 #define IS_UPLINK_UNKNOWN       2
1305 static gint is_uplink;
1306
1307
1308 typedef struct dgt_set_t
1309 {
1310     unsigned char out[15];
1311 }
1312 dgt_set_t;
1313
1314 static dgt_set_t Dgt_mbcd = {
1315     {
1316   /*  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e */
1317      '0','1','2','3','4','5','6','7','8','9','*','#','a','b','c'
1318     }
1319 };
1320
1321 static dgt_set_t Dgt_tbcd = {
1322     {
1323   /*  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e */
1324      '0','1','2','3','4','5','6','7','8','9','?','B','C','*','#'
1325     }
1326 };
1327
1328 static dgt_set_t Dgt1_9_bcd = {
1329     {
1330   /*  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e */
1331      '0','1','2','3','4','5','6','7','8','9','?','?','?','?','?'
1332     }
1333 };
1334
1335 /* FUNCTIONS */
1336
1337 /*
1338  * Unpack BCD input pattern into output ASCII pattern
1339  *
1340  * Input Pattern is supplied using the same format as the digits
1341  *
1342  * Returns: length of unpacked pattern
1343  */
1344 static int
1345 my_dgt_tbcd_unpack(
1346     char        *out,           /* ASCII pattern out */
1347     guchar      *in,            /* packed pattern in */
1348     int         num_octs,       /* Number of octets to unpack */
1349     dgt_set_t   *dgt            /* Digit definitions */
1350     )
1351 {
1352     int cnt = 0;
1353     unsigned char i;
1354
1355     while (num_octs)
1356     {
1357         /*
1358          * unpack first value in byte
1359          */
1360         i = *in++;
1361         *out++ = dgt->out[i & 0x0f];
1362         cnt++;
1363
1364         /*
1365          * unpack second value in byte
1366          */
1367         i >>= 4;
1368
1369         if (i == 0x0f)  /* odd number bytes - hit filler */
1370             break;
1371
1372         *out++ = dgt->out[i];
1373         cnt++;
1374         num_octs--;
1375     }
1376
1377     *out = '\0';
1378
1379     return(cnt);
1380 }
1381
1382
1383 /* ELEMENT FUNCTIONS */
1384
1385 #define EXTRANEOUS_DATA_CHECK(edc_len, edc_max_len) \
1386     if ((edc_len) > (edc_max_len)) \
1387     { \
1388         proto_tree_add_text(tree, tvb, \
1389             curr_offset, (edc_len) - (edc_max_len), "Extraneous Data"); \
1390         curr_offset += ((edc_len) - (edc_max_len)); \
1391     }
1392
1393 #define SHORT_DATA_CHECK(sdc_len, sdc_min_len) \
1394     if ((sdc_len) < (sdc_min_len)) \
1395     { \
1396         proto_tree_add_text(tree, tvb, \
1397             curr_offset, (sdc_len), "Short Data (?)"); \
1398         curr_offset += (sdc_len); \
1399         return(curr_offset - offset); \
1400     }
1401
1402 #define EXACT_DATA_CHECK(edc_len, edc_eq_len) \
1403     if ((edc_len) != (edc_eq_len)) \
1404     { \
1405         proto_tree_add_text(tree, tvb, \
1406             curr_offset, (edc_len), "Unexpected Data Length"); \
1407         curr_offset += (edc_len); \
1408         return(curr_offset - offset); \
1409     }
1410
1411 #define NO_MORE_DATA_CHECK(nmdc_len) \
1412     if ((nmdc_len) == (curr_offset - offset)) return(nmdc_len);
1413
1414 /*
1415  * Decode the MCC/MNC from 3 octets in 'octs'
1416  */
1417 static void
1418 mcc_mnc_aux(guint8 *octs, gchar *mcc, gchar *mnc)
1419 {
1420     if ((octs[0] & 0x0f) <= 9)
1421     {
1422         mcc[0] = Dgt_tbcd.out[octs[0] & 0x0f];
1423     }
1424     else
1425     {
1426         mcc[0] = (octs[0] & 0x0f) + 55;
1427     }
1428
1429     if (((octs[0] & 0xf0) >> 4) <= 9)
1430     {
1431         mcc[1] = Dgt_tbcd.out[(octs[0] & 0xf0) >> 4];
1432     }
1433     else
1434     {
1435         mcc[1] = ((octs[0] & 0xf0) >> 4) + 55;
1436     }
1437
1438     if ((octs[1] & 0x0f) <= 9)
1439     {
1440         mcc[2] = Dgt_tbcd.out[octs[1] & 0x0f];
1441     }
1442     else
1443     {
1444         mcc[2] = (octs[1] & 0x0f) + 55;
1445     }
1446
1447     mcc[3] = '\0';
1448
1449     if (((octs[1] & 0xf0) >> 4) <= 9)
1450     {
1451         mnc[2] = Dgt_tbcd.out[(octs[1] & 0xf0) >> 4];
1452     }
1453     else
1454     {
1455         mnc[2] = ((octs[1] & 0xf0) >> 4) + 55;
1456     }
1457
1458     if ((octs[2] & 0x0f) <= 9)
1459     {
1460         mnc[0] = Dgt_tbcd.out[octs[2] & 0x0f];
1461     }
1462     else
1463     {
1464         mnc[0] = (octs[2] & 0x0f) + 55;
1465     }
1466
1467     if (((octs[2] & 0xf0) >> 4) <= 9)
1468     {
1469         mnc[1] = Dgt_tbcd.out[(octs[2] & 0xf0) >> 4];
1470     }
1471     else
1472     {
1473         mnc[1] = ((octs[2] & 0xf0) >> 4) + 55;
1474     }
1475
1476     if (mnc[1] == 'F')
1477     {
1478         /*
1479          * only a 1 digit MNC (very old)
1480          */
1481         mnc[1] = '\0';
1482     }
1483     else if (mnc[2] == 'F')
1484     {
1485         /*
1486          * only a 2 digit MNC
1487          */
1488         mnc[2] = '\0';
1489     }
1490     else
1491     {
1492         mnc[3] = '\0';
1493     }
1494 }
1495
1496 typedef enum
1497 {
1498     BE_CIC,      /* Circuit Identity Code */
1499     BE_RSVD_1,   /* Reserved */
1500     BE_RES_AVAIL,        /* Resource Available */
1501     BE_CAUSE,    /* Cause */
1502     BE_CELL_ID,  /* Cell Identifier */
1503     BE_PRIO,     /* Priority */
1504     BE_L3_HEADER_INFO,   /* Layer 3 Header Information */
1505     BE_IMSI,     /* IMSI */
1506     BE_TMSI,     /* TMSI */
1507     BE_ENC_INFO,         /* Encryption Information */
1508     BE_CHAN_TYPE,        /* Channel Type */
1509     BE_PERIODICITY,      /* Periodicity */
1510     BE_EXT_RES_IND,      /* Extended Resource Indicator */
1511     BE_NUM_MS,   /* Number Of MSs */
1512     BE_RSVD_2,   /* Reserved */
1513     BE_RSVD_3,   /* Reserved */
1514     BE_RSVD_4,   /* Reserved */
1515     BE_CM_INFO_2,        /* Classmark Information Type 2 */
1516     BE_CM_INFO_3,        /* Classmark Information Type 3 */
1517     BE_INT_BAND,         /* Interference Band To Be Used */
1518     BE_RR_CAUSE,         /* RR Cause */
1519     BE_RSVD_5,   /* Reserved */
1520     BE_L3_INFO,  /* Layer 3 Information */
1521     BE_DLCI,     /* DLCI */
1522     BE_DOWN_DTX_FLAG,    /* Downlink DTX Flag */
1523     BE_CELL_ID_LIST,     /* Cell Identifier List */
1524     BE_RESP_REQ,         /* Response Request */
1525     BE_RES_IND_METHOD,   /* Resource Indication Method */
1526     BE_CM_INFO_1,        /* Classmark Information Type 1 */
1527     BE_CIC_LIST,         /* Circuit Identity Code List */
1528     BE_DIAG,     /* Diagnostic */
1529     BE_L3_MSG,   /* Layer 3 Message Contents */
1530     BE_CHOSEN_CHAN,      /* Chosen Channel */
1531     BE_TOT_RES_ACC,      /* Total Resource Accessible */
1532     BE_CIPH_RESP_MODE,   /* Cipher Response Mode */
1533     BE_CHAN_NEEDED,      /* Channel Needed */
1534     BE_TRACE_TYPE,       /* Trace Type */
1535     BE_TRIGGERID,        /* TriggerID */
1536     BE_TRACE_REF,        /* Trace Reference */
1537     BE_TRANSID,  /* TransactionID */
1538     BE_MID,      /* Mobile Identity */
1539     BE_OMCID,    /* OMCID */
1540     BE_FOR_IND,  /* Forward Indicator */
1541     BE_CHOSEN_ENC_ALG,   /* Chosen Encryption Algorithm */
1542     BE_CCT_POOL,         /* Circuit Pool */
1543     BE_CCT_POOL_LIST,    /* Circuit Pool List */
1544     BE_TIME_IND,         /* Time Indication */
1545     BE_RES_SIT,  /* Resource Situation */
1546     BE_CURR_CHAN_1,      /* Current Channel Type 1 */
1547     BE_QUE_IND,  /* Queueing Indicator */
1548     BE_SPEECH_VER,       /* Speech Version */
1549     BE_ASS_REQ,  /* Assignment Requirement */
1550     BE_TALKER_FLAG,      /* Talker Flag */
1551     BE_CONN_REL_REQ,     /* Connection Release Requested */
1552     BE_GROUP_CALL_REF,   /* Group Call Reference */
1553     BE_EMLPP_PRIO,       /* eMLPP Priority */
1554     BE_CONF_EVO_IND,     /* Configuration Evolution Indication */
1555     BE_OLD2NEW_INFO,     /* Old BSS to New BSS Information */
1556     BE_LSA_ID,   /* LSA Identifier */
1557     BE_LSA_ID_LIST,      /* LSA Identifier List */
1558     BE_LSA_INFO,         /* LSA Information */
1559     BE_LCS_QOS,  /* LCS QoS */
1560     BE_LSA_ACC_CTRL,     /* LSA access control suppression */
1561     BE_LCS_PRIO,         /* LCS Priority */
1562     BE_LOC_TYPE,         /* Location Type */
1563     BE_LOC_EST,  /* Location Estimate */
1564     BE_POS_DATA,         /* Positioning Data */
1565     BE_LCS_CAUSE,        /* LCS Cause */
1566     BE_LCS_CLIENT,       /* LCS Client Type */
1567     BE_APDU,     /* APDU */
1568     BE_NE_ID,    /* Network Element Identity */
1569     BE_GSP_ASSIST_DATA,  /* GPS Assistance Data */
1570     BE_DECIPH_KEYS,      /* Deciphering Keys */
1571     BE_RET_ERR_REQ,      /* Return Error Request */
1572     BE_RET_ERR_CAUSE,    /* Return Error Cause */
1573     BE_SEG,      /* Segmentation */
1574     BE_NONE     /* NONE */
1575 }
1576 bssmap_elem_idx_t;
1577
1578 #define NUM_GSM_BSSMAP_ELEM (sizeof(gsm_bssmap_elem_strings)/sizeof(value_string))
1579 static gint ett_gsm_bssmap_elem[NUM_GSM_BSSMAP_ELEM];
1580
1581 /*
1582  * [2] 3.2.2.2
1583  */
1584 static guint8
1585 be_cic(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
1586 {
1587     guint32     curr_offset;
1588     guint32     value;
1589
1590     len = len;
1591     curr_offset = offset;
1592
1593     value = tvb_get_ntohs(tvb, curr_offset);
1594
1595     other_decode_bitfield_value(a_bigbuf, value, 0xffe0, 16);
1596     proto_tree_add_text(tree,
1597         tvb, curr_offset, 2,
1598         "%s :  PCM Multiplexer: %u",
1599         a_bigbuf,
1600         (value & 0xffe0) >> 5);
1601
1602     other_decode_bitfield_value(a_bigbuf, value, 0x001f, 16);
1603     proto_tree_add_text(tree,
1604         tvb, curr_offset, 2,
1605         "%s :  Timeslot: %u",
1606         a_bigbuf,
1607         value & 0x001f);
1608
1609     curr_offset += 2;
1610
1611     if (add_string)
1612         g_snprintf(add_string, string_len, " - (%u) (0x%04x)", value, value);
1613
1614     /* no length check possible */
1615
1616     return(curr_offset - offset);
1617 }
1618
1619 /*
1620  * [2] 3.2.2.5
1621  */
1622 static guint8
1623 be_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
1624 {
1625     guint8      oct;
1626     guint32     value;
1627     guint32     curr_offset;
1628     const gchar *str = NULL;
1629
1630     curr_offset = offset;
1631
1632     oct = tvb_get_guint8(tvb, curr_offset);
1633
1634     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1635     proto_tree_add_text(tree,
1636         tvb, curr_offset, 1,
1637         "%s :  Extension: %s",
1638         a_bigbuf,
1639         (oct & 0x80) ? "extended" : "not extended");
1640
1641     if (oct & 0x80)
1642     {
1643         /* 2 octet cause */
1644
1645         if ((oct & 0x0f) == 0x00)
1646         {
1647             /* national cause */
1648             switch ((oct & 0x70) >> 4)
1649             {
1650             case 0: str = "Normal Event"; break;
1651             case 1: str = "Normal Event"; break;
1652             case 2: str = "Resource Unavailable"; break;
1653             case 3: str = "Service or option not available"; break;
1654             case 4: str = "Service or option not implemented"; break;
1655             case 5: str = "Invalid message (e.g., parameter out of range)"; break;
1656             case 6: str = "Protocol error"; break;
1657             default:
1658                 str = "Interworking";
1659                 break;
1660             }
1661
1662             other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
1663             proto_tree_add_text(tree,
1664                 tvb, curr_offset, 1,
1665                 "%s :  Cause Class: %s",
1666                 a_bigbuf,
1667                 str);
1668
1669             other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
1670             proto_tree_add_text(tree,
1671                 tvb, curr_offset, 1,
1672                 "%s :  National Cause",
1673                 a_bigbuf);
1674
1675             curr_offset++;
1676
1677             proto_tree_add_text(tree, tvb, curr_offset, 1,
1678                 "Cause Value");
1679
1680             curr_offset++;
1681
1682             if (add_string)
1683                 g_snprintf(add_string, string_len, " - (National Cause)");
1684         }
1685         else
1686         {
1687             value = tvb_get_guint8(tvb, curr_offset + 1);
1688
1689             other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
1690             proto_tree_add_text(tree,
1691                 tvb, curr_offset, 1,
1692                 "%s :  Cause (MSB): %u",
1693                 a_bigbuf,
1694                 ((oct & 0x7f) << 8) | value);
1695
1696             curr_offset++;
1697
1698             other_decode_bitfield_value(a_bigbuf, value, 0xff, 8);
1699             proto_tree_add_text(tree, tvb, curr_offset, 1,
1700                 "%s :  Cause (LSB)",
1701                 a_bigbuf);
1702
1703             curr_offset++;
1704         }
1705     }
1706     else
1707     {
1708         switch (oct)
1709         {
1710         case 0x00: str = "Radio interface message failure"; break;
1711         case 0x01: str = "Radio interface failure"; break;
1712         case 0x02: str = "Uplink quality"; break;
1713         case 0x03: str = "Uplink strength"; break;
1714         case 0x04: str = "Downlink quality"; break;
1715         case 0x05: str = "Downlink strength"; break;
1716         case 0x06: str = "Distance"; break;
1717         case 0x07: str = "O and M intervention"; break;
1718         case 0x08: str = "Response to MSC invocation"; break;
1719         case 0x09: str = "Call control"; break;
1720         case 0x0a: str = "Radio interface failure, reversion to old channel"; break;
1721         case 0x0b: str = "Handover successful"; break;
1722         case 0x0c: str = "Better Cell"; break;
1723         case 0x0d: str = "Directed Retry"; break;
1724         case 0x0e: str = "Joined group call channel"; break;
1725         case 0x0f: str = "Traffic"; break;
1726
1727         case 0x20: str = "Equipment failure"; break;
1728         case 0x21: str = "No radio resource available"; break;
1729         case 0x22: str = "Requested terrestrial resource unavailable"; break;
1730         case 0x23: str = "CCCH overload"; break;
1731         case 0x24: str = "Processor overload"; break;
1732         case 0x25: str = "BSS not equipped"; break;
1733         case 0x26: str = "MS not equipped"; break;
1734         case 0x27: str = "Invalid cell"; break;
1735         case 0x28: str = "Traffic Load"; break;
1736         case 0x29: str = "Preemption"; break;
1737
1738         case 0x30: str = "Requested transcoding/rate adaption unavailable"; break;
1739         case 0x31: str = "Circuit pool mismatch"; break;
1740         case 0x32: str = "Switch circuit pool"; break;
1741         case 0x33: str = "Requested speech version unavailable"; break;
1742         case 0x34: str = "LSA not allowed"; break;
1743
1744         case 0x40: str = "Ciphering algorithm not supported"; break;
1745
1746         case 0x50: str = "Terrestrial circuit already allocated"; break;
1747         case 0x51: str = "Invalid message contents"; break;
1748         case 0x52: str = "Information element or field missing"; break;
1749         case 0x53: str = "Incorrect value"; break;
1750         case 0x54: str = "Unknown Message type"; break;
1751         case 0x55: str = "Unknown Information Element"; break;
1752
1753         case 0x60: str = "Protocol Error between BSS and MSC"; break;
1754         case 0x61: str = "VGCS/VBS call non existent"; break;
1755
1756         default:
1757             if ((oct >= 0x10) && (oct <= 0x17)) { str = "Reserved for international use"; }
1758             else if ((oct >= 0x18) && (oct <= 0x1f)) { str = "Reserved for national use"; }
1759             else if ((oct >= 0x2a) && (oct <= 0x2f)) { str = "Reserved for national use"; }
1760             else if ((oct >= 0x35) && (oct <= 0x3f)) { str = "Reserved for international use"; }
1761             else if ((oct >= 0x41) && (oct <= 0x47)) { str = "Reserved for international use"; }
1762             else if ((oct >= 0x48) && (oct <= 0x4f)) { str = "Reserved for national use"; }
1763             else if ((oct >= 0x56) && (oct <= 0x57)) { str = "Reserved for international use"; }
1764             else if ((oct >= 0x58) && (oct <= 0x5f)) { str = "Reserved for national use"; }
1765             else if ((oct >= 0x62) && (oct <= 0x67)) { str = "Reserved for international use"; }
1766             else if ((oct >= 0x68) && (oct <= 0x6f)) { str = "Reserved for national use"; }
1767             else if ((oct >= 0x70) && (oct <= 0x77)) { str = "Reserved for international use"; }
1768             else if ((oct >= 0x78) && (oct <= 0x7f)) { str = "Reserved for national use"; }
1769             break;
1770         }
1771
1772         other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
1773         proto_tree_add_uint_format(tree, hf_gsm_a_bssmap_cause,
1774             tvb, curr_offset, 1, oct & 0x7f,
1775             "%s :  Cause: (%u) %s",
1776             a_bigbuf,
1777             oct & 0x7f,
1778             str);
1779
1780         curr_offset++;
1781
1782         if (add_string)
1783             g_snprintf(add_string, string_len, " - (%u) %s", oct & 0x7f, str);
1784     }
1785
1786     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
1787
1788     return(curr_offset - offset);
1789 }
1790
1791 /*
1792  * [2] 3.2.2.7
1793  */
1794 static guint8
1795 be_tmsi(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
1796 {
1797     guint32     curr_offset;
1798     guint32     value;
1799
1800     curr_offset = offset;
1801
1802     value = tvb_get_ntohl(tvb, curr_offset);
1803
1804     proto_tree_add_uint(tree, hf_gsm_a_tmsi,
1805         tvb, curr_offset, 4,
1806         value);
1807
1808     if (add_string)
1809         g_snprintf(add_string, string_len, " - (0x%04x)", value);
1810
1811     curr_offset += 4;
1812
1813     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
1814
1815     return(curr_offset - offset);
1816 }
1817
1818 /*
1819  * [2] 3.2.2.9
1820  */
1821 static guint8
1822 be_l3_header_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
1823 {
1824     guint8      oct;
1825     guint32     curr_offset;
1826
1827     curr_offset = offset;
1828
1829     oct = tvb_get_guint8(tvb, curr_offset);
1830
1831     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
1832     proto_tree_add_text(tree,
1833         tvb, curr_offset, 1,
1834         "%s :  Spare",
1835         a_bigbuf);
1836
1837         proto_tree_add_item(tree, hf_gsm_a_L3_protocol_discriminator, tvb, curr_offset, 1, FALSE);
1838
1839
1840     curr_offset++;
1841
1842     NO_MORE_DATA_CHECK(len);
1843
1844     oct = tvb_get_guint8(tvb, curr_offset);
1845
1846     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
1847     proto_tree_add_text(tree,
1848         tvb, curr_offset, 1,
1849         "%s :  Spare",
1850         a_bigbuf);
1851
1852     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
1853     proto_tree_add_text(tree,
1854         tvb, curr_offset, 1,
1855         "%s :  TI flag: %s",
1856         a_bigbuf,
1857         ((oct & 0x08) ?  "allocated by receiver" : "allocated by sender"));
1858
1859     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
1860     proto_tree_add_text(tree,
1861         tvb, curr_offset, 1,
1862         "%s :  TIO: %u",
1863         a_bigbuf,
1864         oct & 0x07);
1865
1866     curr_offset++;
1867
1868     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
1869
1870     return(curr_offset - offset);
1871 }
1872
1873 /*
1874  * [2] 3.2.2.10
1875  */
1876 static guint8
1877 be_enc_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
1878 {
1879     guint8      oct;
1880     guint8      mask;
1881     guint8      alg_id;
1882     guint32     curr_offset;
1883
1884     curr_offset = offset;
1885
1886     oct = tvb_get_guint8(tvb, curr_offset);
1887
1888     mask = 0x80;
1889     alg_id = 7;
1890
1891     do
1892     {
1893         other_decode_bitfield_value(a_bigbuf, oct, mask, 8);
1894         proto_tree_add_text(tree,
1895             tvb, curr_offset, 1,
1896             "%s :  GSM A5/%u: %spermitted",
1897             a_bigbuf,
1898             alg_id,
1899             (mask & oct) ? "" : "not ");
1900
1901         mask >>= 1;
1902         alg_id--;
1903     }
1904     while (mask != 0x01);
1905
1906     other_decode_bitfield_value(a_bigbuf, oct, mask, 8);
1907     proto_tree_add_text(tree,
1908         tvb, curr_offset, 1,
1909         "%s :  No encryption: %spermitted",
1910         a_bigbuf,
1911         (mask & oct) ? "" : "not ");
1912
1913     curr_offset++;
1914
1915     NO_MORE_DATA_CHECK(len);
1916
1917     proto_tree_add_text(tree,
1918         tvb, curr_offset, len - (curr_offset - offset),
1919                         "Key: %s",
1920                         tvb_bytes_to_str(tvb, curr_offset, len-(curr_offset-offset) ));
1921
1922     curr_offset += len - (curr_offset - offset);
1923
1924     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
1925
1926     return(curr_offset - offset);
1927 }
1928
1929 /*
1930  * [2] 3.2.2.11
1931  */
1932 guint8
1933 be_chan_type(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
1934 {
1935     guint8      oct;
1936     guint8      sdi;
1937     guint8      num_chan;
1938     guint32     curr_offset;
1939     const gchar *str;
1940
1941     curr_offset = offset;
1942
1943     oct = tvb_get_guint8(tvb, curr_offset);
1944
1945     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
1946     proto_tree_add_text(tree,
1947         tvb, curr_offset, 1,
1948         "%s :  Spare",
1949         a_bigbuf);
1950
1951     sdi = oct & 0x0f;
1952     switch (sdi)
1953     {
1954     case 1: str = "Speech"; break;
1955     case 2: str = "Data"; break;
1956     case 3: str = "Signalling"; break;
1957     default:
1958         str = "Reserved";
1959         break;
1960     }
1961
1962     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
1963     proto_tree_add_text(tree,
1964         tvb, curr_offset, 1,
1965         "%s :  Speech/Data Indicator: %s",
1966         a_bigbuf,
1967         str);
1968
1969     if (add_string)
1970         g_snprintf(add_string, string_len, " - (%s)", str);
1971
1972     curr_offset++;
1973
1974     NO_MORE_DATA_CHECK(len);
1975
1976     oct = tvb_get_guint8(tvb, curr_offset);
1977
1978     if (sdi == 0x01)
1979     {
1980         /* speech */
1981
1982         switch (oct)
1983         {
1984         case 0x08: str = "Full rate TCH channel Bm.  Prefer full rate TCH"; break;
1985         case 0x09: str = "Half rate TCH channel Lm.  Prefer half rate TCH"; break;
1986         case 0x0a: str = "Full or Half rate channel, Full rate preferred changes allowed after first allocation"; break;
1987         case 0x0b: str = "Full or Half rate channel, Half rate preferred changes allowed after first allocation"; break;
1988         case 0x1a: str = "Full or Half rate channel, Full rate preferred changes between full and half rate not allowed after first allocation"; break;
1989         case 0x1b: str = "Full or Half rate channel, Half rate preferred changes between full and half rate not allowed after first allocation"; break;
1990         case 0x0f: str = "Full or Half rate channel, changes allowed after first allocation"; break;
1991         case 0x1f: str = "Full or Half rate channel, changes between full and half rate not allowed after first allocation"; break;
1992         default:
1993             str = "Reserved";
1994             break;
1995         }
1996
1997         proto_tree_add_text(tree,
1998             tvb, curr_offset, 1,
1999             "Channel Rate and Type: %s",
2000             str);
2001
2002         curr_offset++;
2003
2004         NO_MORE_DATA_CHECK(len);
2005
2006         do
2007         {
2008             oct = tvb_get_guint8(tvb, curr_offset);
2009
2010             other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
2011             proto_tree_add_text(tree,
2012                 tvb, curr_offset, 1,
2013                 "%s :  Extension: %s",
2014                 a_bigbuf,
2015                 (oct & 0x80) ? "extended" : "not extended");
2016
2017             switch (oct & 0x7f)
2018             {
2019             case 0x01: str = "GSM speech full rate version 1"; break;
2020             case 0x11: str = "GSM speech full rate version 2"; break;
2021             case 0x21: str = "GSM speech full rate version 3 (AMR)"; break;
2022
2023             case 0x05: str = "GSM speech half rate version 1"; break;
2024             case 0x15: str = "GSM speech half rate version 2"; break;
2025             case 0x25: str = "GSM speech half rate version 3 (AMR)"; break;
2026
2027             default:
2028                 str = "Reserved";
2029                 break;
2030             }
2031
2032             other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
2033             proto_tree_add_text(tree,
2034                 tvb, curr_offset, 1,
2035                 "%s :  Speech version identifier: %s",
2036                 a_bigbuf,
2037                 str);
2038
2039             curr_offset++;
2040         }
2041         while ((len - (curr_offset - offset)) > 0);
2042     }
2043     else if (sdi == 0x02)
2044     {
2045         /* data */
2046
2047         num_chan = 0;
2048
2049         switch (oct)
2050         {
2051         case 0x08: str = "Full rate TCH channel Bm"; break;
2052         case 0x09: str = "Half rate TCH channel Lm"; break;
2053         case 0x0a: str = "Full or Half rate TCH channel, Full rate preferred, changes allowed also after first channel allocation as a result of the request"; break;
2054         case 0x0b: str = "Full or Half rate TCH channel, Half rate preferred, changes allowed also after first channel allocation as a result of the request"; break;
2055         case 0x1a: str = "Full or Half rate TCH channel, Full rate preferred, changes not allowed after first channel allocation as a result of the request"; break;
2056         case 0x1b: str = "Full or Half rate TCH channel. Half rate preferred, changes not allowed after first channel allocation as a result of the request"; break;
2057         default:
2058             if ((oct >= 0x20) && (oct <= 0x27))
2059             {
2060                 str = "Full rate TCH channels in a multislot configuration, changes by the BSS of the the number of TCHs and if applicable the used radio interface rate per channel allowed after first channel allocation as a result of the request";
2061
2062                 num_chan = (oct - 0x20) + 1;
2063             }
2064             else if ((oct >= 0x30) && (oct <= 0x37))
2065             {
2066                 str = "Full rate TCH channels in a multislot configuration, changes by the BSS of the number of TCHs or the used radio interface rate per channel not allowed after first channel allocation as a result of the request";
2067
2068                 num_chan = (oct - 0x30) + 1;
2069             }
2070             else
2071             {
2072                 str = "Reserved";
2073             }
2074             break;
2075         }
2076
2077         if (num_chan > 0)
2078         {
2079             proto_tree_add_text(tree,
2080                 tvb, curr_offset, 1,
2081                 "Channel Rate and Type: Max channels %u, %s",
2082                 num_chan,
2083                 str);
2084         }
2085         else
2086         {
2087             proto_tree_add_text(tree,
2088                 tvb, curr_offset, 1,
2089                 "Channel Rate and Type: %s",
2090                 str);
2091         }
2092
2093         curr_offset++;
2094
2095         NO_MORE_DATA_CHECK(len);
2096
2097         oct = tvb_get_guint8(tvb, curr_offset);
2098
2099         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
2100         proto_tree_add_text(tree,
2101             tvb, curr_offset, 1,
2102             "%s :  Extension: %s",
2103             a_bigbuf,
2104             (oct & 0x80) ? "extended" : "not extended");
2105
2106         other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
2107         proto_tree_add_text(tree,
2108             tvb, curr_offset, 1,
2109             "%s :  %sTransparent service",
2110             a_bigbuf,
2111             (oct & 0x40) ? "Non-" : "");
2112
2113         if (num_chan == 0)
2114         {
2115             if (oct & 0x40)
2116             {
2117                 /* non-transparent */
2118
2119                 switch (oct & 0x3f)
2120                 {
2121                 case 0x00: str = "12 kbit/s if the channel is a full rate TCH, or 6 kbit/s if the channel is a half rate TCH"; break;
2122                 case 0x18: str = "14.5 kbit/s"; break;
2123                 case 0x10: str = "12 kbits/s"; break;
2124                 case 0x11: str = "6 kbits/s"; break;
2125                 default:
2126                     str = "Reserved";
2127                     break;
2128                 }
2129             }
2130             else
2131             {
2132                 switch (oct & 0x3f)
2133                 {
2134                 case 0x18: str = "14.4 kbit/s"; break;
2135                 case 0x10: str = "9.6kbit/s"; break;
2136                 case 0x11: str = "4.8kbit/s"; break;
2137                 case 0x12: str = "2.4kbit/s"; break;
2138                 case 0x13: str = "1.2Kbit/s"; break;
2139                 case 0x14: str = "600 bit/s"; break;
2140                 case 0x15: str = "1200/75 bit/s (1200 network-to-MS / 75 MS-to-network)"; break;
2141                 default:
2142                     str = "Reserved";
2143                     break;
2144                 }
2145             }
2146         }
2147         else
2148         {
2149             if (oct & 0x40)
2150             {
2151                 /* non-transparent */
2152
2153                 switch (oct & 0x3f)
2154                 {
2155                 case 0x16: str = "58 kbit/s (4x14.5 kbit/s)"; break;
2156                 case 0x14: str = "48.0 / 43.5 kbit/s (4x12 kbit/s or 3x14.5 kbit/s)"; break;
2157                 case 0x13: str = "36.0 / 29.0 kbit/s (3x12 kbit/s or 2x14.5 kbit/s)"; break;
2158                 case 0x12: str = "24.0 / 24.0 (4x6 kbit/s or 2x12 kbit/s)"; break;
2159                 case 0x11: str = "18.0 / 14.5 kbit/s (3x6 kbit/s or 1x14.5 kbit/s)"; break;
2160                 case 0x10: str = "12.0 / 12.0 kbit/s (2x6 kbit/s or 1x12 kbit/s)"; break;
2161                 default:
2162                     str = "Reserved";
2163                     break;
2164                 }
2165             }
2166             else
2167             {
2168                 switch (oct & 0x3f)
2169                 {
2170                 case 0x1f: str = "64 kbit/s, bit transparent"; break;
2171                 case 0x1e: str = "56 kbit/s, bit transparent"; break;
2172                 case 0x1d: str = "56 kbit/s"; break;
2173                 case 0x1c: str = "48 kbit/s"; break;
2174                 case 0x1b: str = "38.4 kbit/s"; break;
2175                 case 0x1a: str = "28.8 kbit/s"; break;
2176                 case 0x19: str = "19.2 kbit/s"; break;
2177                 case 0x18: str = "14.4 kbit/s"; break;
2178                 case 0x10: str = "9.6 kbit/s"; break;
2179                 default:
2180                     str = "Reserved";
2181                     break;
2182                 }
2183             }
2184         }
2185
2186         other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
2187         proto_tree_add_text(tree,
2188             tvb, curr_offset, 1,
2189             "%s :  Rate: %s",
2190             a_bigbuf,
2191             str);
2192
2193         curr_offset++;
2194
2195         NO_MORE_DATA_CHECK(len);
2196
2197         oct = tvb_get_guint8(tvb, curr_offset);
2198
2199         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
2200         proto_tree_add_text(tree,
2201             tvb, curr_offset, 1,
2202             "%s :  Extension: %s",
2203             a_bigbuf,
2204             (oct & 0x80) ? "extended" : "not extended");
2205
2206         other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
2207         proto_tree_add_text(tree,
2208             tvb, curr_offset, 1,
2209             "%s :  Spare",
2210             a_bigbuf);
2211
2212         if (num_chan == 0)
2213         {
2214             other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
2215             proto_tree_add_text(tree,
2216                 tvb, curr_offset, 1,
2217                 "%s :  14.5 kbit/s (TCH/F14.4) %sallowed",
2218                 a_bigbuf,
2219                 (oct & 0x08) ? "" : "not ");
2220
2221             other_decode_bitfield_value(a_bigbuf, oct, 0x04, 8);
2222             proto_tree_add_text(tree,
2223                 tvb, curr_offset, 1,
2224                 "%s :  Spare",
2225                 a_bigbuf);
2226
2227             other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
2228             proto_tree_add_text(tree,
2229                 tvb, curr_offset, 1,
2230                 "%s :  12.0 kbit/s (TCH F/9.6) %sallowed",
2231                 a_bigbuf,
2232                 (oct & 0x02) ? "" : "not ");
2233
2234             other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
2235             proto_tree_add_text(tree,
2236                 tvb, curr_offset, 1,
2237                 "%s :  6.0 kbit/s (TCH F/4.8) %sallowed",
2238                 a_bigbuf,
2239                 (oct & 0x01) ? "" : "not ");
2240         }
2241         else
2242         {
2243             other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
2244             proto_tree_add_text(tree,
2245                 tvb, curr_offset, 1,
2246                 "%s :  14.5/14.4 kbit/s (TCH/F14.4) %sallowed",
2247                 a_bigbuf,
2248                 (oct & 0x08) ? "" : "not ");
2249
2250             other_decode_bitfield_value(a_bigbuf, oct, 0x04, 8);
2251             proto_tree_add_text(tree,
2252                 tvb, curr_offset, 1,
2253                 "%s :  Spare",
2254                 a_bigbuf);
2255
2256             other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
2257             proto_tree_add_text(tree,
2258                 tvb, curr_offset, 1,
2259                 "%s :  12.0/9.6 kbit/s (TCH F/9.6) %sallowed",
2260                 a_bigbuf,
2261                 (oct & 0x02) ? "" : "not ");
2262
2263             other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
2264             proto_tree_add_text(tree,
2265                 tvb, curr_offset, 1,
2266                 "%s :  6.0/4.8 kbit/s (TCH F/4.8) %sallowed",
2267                 a_bigbuf,
2268                 (oct & 0x01) ? "" : "not ");
2269         }
2270
2271         curr_offset++;
2272     }
2273     else if (sdi == 0x03)
2274     {
2275         /* signalling */
2276
2277         switch (oct)
2278         {
2279         case 0x00: str = "SDCCH or Full rate TCH channel Bm or Half rate TCH channel Lm"; break;
2280         case 0x01: str = "SDCCH"; break;
2281         case 0x02: str = "SDCCH or Full rate TCH channel Bm"; break;
2282         case 0x03: str = "SDCCH or Half rate TCH channel Lm"; break;
2283         case 0x08: str = "Full rate TCH channel Bm"; break;
2284         case 0x09: str = "Half rate TCH channel Lm"; break;
2285         case 0x0a: str = "Full or Half rate TCH channel, Full rate preferred, changes allowed also after first channel allocation as a result of the request"; break;
2286         case 0x0b: str = "Full or Half rate TCH channel, Half rate preferred, changes allowed also after first channel allocation as a result of the request"; break;
2287         case 0x1a: str = "Full or Half rate TCH channel, Full rate preferred, changes not allowed after first channel allocation as a result of the request"; break;
2288         case 0x1b: str = "Full or Half rate TCH channel. Half rate preferred, changes not allowed after first channel allocation as a result of the request"; break;
2289         default:
2290             str = "Reserved";
2291             break;
2292         }
2293
2294         proto_tree_add_text(tree,
2295             tvb, curr_offset, 1,
2296             "Channel Rate and Type: %s",
2297             str);
2298
2299         curr_offset++;
2300
2301         NO_MORE_DATA_CHECK(len);
2302
2303         proto_tree_add_text(tree,
2304             tvb, curr_offset, len - (curr_offset - offset),
2305             "Spare");
2306
2307         curr_offset += len - (curr_offset - offset);
2308     }
2309     else
2310     {
2311         /* unknown format */
2312
2313         proto_tree_add_text(tree,
2314             tvb, curr_offset, len - (curr_offset - offset),
2315             "Unknown format");
2316
2317         curr_offset += len - (curr_offset - offset);
2318     }
2319
2320     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2321
2322     return(curr_offset - offset);
2323 }
2324
2325 /*
2326  * [2] 3.2.2.17
2327  * Formats everything after the discriminator, shared function
2328  */
2329 guint8
2330 be_cell_id_aux(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len, guint8 disc)
2331 {
2332     guint8      octs[3];
2333     guint32     value;
2334     guint32     curr_offset;
2335     gchar       mcc[4];
2336     gchar       mnc[4];
2337
2338     if (add_string)
2339         add_string[0] = '\0';
2340     curr_offset = offset;
2341
2342     switch (disc)
2343     {
2344     case 0x00:
2345         /* FALLTHRU */
2346
2347     case 0x04:
2348         /* FALLTHRU */
2349
2350     case 0x08:  /* For intersystem handover from GSM to UMTS or cdma2000: */
2351         octs[0] = tvb_get_guint8(tvb, curr_offset);
2352         octs[1] = tvb_get_guint8(tvb, curr_offset + 1);
2353         octs[2] = tvb_get_guint8(tvb, curr_offset + 2);
2354
2355         mcc_mnc_aux(octs, mcc, mnc);
2356
2357         proto_tree_add_text(tree,
2358             tvb, curr_offset, 3,
2359             "Mobile Country Code (MCC): %s, Mobile Network Code (MNC): %s",
2360             mcc,
2361             mnc);
2362
2363         curr_offset += 3;
2364
2365         /* FALLTHRU */
2366
2367     case 0x01:
2368     case 0x05:
2369     case 0x0a: /*For intersystem handover from GSM to UMTS or cdma2000: */
2370
2371         /* LAC */
2372
2373         value = tvb_get_ntohs(tvb, curr_offset);
2374
2375         proto_tree_add_item(tree, hf_gsm_a_cell_lac, tvb, curr_offset, 2, FALSE);
2376                 
2377         curr_offset += 2;
2378
2379         if (add_string)
2380             g_snprintf(add_string, string_len, " - LAC (0x%04x)", value);
2381
2382         /* FALLTHRU */
2383
2384     case 0x09: /* For intersystem handover from GSM to UMTS or cdma2000: */
2385
2386         if ((disc == 0x08) ||(disc == 0x09) || (disc == 0x0a)){ 
2387                 /* RNC-ID */
2388                 value = tvb_get_ntohs(tvb, curr_offset);
2389                 proto_tree_add_item(tree, hf_gsm_a_be_rnc_id, tvb, curr_offset, 2, FALSE);
2390
2391                 if (add_string)
2392                 {
2393                     if (add_string[0] == '\0')
2394                     {
2395                         g_snprintf(add_string, string_len, " - RNC-ID (%u)", value);
2396                     }
2397                     else
2398                     {
2399                         g_snprintf(add_string, string_len, "%s/RNC-ID (%u)", add_string, value);
2400                     }
2401                 }
2402                 break;
2403         }
2404
2405         if ((disc == 0x04) || (disc == 0x05) || (disc == 0x08)) break;
2406
2407         /* FALLTHRU */
2408
2409     case 0x02:
2410
2411         /* CI */
2412
2413         value = tvb_get_ntohs(tvb, curr_offset);
2414
2415         proto_tree_add_uint(tree, hf_gsm_a_cell_ci, tvb,
2416             curr_offset, 2, value);
2417
2418         curr_offset += 2;
2419
2420         if (add_string)
2421         {
2422             if (add_string[0] == '\0')
2423             {
2424                 g_snprintf(add_string, string_len, " - CI (%u)", value);
2425             }
2426             else
2427             {
2428                 g_snprintf(add_string, string_len, "%s/CI (%u)", add_string, value);
2429             }
2430         }
2431         break;
2432
2433     default:
2434         proto_tree_add_text(tree, tvb, curr_offset, len,
2435             "Cell ID - Unknown format");
2436
2437         curr_offset += (len);
2438         break;
2439     }
2440
2441     return(curr_offset - offset);
2442 }
2443
2444 static guint8
2445 be_cell_id(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
2446 {
2447     guint8      oct;
2448     guint8      disc;
2449     guint32     curr_offset;
2450
2451     len = len;
2452     curr_offset = offset;
2453
2454     oct = tvb_get_guint8(tvb, curr_offset);
2455
2456     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2457     proto_tree_add_text(tree,
2458         tvb, curr_offset, 1,
2459         "%s :  Spare",
2460         a_bigbuf);
2461
2462     proto_tree_add_item(tree, hf_gsm_a_be_cell_id_disc, tvb, curr_offset, 1, FALSE);
2463         disc = oct&0x0f;
2464     curr_offset++;
2465
2466     NO_MORE_DATA_CHECK(len);
2467
2468     curr_offset +=
2469         be_cell_id_aux(tvb, tree, curr_offset, len - (curr_offset - offset), add_string, string_len, disc);
2470
2471     /* no length check possible */
2472
2473     return(curr_offset - offset);
2474 }
2475
2476 /*
2477  * [2] 3.2.2.18
2478  */
2479 static guint8
2480 be_prio(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
2481 {
2482     guint8      oct;
2483     guint32     curr_offset;
2484     const gchar *str;
2485
2486     len = len;
2487     curr_offset = offset;
2488
2489     oct = tvb_get_guint8(tvb, curr_offset);
2490
2491     proto_tree_add_item(tree, hf_gsm_a_b8spare, tvb, curr_offset, 1, FALSE);
2492
2493     other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
2494     proto_tree_add_text(tree,
2495         tvb, curr_offset, 1,
2496         "%s :  Preemption Capability Indicator (PCI): this allocation request %s preempt an existing connection",
2497         a_bigbuf,
2498         (oct & 0x40) ? "may" : "shall not");
2499
2500     switch ((oct & 0x3c) >> 2)
2501     {
2502     case 0x00: str = "Spare"; break;
2503     case 0x0f: str = "priority not used"; break;
2504     default:
2505         str = "1 is highest";
2506         break;
2507     }
2508
2509     other_decode_bitfield_value(a_bigbuf, oct, 0x3c, 8);
2510     proto_tree_add_text(tree,
2511         tvb, curr_offset, 1,
2512         "%s :  Priority Level: (%u) %s",
2513         a_bigbuf,
2514         (oct & 0x3c) >> 2,
2515         str);
2516
2517     if (add_string)
2518         g_snprintf(add_string, string_len, " - (%u)", (oct & 0x3c) >> 2);
2519
2520     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
2521     proto_tree_add_text(tree,
2522         tvb, curr_offset, 1,
2523         "%s :  Queuing Allowed Indicator (QA): queuing %sallowed",
2524         a_bigbuf,
2525         (oct & 0x02) ? "" : "not ");
2526
2527     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
2528     proto_tree_add_text(tree,
2529         tvb, curr_offset, 1,
2530         "%s :  Preemption Vulnerability Indicator (PVI): this connection %s be preempted by another allocation request",
2531         a_bigbuf,
2532         (oct & 0x01) ? "might" : "shall not");
2533
2534     curr_offset++;
2535
2536     /* no length check possible */
2537
2538     return(curr_offset - offset);
2539 }
2540
2541 /*
2542  * [2] 3.2.2.24
2543  */
2544 static guint8
2545 be_l3_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2546 {
2547     guint32     curr_offset;
2548     tvbuff_t    *l3_tvb;
2549
2550     curr_offset = offset;
2551
2552     proto_tree_add_text(tree, tvb, curr_offset, len,
2553         "Layer 3 Information value");
2554
2555     /*
2556      * dissect the embedded DTAP message
2557      */
2558     l3_tvb = tvb_new_subset(tvb, curr_offset, len, len);
2559
2560     call_dissector(dtap_handle, l3_tvb, g_pinfo, g_tree);
2561
2562     curr_offset += len;
2563
2564     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2565
2566     return(curr_offset - offset);
2567 }
2568
2569 /*
2570  * [2] 3.2.2.25
2571  */
2572 static guint8
2573 be_dlci(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2574 {
2575     guint8      oct;
2576     guint32     curr_offset;
2577     proto_item  *item = NULL;
2578     proto_tree  *subtree = NULL;
2579
2580     len = len;
2581     curr_offset = offset;
2582
2583     item =
2584         proto_tree_add_text(tree, tvb, curr_offset, 1,
2585             "Data Link Connection Identifier");
2586
2587     subtree = proto_item_add_subtree(item, ett_dlci);
2588
2589     oct = tvb_get_guint8(tvb, curr_offset);
2590
2591     proto_tree_add_uint(subtree, hf_gsm_a_dlci_cc, tvb, curr_offset, 1, oct);
2592     proto_tree_add_uint(subtree, hf_gsm_a_dlci_spare, tvb, curr_offset, 1, oct);
2593     proto_tree_add_uint(subtree, hf_gsm_a_dlci_sapi, tvb, curr_offset, 1, oct);
2594
2595     curr_offset++;
2596
2597     /* no length check possible */
2598
2599     return(curr_offset - offset);
2600 }
2601
2602 /*
2603  * [2] 3.2.2.26
2604  */
2605 static guint8
2606 be_down_dtx_flag(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2607 {
2608     guint       oct;
2609     guint32     curr_offset;
2610
2611     len = len;
2612     curr_offset = offset;
2613
2614     oct = tvb_get_guint8(tvb, curr_offset);
2615
2616     other_decode_bitfield_value(a_bigbuf, oct, 0xfe, 8);
2617     proto_tree_add_text(tree,
2618         tvb, curr_offset, 1,
2619         "%s :  Spare",
2620         a_bigbuf);
2621
2622     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
2623     proto_tree_add_text(tree,
2624         tvb, curr_offset, 1,
2625         "%s :  BSS is %s to activate DTX in the downlink direction",
2626         a_bigbuf,
2627         (oct & 0x01) ? "forbidden" : "allowed");
2628
2629     curr_offset++;
2630
2631     /* no length check possible */
2632
2633     return(curr_offset - offset);
2634 }
2635
2636 /*
2637  * [2] 3.2.2.27
2638  */
2639 guint8
2640 be_cell_id_list(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
2641 {
2642     guint8      oct;
2643     guint8      consumed;
2644     guint8      disc;
2645     guint8      num_cells;
2646     guint32     curr_offset;
2647     proto_item  *item = NULL;
2648     proto_tree  *subtree = NULL;
2649
2650     curr_offset = offset;
2651
2652     oct = tvb_get_guint8(tvb, curr_offset);
2653
2654     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2655     proto_tree_add_text(tree,
2656         tvb, curr_offset, 1,
2657         "%s :  Spare",
2658         a_bigbuf);
2659
2660         disc = oct & 0x0f;
2661         proto_tree_add_item(tree, hf_gsm_a_be_cell_id_disc, tvb, curr_offset, 1, FALSE);
2662     curr_offset++;
2663
2664     NO_MORE_DATA_CHECK(len);
2665
2666     num_cells = 0;
2667     do
2668     {
2669         item =
2670             proto_tree_add_text(tree,
2671                 tvb, curr_offset, -1,
2672                 "Cell %u",
2673                 num_cells + 1);
2674
2675         subtree = proto_item_add_subtree(item, ett_cell_list);
2676
2677         if (add_string)
2678             add_string[0] = '\0';
2679         consumed =
2680             be_cell_id_aux(tvb, subtree, curr_offset, len - (curr_offset - offset), add_string, string_len, disc);
2681
2682         if (add_string && add_string[0] != '\0')
2683         {
2684             proto_item_append_text(item, "%s", add_string ? add_string : "");
2685         }
2686
2687         proto_item_set_len(item, consumed);
2688
2689         curr_offset += consumed;
2690
2691         num_cells++;
2692     }
2693     while ((len - (curr_offset - offset)) > 0 && consumed > 0);
2694
2695     if (add_string) {
2696         g_snprintf(add_string, string_len, " - %u cell%s",
2697             num_cells, plurality(num_cells, "", "s"));
2698     }
2699
2700     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2701
2702     return(curr_offset - offset);
2703 }
2704
2705 /*
2706  * [2] 3.2.2.33
2707  */
2708 static guint8
2709 be_chosen_chan(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2710 {
2711     guint8      oct;
2712     guint32     curr_offset;
2713     const gchar *str = NULL;
2714
2715     len = len;
2716     curr_offset = offset;
2717
2718     oct = tvb_get_guint8(tvb, curr_offset);
2719
2720     switch ((oct & 0xf0) >> 4)
2721     {
2722     case 0: str = "No channel mode indication"; break;
2723     case 9: str = "Speech (full rate or half rate)"; break;
2724     case 14: str = "Data, 14.5 kbit/s radio interface rate"; break;
2725     case 11: str = "Data, 12.0 kbit/s radio interface rate"; break;
2726     case 12: str = "Data, 6.0 kbit/s radio interface rate"; break;
2727     case 13: str = "Data, 3.6 kbit/s radio interface rate"; break;
2728     case 8: str = "Signalling only"; break;
2729     default:
2730         str = "Reserved";
2731         break;
2732     }
2733
2734     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2735     proto_tree_add_text(tree,
2736         tvb, curr_offset, 1,
2737         "%s :  Channel mode: %s",
2738         a_bigbuf,
2739         str);
2740
2741     switch (oct & 0x0f)
2742     {
2743     case 0: str = "None"; break;
2744     case 1: str = "SDCCH"; break;
2745     case 8: str = "1 Full rate TCH"; break;
2746     case 9: str = "1 Half rate TCH"; break;
2747     case 10: str = "2 Full Rate TCHs"; break;
2748     case 11: str = "3 Full Rate TCHs"; break;
2749     case 12: str = "4 Full Rate TCHs"; break;
2750     case 13: str = "5 Full Rate TCHs"; break;
2751     case 14: str = "6 Full Rate TCHs"; break;
2752     case 15: str = "7 Full Rate TCHs"; break;
2753     case 4: str = "8 Full Rate TCHs"; break;
2754     default:
2755         str = "Reserved";
2756         break;
2757     }
2758
2759     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
2760     proto_tree_add_text(tree,
2761         tvb, curr_offset, 1,
2762         "%s :  Channel: %s",
2763         a_bigbuf,
2764         str);
2765
2766     curr_offset++;
2767
2768     /* no length check possible */
2769
2770     return(curr_offset - offset);
2771 }
2772
2773 /*
2774  * [2] 3.2.2.34
2775  */
2776 static guint8
2777 be_ciph_resp_mode(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2778 {
2779     guint8      oct;
2780     guint32     curr_offset;
2781
2782     len = len;
2783     curr_offset = offset;
2784
2785     oct = tvb_get_guint8(tvb, curr_offset);
2786
2787     other_decode_bitfield_value(a_bigbuf, oct, 0xfe, 8);
2788     proto_tree_add_text(tree,
2789         tvb, curr_offset, 1,
2790         "%s :  Spare",
2791         a_bigbuf);
2792
2793     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
2794     proto_tree_add_text(tree,
2795         tvb, curr_offset, 1,
2796         "%s :  IMEISV must %sbe included by the mobile station",
2797         a_bigbuf,
2798         (oct & 0x01) ? "" : "not ");
2799
2800     curr_offset++;
2801
2802     /* no length check possible */
2803
2804     return(curr_offset - offset);
2805 }
2806
2807
2808 /*
2809  * [2] 3.2.2.35
2810  */
2811 static guint8
2812 be_l3_msg(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2813 {
2814     guint32     curr_offset;
2815     tvbuff_t    *l3_tvb;
2816
2817     curr_offset = offset;
2818
2819     proto_tree_add_text(tree, tvb, curr_offset, len,
2820         "Layer 3 Message Contents");
2821
2822     /*
2823      * dissect the embedded DTAP message
2824      */
2825     l3_tvb = tvb_new_subset(tvb, curr_offset, len, len);
2826
2827     call_dissector(dtap_handle, l3_tvb, g_pinfo, g_tree);
2828
2829     curr_offset += len;
2830
2831     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2832
2833     return(curr_offset - offset);
2834 }
2835
2836 /*
2837  * [2] 3.2.2.36 Channel Needed
2838  */static guint8 
2839 be_cha_needed(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2840 {
2841     guint32     curr_offset;
2842     
2843     len = len;
2844     curr_offset = offset;
2845     
2846     /* no length check possible */
2847         proto_tree_add_item(tree, hf_gsm_a_rr_chnl_needed_ch1, tvb, curr_offset, 1, FALSE);
2848         curr_offset++;  
2849     return(curr_offset - offset);
2850 }
2851
2852
2853 /*
2854  * [2] 3.2.2.43
2855  */
2856 static guint8
2857 be_for_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2858 {
2859     guint8      oct;
2860     guint32     curr_offset;
2861     const gchar *str = NULL;
2862
2863     len = len;
2864     curr_offset = offset;
2865
2866     oct = tvb_get_guint8(tvb, curr_offset);
2867
2868     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2869     proto_tree_add_text(tree,
2870         tvb, curr_offset, 1,
2871         "%s :  Spare",
2872         a_bigbuf);
2873
2874     switch (oct & 0x0f)
2875     {
2876     case 1: str = "forward to subsequent BSS, no trace at MSC"; break;
2877     case 2: str = "forward to subsequent BSS, and trace at MSC"; break;
2878     default:
2879         str = "Reserved";
2880         break;
2881     }
2882
2883     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
2884     proto_tree_add_text(tree,
2885         tvb, curr_offset, 1,
2886         "%s :  %s",
2887         a_bigbuf,
2888         str);
2889
2890     curr_offset++;
2891
2892     /* no length check possible */
2893
2894     return(curr_offset - offset);
2895 }
2896
2897 /*
2898  * [2] 3.2.2.44
2899  */
2900 static guint8
2901 be_chosen_enc_alg(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
2902 {
2903     guint8      oct;
2904     guint32     curr_offset;
2905     const gchar *str = NULL;
2906
2907     len = len;
2908     curr_offset = offset;
2909
2910     oct = tvb_get_guint8(tvb, curr_offset);
2911
2912     switch (oct)
2913     {
2914     case 0x01: str = "No encryption used"; break;
2915     case 0x02: str = "GSM A5/1"; break;
2916     case 0x03: str = "GSM A5/2"; break;
2917     case 0x04: str = "GSM A5/3"; break;
2918     case 0x05: str = "GSM A5/4"; break;
2919     case 0x06: str = "GSM A5/5"; break;
2920     case 0x07: str = "GSM A5/6"; break;
2921     case 0x08: str = "GSM A5/7"; break;
2922     default:
2923         str = "Reserved";
2924         break;
2925     }
2926
2927     proto_tree_add_text(tree,
2928         tvb, curr_offset, 1,
2929         "Algorithm Identifier: %s",
2930         str);
2931
2932     curr_offset++;
2933
2934     if (add_string)
2935         g_snprintf(add_string, string_len, " - %s", str);
2936
2937     /* no length check possible */
2938
2939     return(curr_offset - offset);
2940 }
2941
2942 /*
2943  * [2] 3.2.2.45
2944  */
2945 static guint8
2946 be_cct_pool(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
2947 {
2948     guint8      oct;
2949     guint32     curr_offset;
2950     const gchar *str = NULL;
2951
2952     len = len;
2953     curr_offset = offset;
2954
2955     oct = tvb_get_guint8(tvb, curr_offset);
2956
2957     if (oct <= 32)
2958     {
2959         str = "";
2960     }
2961     else if ((oct >= 0x80) && (oct <= 0x8f))
2962     {
2963         str = ", for national/local use";
2964     }
2965     else
2966     {
2967         str = ", reserved for future international use";
2968     }
2969
2970     proto_tree_add_text(tree,
2971         tvb, curr_offset, 1,
2972         "Circuit pool number: %u%s",
2973         oct,
2974         str);
2975
2976     curr_offset++;
2977
2978     if (add_string)
2979         g_snprintf(add_string, string_len, " - (%u)", oct);
2980
2981     /* no length check possible */
2982
2983     return(curr_offset - offset);
2984 }
2985
2986 /*
2987  * [2] 3.2.2.49
2988  */
2989 static guint8
2990 be_curr_chan_1(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2991 {
2992     guint8      oct;
2993     guint32     curr_offset;
2994     const gchar *str;
2995
2996     len = len;
2997     curr_offset = offset;
2998
2999     oct = tvb_get_guint8(tvb, curr_offset);
3000
3001     switch ((oct & 0xf0) >> 4)
3002     {
3003     case 0x00: str = "Signalling only"; break;
3004     case 0x01: str = "Speech (full rate or half rate)"; break;
3005     case 0x06: str = "Data, 14.5 kbit/s radio interface rate"; break;
3006     case 0x03: str = "Data, 12.0 kbit/s radio interface rate"; break;
3007     case 0x04: str = "Data, 6.0 kbit/s radio interface rate"; break;
3008     case 0x05: str = "Data, 3.6 kbit/s radio interface rate"; break;
3009     default:
3010         str = "Reserved";
3011         break;
3012     }
3013
3014     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
3015     proto_tree_add_text(tree,
3016         tvb, curr_offset, 1,
3017         "%s :  Channel Mode: %s",
3018         a_bigbuf,
3019         str);
3020
3021     switch (oct & 0x0f)
3022     {
3023     case 0x01: str = "SDCCH"; break;
3024     case 0x08: str = "1 Full rate TCH"; break;
3025     case 0x09: str = "1 Half rate TCH"; break;
3026     case 0x0a: str = "2 Full Rate TCHs"; break;
3027     case 0x0b: str = "3 Full Rate TCHs"; break;
3028     case 0x0c: str = "4 Full Rate TCHs"; break;
3029     case 0x0d: str = "5 Full Rate TCHs"; break;
3030     case 0x0e: str = "6 Full Rate TCHs"; break;
3031     case 0x0f: str = "7 Full Rate TCHs"; break;
3032     case 0x04: str = "8 Full Rate TCHs"; break;
3033     default:
3034         str = "Reserved";
3035         break;
3036     }
3037
3038     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
3039     proto_tree_add_text(tree,
3040         tvb, curr_offset, 1,
3041         "%s :  Channel: (%u) %s",
3042         a_bigbuf,
3043         oct & 0x0f,
3044         str);
3045
3046     curr_offset++;
3047
3048     /* no length check possible */
3049
3050     return(curr_offset - offset);
3051 }
3052
3053 /*
3054  * [2] 3.2.2.50
3055  */
3056 static guint8
3057 be_que_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3058 {
3059     guint8      oct;
3060     guint32     curr_offset;
3061
3062     len = len;
3063     curr_offset = offset;
3064
3065     oct = tvb_get_guint8(tvb, curr_offset);
3066
3067     other_decode_bitfield_value(a_bigbuf, oct, 0xfc, 8);
3068     proto_tree_add_text(tree,
3069         tvb, curr_offset, 1,
3070         "%s :  Spare",
3071         a_bigbuf);
3072
3073     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
3074     proto_tree_add_text(tree,
3075         tvb, curr_offset, 1,
3076         "%s :  qri: it is recommended %sto allow queuing",
3077         a_bigbuf,
3078         (oct & 0x02) ? "" : "not ");
3079
3080     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
3081     proto_tree_add_text(tree,
3082         tvb, curr_offset, 1,
3083         "%s :  Spare",
3084         a_bigbuf);
3085
3086     curr_offset++;
3087
3088     /* no length check possible */
3089
3090     return(curr_offset - offset);
3091 }
3092
3093 /*
3094  * [2] 3.2.2.51
3095  */
3096 static guint8
3097 be_speech_ver(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
3098 {
3099     guint8      oct;
3100     guint32     curr_offset;
3101     const gchar *str = NULL;
3102     const gchar *short_str = NULL;
3103
3104     len = len;
3105     curr_offset = offset;
3106
3107     oct = tvb_get_guint8(tvb, curr_offset);
3108
3109     proto_tree_add_item(tree, hf_gsm_a_b8spare, tvb, curr_offset, 1, FALSE);
3110
3111     switch (oct & 0x7f)
3112     {
3113     case 0x01: str = "GSM speech full rate version 1"; short_str = "FR1"; break;
3114     case 0x11: str = "GSM speech full rate version 2"; short_str = "FR2"; break;
3115     case 0x21: str = "GSM speech full rate version 3 (AMR)"; short_str = "FR3 (AMR)"; break;
3116
3117     case 0x05: str = "GSM speech half rate version 1"; short_str = "HR1"; break;
3118     case 0x15: str = "GSM speech half rate version 2"; short_str = "HR2"; break;
3119     case 0x25: str = "GSM speech half rate version 3 (AMR)"; short_str = "HR3 (AMR)"; break;
3120
3121     default:
3122         str = "Reserved";
3123         short_str = str;
3124         break;
3125     }
3126
3127     other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
3128     proto_tree_add_text(tree,
3129         tvb, curr_offset, 1,
3130         "%s :  Speech version identifier: %s",
3131         a_bigbuf,
3132         str);
3133
3134     curr_offset++;
3135
3136     if (add_string)
3137         g_snprintf(add_string, string_len, " - (%s)", short_str);
3138
3139     /* no length check possible */
3140
3141     return(curr_offset - offset);
3142 }
3143
3144 /*
3145  * 3.2.2.68 3GPP TS 48.008 version 6.9.0 Release 6
3146  */
3147
3148 /* BSSLAP the embedded message is as defined in 3GPP TS 48.071
3149  * LLP the embedded message contains a Facility Information Element as defined in 3GPP TS 44.071
3150  *              excluding the Facility IEI and length of Facility IEI octets defined in 3GPP TS 44.071.
3151  * SMLCPP the embedded message is as defined in 3GPP TS 48.031
3152  */
3153 static const value_string gsm_a_apdu_protocol_id_strings[] = {
3154     { 0,        "reserved" },
3155     { 1,        "BSSLAP" },
3156     { 2,        "LLP" },
3157     { 3,        "SMLCPP" },
3158     { 0, NULL },
3159 };
3160
3161 static guint8
3162 be_apdu(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3163 {
3164     guint32     curr_offset;
3165
3166     curr_offset = offset;
3167
3168     proto_tree_add_text(tree, tvb, curr_offset, len,
3169         "APDU (not displayed)");
3170
3171     /*
3172      * dissect the embedded APDU message
3173      * if someone writes a TS 09.31 dissector
3174          *
3175          * The APDU octets 4 to n are coded in the same way as the 
3176          * equivalent octet in the APDU element of 3GPP TS 49.031.
3177      */
3178
3179         proto_tree_add_item(tree, hf_gsm_a_apdu_protocol_id, tvb, curr_offset, 1, FALSE);
3180
3181     curr_offset += len;
3182
3183     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3184
3185     return(curr_offset - offset);
3186 }
3187
3188 typedef enum
3189 {
3190     /* Common Information Elements 10.5.1 */
3191         /* Pos 0 */
3192     DE_CELL_ID,                         /* Cell Identity */
3193     DE_CIPH_KEY_SEQ_NUM,        /* Ciphering Key Sequence Number */
3194     DE_LAI,                                     /* Location Area Identification */
3195     DE_MID,                                     /* Mobile Identity */
3196     DE_MS_CM_1,                         /* Mobile Station Classmark 1 */
3197     DE_MS_CM_2,                         /* Mobile Station Classmark 2 */
3198     DE_MS_CM_3,                         /* Mobile Station Classmark 3 */
3199     DE_D_GB_CALL_REF,           /* Descriptive group or broadcast call reference */
3200     DE_G_CIPH_KEY_NUM,          /* Group Cipher Key Number */
3201     DE_PD_SAPI,                         /* PD and SAPI $(CCBS)$ */
3202         /* Pos 10 */
3203     DE_PRIO,                            /* Priority Level */
3204     DE_PLMN_LIST,                       /* PLMN List */
3205
3206     /* Radio Resource Management Information Elements 10.5.2, most are from 10.5.1      */
3207 /*
3208  * [3]  10.5.2.1a       BA Range
3209  */
3210         DE_RR_CELL_CH_DSC,                              /* [3]  10.5.2.1b       Cell Channel Description        */
3211
3212 /* [3]  10.5.2.1c       BA List Pref
3213  * [3]  10.5.2.1d       UTRAN Frequency List
3214  * [3]  10.5.2.1e       Cell selection indicator after release of all TCH and SDCCH IE
3215  */
3216         DE_RR_CELL_DSC,                                 /* 10.5.2.2   RR Cell Description                               */
3217 /*
3218  * [3]  10.5.2.3        Cell Options (BCCH)     
3219  * [3]  10.5.2.3a       Cell Options (SACCH)
3220  * [3]  10.5.2.4        Cell Selection Parameters
3221  * [3]  10.5.2.4a       (void)
3222  */
3223         DE_RR_CH_DSC,                                   /* [3]  10.5.2.5        Channel Description                     */
3224         DE_RR_CH_DSC2,                                  /* [3]  10.5.2.5a   Channel Description 2               */
3225         DE_RR_CH_MODE,                                  /* [3]  10.5.2.6        Channel Mode                            */
3226         DE_RR_CH_MODE2,                                 /* [3]  10.5.2.7        Channel Mode 2                          */
3227 /* [3]  10.5.2.7a       UTRAN predefined configuration status information / START-CS / UE CapabilityUTRAN Classmark information element 218
3228  * [3]  10.5.2.7b       (void) */
3229         DE_RR_CM_ENQ_MASK,                              /* [3]  10.5.2.7c       Classmark Enquiry Mask          */
3230 /* [3]  10.5.2.7d       GERAN Iu Mode Classmark information element                                             */
3231         DE_RR_CHNL_NEEDED,                              /* [3]  10.5.2.8        Channel Needed
3232  * [3]  10.5.2.8a       (void)  
3233  * [3]  10.5.2.8b       Channel Request Description 2 */
3234         /* Pos 20 */
3235         DE_RR_CIP_MODE_SET,                             /* [3]  10.5.2.9        Cipher Mode Setting                     */
3236 /* [3]  10.5.2.10       Cipher Response
3237  * [3]  10.5.2.11       Control Channel Description
3238  * [3]  10.5.2.11a      DTM Information Details */
3239         DE_RR_DYN_ARFCN_MAP,                    /* [3]  10.5.2.11b      Dynamic ARFCN Mapping           */
3240         DE_RR_FREQ_CH_SEQ,                              /* [3]  10.5.2.12       Frequency Channel Sequence      */
3241         DE_RR_FREQ_LIST,                                /* [3]  10.5.2.13       Frequency List                          */
3242         DE_RR_FREQ_SHORT_LIST,                  /* [3]  10.5.2.14       Frequency Short List            */
3243         DE_RR_FREQ_SHORT_LIST2,                 /* [3]  10.5.2.14a      Frequency Short List 2          */
3244 /* [3]  10.5.2.14b      Group Channel Description
3245  * [3]  10.5.2.14c      GPRS Resumption
3246  * [3]  10.5.2.14d      GPRS broadcast information
3247  * [3]  10.5.2.14e      Enhanced DTM CS Release Indication
3248  */
3249
3250         DE_RR_HO_REF,                                   /* 10.5.2.15  Handover Reference                                */
3251 /*
3252  * [3] 10.5.2.16 IA Rest Octets
3253  * [3] 10.5.2.17 IAR Rest Octets
3254  * [3] 10.5.2.18 IAX Rest Octets
3255  * [3] 10.5.2.19 L2 Pseudo Length
3256  * [3] 10.5.2.20 Measurement Results
3257  * [3] 10.5.2.20a GPRS Measurement Results
3258  */
3259         DE_RR_MOB_ALL,                                  /* [3] 10.5.2.21 Mobile Allocation                              */
3260         DE_RR_MOB_TIME_DIFF,                    /* [3] 10.5.2.21a Mobile Time Difference                */
3261         DE_RR_MULTIRATE_CONF,                   /* [3] 10.5.2.21aa MultiRate configuration              */
3262         /* Pos 30 */
3263         DE_RR_MULT_ALL,                                 /* [3] 10.5.2.21b Multislot Allocation                  */
3264
3265 /*
3266  * [3] 10.5.2.21c NC mode
3267  * [3] 10.5.2.22 Neighbour Cell Description
3268  * [3] 10.5.2.22a Neighbour Cell Description 2
3269  * [3] 10.5.2.22b (void)
3270  * [3] 10.5.2.22c NT/N Rest Octets
3271  * [3] 10.5.2.23 P1 Rest Octets
3272  * [3] 10.5.2.24 P2 Rest Octets
3273  * [3] 10.5.2.25 P3 Rest Octets
3274  * [3] 10.5.2.25a Packet Channel Description
3275  * [3] 10.5.2.25b Dedicated mode or TBF
3276  * [3] 10.5.2.25c RR Packet Uplink Assignment
3277  * [3] 10.5.2.25d RR Packet Downlink Assignment
3278  * [3] 10.5.2.26 Page Mode
3279  * [3] 10.5.2.26a (void)
3280  * [3] 10.5.2.26b (void)
3281  * [3] 10.5.2.26c (void)
3282  * [3] 10.5.2.26d (void)
3283  * [3] 10.5.2.27 NCC Permitted
3284  */
3285         DE_RR_POW_CMD,                                  /* 10.5.2.28  Power Command                                             */
3286         DE_RR_POW_CMD_AND_ACC_TYPE,             /* 10.5.2.28a Power Command and access type             */
3287 /*
3288  * [3] 10.5.2.29 RACH Control Parameters
3289  * [3] 10.5.2.30 Request Reference
3290  */
3291     DE_RR_CAUSE,                                        /* 10.5.2.31  RR Cause                                                  */
3292         DE_RR_SYNC_IND,                                 /* 10.5.2.39  Synchronization Indication                */
3293 /* [3] 10.5.2.32 SI 1 Rest Octets
3294  * [3] 10.5.2.33 SI 2bis Rest Octets 
3295  * [3] 10.5.2.33a SI 2ter Rest Octets
3296  * [3] 10.5.2.33b SI 2quater Rest Octets
3297  * [3] 10.5.2.34 SI 3 Rest Octets
3298  * [3] 10.5.2.35 SI 4 Rest Octets
3299  * [3] 10.5.2.35a SI 6 Rest Octets
3300  * [3] 10.5.2.36 SI 7 Rest Octets
3301  * [3] 10.5.2.37 SI 8 Rest Octets
3302  * [3] 10.5.2.37a SI 9 Rest Octets
3303  * [3] 10.5.2.37b SI 13 Rest Octets
3304  * [3] 10.5.2.37c (void)
3305  * [3] 10.5.2.37d (void)
3306  * [3] 10.5.2.37e SI 16 Rest Octets
3307  * [3] 10.5.2.37f SI 17 Rest Octets
3308  * [3] 10.5.2.37g SI 19 Rest Octets
3309  * [3] 10.5.2.37h SI 18 Rest Octets
3310  * [3] 10.5.2.37i SI 20 Rest Octets */
3311         DE_RR_STARTING_TIME,                    /* [3] 10.5.2.38 Starting Time                                  */
3312         DE_RR_TIMING_ADV,                               /* [3] 10.5.2.40 Timing Advance                                 */
3313         DE_RR_TIME_DIFF,                                /* [3] 10.5.2.41 Time Difference                                */
3314         DE_RR_TLLI,                                             /* [3] 10.5.2.41a TLLI                                                  */
3315 /*
3316  * [3] 10.5.2.42 TMSI/P-TMSI */
3317         DE_RR_VGCS_TAR_MODE_IND,                /* [3] 10.5.2.42a VGCS target mode Indication   */
3318         /* Pos 40 */
3319         DE_RR_VGCS_CIP_PAR,                             /* [3] 10.5.2.42b       VGCS Ciphering Parameters       */
3320
3321 /* [3] 10.5.2.43 Wait Indication
3322  * [3] 10.5.2.44 SI10 rest octets $(ASCI)$
3323  * [3] 10.5.2.45 EXTENDED MEASUREMENT RESULTS
3324  * [3] 10.5.2.46 Extended Measurement Frequency List */
3325         DE_RR_SUS_CAU,                                  /* [3] 10.5.2.47 Suspension Cause                               */
3326 /* [3] 10.5.2.48 APDU ID 
3327  * [3] 10.5.2.49 APDU Flags
3328  * [3] 10.5.2.50 APDU Data
3329  * [3] 10.5.2.51 Handover To UTRAN Command
3330  * [3] 10.5.2.52 Handover To cdma2000 Command 
3331  * [3] 10.5.2.53 (void)
3332  * [3] 10.5.2.54 (void)
3333  * [3] 10.5.2.55 (void)
3334  * [3] 10.5.2.56 3G Target Cell */
3335         DE_RR_DED_SERV_INF,                             /* [3] 10.5.2.59        Dedicated Service Information */
3336
3337
3338     /* Mobility Management Information Elements 10.5.3 */
3339     DE_AUTH_PARAM_RAND,                         /* Authentication Parameter RAND */
3340     DE_AUTH_PARAM_AUTN,                         /* Authentication Parameter AUTN (UMTS authentication challenge only) */
3341     DE_AUTH_RESP_PARAM,                         /* Authentication Response Parameter */
3342     DE_AUTH_RESP_PARAM_EXT,                     /* Authentication Response Parameter (extension) (UMTS authentication challenge only) */
3343     DE_AUTH_FAIL_PARAM,                         /* Authentication Failure Parameter (UMTS authentication challenge only) */
3344     DE_CM_SRVC_TYPE,                            /* CM Service Type */
3345     DE_ID_TYPE,                                         /* Identity Type */
3346         /* Pos 50 */
3347     DE_LOC_UPD_TYPE,                            /* Location Updating Type */
3348     DE_NETWORK_NAME,                            /* Network Name */
3349     DE_REJ_CAUSE,                                       /* Reject Cause */
3350     DE_FOP,                                                     /* Follow-on Proceed */
3351     DE_TIME_ZONE,                                       /* Time Zone */
3352     DE_TIME_ZONE_TIME,                          /* Time Zone and Time */
3353     DE_CTS_PERM,                                        /* CTS Permission */
3354     DE_LSA_ID,                                          /* LSA Identifier */
3355     DE_DAY_SAVING_TIME,                         /* Daylight Saving Time */
3356     DE_EMERGENCY_NUM_LIST,                      /* Emergency Number List */
3357     /* Call Control Information Elements 10.5.4 */
3358         /* Pos 60 */
3359     DE_AUX_STATES,                                      /* Auxiliary States */
3360     DE_BEARER_CAP,                                      /* Bearer Capability */
3361     DE_CC_CAP,                                          /* Call Control Capabilities */
3362     DE_CALL_STATE,                                      /* Call State */
3363     DE_CLD_PARTY_BCD_NUM,                       /* Called Party BCD Number */
3364     DE_CLD_PARTY_SUB_ADDR,                      /* Called Party Subaddress */
3365     DE_CLG_PARTY_BCD_NUM,                       /* Calling Party BCD Number */
3366     DE_CLG_PARTY_SUB_ADDR,                      /* Calling Party Subaddress */
3367     DE_CAUSE,                                           /* Cause */
3368     DE_CLIR_SUP,                                        /* CLIR Suppression */
3369     DE_CLIR_INV,                                        /* CLIR Invocation */
3370     DE_CONGESTION,                                      /* Congestion Level */
3371     DE_CONN_NUM,                                        /* Connected Number */
3372     DE_CONN_SUB_ADDR,                           /* Connected Subaddress */
3373     DE_FACILITY,                                        /* Facility */
3374     DE_HLC,                                                     /* High Layer Compatibility */
3375     DE_KEYPAD_FACILITY,                         /* Keypad Facility */
3376     DE_LLC,                                                     /* Low Layer Compatibility */
3377     DE_MORE_DATA,                                       /* More Data */
3378     DE_NOT_IND,                                         /* Notification Indicator */
3379     DE_PROG_IND,                                        /* Progress Indicator */
3380     DE_RECALL_TYPE,                                     /* Recall type $(CCBS)$ */
3381     DE_RED_PARTY_BCD_NUM,                       /* Redirecting Party BCD Number */
3382     DE_RED_PARTY_SUB_ADDR,                      /* Redirecting Party Subaddress */
3383     DE_REPEAT_IND,                                      /* Repeat Indicator */
3384     DE_REV_CALL_SETUP_DIR,                      /* Reverse Call Setup Direction */
3385     DE_SETUP_CONTAINER,                         /* SETUP Container $(CCBS)$ */
3386     DE_SIGNAL,                                          /* Signal */
3387     DE_SS_VER_IND,                                      /* SS Version Indicator */
3388     DE_USER_USER,                                       /* User-user */
3389     DE_ALERT_PATTERN,                           /* Alerting Pattern $(NIA)$ */
3390     DE_ALLOWED_ACTIONS,                         /* Allowed Actions $(CCBS)$ */
3391     DE_SI,                                                      /* Stream Identifier */
3392     DE_NET_CC_CAP,                                      /* Network Call Control Capabilities */
3393     DE_CAUSE_NO_CLI,                            /* Cause of No CLI */
3394     DE_IMM_MOD_IND,                                     /* Immediate Modification Indicator */
3395     DE_SUP_CODEC_LIST,                          /* Supported Codec List */
3396     DE_SRVC_CAT,                                        /* Service Category */
3397     /* GPRS Mobility Management Information Elements 10.5.5 */
3398     DE_ATTACH_RES,                                      /* [7] 10.5.1 Attach Result*/
3399     DE_ATTACH_TYPE,                                     /* [7] 10.5.2 Attach Type */
3400     DE_CIPH_ALG,                                        /* [7] 10.5.3 Cipher Algorithm */
3401     DE_TMSI_STAT,                                       /* [7] 10.5.4 TMSI Status */
3402     DE_DETACH_TYPE,                                     /* [7] 10.5.5 Detach Type */
3403     DE_DRX_PARAM,                                       /* [7] 10.5.6 DRX Parameter */
3404     DE_FORCE_TO_STAND,                          /* [7] 10.5.7 Force to Standby */
3405     DE_FORCE_TO_STAND_H,                        /* [7] 10.5.8 Force to Standby - Info is in the high nibble */
3406     DE_P_TMSI_SIG,                                      /* [7] 10.5.9 P-TMSI Signature */
3407     DE_P_TMSI_SIG_2,                            /* [7] 10.5.10 P-TMSI Signature 2 */
3408     DE_ID_TYPE_2,                                       /* [7] 10.5.11 Identity Type 2 */
3409     DE_IMEISV_REQ,                                      /* [7] 10.5.12 IMEISV Request */
3410     DE_REC_N_PDU_NUM_LIST,                      /* [7] 10.5.13 Receive N-PDU Numbers List */
3411     DE_MS_NET_CAP,                                      /* [7] 10.5.14 MS Network Capability */
3412     DE_MS_RAD_ACC_CAP,                          /* [7] 10.5.15 MS Radio Access Capability */
3413     DE_GMM_CAUSE,                                       /* [7] 10.5.16 GMM Cause */
3414     DE_RAI,                                                     /* [7] 10.5.17 Routing Area Identification */
3415     DE_UPD_RES,                                         /* [7] 10.5.18 Update Result */
3416     DE_UPD_TYPE,                                        /* [7] 10.5.19 Update Type */
3417     DE_AC_REF_NUM,                                      /* [7] 10.5.20 A&C Reference Number */
3418     DE_AC_REF_NUM_H,                            /* A&C Reference Number - Info is in the high nibble */
3419     DE_SRVC_TYPE,                                       /* [7] 10.5.20 Service Type */
3420     DE_CELL_NOT,                                        /* [7] 10.5.21 Cell Notification */
3421     DE_PS_LCS_CAP,                                      /* [7] 10.5.22 PS LCS Capability */
3422     DE_NET_FEAT_SUP,                            /* [7] 10.5.23 Network Feature Support */
3423         DE_RAT_INFO_CONTAINER,                  /* [7] 10.5.24 Inter RAT information container */
3424         /* [7] 10.5.25 Requested MS information */
3425
3426     /* Short Message Service Information Elements [5] 8.1.4 */
3427     DE_CP_USER_DATA,                            /* CP-User Data */
3428     DE_CP_CAUSE,                                        /* CP-Cause */
3429     /* Short Message Service Information Elements [5] 8.2 */
3430     DE_RP_MESSAGE_REF,                          /* RP-Message Reference */
3431     DE_RP_ORIG_ADDR,                            /* RP-Origination Address */
3432     DE_RP_DEST_ADDR,                            /* RP-Destination Address */
3433     DE_RP_USER_DATA,                            /* RP-User Data */
3434     DE_RP_CAUSE,                                        /* RP-Cause */
3435     /* Session Management Information Elements 10.5.6 */
3436     DE_ACC_POINT_NAME,                          /* Access Point Name */
3437     DE_NET_SAPI,                                        /* Network Service Access Point Identifier */
3438     DE_PRO_CONF_OPT,                            /* Protocol Configuration Options */
3439     DE_PD_PRO_ADDR,                                     /* Packet Data Protocol Address */
3440     DE_QOS,                                                     /* Quality Of Service */
3441     DE_SM_CAUSE,                                        /* SM Cause */
3442     DE_LINKED_TI,                                       /* Linked TI */
3443     DE_LLC_SAPI,                                        /* LLC Service Access Point Identifier */
3444     DE_TEAR_DOWN_IND,                           /* Tear Down Indicator */
3445     DE_PACKET_FLOW_ID,                          /* Packet Flow Identifier */
3446     DE_TRAFFIC_FLOW_TEMPLATE,           /* Traffic Flow Template */
3447     /* GPRS Common Information Elements 10.5.7 */
3448     DE_PDP_CONTEXT_STAT,                        /* [8] 10.5.7.1         PDP Context Status */
3449     DE_RAD_PRIO,                                        /* [8] 10.5.7.2         Radio Priority */
3450     DE_GPRS_TIMER,                                      /* [8] 10.5.7.3         GPRS Timer */
3451     DE_GPRS_TIMER_2,                            /* [8] 10.5.7.4         GPRS Timer 2 */
3452     DE_RAD_PRIO_2,                                      /* [8] 10.5.7.5         Radio Priority 2 */
3453         DE_MBMS_CTX_STATUS,                             /* [8] 10.5.7.6         MBMS context status */
3454     DE_SPARE_NIBBLE,                            /* Spare Nibble */
3455     DE_NONE                                                     /* NONE */
3456 }
3457 dtap_elem_idx_t;
3458
3459 #define NUM_GSM_DTAP_ELEM (sizeof(gsm_dtap_elem_strings)/sizeof(value_string))
3460 static gint ett_gsm_dtap_elem[NUM_GSM_DTAP_ELEM];
3461
3462 /* 3GPP TS 24.008
3463  * [3] 10.5.1.1 Cell Identity
3464  */
3465 guint8
3466 de_cell_id(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
3467 {
3468     guint32     curr_offset;
3469
3470     curr_offset = offset;
3471
3472     curr_offset +=
3473         /* 0x02 CI */
3474         be_cell_id_aux(tvb, tree, offset, len, add_string, string_len, 0x02);
3475
3476     /* no length check possible */
3477
3478     return(curr_offset - offset);
3479 }
3480
3481 /*
3482  * [3] 10.5.1.3
3483  */
3484 guint8
3485 de_lai(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3486 {
3487     guint8      octs[3];
3488     guint16     value;
3489     guint32     curr_offset;
3490     proto_tree  *subtree;
3491     proto_item  *item;
3492     gchar       mcc[4];
3493     gchar       mnc[4];
3494
3495     len = len;
3496     curr_offset = offset;
3497
3498     item =
3499         proto_tree_add_text(tree,
3500             tvb, curr_offset, 5,
3501             gsm_dtap_elem_strings[DE_LAI].strptr);
3502
3503     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_LAI]);
3504
3505     octs[0] = tvb_get_guint8(tvb, curr_offset);
3506     octs[1] = tvb_get_guint8(tvb, curr_offset + 1);
3507     octs[2] = tvb_get_guint8(tvb, curr_offset + 2);
3508
3509     mcc_mnc_aux(octs, mcc, mnc);
3510
3511
3512     proto_tree_add_text(subtree,
3513         tvb, curr_offset, 3,
3514         "Mobile Country Code (MCC): %s, Mobile Network Code (MNC): %s",
3515         mcc,
3516         mnc);
3517
3518     curr_offset += 3;
3519
3520     value = tvb_get_ntohs(tvb, curr_offset);
3521
3522     proto_tree_add_text(subtree,
3523         tvb, curr_offset, 2,
3524         "Location Area Code (LAC): 0x%04x (%u)",
3525         value,
3526         value);
3527
3528     proto_item_append_text(item, " - LAC (0x%04x)", value);
3529
3530     curr_offset += 2;
3531
3532     /* no length check possible */
3533
3534     return(curr_offset - offset);
3535 }
3536
3537 /*
3538  * [3] 10.5.1.4
3539  */
3540 guint8
3541 de_mid(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
3542 {
3543     guint8      oct;
3544     guint32     curr_offset;
3545     guint8      *poctets;
3546     guint32     value;
3547     gboolean    odd;
3548
3549     curr_offset = offset;
3550     odd = FALSE;
3551
3552     oct = tvb_get_guint8(tvb, curr_offset);
3553
3554     switch (oct & 0x07)
3555     {
3556     case 0:     /* No Identity */
3557         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
3558         proto_tree_add_text(tree,
3559             tvb, curr_offset, 1,
3560             "%s :  Unused",
3561             a_bigbuf);
3562
3563         proto_tree_add_item(tree, hf_gsm_a_odd_even_ind, tvb, curr_offset, 1, FALSE);
3564
3565         proto_tree_add_item(tree, hf_gsm_a_mobile_identity_type, tvb, curr_offset, 1, FALSE);
3566
3567         if (add_string)
3568             g_snprintf(add_string, string_len, " - No Identity Code");
3569
3570         curr_offset++;
3571
3572         if (len > 1)
3573         {
3574             proto_tree_add_text(tree, tvb, curr_offset, len - 1,
3575                 "Format not supported");
3576         }
3577
3578         curr_offset += len - 1;
3579         break;
3580
3581     case 3:     /* IMEISV */
3582
3583         /* FALLTHRU */
3584
3585     case 1:     /* IMSI */
3586
3587         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
3588         proto_tree_add_text(tree,
3589             tvb, curr_offset, 1,
3590             "%s :  Identity Digit 1: %c",
3591             a_bigbuf,
3592             Dgt1_9_bcd.out[(oct & 0xf0) >> 4]);
3593
3594         odd = oct & 0x08;
3595
3596         proto_tree_add_item(tree, hf_gsm_a_odd_even_ind, tvb, curr_offset, 1, FALSE);
3597
3598         proto_tree_add_item(tree, hf_gsm_a_mobile_identity_type, tvb, curr_offset, 1, FALSE);
3599
3600
3601         a_bigbuf[0] = Dgt1_9_bcd.out[(oct & 0xf0) >> 4];
3602         curr_offset++;
3603
3604         poctets = tvb_get_ephemeral_string(tvb, curr_offset, len - (curr_offset - offset));
3605
3606         my_dgt_tbcd_unpack(&a_bigbuf[1], poctets, len - (curr_offset - offset),
3607             &Dgt1_9_bcd);
3608
3609         proto_tree_add_string_format(tree,
3610             ((oct & 0x07) == 3) ? hf_gsm_a_imeisv : hf_gsm_a_imsi,
3611             tvb, curr_offset, len - (curr_offset - offset),
3612             a_bigbuf,
3613             "BCD Digits: %s",
3614                 a_bigbuf);
3615
3616         if (sccp_assoc && ! sccp_assoc->calling_party) {
3617                 sccp_assoc->calling_party = se_strdup_printf(
3618                         ((oct & 0x07) == 3) ? "IMEISV: %s" : "IMSI: %s",
3619                         a_bigbuf );
3620         }
3621         
3622         if (add_string)
3623             g_snprintf(add_string, string_len, " - %s (%s)",
3624                 ((oct & 0x07) == 3) ? "IMEISV" : "IMSI",
3625                 a_bigbuf);
3626
3627         curr_offset += len - (curr_offset - offset);
3628
3629         if (!odd)
3630         {
3631             oct = tvb_get_guint8(tvb, curr_offset - 1);
3632
3633             other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
3634             proto_tree_add_text(tree,
3635                 tvb, curr_offset - 1, 1,
3636                 "%s :  Filler",
3637                 a_bigbuf);
3638         }
3639         break;
3640
3641     case 2:     /* IMEI */
3642         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
3643         proto_tree_add_text(tree,
3644             tvb, curr_offset, 1,
3645             "%s :  Identity Digit 1: %c",
3646             a_bigbuf,
3647             Dgt1_9_bcd.out[(oct & 0xf0) >> 4]);
3648
3649         proto_tree_add_item(tree, hf_gsm_a_odd_even_ind, tvb, curr_offset, 1, FALSE);
3650
3651         proto_tree_add_item(tree, hf_gsm_a_mobile_identity_type, tvb, curr_offset, 1, FALSE);
3652
3653
3654         a_bigbuf[0] = Dgt1_9_bcd.out[(oct & 0xf0) >> 4];
3655         curr_offset++;
3656
3657         poctets = tvb_get_ephemeral_string(tvb, curr_offset, len - (curr_offset - offset));
3658
3659         my_dgt_tbcd_unpack(&a_bigbuf[1], poctets, len - (curr_offset - offset),
3660             &Dgt1_9_bcd);
3661
3662         proto_tree_add_string_format(tree,
3663             hf_gsm_a_imei,
3664             tvb, curr_offset, len - (curr_offset - offset),
3665             a_bigbuf,
3666             "BCD Digits: %s",
3667             a_bigbuf);
3668
3669         if (add_string)
3670             g_snprintf(add_string, string_len, " - IMEI (%s)", a_bigbuf);
3671
3672         curr_offset += len - (curr_offset - offset);
3673         break;
3674
3675     case 4:     /* TMSI/P-TMSI */
3676         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
3677         proto_tree_add_text(tree,
3678             tvb, curr_offset, 1,
3679             "%s :  Unused",
3680             a_bigbuf);
3681
3682         proto_tree_add_item(tree, hf_gsm_a_odd_even_ind, tvb, curr_offset, 1, FALSE);
3683
3684         proto_tree_add_item(tree, hf_gsm_a_mobile_identity_type, tvb, curr_offset, 1, FALSE);
3685
3686
3687         curr_offset++;
3688
3689         value = tvb_get_ntohl(tvb, curr_offset);
3690
3691         proto_tree_add_uint(tree, hf_gsm_a_tmsi,
3692             tvb, curr_offset, 4,
3693             value);
3694
3695         if (add_string)
3696             g_snprintf(add_string, string_len, " - TMSI/P-TMSI (0x%04x)", value);
3697
3698         curr_offset += 4;
3699         break;
3700
3701     default:    /* Reserved */
3702         proto_tree_add_item(tree, hf_gsm_a_odd_even_ind, tvb, curr_offset, 1, FALSE);
3703         proto_tree_add_item(tree, hf_gsm_a_mobile_identity_type, tvb, curr_offset, 1, FALSE);
3704         proto_tree_add_text(tree, tvb, curr_offset, len,
3705             "Mobile station identity Format %u, Format Unknown",(oct & 0x07));
3706
3707         if (add_string)
3708             g_snprintf(add_string, string_len, " - Format Unknown");
3709
3710         curr_offset += len;
3711         break;
3712     }
3713
3714     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3715
3716     return(curr_offset - offset);
3717 }
3718
3719 /*
3720  * [3] 10.5.1.5
3721  */
3722 guint8
3723 de_ms_cm_1(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3724 {
3725     guint8      oct;
3726     guint32     curr_offset;
3727     proto_tree  *subtree;
3728     proto_item  *item;
3729     len = len;
3730     curr_offset = offset;
3731
3732     oct = tvb_get_guint8(tvb, curr_offset);
3733
3734     item =
3735         proto_tree_add_text(tree,
3736             tvb, curr_offset, 1,
3737             gsm_dtap_elem_strings[DE_MS_CM_1].strptr);
3738
3739     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_MS_CM_1]);
3740
3741     proto_tree_add_item(tree, hf_gsm_a_b8spare, tvb, curr_offset, 1, FALSE);
3742
3743     proto_tree_add_item(subtree, hf_gsm_a_MSC_rev, tvb, curr_offset, 1, FALSE);
3744
3745         proto_tree_add_item(subtree, hf_gsm_a_ES_IND, tvb, curr_offset, 1, FALSE);
3746
3747         proto_tree_add_item(subtree, hf_gsm_a_A5_1_algorithm_sup, tvb, curr_offset, 1, FALSE);
3748
3749     proto_tree_add_item(subtree, hf_gsm_a_RF_power_capability, tvb, curr_offset, 1, FALSE);
3750
3751     curr_offset++;
3752
3753     /* no length check possible */
3754
3755     return(curr_offset - offset);
3756 }
3757
3758 /*
3759  * [3] 10.5.1.6
3760  */
3761 guint8
3762 de_ms_cm_2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3763 {
3764     guint32     curr_offset;
3765     curr_offset = offset;
3766
3767
3768     proto_tree_add_item(tree, hf_gsm_a_b8spare, tvb, curr_offset, 1, FALSE);
3769
3770         proto_tree_add_item(tree, hf_gsm_a_MSC_rev, tvb, curr_offset, 1, FALSE);
3771
3772         proto_tree_add_item(tree, hf_gsm_a_ES_IND, tvb, curr_offset, 1, FALSE);
3773
3774         proto_tree_add_item(tree, hf_gsm_a_A5_1_algorithm_sup, tvb, curr_offset, 1, FALSE);
3775
3776     proto_tree_add_item(tree, hf_gsm_a_RF_power_capability, tvb, curr_offset, 1, FALSE);
3777
3778     curr_offset++;
3779
3780     NO_MORE_DATA_CHECK(len);
3781
3782     proto_tree_add_item(tree, hf_gsm_a_b8spare, tvb, curr_offset, 1, FALSE);
3783
3784     proto_tree_add_item(tree, hf_gsm_a_ps_sup_cap, tvb, curr_offset, 1, FALSE);
3785
3786     proto_tree_add_item(tree, hf_gsm_a_SS_screening_indicator, tvb, curr_offset, 1, FALSE);
3787
3788     /* SM capability (MT SMS pt to pt capability) (octet 4)*/
3789         proto_tree_add_item(tree, hf_gsm_a_SM_capability, tvb, curr_offset, 1, FALSE);
3790         /* VBS notification reception (octet 4) */
3791         proto_tree_add_item(tree, hf_gsm_a_VBS_notification_rec, tvb, curr_offset, 1, FALSE);
3792         /*VGCS notification reception (octet 4)*/
3793         proto_tree_add_item(tree, hf_gsm_a_VGCS_notification_rec, tvb, curr_offset, 1, FALSE);
3794         /* FC Frequency Capability (octet 4 ) */
3795         proto_tree_add_item(tree, hf_gsm_a_FC_frequency_cap, tvb, curr_offset, 1, FALSE);
3796
3797     curr_offset++;
3798
3799     NO_MORE_DATA_CHECK(len);
3800
3801         /* CM3 (octet 5, bit 8) */
3802         proto_tree_add_item(tree, hf_gsm_a_CM3, tvb, curr_offset, 1, FALSE);
3803         /* spare bit 7 */
3804         proto_tree_add_item(tree, hf_gsm_a_b7spare, tvb, curr_offset, 1, FALSE);
3805         /* LCS VA capability (LCS value added location request notification capability) (octet 5,bit 6) */
3806         proto_tree_add_item(tree, hf_gsm_a_LCS_VA_cap, tvb, curr_offset, 1, FALSE);
3807         /* UCS2 treatment (octet 5, bit 5) */
3808         proto_tree_add_item(tree, hf_gsm_a_UCS2_treatment, tvb, curr_offset, 1, FALSE);
3809         /* SoLSA (octet 5, bit 4) */
3810         proto_tree_add_item(tree, hf_gsm_a_SoLSA, tvb, curr_offset, 1, FALSE);
3811         /* CMSP: CM Service Prompt (octet 5, bit 3) */
3812         proto_tree_add_item(tree, hf_gsm_a_CMSP, tvb, curr_offset, 1, FALSE);
3813         /* A5/3 algorithm supported (octet 5, bit 2) */
3814         proto_tree_add_item(tree, hf_gsm_a_A5_3_algorithm_sup, tvb, curr_offset, 1, FALSE);
3815         /* A5/2 algorithm supported (octet 5, bit 1) */
3816         proto_tree_add_item(tree, hf_gsm_a_A5_2_algorithm_sup, tvb, curr_offset, 1, FALSE);
3817
3818     curr_offset++;
3819
3820     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3821
3822     return(curr_offset - offset);
3823 }
3824
3825 /*
3826  * [3] 10.5.1.9
3827  */
3828
3829 static guint8
3830 de_d_gb_call_ref(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3831 {
3832     guint8      oct;
3833     guint32     value;
3834     guint32     curr_offset;
3835     const gchar *str;
3836
3837     len = len;
3838     curr_offset = offset;
3839
3840     value = tvb_get_ntohl(tvb, curr_offset);
3841
3842     other_decode_bitfield_value(a_bigbuf, value, 0xffffffe0, 32);
3843     proto_tree_add_text(tree, tvb, curr_offset, 4,
3844         "%s :  Group or Broadcast call reference: %u (0x%04x)",
3845         a_bigbuf,
3846         (value & 0xffffffe0) >> 5,
3847         (value & 0xffffffe0) >> 5);
3848
3849     other_decode_bitfield_value(a_bigbuf, value, 0x00000010, 32);
3850     proto_tree_add_text(tree, tvb, curr_offset, 4,
3851         "%s :  SF Service Flag: %s",
3852         a_bigbuf,
3853         (value & 0x00000010) ?
3854             "VGCS (Group call reference)" : "VBS (Broadcast call reference)");
3855
3856     other_decode_bitfield_value(a_bigbuf, value, 0x00000008, 32);
3857     proto_tree_add_text(tree, tvb, curr_offset, 4,
3858         "%s :  AF Acknowledgement Flag: acknowledgment is %srequired",
3859         a_bigbuf,
3860         (value & 0x00000008) ? "" : "not ");
3861
3862     switch (value & 0x00000007)
3863     {
3864     case 1: str = "call priority level 4"; break;
3865     case 2: str = "call priority level 3"; break;
3866     case 3: str = "call priority level 2"; break;
3867     case 4: str = "call priority level 1"; break;
3868     case 5: str = "call priority level 0"; break;
3869     case 6: str = "call priority level B"; break;
3870     case 7: str = "call priority level A"; break;
3871     default:
3872         str = "no priority applied";
3873         break;
3874     }
3875
3876     other_decode_bitfield_value(a_bigbuf, value, 0x00000007, 32);
3877     proto_tree_add_text(tree, tvb, curr_offset, 4,
3878         "%s :  Call Priority: %s",
3879         a_bigbuf,
3880         str);
3881
3882     curr_offset += 4;
3883
3884     oct = tvb_get_guint8(tvb, curr_offset);
3885
3886     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
3887     proto_tree_add_text(tree, tvb, curr_offset, 1,
3888         "%s :  Ciphering Information",
3889         a_bigbuf);
3890
3891     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
3892     proto_tree_add_text(tree, tvb, curr_offset, 1,
3893         "%s :  Spare",
3894         a_bigbuf);
3895
3896     curr_offset++;
3897
3898     /* no length check possible */
3899
3900     return(curr_offset - offset);
3901 }
3902
3903 /*
3904  * [3] 10.5.1.10a
3905  */
3906 static guint8
3907 de_pd_sapi(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3908 {
3909     guint8      oct;
3910     guint32     curr_offset;
3911     proto_tree  *subtree;
3912     proto_item  *item;
3913     const gchar *str;
3914
3915     len = len;
3916     curr_offset = offset;
3917
3918     oct = tvb_get_guint8(tvb, curr_offset);
3919
3920     item =
3921         proto_tree_add_text(tree,
3922             tvb, curr_offset, 1,
3923             gsm_dtap_elem_strings[DE_PD_SAPI].strptr);
3924
3925     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_PD_SAPI]);
3926
3927     other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
3928     proto_tree_add_text(subtree, tvb, curr_offset, 1,
3929         "%s :  Spare",
3930         a_bigbuf);
3931
3932     switch ((oct & 0x30) >> 4)
3933     {
3934     case 0: str = "SAPI 0"; break;
3935     case 3: str = "SAPI 3"; break;
3936     default:
3937         str = "Reserved";
3938         break;
3939     }
3940
3941     other_decode_bitfield_value(a_bigbuf, oct, 0x30, 8);
3942     proto_tree_add_text(subtree, tvb, curr_offset, 1,
3943         "%s :  SAPI (Sevice Access Point Identifier): %s",
3944         a_bigbuf,
3945         str);
3946
3947     proto_tree_add_item(tree, hf_gsm_a_L3_protocol_discriminator, tvb, curr_offset, 1, FALSE);
3948
3949     curr_offset++;
3950
3951     /* no length check possible */
3952
3953     return(curr_offset - offset);
3954 }
3955
3956 /*
3957  * [3] 10.5.1.11
3958  */
3959
3960 static guint8
3961 de_prio(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3962 {
3963     guint8      oct;
3964     guint32     curr_offset;
3965     const gchar *str;
3966
3967     len = len;
3968     curr_offset = offset;
3969
3970     oct = tvb_get_guint8(tvb, curr_offset);
3971
3972     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
3973     proto_tree_add_text(tree,
3974         tvb, curr_offset, 1,
3975         "%s :  Spare",
3976         a_bigbuf);
3977
3978     switch (oct & 0x07)
3979     {
3980     case 1: str = "Call priority level 4"; break;
3981     case 2: str = "Call priority level 3"; break;
3982     case 3: str = "Call priority level 2"; break;
3983     case 4: str = "Call priority level 1"; break;
3984     case 5: str = "Call priority level 0"; break;
3985     case 6: str = "Call priority level B"; break;
3986     case 7: str = "Call priority level A"; break;
3987     default:
3988         str = "No priority applied";
3989         break;
3990     }
3991
3992     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
3993     proto_tree_add_text(tree,
3994         tvb, curr_offset, 1,
3995         "%s :  %s",
3996         a_bigbuf,
3997         str);
3998
3999     curr_offset++;
4000
4001     /* no length check possible */
4002
4003     return(curr_offset - offset);
4004 }
4005
4006 /*
4007  * [3] 10.5.1.13
4008  */
4009 static guint8
4010 de_plmn_list(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
4011 {
4012     guint8      octs[3];
4013     guint32     curr_offset;
4014     gchar       mcc[4];
4015     gchar       mnc[4];
4016     guint8      num_plmn;
4017
4018     curr_offset = offset;
4019
4020     num_plmn = 0;
4021     while ((len - (curr_offset - offset)) >= 3)
4022     {
4023         octs[0] = tvb_get_guint8(tvb, curr_offset);
4024         octs[1] = tvb_get_guint8(tvb, curr_offset + 1);
4025         octs[2] = tvb_get_guint8(tvb, curr_offset + 2);
4026
4027         mcc_mnc_aux(octs, mcc, mnc);
4028
4029         proto_tree_add_text(tree,
4030             tvb, curr_offset, 3,
4031             "PLMN[%u]  Mobile Country Code (MCC): %s, Mobile Network Code (MNC): %s",
4032             num_plmn + 1,
4033             mcc,
4034             mnc);
4035
4036         curr_offset += 3;
4037
4038         num_plmn++;
4039     }
4040
4041     if (add_string)
4042         g_snprintf(add_string, string_len, " - %u PLMN%s",
4043             num_plmn, plurality(num_plmn, "", "s"));
4044
4045     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
4046
4047     return(curr_offset - offset);
4048 }
4049 /*
4050 10.5.2 Radio Resource management information elements
4051  * [3] 10.5.2.1a BA Range
4052  */
4053 /*
4054  * [3] 10.5.2.1b Cell Channel Description
4055  */
4056 static guint8
4057 de_rr_cell_ch_dsc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4058 {
4059     guint32     curr_offset;
4060     guint8  oct,bit,byte;
4061         guint16 arfcn;
4062         proto_item      *item;
4063
4064
4065     len = len;
4066     curr_offset = offset;
4067
4068     oct = tvb_get_guint8(tvb, curr_offset);
4069
4070         /* FORMAT-ID, Format Identifier (part of octet 3)*/
4071         proto_tree_add_item(tree, hf_gsm_a_rr_format_id, tvb, curr_offset, 1, FALSE);
4072         /* Cell Channel Description */ 
4073
4074         if ((oct & 0xc0) == 0x00)
4075         {
4076                 /* bit map 0 */
4077                 item = proto_tree_add_text(tree,tvb, curr_offset, 16,"list of ARFCN for hopping = ");
4078                 bit = 4;
4079                 arfcn = 125;
4080                 for (byte = 0;byte <= 15;byte++)
4081                 {
4082                         oct = tvb_get_guint8(tvb, curr_offset);
4083                         while (bit-- != 0)
4084                         {
4085                                 arfcn--;
4086                                 if (((oct >> bit) & 1) == 1)
4087                                 {
4088                                         proto_item_append_text(item," %4d",arfcn);
4089                                 }
4090                         }
4091                         bit = 8;
4092                         curr_offset++;
4093                 }
4094         }
4095     else if ((oct & 0xf8) == 0x80)
4096         { 
4097                 /* 1024 range */
4098                 proto_tree_add_text(tree,tvb, curr_offset, 16,"Cell Channel Description (1024 range) (Not decoded)");
4099                 curr_offset = curr_offset + 16;
4100         }
4101         else if ((oct & 0xfe) == 0x88)
4102         {
4103                 /* 512 range */
4104                 proto_tree_add_text(tree,tvb, curr_offset, 16,"Cell Channel Description (512 range) (Not decoded)");
4105                 curr_offset = curr_offset + 16;
4106         }
4107         else if ((oct & 0xfe) == 0x8a)
4108         {
4109                 /* 256 range */
4110                 proto_tree_add_text(tree,tvb, curr_offset, 16,"Cell Channel Description (256 range) (Not decoded)");
4111                 curr_offset = curr_offset + 16;
4112         }
4113         else if ((oct & 0xfe) == 0x8c)
4114         {
4115                 /* 128 range */
4116                 proto_tree_add_text(tree,tvb, curr_offset, 16,"Cell Channel Description (128 range) (Not decoded)");
4117                 curr_offset = curr_offset + 16;
4118         }
4119         else if ((oct & 0xfe) == 0x8e)
4120         {
4121                 /* variable bit map */
4122                 arfcn = ((oct & 0x01) << 9) | (tvb_get_guint8(tvb, curr_offset+1) << 1) | ((tvb_get_guint8(tvb, curr_offset + 2) & 0x80) >> 7);
4123                 item = proto_tree_add_text(tree,tvb, curr_offset, 16,"list of ARFCN for hopping = %d",arfcn);
4124                 curr_offset = curr_offset + 2;
4125                 bit = 7;
4126                 for (byte = 0;byte <= 13;byte++)
4127                 {
4128                         oct = tvb_get_guint8(tvb, curr_offset);
4129                         while (bit-- != 0)
4130                         {
4131                                 arfcn++;
4132                                 if (((oct >> bit) & 1) == 1)
4133                                 {
4134                                         proto_item_append_text(item," %4d",arfcn);
4135                                 }
4136                         }
4137                         bit = 8;
4138                         curr_offset++;
4139                 }
4140         }       
4141         
4142
4143     return(curr_offset - offset);
4144 }
4145 /*
4146  * [3] 10.5.2.1c BA List Pref 
4147  * [3] 10.5.2.1d UTRAN Frequency List 
4148  */
4149 /*
4150  * [3] 10.5.2.2 Cell Description 
4151  */
4152 guint8
4153 de_rr_cell_dsc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4154 {
4155     proto_tree  *subtree;
4156     proto_item  *item;
4157     guint8      oct;
4158     guint32     curr_offset;
4159         guint16 bcch_arfcn;
4160
4161     len = len;
4162     curr_offset = offset;
4163
4164     oct = tvb_get_guint8(tvb, curr_offset);
4165         item =
4166         proto_tree_add_text(tree,
4167             tvb, curr_offset, 2,
4168             gsm_dtap_elem_strings[DE_RR_CELL_DSC].strptr);
4169
4170     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_RR_CELL_DSC]);
4171
4172         proto_tree_add_item(subtree, hf_gsm_a_ncc, tvb, curr_offset, 1, FALSE);
4173         proto_tree_add_item(subtree, hf_gsm_a_bcc, tvb, curr_offset, 1, FALSE);
4174         bcch_arfcn = (tvb_get_guint8(tvb,curr_offset) & 0xc0) << 2;
4175         bcch_arfcn = bcch_arfcn | tvb_get_guint8(tvb,curr_offset+1);
4176         proto_tree_add_uint(subtree, hf_gsm_a_bcch_arfcn , tvb, curr_offset, 2, bcch_arfcn );
4177
4178
4179     curr_offset = curr_offset + 2;
4180
4181
4182     return(curr_offset - offset);
4183 }
4184 /*
4185  * [3] 10.5.2.3 Cell Options (BCCH) 
4186  * [3] 10.5.2.3a Cell Options (SACCH) 
4187  * [3] 10.5.2.4 Cell Selection Parameters
4188  * [3] 10.5.2.4a MAC Mode and Channel Coding Requested 
4189  * [3] 10.5.2.5 Channel Description
4190  */
4191 static guint8
4192 de_rr_ch_dsc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4193 {
4194     guint32     curr_offset;
4195     guint8      oct8,subchannel;
4196     guint16 arfcn, hsn, maio;
4197         proto_tree      *subtree;
4198         proto_item      *item;
4199     const gchar *str;
4200
4201     len = len;
4202     curr_offset = offset;
4203
4204     item = proto_tree_add_text(tree,tvb, curr_offset, 3,gsm_dtap_elem_strings[DE_RR_CH_DSC].strptr);
4205
4206         subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_RR_CH_DSC]);
4207
4208     /* Octet 2 */
4209     oct8 = tvb_get_guint8(tvb, curr_offset);
4210     
4211     if ((oct8 & 0xf8) == 0x08)
4212     {
4213         str = "TCH/F + ACCHs"; 
4214                 other_decode_bitfield_value(a_bigbuf, oct8, 0xf8, 8);
4215         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = %s",a_bigbuf,str);
4216     }
4217     else 
4218     {
4219         if ((oct8 & 0xf0) == 0x10) 
4220         {
4221                 str = "TCH/H + ACCHs, Subchannel";
4222                 subchannel = ((oct8 & 0x08)>>3);
4223         }
4224         else if ((oct8 & 0xe0) == 0x20)
4225         {
4226                 str = "SDCCH/4 + SACCH/C4 or CBCH (SDCCH/4), Subchannel";
4227                 subchannel = ((oct8 & 0x18)>>3);
4228         }
4229         else if ((oct8 & 0xc0) == 0x40)
4230         {
4231                 str = "SDCCH/8 + SACCH/C8 or CBCH (SDCCH/8), Subchannel";
4232                 subchannel = ((oct8 % 0x38)>>3);
4233                 } else {
4234                         str = "";
4235                         subchannel = 0;
4236                         DISSECTOR_ASSERT_NOT_REACHED();
4237                 }
4238                 
4239                 other_decode_bitfield_value(a_bigbuf, oct8, 0xf8, 8);
4240         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = %s %d",a_bigbuf,str,subchannel);
4241     }
4242
4243         other_decode_bitfield_value(a_bigbuf, oct8, 0x07, 8);
4244     proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Timeslot: %d",a_bigbuf,(oct8 & 0x07));
4245
4246         curr_offset +=1;
4247                 
4248         /* Octet 3 */
4249         oct8 = tvb_get_guint8(tvb, curr_offset);
4250     other_decode_bitfield_value(a_bigbuf, oct8, 0xe0, 8);
4251         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Training Sequence: %d",a_bigbuf,((oct8 & 0xe0)>>5));
4252                 
4253     
4254         if ((oct8 & 0x10) == 0x10)
4255         {
4256                 /* Hopping sequence */
4257                 maio = ((oct8 & 0x0f)<<2) | ((tvb_get_guint8(tvb,curr_offset+1) & 0xc0) >> 6);
4258                 hsn = (tvb_get_guint8(tvb,curr_offset+1) & 0x3f);
4259                 str = "Yes";
4260
4261                 other_decode_bitfield_value(a_bigbuf, oct8, 0x10, 8);
4262                 proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Hopping channel: %s",a_bigbuf,str);
4263                 proto_tree_add_text(subtree,tvb, curr_offset, 2,"Hopping channel: MAIO %d",maio);
4264                 proto_tree_add_text(subtree,tvb, curr_offset, 2,"Hopping channel: HSN %d",hsn);
4265         }
4266         else
4267         {
4268                 /* sinlge ARFCN */
4269                 arfcn = ((oct8 & 0x03) << 8) | tvb_get_guint8(tvb,curr_offset+1);
4270                 str = "No";
4271
4272                 other_decode_bitfield_value(a_bigbuf, oct8, 0x10, 8);
4273                 proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Hopping channel: %s",a_bigbuf,str);
4274                 other_decode_bitfield_value(a_bigbuf, oct8, 0x0c, 8);
4275                 proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Spare",a_bigbuf);
4276                 proto_tree_add_text(subtree,tvb, curr_offset, 2,"Single channel : ARFCN %d",arfcn);
4277         }
4278                 
4279         curr_offset = curr_offset + 2;
4280
4281     return(curr_offset - offset);
4282 }
4283 /*
4284  * [3] 10.5.2.5a Channel Description 2
4285  */
4286 static guint8
4287 de_rr_ch_dsc2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4288 {
4289     guint32     curr_offset;
4290     guint8      oct8,subchannel;
4291     guint16 arfcn, hsn, maio;
4292         proto_tree      *subtree;
4293         proto_item      *item;
4294     const gchar *str;
4295
4296     len = len;
4297     curr_offset = offset;
4298
4299     item = proto_tree_add_text(tree,tvb, curr_offset, 3,gsm_dtap_elem_strings[DE_RR_CH_DSC2].strptr);
4300
4301         subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_RR_CH_DSC2]);
4302
4303     /* Octet 2 */
4304     oct8 = tvb_get_guint8(tvb, curr_offset);
4305     
4306     if ((oct8 & 0xf8) == 0x0)
4307     {
4308         str = "TCH/F + FACCH/F and SACCH/M"; 
4309                 other_decode_bitfield_value(a_bigbuf, oct8, 0xf8, 8);
4310         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = %s",a_bigbuf,str);
4311     }
4312         else if ((oct8 & 0xf8) == 0x08)
4313     {
4314         str = "TCH/F + FACCH/F and SACCH/F"; 
4315                 other_decode_bitfield_value(a_bigbuf, oct8, 0xf8, 8);
4316         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = %s",a_bigbuf,str);
4317     }
4318         else if ((oct8 & 0xf8) == 0xf0)
4319         {
4320                 str = "TCH/F + FACCH/F and SACCH/M + bi- and unidirectional channels";
4321                 other_decode_bitfield_value(a_bigbuf, oct8, 0xf8, 8);
4322         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = %s",a_bigbuf,str);
4323         }
4324     else 
4325     {
4326         if ((oct8 & 0xf0) == 0x10) 
4327         {
4328                 str = "TCH/H + ACCHs, Subchannel";
4329                 subchannel = ((oct8 & 0x08)>>3);
4330         }
4331         else if ((oct8 & 0xe0) == 0x20)
4332         {
4333                 str = "SDCCH/4 + SACCH/C4 or CBCH (SDCCH/4), Subchannel";
4334                 subchannel = ((oct8 & 0x18)>>3);
4335         }
4336         else if ((oct8 & 0xc0) == 0x40)
4337         {
4338                 str = "SDCCH/8 + SACCH/C8 or CBCH (SDCCH/8), Subchannel";
4339                 subchannel = ((oct8 % 0x38)>>3);
4340                 }
4341                 else if ((oct8 & 0xc0) == 0x80)
4342                 {
4343                         str = "TCH/F + FACCH/F and SACCH/M + bidirectional channels at timeslot";
4344                         subchannel = ((oct8 % 0x38)>>3);
4345                 }
4346                 else if ((oct8 & 0xe0) == 0xc0)
4347                 {
4348                         str = "TCH/F + FACCH/F and SACCH/M + unidirectional channels at timeslot";
4349                         subchannel = ((oct8 % 0x38)>>3);
4350                 } else {
4351                         str = "";
4352                         subchannel = 0;
4353                         DISSECTOR_ASSERT_NOT_REACHED();
4354                 }
4355                 other_decode_bitfield_value(a_bigbuf, oct8, 0xf8, 8);
4356         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = %s %d",a_bigbuf,str,subchannel);
4357     }
4358
4359         other_decode_bitfield_value(a_bigbuf, oct8, 0x07, 8);
4360     proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Timeslot: %d",a_bigbuf,(oct8 & 0x07));
4361
4362         curr_offset +=1;
4363                 
4364         /* Octet 3 */
4365         oct8 = tvb_get_guint8(tvb, curr_offset);
4366     other_decode_bitfield_value(a_bigbuf, oct8, 0xe0, 8);
4367         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Training Sequence: %d",a_bigbuf,((oct8 & 0xe0)>>5));
4368                 
4369     
4370         if ((oct8 & 0x10) == 0x10)
4371         {
4372                 /* Hopping sequence */
4373                 maio = ((oct8 & 0x0f)<<2) | ((tvb_get_guint8(tvb,curr_offset+1) & 0xc0) >> 6);
4374                 hsn = (tvb_get_guint8(tvb,curr_offset+1) & 0x3f);
4375                 str = "Yes";
4376
4377                 other_decode_bitfield_value(a_bigbuf, oct8, 0x10, 8);
4378                 proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Hopping channel: %s",a_bigbuf,str);
4379                 proto_tree_add_text(subtree,tvb, curr_offset, 2,"Hopping channel: MAIO %d",maio);
4380                 proto_tree_add_text(subtree,tvb, curr_offset, 2,"Hopping channel: HSN %d",hsn);
4381         }
4382         else
4383         {
4384                 /* sinlge ARFCN */
4385                 arfcn = ((oct8 & 0x03) << 8) | tvb_get_guint8(tvb,curr_offset+1);
4386                 str = "No";
4387
4388                 other_decode_bitfield_value(a_bigbuf, oct8, 0x10, 8);
4389                 proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Hopping channel: %s",a_bigbuf,str);
4390                 other_decode_bitfield_value(a_bigbuf, oct8, 0x0c, 8);
4391                 proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Spare",a_bigbuf);
4392                 proto_tree_add_text(subtree,tvb, curr_offset, 2,"Single channel : ARFCN %d",arfcn);
4393         }
4394                 
4395         curr_offset = curr_offset + 2;
4396
4397     return(curr_offset - offset);
4398 }
4399 /*
4400  * [3] 10.5.2.6 Channel Mode
4401  */
4402
4403 /* Channel Mode  */
4404 static const value_string gsm_a_rr_channel_mode_vals[] = {
4405 { 0x00,         "signalling only"},
4406 { 0x01,         "speech full rate or half rate version 1(GSM FR or GSM HR)"},
4407 { 0x21,         "speech full rate or half rate version 2(GSM EFR)"},
4408 { 0x41,         "speech full rate or half rate version 3(FR AMR or HR AMR)"},
4409 { 0x81,         "speech full rate or half rate version 4(OFR AMR-WB or OHR AMR-WB)"},
4410 { 0x82,         "speech full rate or half rate version 5(FR AMR-WB )"},
4411 { 0x83,         "speech full rate or half rate version 6(OHR AMR )"},
4412 { 0x61,         "data, 43.5 kbit/s (downlink)+14.5 kbps (uplink)"},
4413 { 0x62,         "data, 29.0 kbit/s (downlink)+14.5 kbps (uplink)"},
4414 { 0x64,         "data, 43.5 kbit/s (downlink)+29.0 kbps (uplink)"},
4415 { 0x67,         "data, 14.5 kbit/s (downlink)+43.5 kbps (uplink)"},
4416 { 0x65,         "data, 14.5 kbit/s (downlink)+29.0 kbps (uplink)"},
4417 { 0x66,         "data, 29.0 kbit/s (downlink)+43.5 kbps (uplink)"},
4418 { 0x27,         "data, 43.5 kbit/s radio interface rate"},
4419 { 0x63,         "data, 32.0 kbit/s radio interface rate"},
4420 { 0x43,         "data, 29.0 kbit/s radio interface rate"},
4421 { 0x0f,         "data, 14.5 kbit/s radio interface rate"},
4422 { 0x03,         "data, 12.0 kbit/s radio interface rate"},
4423 { 0x0b,         "data, 6.0 kbit/s radio interface rate"},
4424 { 0x13,         "data, 3.6 kbit/s radio interface rate"},
4425         { 0,    NULL }
4426 };
4427
4428 guint8
4429 de_rr_ch_mode(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4430 {
4431     guint32     curr_offset;
4432
4433     len = len;
4434     curr_offset = offset;
4435
4436     proto_tree_add_item(tree, hf_gsm_a_rr_channel_mode, tvb, curr_offset, 1, FALSE);
4437         
4438         curr_offset = curr_offset + 1;
4439
4440     return(curr_offset - offset);
4441 }
4442 /*
4443  * [3] 10.5.2.7 Channel Mode 2 
4444  */
4445
4446 static const value_string gsm_a_rr_channel_mode2_vals[] = {
4447 { 0x00,         "signalling only"},
4448 { 0x05,         "speech half rate version 1(GSM HR)"},
4449 { 0x25,         "speech half rate version 2(GSM EFR)"},
4450 { 0x45,         "speech half rate version 3(HR AMR)"},
4451 { 0x85,         "speech half rate version 4(OHR AMR-WB)"},
4452 { 0x06,         "speech half rate version 6(OHR AMR )"},
4453 { 0x0f,         "data, 6.0 kbit/s radio interface rate"},
4454 { 0x17,         "data, 3.6 kbit/s radio interface rate"},
4455         { 0,    NULL }
4456 };
4457
4458 static guint8
4459 de_rr_ch_mode2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4460 {
4461     guint32     curr_offset;
4462
4463     len = len;
4464     curr_offset = offset;
4465
4466     proto_tree_add_item(tree, hf_gsm_a_rr_channel_mode2, tvb, curr_offset, 1, FALSE);
4467         
4468         curr_offset = curr_offset + 1;
4469
4470     return(curr_offset - offset);
4471 }  
4472 /*
4473  * [3] 10.5.2.7a UTRAN Classmark information element
4474  * [3] 10.5.2.7b (void)
4475  */
4476 /*
4477  * [3] 10.5.2.7c Classmark Enquiry Mask
4478  * Bit 8:
4479  * 0    CLASSMARK CHANGE message is requested
4480  * 1    CLASSMARK CHANGE message is not requested
4481  * Bits 7-5 . 5
4482  * 000  UTRAN CLASSMARK CHANGE message including status on predefined configurations (i.e. Sequence Description) is requested
4483  * 111  UTRAN CLASSMARK CHANGE message including status on predefined configurations (i.e. Sequence Description) is not requested.
4484  * All other values shall not be sent. If received, they shall be interpreted as '000'.
4485  * Bit 4:
4486  * 0    CDMA2000 CLASSMARK CHANGE message requested
4487  * 1    CDMA2000 CLASSMARK CHANGE message not requested.
4488  * Bit 3:
4489  * 0    GERAN IU MODE CLASSMARK CHANGE message requested
4490  * 1    GERAN IU MODE CLASSMARK CHANGE message not requested.
4491  * Bits 2 - 1: spare(0).
4492  */
4493 static const true_false_string gsm_a_msg_req_value  = {
4494   "message is not requested",
4495   "message is requested"
4496 };
4497 static const value_string gsm_a_rr_utran_cm_cng_msg_req_vals[] = {
4498 { 0x0,          "message including status on predefined configurations (i.e. Sequence Description) is requested"},
4499 { 0x1,          "message including status on predefined configurations (i.e. Sequence Description) is requested"},
4500 { 0x2,          "message including status on predefined configurations (i.e. Sequence Description) is requested"},
4501 { 0x3,          "message including status on predefined configurations (i.e. Sequence Description) is requested"},
4502 { 0x4,          "message including status on predefined configurations (i.e. Sequence Description) is requested"},
4503 { 0x5,          "message including status on predefined configurations (i.e. Sequence Description) is requested"},
4504 { 0x6,          "message including status on predefined configurations (i.e. Sequence Description) is requested"},
4505 { 0x7,          "message including status on predefined configurations (i.e. Sequence Description) is not requested."},
4506         { 0,    NULL }
4507 };
4508 guint8
4509 de_rr_cm_enq_mask(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4510 {
4511     guint32     curr_offset;
4512
4513     len = len;
4514     curr_offset = offset;
4515         
4516         proto_tree_add_item(tree, hf_gsm_a_rr_cm_cng_msg_req, tvb, curr_offset, 1, FALSE);
4517         proto_tree_add_item(tree, hf_gsm_a_rr_utran_cm_cng_msg_req, tvb, curr_offset, 1, FALSE);
4518         proto_tree_add_item(tree, hf_gsm_a_rr_cdma200_cm_cng_msg_req, tvb, curr_offset, 1, FALSE);
4519         proto_tree_add_item(tree, hf_gsm_a_rr_geran_iu_cm_cng_msg_req, tvb, curr_offset, 1, FALSE);
4520
4521         curr_offset = curr_offset + 1;
4522
4523     return(curr_offset - offset);
4524 }
4525 /*
4526  * [3] 10.5.2.8 Channel Needed
4527  */
4528 static const value_string gsm_a_rr_channel_needed_vals[] = {
4529 { 0x00,         "Any channel"},
4530 { 0x01,         "SDCCH"},
4531 { 0x02,         "TCH/F (Full rate)"},
4532 { 0x03,         "TCH/H or TCH/F (Dual rate)"},
4533         { 0,    NULL }
4534 };
4535 guint8
4536 de_rr_chnl_needed(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4537 {
4538     guint32     curr_offset;
4539
4540     len = len;
4541     curr_offset = offset;
4542         
4543         proto_tree_add_item(tree, hf_gsm_a_rr_chnl_needed_ch1, tvb, curr_offset, 1, FALSE);
4544         proto_tree_add_item(tree, hf_gsm_a_rr_chnl_needed_ch2, tvb, curr_offset, 1, FALSE);
4545
4546         curr_offset = curr_offset + 1;
4547
4548     return(curr_offset - offset);
4549 }
4550 /*
4551  * [3] 10.5.2.8a Channel Request Description
4552  * [3] 10.5.2.8b Channel Request Description 2
4553  */
4554 /*
4555  * [3] 10.5.2.9 Cipher Mode Setting
4556  */
4557 /* SC (octet 1) */
4558 static const value_string gsm_a_rr_sc_vals[] = {
4559         { 0,            "No ciphering"},
4560         { 1,            "Start ciphering"},
4561         { 0,    NULL }
4562 };
4563 /* algorithm identifier
4564  * If SC=1 then:
4565  * bits
4566  * 4 3 2
4567  */
4568
4569 guint8
4570 de_rr_cip_mode_set(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4571 {
4572     guint32     curr_offset;
4573         guint8 oct;
4574
4575     len = len;
4576     curr_offset = offset;               
4577
4578         /* Cipher Mode Setting
4579                  * Note: The coding of fields SC and algorithm identifier is defined in [44.018] 
4580                  * as part of the Cipher Mode Setting IE.
4581                  */
4582                 proto_tree_add_item(tree, hf_gsm_a_rr_sc, tvb, curr_offset, 1, FALSE);
4583                 oct = tvb_get_guint8(tvb,curr_offset);
4584                 if ( (oct & 1) == 1){ /* Start ciphering */
4585                         /* algorithm identifier */
4586                         proto_tree_add_item(tree, hf_gsm_a_algorithm_id, tvb, curr_offset, 1, FALSE);
4587                 }
4588         curr_offset = curr_offset + 1;
4589
4590     return(curr_offset - offset);
4591 }
4592 /*
4593  * [3] 10.5.2.10 Cipher Response
4594  * [3] 10.5.2.11 Control Channel Description
4595  * [3] 10.5.2.11a DTM Information Details
4596  */
4597 /* 
4598  * [3]  10.5.2.11b      Dynamic ARFCN Mapping           
4599  */
4600 static guint8
4601 de_rr_dyn_arfcn_map(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4602 {
4603     guint32     curr_offset;
4604
4605     len = len;
4606     curr_offset = offset;
4607
4608         proto_tree_add_text(tree,tvb, curr_offset, len,"Dynamic ARFCN Mapping content(Not decoded)");
4609
4610         
4611         curr_offset = curr_offset + len;
4612
4613     return(curr_offset - offset);
4614 }  
4615 /*
4616  * [3] 10.5.2.12 Frequency Channel Sequence
4617  */
4618 static guint8
4619 de_rr_freq_ch_seq(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4620 {
4621     guint32     curr_offset;
4622
4623     len = len;
4624     curr_offset = offset;
4625
4626         proto_tree_add_text(tree,tvb, curr_offset, 9,"Frequency Channel Sequence(Not decoded)");
4627
4628         
4629         curr_offset = curr_offset + 9;
4630
4631     return(curr_offset - offset);
4632 }  
4633 /*
4634  * [3] 10.5.2.13 Frequency List
4635  * 
4636  * Bit Bit Bit Bit Bit format notation
4637  * 8 7  4 3 2
4638  * 0 0  X X X bit map 0
4639  * 1 0  0 X X 1024 range
4640  * 1 0  1 0 0 512 range
4641  * 1 0  1 0 1 256 range
4642  * 1 0  1 1 0 128 range
4643  * 1 0  1 1 1 variable bit map
4644  */
4645 /* The mask 0xce (1100 1110) will produce the result 0110 0111*/ 
4646 static const value_string gsm_a_rr_freq_list_format_id_vals[] = {
4647         { 0x00,         "bit map 0"},
4648         { 0x02,         "bit map 0"},
4649         { 0x04,         "bit map 0"},
4650         { 0x06,         "bit map 0"},
4651         { 0x08,         "bit map 0"},
4652         { 0x0a,         "bit map 0"},
4653         { 0x0c,         "bit map 0"},
4654         { 0x0e,         "bit map 0"},
4655         { 0x40,         "1024 range"},
4656         { 0x41,         "1024 range"},
4657         { 0x42,         "1024 range"},
4658         { 0x43,         "1024 range"},
4659         { 0x44,         "512 range"},
4660         { 0x45,         "256 range"},
4661         { 0x46,         "128 range"},
4662         { 0x47,         "variable bit map"},
4663         { 0x00, NULL }
4664 };
4665 static guint8
4666 de_rr_freq_list(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4667 {
4668     guint32     curr_offset;
4669
4670     len = len;
4671     curr_offset = offset;
4672
4673         /* FORMAT-ID, Format Identifier (part of octet 3)*/
4674         proto_tree_add_item(tree, hf_gsm_a_rr_format_id, tvb, curr_offset, 1, FALSE);
4675         /* Frequency list */ 
4676         proto_tree_add_text(tree,tvb, curr_offset, len-1,"Frequency Data(Not decoded)");
4677
4678         curr_offset = curr_offset + len;
4679     return(curr_offset - offset);
4680
4681 }
4682 /*
4683  * [3] 10.5.2.13.1 General description
4684  * [3] 10.5.2.13.2 Bit map 0 format
4685  * [3] 10.5.2.13.3 Range 1024 format
4686  * [3] 10.5.2.13.4 Range 512 format
4687  * [3] 10.5.2.13.5 Range 256 format
4688  * [3] 10.5.2.13.6 Range 128 format
4689  * [3] 10.5.2.13.7 Variable bit map format
4690  */
4691 /*
4692  * [3] 10.5.2.14 Frequency Short List
4693  *
4694  *The Frequency Short List information element is a type 3 information element of 10 octet length.
4695  *
4696  * This element is encoded exactly as the Frequency List information element, 
4697  * except that it has a fixed length instead of a variable length and does 
4698  * not contain a length indicator and that it shall not be encoded in bitmap 0 format.
4699  */
4700 static guint8
4701 de_rr_freq_short_list(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4702 {
4703     guint32     curr_offset;
4704
4705     len = len;
4706     curr_offset = offset;
4707
4708         /* FORMAT-ID, Format Identifier (part of octet 3)*/
4709         proto_tree_add_item(tree, hf_gsm_a_rr_format_id, tvb, curr_offset, 1, FALSE);
4710         /* Frequency list */ 
4711         proto_tree_add_text(tree,tvb, curr_offset, 9,"Frequency Data(Not decoded)");
4712
4713         curr_offset = curr_offset + 9;
4714     return(curr_offset - offset);
4715
4716 }
4717 /*
4718  * [3] 10.5.2.14a Frequency Short List 2
4719  *
4720  * The Frequency Short List information element is a type 3 information element of 8 octet length.
4721  *
4722  * This element is encoded exactly as the Frequency List information element, 
4723  * except that it has a fixed length instead of a variable length and does 
4724  * not contain a length indicator and that it shall not be encoded in bitmap 0 format.
4725  */
4726 static guint8
4727 de_rr_freq_short_list2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4728 {
4729     guint32     curr_offset;
4730
4731     len = len;
4732     curr_offset = offset;
4733
4734         /* FORMAT-ID, Format Identifier (part of octet 3)*/
4735         proto_tree_add_item(tree, hf_gsm_a_rr_format_id, tvb, curr_offset, 1, FALSE);
4736
4737         /* Frequency list */ 
4738         proto_tree_add_text(tree,tvb, curr_offset, 7,"Frequency Data(Not decoded)");
4739
4740         curr_offset = curr_offset + 8;
4741     return(curr_offset - offset);
4742
4743 }
4744 /*
4745  * [3] 10.5.2.14b Group Channel Description
4746  * [3] 10.5.2.14c GPRS Resumption
4747  * [3] 10.5.2.14d GPRS broadcast information
4748  */
4749 /*
4750  * [3] 10.5.2.15 Handover Reference
4751  */
4752 static guint8
4753 de_rr_ho_ref(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4754 {
4755     proto_tree  *subtree;
4756     proto_item  *item;
4757     guint32     curr_offset;
4758
4759     len = len;
4760     curr_offset = offset;
4761
4762         item =
4763         proto_tree_add_text(tree,
4764             tvb, curr_offset, 1,
4765             gsm_dtap_elem_strings[DE_RR_HO_REF].strptr);
4766
4767     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_RR_HO_REF]);
4768
4769         /* Handover reference value */
4770     proto_tree_add_item(subtree, hf_gsm_a_rr_ho_ref_val, tvb, curr_offset, 1, FALSE);
4771         
4772         curr_offset = curr_offset + 1;
4773
4774     return(curr_offset - offset);
4775 }
4776 /*
4777  * [3] 10.5.2.16 IA Rest Octets
4778  * [3] 10.5.2.17 IAR Rest Octets
4779  * [3] 10.5.2.18 IAX Rest Octets
4780  * [3] 10.5.2.19 L2 Pseudo Length
4781  * [3] 10.5.2.20 Measurement Results
4782  * [3] 10.5.2.20a GPRS Measurement Results
4783  */
4784 /*
4785  * [3] 10.5.2.21 Mobile Allocation
4786  */
4787 static guint8
4788 de_rr_mob_all(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4789 {
4790     guint32     curr_offset;
4791
4792     len = len;
4793     curr_offset = offset;
4794
4795         proto_tree_add_text(tree,tvb, curr_offset, len ,"Data(Not decoded)");
4796
4797         curr_offset = curr_offset + len;
4798     return(curr_offset - offset);
4799
4800 }
4801 /*
4802  * [3] 10.5.2.21a Mobile Time Difference
4803  */
4804 static guint8
4805 de_rr_mob_time_diff(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4806 {
4807     guint32     curr_offset;
4808
4809     len = len;
4810     curr_offset = offset;
4811
4812         proto_tree_add_text(tree,tvb, curr_offset, len ,"Data(Not decoded)");
4813
4814         curr_offset = curr_offset + len;
4815     return(curr_offset - offset);
4816
4817 }
4818 /*
4819  * [3] 10.5.2.21aa MultiRate configuration
4820  */
4821 /*      Multirate speech version Octet 3 Bits 8 7 6 */
4822 static const value_string multirate_speech_ver_vals[] = {
4823         { 1,            "Adaptive Multirate speech version 1"},
4824         { 2,            "Adaptive Multirate speech version 2"},
4825         { 0,    NULL }
4826 };
4827 /* Bit  5       NSCB: Noise Suppression Control Bit */
4828 static const value_string NSCB_vals[] = {
4829         { 0,            "Noise Suppression can be used (default)"},
4830         { 1,            "Noise Suppression shall be turned off"},
4831         { 0,    NULL }
4832 };
4833 /* Bit  4       ICMI: Initial Codec Mode Indicator */
4834 static const value_string ICMI_vals[] = {
4835         { 0,            "The initial codec mode is defined by the implicit rule provided in 3GPP TS 05.09"},
4836         { 1,            "The initial codec mode is defined by the Start Mode field"},
4837         { 0,    NULL }
4838 };
4839 /*
4840 Table 10.5.2.21aa.2: Set of adaptive multirate codec modes field (octet 4)
4841 for the Multirate speech version 1
4842 */
4843 static const true_false_string gsm_a_rr_set_of_amr_codec_modes  = {
4844   "is part of the subset",
4845   "is not part of the subset"
4846 };
4847
4848
4849
4850 guint8
4851 de_rr_multirate_conf(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4852 {
4853     guint32     curr_offset;
4854         guint8 oct;
4855
4856     len = len;
4857     curr_offset = offset;
4858
4859         proto_tree_add_item(tree, hf_gsm_a_rr_multirate_speech_ver, tvb, curr_offset, 1, FALSE);
4860         proto_tree_add_item(tree, hf_gsm_a_rr_NCSB, tvb, curr_offset, 1, FALSE);
4861         proto_tree_add_item(tree, hf_gsm_a_rr_ICMI, tvb, curr_offset, 1, FALSE);
4862         /* The initial codec mode is coded as in 3GPP TS 45.009 */
4863         proto_tree_add_item(tree, hf_gsm_a_rr_start_mode, tvb, curr_offset, 1, FALSE);
4864         oct = ( tvb_get_guint8(tvb,curr_offset) &0xe0 ) >> 5;
4865         curr_offset++;
4866         switch ( oct){
4867         case 1:
4868                 /* Adaptive Multirate speech version 1 */
4869                 /* Set of AMR codec modes */
4870                 proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v1_b8, tvb, curr_offset, 1, FALSE);
4871                 proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v1_b7, tvb, curr_offset, 1, FALSE);
4872                 proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v1_b6, tvb, curr_offset, 1, FALSE);
4873                 proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v1_b5, tvb, curr_offset, 1, FALSE);
4874                 proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v1_b4, tvb, curr_offset, 1, FALSE);
4875                 proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v1_b3, tvb, curr_offset, 1, FALSE);
4876                 proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v1_b2, tvb, curr_offset, 1, FALSE);
4877                 proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v1_b1, tvb, curr_offset, 1, FALSE);
4878                 curr_offset++;
4879
4880                 proto_tree_add_text(tree,tvb, curr_offset, len-2 ,"Parameters for multirate speech field(Not decoded)");
4881
4882                 break;
4883         case 2:
4884                 /* Adaptive Multirate speech version 2 */
4885                 proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v2_b5, tvb, curr_offset, 1, FALSE);
4886                 proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v2_b4, tvb, curr_offset, 1, FALSE);
4887                 proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v2_b3, tvb, curr_offset, 1, FALSE);
4888                 proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v2_b2, tvb, curr_offset, 1, FALSE);
4889                 proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v2_b1, tvb, curr_offset, 1, FALSE);
4890                 curr_offset++;
4891
4892                 proto_tree_add_text(tree,tvb, curr_offset, len-2 ,"Parameters for multirate speech field(Not decoded)");
4893                 break;
4894         default:
4895                 proto_tree_add_text(tree,tvb,offset,1,"Unknown version");
4896                 proto_tree_add_text(tree,tvb, curr_offset, len-1 ,"Data(Not decoded)");
4897                         break;
4898         }
4899
4900         curr_offset = offset + len;
4901     return(curr_offset - offset);
4902
4903 }
4904 /*
4905  * [3] 10.5.2.21b Multislot Allocation
4906  */
4907 static guint8
4908 de_rr_mult_all(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4909 {
4910     guint32     curr_offset;
4911
4912     len = len;
4913     curr_offset = offset;
4914
4915         proto_tree_add_text(tree,tvb, curr_offset, len ,"Data(Not decoded)");
4916
4917         curr_offset = curr_offset + len;
4918     return(curr_offset - offset);
4919
4920 }
4921 /*
4922  * [3] 10.5.2.21c NC mode
4923  * [3] 10.5.2.22 Neighbour Cell Description
4924  * [3] 10.5.2.22a Neighbour Cell Description 2
4925  * [3] 10.5.2.22b (void)
4926  * [3] 10.5.2.22c NT/N Rest Octets
4927  * [3] 10.5.2.23 P1 Rest Octets
4928  * [3] 10.5.2.24 P2 Rest Octets
4929  * [3] 10.5.2.25 P3 Rest Octets
4930  * [3] 10.5.2.25a Packet Channel Description
4931  * [3] 10.5.2.25b Dedicated mode or TBF
4932  * [3] 10.5.2.25c RR Packet Uplink Assignment
4933  * [3] 10.5.2.25d RR Packet Downlink Assignment
4934  * [3] 10.5.2.26 Page Mode
4935  * [3] 10.5.2.26a (void)
4936  * [3] 10.5.2.26b (void)
4937  * [3] 10.5.2.26c (void)
4938  * [3] 10.5.2.26d (void)
4939  * [3] 10.5.2.27 NCC Permitted
4940  */
4941 /*
4942  * [3] 10.5.2.28 Power Command
4943  *
4944  *
4945  * ATC (Access Type Control) (octet 2)Bit 8
4946  * 0    Sending of Handover access is mandatory
4947  * 1    Sending of Handover access is optional
4948  */
4949 static const true_false_string gsm_a_rr_pow_cmd_atc_value  = {
4950   "Sending of Handover access is optional",
4951   "Sending of Handover access is mandatory"
4952 };
4953 /*
4954  *  The EPC mode field (octet 2) indicates whether the assigned channel(s) 
4955  *  shall be in enhanced power control (EPC) mode. It is only valid for channels
4956  *  on which EPC may be used. It is coded as follows:
4957 */
4958 static const true_false_string gsm_a_rr_pow_cmd_epc_value  = {
4959   "Channel(s) in EPC mode",
4960   "Channel(s) not in EPC mode"
4961 };
4962 /*
4963  * FPC_EPC (octet 2)
4964  * The FPC_EPC field (octet 2) has different interpretation depending
4965  *              on the channel mode     of the assigned channel (s) and the value 
4966  *              of the EPC mode field.
4967  * If the channel mode is such that fast power control (FPC) may be 
4968  *              used, the FPC_EPC field indicates whether Fast Measurement
4969  *              Reporting and Power Control mechanism is used.
4970  *              It is coded as follows:
4971  * Value 0      FPC not in use
4972  *       1      FPC in use
4973  * If the channel mode is such that EPC may be used and the EPC mode 
4974  *              field indicates that the channel is in EPC mode, the FPC_EPC
4975  *              field indicates whether EPC shall be used for uplink power control. 
4976  * It is coded as follows:
4977  * Value 0      EPC not in use for uplink power control
4978  *               1      EPC in use for uplink power control
4979  *
4980  */
4981 static const true_false_string gsm_a_rr_pow_cmd_fpcepc_value  = {
4982   "FPC in use/EPC in use for uplink power control",
4983   "FPC not in use/C not in use for uplink power control"
4984 };
4985
4986 /*
4987  * Power level (octet 2)The power level field is coded as the binaryRepresentation 
4988  * of the "power control level", see 3GPP TS 3GPP TS 45.005. This value shall be used 
4989  * by the mobile station According to 3GPP TS 45.008.Range: 0 to 31.
4990  */
4991
4992 static guint8
4993 de_rr_pow_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4994 {
4995     proto_tree  *subtree;
4996     proto_item  *item;
4997     guint32     curr_offset;
4998
4999     len = len;
5000     curr_offset = offset;
5001
5002         item =
5003         proto_tree_add_text(tree,
5004             tvb, curr_offset, 1,
5005             gsm_dtap_elem_strings[DE_RR_POW_CMD].strptr);
5006
5007     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_RR_POW_CMD]);
5008
5009     proto_tree_add_item(subtree, hf_gsm_a_b8spare, tvb, curr_offset, 1, FALSE);
5010         /*EPC mode */   
5011     proto_tree_add_item(subtree, hf_gsm_a_rr_pow_cmd_epc, tvb, curr_offset, 1, FALSE);
5012         /*FPC_EPC*/
5013     proto_tree_add_item(subtree, hf_gsm_a_rr_pow_cmd_fpcepc, tvb, curr_offset, 1, FALSE);
5014         /*POWER LEVEL*/
5015     proto_tree_add_item(subtree, hf_gsm_a_rr_pow_cmd_powlev, tvb, curr_offset, 1, FALSE);
5016         
5017         curr_offset = curr_offset + 1;
5018
5019     return(curr_offset - offset);
5020 }
5021
5022 /*
5023  * [3] 10.5.2.28a Power Command and access type
5024  */
5025 static guint8
5026 de_rr_pow_cmd_and_acc_type(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5027 {
5028     proto_tree  *subtree;
5029     proto_item  *item;
5030     guint32     curr_offset;
5031
5032     len = len;
5033     curr_offset = offset;
5034
5035         item =
5036         proto_tree_add_text(tree,
5037             tvb, curr_offset, 1,
5038             gsm_dtap_elem_strings[DE_RR_POW_CMD_AND_ACC_TYPE].strptr);
5039
5040     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_RR_POW_CMD_AND_ACC_TYPE]);
5041
5042         /*ATC */        
5043     proto_tree_add_item(subtree, hf_gsm_a_rr_pow_cmd_atc, tvb, curr_offset, 1, FALSE);
5044         /*EPC mode */   
5045     proto_tree_add_item(subtree, hf_gsm_a_rr_pow_cmd_epc, tvb, curr_offset, 1, FALSE);
5046         /*FPC_EPC*/
5047     proto_tree_add_item(subtree, hf_gsm_a_rr_pow_cmd_fpcepc, tvb, curr_offset, 1, FALSE);
5048         /*POWER LEVEL*/
5049     proto_tree_add_item(subtree, hf_gsm_a_rr_pow_cmd_powlev, tvb, curr_offset, 1, FALSE);
5050         
5051         curr_offset = curr_offset + 1;
5052
5053     return(curr_offset - offset);
5054 }
5055 /*
5056  * [3] 10.5.2.29 RACH Control Parameters
5057  * [3] 10.5.2.30 Request Reference
5058  */
5059
5060 /*
5061  * [3] 10.5.2.31
5062  */
5063 guint8
5064 de_rr_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5065 {
5066     guint32     curr_offset;
5067
5068     len = len;
5069     curr_offset = offset;
5070
5071         proto_tree_add_item(tree, hf_gsm_a_rr_RR_cause, tvb, curr_offset, 1, FALSE);
5072
5073     curr_offset++;
5074
5075     return(curr_offset - offset);
5076 }
5077 /*
5078  * [3] 10.5.2.32 SI 1 Rest Octets
5079  * [3] 10.5.2.33 SI 2bis Rest Octets 
5080  * [3] 10.5.2.33a SI 2ter Rest Octets
5081  * [3] 10.5.2.33b SI 2quater Rest Octets
5082  * [3] 10.5.2.34 SI 3 Rest Octets
5083  * [3] 10.5.2.35 SI 4 Rest Octets
5084  * [3] 10.5.2.35a SI 6 Rest Octets
5085  * [3] 10.5.2.36 SI 7 Rest Octets
5086  * [3] 10.5.2.37 SI 8 Rest Octets
5087  * [3] 10.5.2.37a SI 9 Rest Octets
5088  * [3] 10.5.2.37b SI 13 Rest Octets
5089  * [3] 10.5.2.37c (void)
5090  * [3] 10.5.2.37d (void)
5091  * [3] 10.5.2.37e SI 16 Rest Octets
5092  * [3] 10.5.2.37f SI 17 Rest Octets
5093  * [3] 10.5.2.37g SI 19 Rest Octets
5094  * [3] 10.5.2.37h SI 18 Rest Octets
5095  * [3] 10.5.2.37i SI 20 Rest Octets
5096  */
5097 /*
5098  * [3] 10.5.2.38 Starting Time
5099  */
5100 static guint8
5101 de_rr_starting_time(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5102 {
5103     guint32     curr_offset;
5104
5105     len = len;
5106     curr_offset = offset;
5107
5108         proto_tree_add_text(tree,tvb, curr_offset, 3 ,"Data(Not decoded)");
5109
5110         curr_offset = curr_offset + 2;
5111     return(curr_offset - offset);
5112 }
5113 /*
5114  * [3] 10.5.2.39 Synchronization Indication
5115  */
5116 /*
5117  * ROT: Report Observed Time Difference (Octet1 bit 3) */
5118
5119 static const true_false_string sm_a_rr_sync_ind_rot_value  = {
5120   "Mobile Time Difference IE shall be included in the HANDOVER COMPLETE message",
5121   "Mobile Time Difference IE shall not be included in the HANDOVER COMPLETE message"
5122 };
5123
5124 /* SI: Synchronization indication (octet 1)Bit2 1 */
5125
5126 static const value_string gsm_a_rr_sync_ind_si_vals[] = {
5127         { 0,            "Non-synchronized"},
5128         { 1,            "Synchronized"},
5129         { 2,            "Pre-synchronised"},
5130         { 3,            "Pseudo-synchronised"},
5131         { 0,    NULL }
5132 };
5133 /* NCI: Normal cell indication (octet 1, bit 4) */
5134
5135 static const true_false_string gsm_a_rr_sync_ind_nci_value  = {
5136   "Out of range timing advance shall trigger a handover failure procedure",
5137   "Out of range timing advance is ignored"
5138 };
5139
5140
5141 static guint8
5142 de_rr_sync_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5143 {
5144     guint32     curr_offset;
5145
5146     len = len;
5147     curr_offset = offset;
5148
5149         /*NCI */        
5150     proto_tree_add_item(tree, hf_gsm_a_rr_sync_ind_nci, tvb, curr_offset, 1, FALSE);
5151         /*ROT */        
5152     proto_tree_add_item(tree, hf_gsm_a_rr_sync_ind_rot, tvb, curr_offset, 1, FALSE);
5153         /*SI*/
5154     proto_tree_add_item(tree, hf_gsm_a_rr_sync_ind_si, tvb, curr_offset, 1, FALSE);
5155         
5156         curr_offset = curr_offset + 1;
5157
5158     return(curr_offset - offset);
5159 }
5160
5161 /*
5162  * [3] 10.5.2.40 Timing Advance
5163  */
5164 static guint8
5165 de_rr_timing_adv(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5166 {
5167     guint32     curr_offset;
5168
5169     len = len;
5170     curr_offset = offset;
5171
5172         proto_tree_add_item(tree, hf_gsm_a_rr_timing_adv, tvb, curr_offset, 1, FALSE);
5173         curr_offset = curr_offset + 1;
5174
5175     return(curr_offset - offset);
5176 }
5177
5178 /*
5179  * [3] 10.5.2.41 Time Difference
5180  */
5181 static guint8
5182 de_rr_time_diff(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5183 {
5184     guint32     curr_offset;
5185
5186     len = len;
5187     curr_offset = offset;
5188
5189         proto_tree_add_item(tree, hf_gsm_a_rr_time_diff, tvb, curr_offset, 1, FALSE);
5190         curr_offset = curr_offset + 1;
5191
5192     return(curr_offset - offset);
5193 }
5194 /*
5195  * [3] 10.5.2.41a TLLI
5196  * The TLLI is encoded as a binary number with a length of 4 octets. TLLI is defined in 3GPP TS 23.003
5197  */
5198 guint8
5199 de_rr_tlli(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5200 {
5201     guint32     curr_offset;
5202
5203     len = len;
5204     curr_offset = offset;
5205
5206         proto_tree_add_item(tree, hf_gsm_a_rr_tlli, tvb, curr_offset, 4, FALSE);
5207         curr_offset = curr_offset + 4;
5208
5209     return(curr_offset - offset);
5210 }
5211 /*
5212  * [3] 10.5.2.42 TMSI/P-TMSI
5213  */
5214 /*
5215  * [3] 10.5.2.42a VGCS target mode Indication
5216  */
5217 /*
5218 Target mode (octet 3)
5219 Bit     8 7
5220         0 0     dedicated mode
5221         0 1     group transmit mode
5222         Other values are reserved for future use.
5223 */
5224 static const value_string gsm_a_rr_target_mode_vals[] = {
5225         { 0,            "Dedicated mode"},
5226         { 1,            "Group transmit mode"},
5227         { 0,    NULL }
5228 };
5229 static guint8
5230 de_rr_vgcs_tar_mode_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5231 {
5232     guint32     curr_offset;
5233
5234     len = len;
5235     curr_offset = offset;
5236
5237         proto_tree_add_item(tree, hf_gsm_a_rr_target_mode, tvb, curr_offset, 1, FALSE);
5238         proto_tree_add_item(tree, hf_gsm_a_rr_group_cipher_key_number, tvb, curr_offset, 1, FALSE);
5239         curr_offset = curr_offset + 1;
5240
5241     return(curr_offset - offset);
5242 }
5243
5244 /* 
5245  * [3] 10.5.2.42b       VGCS Ciphering Parameters       
5246  */
5247 static guint8
5248 de_rr_vgcs_cip_par(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5249 {
5250     guint32     curr_offset;
5251
5252     len = len;
5253     curr_offset = offset;
5254
5255         proto_tree_add_text(tree,tvb, curr_offset, len ,"Data(Not decoded)");
5256
5257         curr_offset = curr_offset + 2;
5258     return(curr_offset - offset);
5259 }
5260 /*
5261  * [3] 10.5.2.43 Wait Indication
5262  * [3] 10.5.2.44 SI10 rest octets $(ASCI)$
5263  * [3] 10.5.2.45 EXTENDED MEASUREMENT RESULTS
5264  * [3] 10.5.2.46 Extended Measurement Frequency List
5265  */
5266 /*
5267  * [3] 10.5.2.47 Suspension Cause
5268  */
5269 /*Suspension cause value (octet 2)*/
5270 static const value_string gsm_a_rr_suspension_cause_vals[] = {
5271         { 0,            "Emergency call, mobile originating call or call re-establishment"},
5272         { 1,            "Location Area Update"},
5273         { 2,            "MO Short message service"},
5274         { 3,            "Other procedure which can be completed with an SDCCH"},
5275         { 4,            "MO Voice broadcast or group call"},
5276         { 5,            "Mobile terminating CS connection"},
5277         { 6,            "DTM not supported in the cell"},
5278         { 0,    NULL }
5279 };
5280 guint8
5281 de_rr_sus_cau(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5282 {
5283     guint32     curr_offset;
5284
5285     len = len;
5286     curr_offset = offset;
5287
5288         proto_tree_add_item(tree, hf_gsm_a_rr_suspension_cause, tvb, curr_offset, 1, FALSE);
5289
5290         curr_offset = curr_offset + 1;
5291     return(curr_offset - offset);
5292 }
5293 /*
5294  * [3] 10.5.2.48 APDU ID 
5295  * [3] 10.5.2.49 APDU Flags
5296  * [3] 10.5.2.50 APDU Data
5297  * [3] 10.5.2.51 Handover To UTRAN Command
5298  * [3] 10.5.2.52 Handover To cdma2000 Command 
5299  * [3] 10.5.2.53 (void)
5300  * [3] 10.5.2.54 (void)
5301  * [3] 10.5.2.55 (void)
5302  * [3] 10.5.2.56 3G Target Cell
5303 */
5304 /* 
5305  * [3] 10.5.2.59        Dedicated Service Information 
5306  */
5307 /*
5308 Last Segment (octet 2)
5309 bit 1
5310 0       mobile station shall not perform Service Information Sending procedure on new cell.
5311 1       mobile station shall perform Service Information Sending procedure on new cell.
5312 */
5313 static const true_false_string gsm_a_rr_last_segment_value  = {
5314   "Mobile station shall perform Service Information Sending procedure on new cell.",
5315   "mobile station shall not perform Service Information Sending procedure on new cell."
5316 };
5317 static guint8
5318 de_rr_ded_serv_inf(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5319 {
5320     guint32     curr_offset;
5321
5322     len = len;
5323     curr_offset = offset;
5324
5325         proto_tree_add_item(tree, hf_gsm_a_rr_last_segment, tvb, curr_offset, 1, FALSE);
5326
5327         curr_offset = curr_offset + 3;
5328     return(curr_offset - offset);
5329 }
5330
5331
5332
5333 /*
5334  * [3] 10.5.3.1
5335  */
5336 static guint8
5337 de_auth_param_rand(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5338 {
5339     guint32     curr_offset;
5340
5341     len = len;
5342     curr_offset = offset;
5343
5344 /*
5345  * 16 octets == 128 bits
5346  */
5347 #define AUTH_PARAM_RAND_LEN     16
5348
5349     proto_tree_add_text(tree,
5350         tvb, curr_offset, AUTH_PARAM_RAND_LEN,
5351                         "RAND value: %s",
5352                         tvb_bytes_to_str(tvb, curr_offset, AUTH_PARAM_RAND_LEN));
5353
5354     curr_offset += AUTH_PARAM_RAND_LEN;
5355
5356     /* no length check possible */
5357
5358     return(curr_offset - offset);
5359 }
5360
5361 /*
5362  * [3] 10.5.3.1.1
5363  */
5364 static guint8
5365 de_auth_param_autn(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5366 {
5367     guint32     curr_offset;
5368
5369     curr_offset = offset;
5370
5371     proto_tree_add_text(tree,
5372         tvb, curr_offset, len,
5373         "AUTN value: %s",
5374         tvb_bytes_to_str(tvb, curr_offset, len));
5375
5376     curr_offset += len;
5377
5378     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5379
5380     return(curr_offset - offset);
5381 }
5382
5383 /*
5384  * [3] 10.5.3.2
5385  */
5386 static guint8
5387 de_auth_resp_param(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5388 {
5389     guint32     curr_offset;
5390
5391     len = len;
5392     curr_offset = offset;
5393
5394 /*
5395  * 4 octets == 32 bits
5396  */
5397 #define AUTH_PARAM_SRES_LEN     4
5398
5399     proto_tree_add_text(tree,
5400         tvb, curr_offset, AUTH_PARAM_SRES_LEN,
5401                         "SRES value: %s",
5402                         tvb_bytes_to_str(tvb, curr_offset, AUTH_PARAM_SRES_LEN));
5403
5404     curr_offset += AUTH_PARAM_SRES_LEN;
5405
5406     /* no length check possible */
5407
5408     return(curr_offset - offset);
5409 }
5410
5411 /*
5412  * [3] 10.5.3.2.1
5413  */
5414 static guint8
5415 de_auth_resp_param_ext(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5416 {
5417     guint32     curr_offset;
5418
5419     curr_offset = offset;
5420
5421     proto_tree_add_text(tree,
5422         tvb, curr_offset, len,
5423          "XRES value: %s",
5424          tvb_bytes_to_str(tvb, curr_offset, len));
5425
5426     curr_offset += len;
5427
5428     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5429
5430     return(curr_offset - offset);
5431 }
5432
5433 /*
5434  * [3] 10.5.3.2.2
5435  */
5436 static guint8
5437 de_auth_fail_param(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5438 {
5439     guint32     curr_offset;
5440
5441     curr_offset = offset;
5442
5443     proto_tree_add_text(tree,
5444         tvb, curr_offset, len,
5445         "AUTS value: %s",
5446         tvb_bytes_to_str(tvb, curr_offset, len));
5447
5448     curr_offset += len;
5449
5450     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5451
5452     return(curr_offset - offset);
5453 }
5454
5455 /*
5456  * [3] 10.5.3.5a
5457  */
5458 static guint8
5459 de_network_name(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5460 {
5461     guint8      oct;
5462     guint32     curr_offset;
5463     const gchar *str;
5464
5465     curr_offset = offset;
5466
5467     oct = tvb_get_guint8(tvb, curr_offset);
5468
5469     proto_tree_add_item(tree, hf_gsm_a_extension, tvb, curr_offset, 1, FALSE);
5470
5471     switch ((oct & 0x70) >> 4)
5472     {
5473     case 0x00: str = "Cell Broadcast data coding scheme, GSM default alphabet, language unspecified, defined in 3GPP TS 03.38"; break;
5474     case 0x01: str = "UCS2 (16 bit)"; break;
5475     default:
5476         str = "Reserved";
5477         break;
5478     }
5479
5480     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
5481     proto_tree_add_text(tree,
5482         tvb, curr_offset, 1,
5483         "%s :  Coding Scheme: %s",
5484         a_bigbuf,
5485         str);
5486
5487     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
5488     proto_tree_add_text(tree,
5489         tvb, curr_offset, 1,
5490         "%s :  Add CI: The MS should %s",
5491         a_bigbuf,
5492         (oct & 0x08) ?
5493             "add the letters for the Country's Initials and a separator (e.g. a space) to the text string" :
5494             "The MS should not add the letters for the Country's Initials to the text string");
5495
5496     switch (oct & 0x07)
5497     {
5498     case 1: str = "bit 8 is spare and set to '0' in octet n"; break;
5499     case 2: str = "bits 7 and 8 are spare and set to '0' in octet n"; break;
5500     case 3: str = "bits 6 to 8(inclusive) are spare and set to '0' in octet n"; break;
5501     case 4: str = "bits 5 to 8(inclusive) are spare and set to '0' in octet n"; break;
5502     case 5: str = "bits 4 to 8(inclusive) are spare and set to '0' in octet n"; break;
5503     case 6: str = "bits 3 to 8(inclusive) are spare and set to '0' in octet n"; break;
5504     case 7: str = "bits 2 to 8(inclusive) are spare and set to '0' in octet n"; break;
5505     default:
5506         str = "this field carries no information about the number of spare bits in octet n";
5507         break;
5508     }
5509
5510     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
5511     proto_tree_add_text(tree,
5512         tvb, curr_offset, 1,
5513         "%s :  Number of spare bits in last octet: %s",
5514         a_bigbuf,
5515         str);
5516
5517     curr_offset++;
5518
5519     NO_MORE_DATA_CHECK(len);
5520
5521     proto_tree_add_text(tree,
5522         tvb, curr_offset, len - 1,
5523         "Text string encoded according to Coding Scheme");
5524
5525     curr_offset += len - 1;
5526
5527     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5528
5529     return(curr_offset - offset);
5530 }
5531
5532 /* 3GPP TS 24.008
5533  * [3] 10.5.3.6 Reject cause
5534  */
5535 guint8
5536 de_rej_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5537 {
5538     guint8      oct;
5539     guint32     curr_offset;
5540     const gchar *str;
5541
5542     len = len;
5543     curr_offset = offset;
5544
5545     oct = tvb_get_guint8(tvb, curr_offset);
5546
5547     switch (oct)
5548     {
5549     case 0x02: str = "IMSI unknown in HLR"; break;
5550     case 0x03: str = "Illegal MS"; break;
5551     case 0x04: str = "IMSI unknown in VLR"; break;
5552     case 0x05: str = "IMEI not accepted"; break;
5553     case 0x06: str = "Illegal ME"; break;
5554     case 0x0b: str = "PLMN not allowed"; break;
5555     case 0x0c: str = "Location Area not allowed"; break;
5556     case 0x0d: str = "Roaming not allowed in this location area"; break;
5557     case 0x0f: str = "No Suitable Cells In Location Area"; break;
5558     case 0x11: str = "Network failure"; break;
5559     case 0x14: str = "MAC failure"; break;
5560     case 0x15: str = "Synch failure"; break;
5561     case 0x16: str = "Congestion"; break;
5562     case 0x17: str = "GSM authentication unacceptable"; break;
5563     case 0x20: str = "Service option not supported"; break;
5564     case 0x21: str = "Requested service option not subscribed"; break;
5565     case 0x22: str = "Service option temporarily out of order"; break;
5566     case 0x26: str = "Call cannot be identified"; break;
5567     case 0x5f: str = "Semantically incorrect message"; break;
5568     case 0x60: str = "Invalid mandatory information"; break;
5569     case 0x61: str = "Message type non-existent or not implemented"; break;
5570     case 0x62: str = "Message type not compatible with the protocol state"; break;
5571     case 0x63: str = "Information element non-existent or not implemented"; break;
5572     case 0x64: str = "Conditional IE error"; break;
5573     case 0x65: str = "Message not compatible with the protocol state"; break;
5574     case 0x6f: str = "Protocol error, unspecified"; break;
5575     default:
5576         switch (is_uplink)
5577         {
5578         case IS_UPLINK_FALSE:
5579             str = "Service option temporarily out of order";
5580             break;
5581         default:
5582             str = "Protocol error, unspecified";
5583             break;
5584         }
5585         break;
5586     }
5587
5588     proto_tree_add_text(tree,
5589         tvb, curr_offset, 1,
5590         "Reject Cause value: 0x%02x (%u) %s",
5591         oct,
5592         oct,
5593         str);
5594
5595     curr_offset++;
5596
5597     /* no length check possible */
5598
5599     return(curr_offset - offset);
5600 }
5601
5602 /*
5603  * [3] 10.5.3.8
5604  */
5605 static guint8
5606 de_time_zone(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5607 {
5608     guint8      oct;
5609     guint32     curr_offset;
5610     char sign;
5611
5612     len = len;
5613     curr_offset = offset;
5614
5615         /* 3GPP TS 23.040 version 6.6.0 Release 6 
5616          * 9.2.3.11 TP-Service-Centre-Time-Stamp (TP-SCTS)
5617          * :
5618          * The Time Zone indicates the difference, expressed in quarters of an hour, 
5619          * between the local time and GMT. In the first of the two semi-octets, 
5620          * the first bit (bit 3 of the seventh octet of the TP-Service-Centre-Time-Stamp field)
5621          * represents the algebraic sign of this difference (0: positive, 1: negative).
5622          */
5623
5624     oct = tvb_get_guint8(tvb, curr_offset);
5625     sign = (oct & 0x08)?'-':'+';
5626     oct = (oct >> 4) + (oct & 0x07) * 10;
5627
5628     proto_tree_add_text(tree,
5629         tvb, offset, 1,
5630         "Timezone: GMT %c %d hours %d minutes",
5631         sign, oct / 4, oct % 4 * 15);
5632     curr_offset++;
5633
5634     /* no length check possible */
5635
5636     return(curr_offset - offset);
5637 }
5638
5639 /*
5640  * [3] 10.5.3.9
5641  */
5642 static guint8
5643 de_time_zone_time(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5644 {
5645     guint8      oct, oct2, oct3;
5646     guint32     curr_offset;
5647     char sign;
5648
5649     len = len;
5650     curr_offset = offset;
5651
5652     oct = tvb_get_guint8(tvb, curr_offset);
5653     oct2 = tvb_get_guint8(tvb, curr_offset+1);
5654     oct3 = tvb_get_guint8(tvb, curr_offset+2);
5655
5656     proto_tree_add_text(tree,
5657         tvb, curr_offset, 3,
5658         "Year %u%u, Month %u%u, Day %u%u",
5659         oct & 0x0f,
5660         (oct & 0xf0) >> 4,
5661         oct2 & 0x0f,
5662         (oct2 & 0xf0) >> 4,
5663         oct3 & 0x0f,
5664         (oct3 & 0xf0) >> 4);
5665
5666     curr_offset += 3;
5667
5668     oct = tvb_get_guint8(tvb, curr_offset);
5669     oct2 = tvb_get_guint8(tvb, curr_offset+1);
5670     oct3 = tvb_get_guint8(tvb, curr_offset+2);
5671
5672     proto_tree_add_text(tree,
5673         tvb, curr_offset, 3,
5674         "Hour %u%u, Minutes %u%u, Seconds %u%u",
5675         oct & 0x0f,
5676         (oct & 0xf0) >> 4,
5677         oct2 & 0x0f,
5678         (oct2 & 0xf0) >> 4,
5679         oct3 & 0x0f,
5680         (oct3 & 0xf0) >> 4);
5681
5682     curr_offset += 3;
5683
5684         /* 3GPP TS 23.040 version 6.6.0 Release 6 
5685          * 9.2.3.11 TP-Service-Centre-Time-Stamp (TP-SCTS)
5686          * :
5687          * The Time Zone indicates the difference, expressed in quarters of an hour, 
5688          * between the local time and GMT. In the first of the two semi-octets, 
5689          * the first bit (bit 3 of the seventh octet of the TP-Service-Centre-Time-Stamp field)
5690          * represents the algebraic sign of this difference (0: positive, 1: negative).
5691          */
5692
5693     oct = tvb_get_guint8(tvb, curr_offset);
5694     sign = (oct & 0x08)?'-':'+';
5695     oct = (oct >> 4) + (oct & 0x07) * 10;
5696
5697     proto_tree_add_text(tree,
5698         tvb, offset, 1,
5699         "Timezone: GMT %c %d hours %d minutes",
5700         sign, oct / 4, oct % 4 * 15);
5701
5702     curr_offset++;
5703
5704     /* no length check possible */
5705
5706     return(curr_offset - offset);
5707 }
5708
5709 /*
5710  * [3] 10.5.3.11 3GPP TS 24.008 version 6.8.0 Release 6
5711  */
5712 static guint8
5713 de_lsa_id(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5714 {
5715     guint32     curr_offset;
5716
5717     curr_offset = offset;
5718
5719         if (len == 0){
5720                 proto_tree_add_text(tree,tvb, curr_offset, len,"LSA ID not included");
5721         }else{
5722                 proto_tree_add_item(tree, hf_gsm_a_lsa_id, tvb, curr_offset, 3, FALSE);
5723         }
5724
5725     curr_offset += len;
5726
5727     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5728
5729     return(curr_offset - offset);
5730 }
5731
5732 /*
5733  * [3] 10.5.3.12
5734  */
5735 static guint8
5736 de_day_saving_time(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5737 {
5738     guint8      oct;
5739     guint32     curr_offset;
5740     const gchar *str;
5741
5742     curr_offset = offset;
5743
5744     oct = tvb_get_guint8(tvb, curr_offset);
5745
5746     other_decode_bitfield_value(a_bigbuf, oct, 0xfc, 8);
5747     proto_tree_add_text(tree,
5748         tvb, curr_offset, 1,
5749         "%s :  Spare",
5750         a_bigbuf);
5751
5752     switch (oct & 0x03)
5753     {
5754     case 0: str = "No adjustment for Daylight Saving Time"; break;
5755     case 1: str = "+1 hour adjustment for Daylight Saving Time"; break;
5756     case 2: str = "+2 hours adjustment for Daylight Saving Time"; break;
5757     default:
5758         str = "Reserved";
5759         break;
5760     }
5761
5762     other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
5763     proto_tree_add_text(tree,
5764         tvb, curr_offset, 1,
5765         "%s :  %s",
5766         a_bigbuf,
5767         str);
5768
5769     curr_offset++;
5770
5771     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5772
5773     return(curr_offset - offset);
5774 }
5775
5776 /*
5777  * [3] 10.5.4.4
5778  */
5779 static guint8
5780 de_aux_states(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5781 {
5782     guint8      oct;
5783     guint32     curr_offset;
5784     const gchar *str;
5785
5786     curr_offset = offset;
5787
5788     oct = tvb_get_guint8(tvb, curr_offset);
5789
5790     proto_tree_add_item(tree, hf_gsm_a_extension, tvb, curr_offset, 1, FALSE);
5791
5792     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
5793     proto_tree_add_text(tree,
5794         tvb, curr_offset, 1,
5795         "%s :  Spare",
5796         a_bigbuf);
5797
5798     switch ((oct & 0x0c) >> 2)
5799     {
5800     case 0: str = "Idle"; break;
5801     case 1: str = "Hold request"; break;
5802     case 2: str = "Call held"; break;
5803     default:
5804         str = "Retrieve request";
5805         break;
5806     }
5807
5808     other_decode_bitfield_value(a_bigbuf, oct, 0x0c, 8);
5809     proto_tree_add_text(tree,
5810         tvb, curr_offset, 1,
5811         "%s :  Hold auxiliary state: %s",
5812         a_bigbuf,
5813         str);
5814
5815     switch (oct & 0x03)
5816     {
5817     case 0: str = "Idle"; break;
5818     case 1: str = "MPTY request"; break;
5819     case 2: str = "Call in MPTY"; break;
5820     default:
5821         str = "Split request";
5822         break;
5823     }
5824
5825     other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
5826     proto_tree_add_text(tree,
5827         tvb, curr_offset, 1,
5828         "%s :  Multi party auxiliary state: %s",
5829         a_bigbuf,
5830         str);
5831
5832     curr_offset++;
5833
5834     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5835
5836     return(curr_offset - offset);
5837 }
5838
5839 /*
5840  * [3] 10.5.4.5
5841  */
5842 static guint8
5843 de_bearer_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
5844 {
5845     guint8      oct;
5846     guint8      itc;
5847     gboolean    extended;
5848     guint32     curr_offset;
5849     guint32     saved_offset;
5850     proto_tree  *subtree;
5851     proto_item  *item;
5852     const gchar *str;
5853
5854 #define DE_BC_ITC_SPEECH        0x00
5855 #define DE_BC_ITC_UDI           0x01
5856 #define DE_BC_ITC_EX_PLMN       0x02
5857 #define DE_BC_ITC_FASC_G3       0x03
5858 #define DE_BC_ITC_OTHER_ITC     0x05
5859 #define DE_BC_ITC_RSVD_NET      0x07
5860
5861     curr_offset = offset;
5862
5863     oct = tvb_get_guint8(tvb, curr_offset);
5864
5865     /* octet 3 */
5866
5867     /*
5868      * warning, bearer cap uses extended values that
5869      * are reversed from other parameters!
5870      */
5871     extended = (oct & 0x80) ? FALSE : TRUE;
5872     itc = oct & 0x07;
5873
5874     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
5875     proto_tree_add_text(tree,
5876         tvb, curr_offset, 1,
5877         "%s :  Extension: %s",
5878         a_bigbuf,
5879         extended ? "extended" : "not extended");
5880
5881     switch (is_uplink)
5882     {
5883     case IS_UPLINK_FALSE:
5884         str = "Spare";
5885         break;
5886
5887     case IS_UPLINK_TRUE:
5888         /*
5889          * depends on Information transfer capability
5890          */
5891         switch (itc)
5892         {
5893         case DE_BC_ITC_SPEECH:
5894             if (extended)
5895             {
5896                 switch ((oct & 0x60) >> 5)
5897                 {
5898                 case 1: str = "MS supports at least full rate speech version 1 but does not support half rate speech version 1"; break;
5899                 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;
5900                 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;
5901                 default:
5902                     str = "Reserved";
5903                     break;
5904                 }
5905                 break;
5906             }
5907             else
5908             {
5909                 switch ((oct & 0x60) >> 5)
5910                 {
5911                 case 1: str = "Full rate support only MS/fullrate speech version 1 supported"; break;
5912                 case 2: str = "Dual rate support MS/half rate speech version 1 preferred, full rate speech version 1 also supported"; break;
5913                 case 3: str = "Dual rate support MS/full rate speech version 1 preferred, half rate speech version 1 also supported"; break;
5914                 default:
5915                     str = "Reserved";
5916                     break;
5917                 }
5918                 break;
5919             }
5920             break;
5921
5922         default:
5923             switch ((oct & 0x60) >> 5)
5924             {
5925             case 1: str = "Full rate support only MS"; break;
5926             case 2: str = "Dual rate support MS/half rate preferred"; break;
5927             case 3: str = "Dual rate support MS/full rate preferred"; break;
5928             default:
5929                 str = "Reserved";
5930                 break;
5931             }
5932             break;
5933         }
5934         break;
5935
5936     default:
5937         str = "(dissect problem)";
5938         break;
5939     }
5940
5941     other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
5942     proto_tree_add_text(tree,
5943         tvb, curr_offset, 1,
5944         "%s :  Radio channel requirement: %s",
5945         a_bigbuf,
5946         str);
5947
5948     other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
5949     proto_tree_add_text(tree,
5950         tvb, curr_offset, 1,
5951         "%s :  Coding standard: %s",
5952         a_bigbuf,
5953         (oct & 0x10) ? "reserved" : "GSM standardized coding");
5954
5955     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
5956     proto_tree_add_text(tree,
5957         tvb, curr_offset, 1,
5958         "%s :  Transfer mode: %s",
5959         a_bigbuf,
5960         (oct & 0x08) ? "packet" : "circuit");
5961
5962     switch (itc)
5963     {
5964     case DE_BC_ITC_SPEECH: str = "Speech"; break;
5965     case DE_BC_ITC_UDI: str = "Unrestricted digital information"; break;
5966     case DE_BC_ITC_EX_PLMN: str = "3.1 kHz audio, ex PLMN"; break;
5967     case DE_BC_ITC_FASC_G3: str = "Facsimile group 3"; break;
5968     case DE_BC_ITC_OTHER_ITC: str = "Other ITC (See Octet 5a)"; break;
5969     case DE_BC_ITC_RSVD_NET: str = "Reserved, to be used in the network"; break;
5970     default:
5971         str = "Reserved";
5972         break;
5973     }
5974
5975     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
5976     proto_tree_add_text(tree,
5977         tvb, curr_offset, 1,
5978         "%s :  Information transfer capability: %s",
5979         a_bigbuf,
5980         str);
5981
5982     if (add_string)
5983         g_snprintf(add_string, string_len, " - (%s)", str);
5984
5985     curr_offset++;
5986
5987     NO_MORE_DATA_CHECK(len);
5988
5989     switch (itc)
5990     {
5991     case DE_BC_ITC_SPEECH:
5992         /* octets 3a */
5993
5994         item =
5995             proto_tree_add_text(tree,
5996                 tvb, curr_offset, -1,
5997                 "Octets 3a - Speech Versions");
5998
5999         subtree = proto_item_add_subtree(item, ett_bc_oct_3a);
6000
6001         saved_offset = curr_offset;
6002
6003         do
6004         {
6005             oct = tvb_get_guint8(tvb, curr_offset);
6006
6007             extended = (oct & 0x80) ? FALSE : TRUE;
6008
6009             other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6010             proto_tree_add_text(subtree,
6011                 tvb, curr_offset, 1,
6012                 "%s :  Extension: %s",
6013                 a_bigbuf,
6014                 extended ? "extended" : "not extended");
6015
6016             other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
6017             proto_tree_add_text(subtree,
6018                 tvb, curr_offset, 1,
6019                 "%s :  Coding: octet used for %s",
6020                 a_bigbuf,
6021                 (oct & 0x40) ? "other extension of octet 3" :
6022                     "extension of information transfer capability");
6023
6024             other_decode_bitfield_value(a_bigbuf, oct, 0x30, 8);
6025             proto_tree_add_text(subtree,
6026                 tvb, curr_offset, 1,
6027                 "%s :  Spare",
6028                 a_bigbuf);
6029
6030             switch (oct & 0x0f)
6031             {
6032             case 0: str = "GSM full rate speech version 1"; break;
6033             case 2: str = "GSM full rate speech version 2"; break;
6034             case 4: str = "GSM full rate speech version 3"; break;
6035             case 1: str = "GSM half rate speech version 1"; break;
6036             case 5: str = "GSM half rate speech version 3"; break;
6037             default:
6038                 str = "Speech version TBD";
6039                 break;
6040             }
6041
6042             other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
6043             proto_tree_add_text(subtree,
6044                 tvb, curr_offset, 1,
6045                 "%s :  Speech version indication: %s",
6046                 a_bigbuf,
6047                 str);
6048
6049             curr_offset++;
6050         }
6051         while (extended &&
6052             ((len - (curr_offset - offset)) > 0));
6053
6054         proto_item_set_len(item, curr_offset - saved_offset);
6055         break;
6056
6057     default:
6058         /* octet 4 */
6059
6060         item =
6061             proto_tree_add_text(tree,
6062                 tvb, curr_offset, 1,
6063                 "Octet 4");
6064
6065         subtree = proto_item_add_subtree(item, ett_bc_oct_4);
6066
6067         oct = tvb_get_guint8(tvb, curr_offset);
6068
6069         extended = (oct & 0x80) ? FALSE : TRUE;
6070
6071         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6072         proto_tree_add_text(subtree,
6073             tvb, curr_offset, 1,
6074             "%s :  Extension: %s",
6075             a_bigbuf,
6076             extended ? "extended" : "not extended");
6077
6078         other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
6079         proto_tree_add_text(subtree,
6080             tvb, curr_offset, 1,
6081             "%s :  Compression: data compression %s%s",
6082             a_bigbuf,
6083             (oct & 0x40) ? "" : "not ",
6084             is_uplink ? "allowed" : "possible");
6085
6086         switch ((oct & 0x30) >> 4)
6087         {
6088         case 0x00: str = "Service data unit integrity"; break;
6089         case 0x03: str = "Unstructured"; break;
6090         default:
6091             str = "Reserved";
6092             break;
6093         }
6094
6095         other_decode_bitfield_value(a_bigbuf, oct, 0x30, 8);
6096         proto_tree_add_text(subtree,
6097             tvb, curr_offset, 1,
6098             "%s :  Structure: %s",
6099             a_bigbuf,
6100             str);
6101
6102         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
6103         proto_tree_add_text(subtree,
6104             tvb, curr_offset, 1,
6105             "%s :  Duplex mode: %s",
6106             a_bigbuf,
6107             (oct & 0x08) ? "Full" : "Half");
6108
6109         other_decode_bitfield_value(a_bigbuf, oct, 0x04, 8);
6110         proto_tree_add_text(subtree,
6111             tvb, curr_offset, 1,
6112             "%s :  Configuration: %s",
6113             a_bigbuf,
6114             (oct & 0x04) ? "Reserved" : "Point-to-point");
6115
6116         other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
6117         proto_tree_add_text(subtree,
6118             tvb, curr_offset, 1,
6119             "%s :  NIRR: %s",
6120             a_bigbuf,
6121             (oct & 0x02) ?
6122                 "Data up to and including 4.8 kb/s, full rate, non-transparent, 6 kb/s radio interface rate is requested" :
6123                 "No meaning is associated with this value");
6124
6125         other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
6126         proto_tree_add_text(subtree,
6127             tvb, curr_offset, 1,
6128             "%s :  Establishment: %s",
6129             a_bigbuf,
6130             (oct & 0x01) ? "Reserved" : "Demand");
6131
6132         curr_offset++;
6133
6134         NO_MORE_DATA_CHECK(len);
6135
6136         /* octet 5 */
6137
6138         item =
6139             proto_tree_add_text(tree,
6140                 tvb, curr_offset, 1,
6141                 "Octet 5");
6142
6143         subtree = proto_item_add_subtree(item, ett_bc_oct_5);
6144
6145         oct = tvb_get_guint8(tvb, curr_offset);
6146
6147         extended = (oct & 0x80) ? FALSE : TRUE;
6148
6149         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6150         proto_tree_add_text(subtree,
6151             tvb, curr_offset, 1,
6152             "%s :  Extension: %s",
6153             a_bigbuf,
6154             extended ? "extended" : "not extended");
6155
6156         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
6157         proto_tree_add_text(subtree,
6158             tvb, curr_offset, 1,
6159             "%s :  Access Identity: %s",
6160             a_bigbuf,
6161             (oct & 0x60) ? "Reserved" : "Octet identifier");
6162
6163         switch ((oct & 0x18) >> 3)
6164         {
6165         case 0x00: str = "No rate adaption"; break;
6166         case 0x01: str = "V.110, I.460/X.30 rate adaptation"; break;
6167         case 0x02: str = "ITU-T X.31 flag stuffing"; break;
6168         default:
6169             str = "Other rate adaption (see octet 5a)"; break;
6170             break;
6171         }
6172
6173         other_decode_bitfield_value(a_bigbuf, oct, 0x18, 8);
6174         proto_tree_add_text(subtree,
6175             tvb, curr_offset, 1,
6176             "%s :  Rate Adaption: %s",
6177             a_bigbuf,
6178             str);
6179
6180         switch (oct & 0x07)
6181         {
6182         case 0x01: str = "I.440/450"; break;
6183         case 0x02: str = "Reserved: was allocated in earlier phases of the protocol"; break;
6184         case 0x03: str = "Reserved: was allocated in earlier phases of the protocol"; break;
6185         case 0x04: str = "Reserved: was allocated in earlier phases of the protocol"; break;
6186         case 0x05: str = "Reserved: was allocated in earlier phases of the protocol"; break;
6187         case 0x06: str = "Reserved: was allocated in earlier phases of the protocol"; break;
6188         default:
6189             str = "Reserved"; break;
6190             break;
6191         }
6192
6193         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
6194         proto_tree_add_text(subtree,
6195             tvb, curr_offset, 1,
6196             "%s :  Signalling Access Protocol: %s",
6197             a_bigbuf,
6198             str);
6199
6200         curr_offset++;
6201
6202         NO_MORE_DATA_CHECK(len);
6203
6204         if (!extended) goto bc_octet_6;
6205
6206         /* octet 5a */
6207
6208         item =
6209             proto_tree_add_text(tree,
6210                 tvb, curr_offset, 1,
6211                 "Octet 5a");
6212
6213         subtree = proto_item_add_subtree(item, ett_bc_oct_5a);
6214
6215         oct = tvb_get_guint8(tvb, curr_offset);
6216
6217         extended = (oct & 0x80) ? FALSE : TRUE;
6218
6219         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6220         proto_tree_add_text(subtree,
6221             tvb, curr_offset, 1,
6222             "%s :  Extension: %s",
6223             a_bigbuf,
6224             extended ? "extended" : "not extended");
6225
6226         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
6227         proto_tree_add_text(subtree,
6228             tvb, curr_offset, 1,
6229             "%s :  Other ITC: %s",
6230             a_bigbuf,
6231             (oct & 0x60) ? "Reserved" : "Restricted digital information");
6232
6233         switch ((oct & 0x18) >> 3)
6234         {
6235         case 0x00: str = "V.120"; break;
6236         case 0x01: str = "H.223 & H.245"; break;
6237         case 0x02: str = "PIAFS"; break;
6238         default:
6239             str = "Reserved";
6240             break;
6241         }
6242
6243         other_decode_bitfield_value(a_bigbuf, oct, 0x18, 8);
6244         proto_tree_add_text(subtree,
6245             tvb, curr_offset, 1,
6246             "%s :  Other Rate Adaption: %s",
6247             a_bigbuf,
6248             str);
6249
6250         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
6251         proto_tree_add_text(subtree,
6252             tvb, curr_offset, 1,
6253             "%s :  Spare",
6254             a_bigbuf);
6255
6256         curr_offset++;
6257
6258         NO_MORE_DATA_CHECK(len);
6259
6260         if (!extended) goto bc_octet_6;
6261
6262         /* octet 5b */
6263
6264         item =
6265             proto_tree_add_text(tree,
6266                 tvb, curr_offset, 1,
6267                 "Octet 5b");
6268
6269         subtree = proto_item_add_subtree(item, ett_bc_oct_5b);
6270
6271         oct = tvb_get_guint8(tvb, curr_offset);
6272
6273         extended = (oct & 0x80) ? FALSE : TRUE;
6274
6275         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6276         proto_tree_add_text(subtree,
6277             tvb, curr_offset, 1,
6278             "%s :  Extension: %s",
6279             a_bigbuf,
6280             extended ? "extended" : "not extended");
6281
6282         other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
6283         proto_tree_add_text(subtree,
6284             tvb, curr_offset, 1,
6285             "%s :  Rate Adaption Header: %sincluded",
6286             a_bigbuf,
6287             (oct & 0x40) ? "" : "not ");
6288
6289         other_decode_bitfield_value(a_bigbuf, oct, 0x20, 8);
6290         proto_tree_add_text(subtree,
6291             tvb, curr_offset, 1,
6292             "%s :  Multiple frame establishment support in data link: %s",
6293             a_bigbuf,
6294             (oct & 0x20) ? "Supported" : "Not supported, only UI frames allowed");
6295
6296         other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
6297         proto_tree_add_text(subtree,
6298             tvb, curr_offset, 1,
6299             "%s :  Mode of operation: %s",
6300             a_bigbuf,
6301             (oct & 0x10) ? "Protocol sensitive" : "Bit transparent");
6302
6303         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
6304         proto_tree_add_text(subtree,
6305             tvb, curr_offset, 1,
6306             "%s :  Logical link identifier negotiation: %s",
6307             a_bigbuf,
6308             (oct & 0x08) ? "Full protocol negotiation" : "Default, LLI=256 only");
6309
6310         other_decode_bitfield_value(a_bigbuf, oct, 0x04, 8);
6311         proto_tree_add_text(subtree,
6312             tvb, curr_offset, 1,
6313             "%s :  Assignor/Assignee: Message originator is '%s'",
6314             a_bigbuf,
6315             (oct & 0x04) ? "assignor only" : "default assignee");
6316
6317         other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
6318         proto_tree_add_text(subtree,
6319             tvb, curr_offset, 1,
6320             "%s :  In band/Out of band negotiation: Negotiation is done %s",
6321             a_bigbuf,
6322             (oct & 0x02) ?
6323                 "with USER INFORMATION messages on a temporary signalling connection" :
6324                 "in-band using logical link zero");
6325
6326         other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
6327         proto_tree_add_text(subtree,
6328             tvb, curr_offset, 1,
6329             "%s :  Spare",
6330             a_bigbuf);
6331
6332         curr_offset++;
6333
6334         NO_MORE_DATA_CHECK(len);
6335
6336 bc_octet_6:
6337
6338         /* octet 6 */
6339
6340         item =
6341             proto_tree_add_text(tree,
6342                 tvb, curr_offset, 1,
6343                 "Octet 6");
6344
6345         subtree = proto_item_add_subtree(item, ett_bc_oct_6);
6346
6347         oct = tvb_get_guint8(tvb, curr_offset);
6348
6349         extended = (oct & 0x80) ? FALSE : TRUE;
6350
6351         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6352         proto_tree_add_text(subtree,
6353             tvb, curr_offset, 1,
6354             "%s :  Extension: %s",
6355             a_bigbuf,
6356             extended ? "extended" : "not extended");
6357
6358         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
6359         proto_tree_add_text(subtree,
6360             tvb, curr_offset, 1,
6361             "%s :  Layer 1 Identity: %s",
6362             a_bigbuf,
6363             ((oct & 0x60) == 0x20) ? "Octet identifier" : "Reserved");
6364
6365         other_decode_bitfield_value(a_bigbuf, oct, 0x1e, 8);
6366         proto_tree_add_text(subtree,
6367             tvb, curr_offset, 1,
6368             "%s :  User information layer 1 protocol: %s",
6369             a_bigbuf,
6370             (oct & 0x1e) ? "Reserved" : "Default layer 1 protocol");
6371
6372         other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
6373         proto_tree_add_text(subtree,
6374             tvb, curr_offset, 1,
6375             "%s :  Synchronous/asynchronous: %s",
6376             a_bigbuf,
6377             (oct & 0x01) ? "Asynchronous" : "Synchronous");
6378
6379         curr_offset++;
6380
6381         NO_MORE_DATA_CHECK(len);
6382
6383         if (!extended) goto bc_octet_7;
6384
6385         /* octet 6a */
6386
6387         item =
6388             proto_tree_add_text(tree,
6389                 tvb, curr_offset, 1,
6390                 "Octet 6a");
6391
6392         subtree = proto_item_add_subtree(item, ett_bc_oct_6a);
6393
6394         oct = tvb_get_guint8(tvb, curr_offset);
6395
6396         extended = (oct & 0x80) ? FALSE : TRUE;
6397
6398         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6399         proto_tree_add_text(subtree,
6400             tvb, curr_offset, 1,
6401             "%s :  Extension: %s",
6402             a_bigbuf,
6403             extended ? "extended" : "not extended");
6404
6405         other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
6406         proto_tree_add_text(subtree,
6407             tvb, curr_offset, 1,
6408             "%s :  Number of Stop Bits: %s",
6409             a_bigbuf,
6410             (oct & 0x40) ? "2" : "1");
6411
6412         other_decode_bitfield_value(a_bigbuf, oct, 0x20, 8);
6413         proto_tree_add_text(subtree,
6414             tvb, curr_offset, 1,
6415             "%s :  Negotiation: %s",
6416             a_bigbuf,
6417             (oct & 0x20) ? "Reserved" : "In-band negotiation not possible");
6418
6419         other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
6420         proto_tree_add_text(subtree,
6421             tvb, curr_offset, 1,
6422             "%s :  Number of data bits excluding parity bit if present: %s",
6423             a_bigbuf,
6424             (oct & 0x10) ? "8" : "7");
6425
6426         switch (oct & 0x0f)
6427         {
6428         case 0x01: str = "0.3 kbit/s Recommendation X.1 and V.110"; break;
6429         case 0x02: str = "1.2 kbit/s Recommendation X.1 and V.110"; break;
6430         case 0x03: str = "2.4 kbit/s Recommendation X.1 and V.110"; break;
6431         case 0x04: str = "4.8 kbit/s Recommendation X.1 and V.110"; break;
6432         case 0x05: str = "9.6 kbit/s Recommendation X.1 and V.110"; break;
6433         case 0x06: str = "12.0 kbit/s transparent (non compliance with X.1 and V.110)"; break;
6434         case 0x07: str = "Reserved: was allocated in earlier phases of the protocol"; break;
6435         default:
6436             str = "Reserved";
6437             break;
6438         }
6439
6440         other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
6441         proto_tree_add_text(subtree,
6442             tvb, curr_offset, 1,
6443             "%s :  User rate: %s",
6444             a_bigbuf,
6445             str);
6446
6447         curr_offset++;
6448
6449         NO_MORE_DATA_CHECK(len);
6450
6451         if (!extended) goto bc_octet_7;
6452
6453         /* octet 6b */
6454
6455         item =
6456             proto_tree_add_text(tree,
6457                 tvb, curr_offset, 1,
6458                 "Octet 6b");
6459
6460         subtree = proto_item_add_subtree(item, ett_bc_oct_6b);
6461
6462         oct = tvb_get_guint8(tvb, curr_offset);
6463
6464         extended = (oct & 0x80) ? FALSE : TRUE;
6465
6466         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6467         proto_tree_add_text(subtree,
6468             tvb, curr_offset, 1,
6469             "%s :  Extension: %s",
6470             a_bigbuf,
6471             extended ? "extended" : "not extended");
6472
6473         switch ((oct & 0x60) >> 5)
6474         {
6475         case 0x02: str = "8 kbit/s"; break;
6476         case 0x03: str = "16 kbit/s"; break;
6477         default:
6478             str = "Reserved";
6479             break;
6480         }
6481
6482         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
6483         proto_tree_add_text(subtree,
6484             tvb, curr_offset, 1,
6485             "%s :  V.110/X.30 rate adaptation Intermediate rate: %s",
6486             a_bigbuf,
6487             str);
6488
6489         other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
6490         proto_tree_add_text(subtree,
6491             tvb, curr_offset, 1,
6492             "%s :  Network independent clock (NIC) on transmission (Tx): %s to send data with network independent clock",
6493             a_bigbuf,
6494             (oct & 0x10) ? "requires" : "does not require");
6495
6496         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
6497         proto_tree_add_text(subtree,
6498             tvb, curr_offset, 1,
6499             "%s :  Network independent clock (NIC) on reception (Rx): %s accept data with network independent clock",
6500             a_bigbuf,
6501             (oct & 0x08) ? "can" : "cannot");
6502
6503         switch (oct & 0x07)
6504         {
6505         case 0x00: str = "Odd"; break;
6506         case 0x02: str = "Even"; break;
6507         case 0x03: str = "None"; break;
6508         case 0x04: str = "Forced to 0"; break;
6509         case 0x05: str = "Forced to 1"; break;
6510         default:
6511             str = "Reserved";
6512             break;
6513         }
6514
6515         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
6516         proto_tree_add_text(subtree,
6517             tvb, curr_offset, 1,
6518             "%s :  Parity information: %s",
6519             a_bigbuf,
6520             str);
6521
6522         curr_offset++;
6523
6524         NO_MORE_DATA_CHECK(len);
6525
6526         if (!extended) goto bc_octet_7;
6527
6528         /* octet 6c */
6529
6530         item =
6531             proto_tree_add_text(tree,
6532                 tvb, curr_offset, 1,
6533                 "Octet 6c");
6534
6535         subtree = proto_item_add_subtree(item, ett_bc_oct_6c);
6536
6537         oct = tvb_get_guint8(tvb, curr_offset);
6538
6539         extended = (oct & 0x80) ? FALSE : TRUE;
6540
6541         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6542         proto_tree_add_text(subtree,
6543             tvb, curr_offset, 1,
6544             "%s :  Extension: %s",
6545             a_bigbuf,
6546             extended ? "extended" : "not extended");
6547
6548         switch ((oct & 0x60) >> 5)
6549         {
6550         case 0x01: str = "Non transparent (RLP)"; break;
6551         case 0x02: str = "Both, transparent preferred"; break;
6552         case 0x03: str = "Both, non transparent preferred"; break;
6553         default:
6554             str = "Transparent";
6555             break;
6556         }
6557
6558         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
6559         proto_tree_add_text(subtree,
6560             tvb, curr_offset, 1,
6561             "%s :  Connection element: %s",
6562             a_bigbuf,
6563             str);
6564
6565         switch (oct & 0x1f)
6566         {
6567         case 0x00: str = "None"; break;
6568         case 0x01: str = "V.21"; break;
6569         case 0x02: str = "V.22"; break;
6570         case 0x03: str = "V.22 bis"; break;
6571         case 0x04: str = "Reserved: was allocated in earlier phases of the protocol"; break;
6572         case 0x05: str = "V.26 ter"; break;
6573         case 0x06: str = "V.32"; break;
6574         case 0x07: str = "Modem for undefined interface"; break;
6575         case 0x08: str = "Autobauding type 1"; break;
6576         default:
6577             str = "Reserved";
6578             break;
6579         }
6580
6581         other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
6582         proto_tree_add_text(subtree,
6583             tvb, curr_offset, 1,
6584             "%s :  Modem type: %s",
6585             a_bigbuf,
6586             str);
6587
6588         curr_offset++;
6589
6590         NO_MORE_DATA_CHECK(len);
6591
6592         if (!extended) goto bc_octet_7;
6593
6594         /* octet 6d */
6595
6596         item =
6597             proto_tree_add_text(tree,
6598                 tvb, curr_offset, 1,
6599                 "Octet 6d");
6600
6601         subtree = proto_item_add_subtree(item, ett_bc_oct_6d);
6602
6603         oct = tvb_get_guint8(tvb, curr_offset);
6604
6605         extended = (oct & 0x80) ? FALSE : TRUE;
6606
6607         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6608         proto_tree_add_text(subtree,
6609             tvb, curr_offset, 1,
6610             "%s :  Extension: %s",
6611             a_bigbuf,
6612             extended ? "extended" : "not extended");
6613
6614         switch ((oct & 0x60) >> 5)
6615         {
6616         case 0x00: str = "No other modem type specified in this field"; break;
6617         case 0x02: str = "V.34"; break;
6618         default:
6619             str = "Reserved";
6620             break;
6621         }
6622
6623         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
6624         proto_tree_add_text(subtree,
6625             tvb, curr_offset, 1,
6626             "%s :  Other modem type: %s",
6627             a_bigbuf,
6628             str);
6629
6630         switch (oct & 0x1f)
6631         {
6632         case 0x00: str = "Fixed network user rate not applicable/No meaning is associated with this value"; break;
6633         case 0x01: str = "9.6 kbit/s Recommendation X.1 and V.110"; break;
6634         case 0x02: str = "14.4 kbit/s Recommendation X.1 and V.110"; break;
6635         case 0x03: str = "19.2 kbit/s Recommendation X.1 and V.110"; break;
6636         case 0x04: str = "28.8 kbit/s Recommendation X.1 and V.110"; break;
6637         case 0x05: str = "38.4 kbit/s Recommendation X.1 and V.110"; break;
6638         case 0x06: str = "48.0 kbit/s Recommendation X.1 and V.110(synch)"; break;
6639         case 0x07: str = "56.0 kbit/s Recommendation X.1 and V.110(synch) /bit transparent"; break;
6640         case 0x08: str = "64.0 kbit/s bit transparent"; break;
6641         case 0x09: str = "33.6 kbit/s bit transparent"; break;
6642         case 0x0a: str = "32.0 kbit/s Recommendation I.460"; break;
6643         case 0x0b: str = "31.2 kbit/s Recommendation V.34"; break;
6644         default:
6645             str = "Reserved";
6646             break;
6647         }
6648
6649         other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
6650         proto_tree_add_text(subtree,
6651             tvb, curr_offset, 1,
6652             "%s :  Fixed network user rate: %s",
6653             a_bigbuf,
6654             str);
6655
6656         curr_offset++;
6657
6658         NO_MORE_DATA_CHECK(len);
6659
6660         if (!extended) goto bc_octet_7;
6661
6662         /* octet 6e */
6663
6664         item =
6665             proto_tree_add_text(tree,
6666                 tvb, curr_offset, 1,
6667                 "Octet 6e");
6668
6669         subtree = proto_item_add_subtree(item, ett_bc_oct_6e);
6670
6671         oct = tvb_get_guint8(tvb, curr_offset);
6672
6673         extended = (oct & 0x80) ? FALSE : TRUE;
6674
6675         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6676         proto_tree_add_text(subtree,
6677             tvb, curr_offset, 1,
6678             "%s :  Extension: %s",
6679             a_bigbuf,
6680             extended ? "extended" : "not extended");
6681
6682         if (is_uplink == IS_UPLINK_TRUE)
6683         {
6684             other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
6685             proto_tree_add_text(subtree,
6686                 tvb, curr_offset, 1,
6687                 "%s :  Acceptable channel codings: TCH/F14.4 %sacceptable",
6688                 a_bigbuf,
6689                 (oct & 0x40) ? "" : "not ");
6690
6691             other_decode_bitfield_value(a_bigbuf, oct, 0x20, 8);
6692             proto_tree_add_text(subtree,
6693                 tvb, curr_offset, 1,
6694                 "%s :  Acceptable channel codings: Spare",
6695                 a_bigbuf);
6696
6697             other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
6698             proto_tree_add_text(subtree,
6699                 tvb, curr_offset, 1,
6700                 "%s :  Acceptable channel codings: TCH/F9.6 %sacceptable",
6701                 a_bigbuf,
6702                 (oct & 0x10) ? "" : "not ");
6703
6704             other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
6705             proto_tree_add_text(subtree,
6706                 tvb, curr_offset, 1,
6707                 "%s :  Acceptable channel codings: TCH/F4.8 %sacceptable",
6708                 a_bigbuf,
6709                 (oct & 0x08) ? "" : "not ");
6710
6711             other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
6712             proto_tree_add_text(subtree,
6713                 tvb, curr_offset, 1,
6714                 "%s :  Maximum number of traffic channels: %u TCH",
6715                 a_bigbuf,
6716                 (oct & 0x07) + 1);
6717         }
6718         else
6719         {
6720             other_decode_bitfield_value(a_bigbuf, oct, 0x78, 8);
6721             proto_tree_add_text(subtree,
6722                 tvb, curr_offset, 1,
6723                 "%s :  Acceptable channel codings: Spare",
6724                 a_bigbuf);
6725
6726             other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
6727             proto_tree_add_text(subtree,
6728                 tvb, curr_offset, 1,
6729                 "%s :  Maximum number of traffic channels: Spare",
6730                 a_bigbuf);
6731         }
6732
6733         curr_offset++;
6734
6735         NO_MORE_DATA_CHECK(len);
6736
6737         if (!extended) goto bc_octet_7;
6738
6739         /* octet 6f */
6740
6741         item =
6742             proto_tree_add_text(tree,
6743                 tvb, curr_offset, 1,
6744                 "Octet 6f");
6745
6746         subtree = proto_item_add_subtree(item, ett_bc_oct_6f);
6747
6748         oct = tvb_get_guint8(tvb, curr_offset);
6749
6750         extended = (oct & 0x80) ? FALSE : TRUE;
6751
6752         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6753         proto_tree_add_text(subtree,
6754             tvb, curr_offset, 1,
6755             "%s :  Extension: %s",
6756             a_bigbuf,
6757             extended ? "extended" : "not extended");
6758
6759         switch ((oct & 0x70) >> 4)
6760         {
6761         case 0x00: str = "not allowed/required/applicable"; break;
6762         case 0x01: str = "up to 1 TCH/F allowed/may be requested"; break;
6763         case 0x02: str = "up to 2 TCH/F allowed/may be requested"; break;
6764         case 0x03: str = "up to 3 TCH/F allowed/may be requested"; break;
6765         case 0x04: str = "up to 4 TCH/F allowed/may be requested"; break;
6766         default:
6767             str = "up to 4 TCH/F may be requested";
6768             break;
6769         }
6770
6771         other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
6772         proto_tree_add_text(subtree,
6773             tvb, curr_offset, 1,
6774             "%s :  UIMI, User initiated modification indication: %s",
6775             a_bigbuf,
6776             str);
6777
6778         if (is_uplink == IS_UPLINK_TRUE)
6779         {
6780             switch (oct & 0x0f)
6781             {
6782             case 0x00: str = "Air interface user rate not applicable/No meaning associated with this value"; break;
6783             case 0x01: str = "9.6 kbit/s"; break;
6784             case 0x02: str = "14.4 kbit/s"; break;
6785             case 0x03: str = "19.2 kbit/s"; break;
6786             case 0x05: str = "28.8 kbit/s"; break;
6787             case 0x06: str = "38.4 kbit/s"; break;
6788             case 0x07: str = "43.2 kbit/s"; break;
6789             case 0x08: str = "57.6 kbit/s"; break;
6790             case 0x09: str = "interpreted by the network as 38.4 kbit/s in this version of the protocol"; break;
6791             case 0x0a: str = "interpreted by the network as 38.4 kbit/s in this version of the protocol"; break;
6792             case 0x0b: str = "interpreted by the network as 38.4 kbit/s in this version of the protocol"; break;
6793             case 0x0c: str = "interpreted by the network as 38.4 kbit/s in this version of the protocol"; break;
6794             default:
6795                 str = "Reserved";
6796                 break;
6797             }
6798
6799             other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
6800             proto_tree_add_text(subtree,
6801                 tvb, curr_offset, 1,
6802                 "%s :  Wanted air interface user rate: %s",
6803                 a_bigbuf,
6804                 str);
6805         }
6806         else
6807         {
6808             other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
6809             proto_tree_add_text(subtree,
6810                 tvb, curr_offset, 1,
6811                 "%s :  Wanted air interface user rate: Spare",
6812                 a_bigbuf);
6813         }
6814
6815         curr_offset++;
6816
6817         NO_MORE_DATA_CHECK(len);
6818
6819         if (!extended) goto bc_octet_7;
6820
6821         /* octet 6g */
6822
6823         item =
6824             proto_tree_add_text(tree,
6825                 tvb, curr_offset, 1,
6826                 "Octet 6g");
6827
6828         subtree = proto_item_add_subtree(item, ett_bc_oct_6g);
6829
6830         oct = tvb_get_guint8(tvb, curr_offset);
6831
6832         extended = (oct & 0x80) ? FALSE : TRUE;
6833
6834         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6835         proto_tree_add_text(subtree,
6836             tvb, curr_offset, 1,
6837             "%s :  Extension: %s",
6838             a_bigbuf,
6839             extended ? "extended" : "not extended");
6840
6841         if (is_uplink == IS_UPLINK_TRUE)
6842         {
6843             other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
6844             proto_tree_add_text(subtree,
6845                 tvb, curr_offset, 1,
6846                 "%s :  Acceptable channel codings extended: TCH/F28.8 %sacceptable",
6847                 a_bigbuf,
6848                 (oct & 0x40) ? "" : "not ");
6849
6850             other_decode_bitfield_value(a_bigbuf, oct, 0x20, 8);
6851             proto_tree_add_text(subtree,
6852                 tvb, curr_offset, 1,
6853                 "%s :  Acceptable channel codings extended: TCH/F32.0 %sacceptable",
6854                 a_bigbuf,
6855                 (oct & 0x20) ? "" : "not ");
6856
6857             other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
6858             proto_tree_add_text(subtree,
6859                 tvb, curr_offset, 1,
6860                 "%s :  Acceptable channel codings extended: TCH/F43.2 %sacceptable",
6861                 a_bigbuf,
6862                 (oct & 0x10) ? "" : "not ");
6863
6864             other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
6865             proto_tree_add_text(subtree,
6866                 tvb, curr_offset, 1,
6867                 "%s :  Acceptable channel codings extended: TCH/F43.2 %sacceptable",
6868                 a_bigbuf,
6869                 (oct & 0x10) ? "" : "not ");
6870
6871             switch ((oct & 0x0c) >> 2)
6872             {
6873             case 0: str = "Channel coding symmetry preferred"; break;
6874             case 2: str = "Downlink biased channel coding asymmetry is preferred"; break;
6875             case 1: str = "Uplink biased channel coding asymmetry is preferred"; break;
6876             default:
6877                 str = "Unused, treat as Channel coding symmetry preferred";
6878                 break;
6879             }
6880
6881             other_decode_bitfield_value(a_bigbuf, oct, 0x0c, 8);
6882             proto_tree_add_text(subtree,
6883                 tvb, curr_offset, 1,
6884                 "%s :  Channel Coding Asymmetry Indication: %s",
6885                 a_bigbuf,
6886                 str);
6887         }
6888         else
6889         {
6890             other_decode_bitfield_value(a_bigbuf, oct, 0x7c, 8);
6891             proto_tree_add_text(subtree,
6892                 tvb, curr_offset, 1,
6893                 "%s :  EDGE Channel Codings: Spare",
6894                 a_bigbuf);
6895         }
6896
6897         other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
6898         proto_tree_add_text(subtree,
6899             tvb, curr_offset, 1,
6900             "%s :  Spare",
6901             a_bigbuf);
6902
6903         curr_offset++;
6904
6905         NO_MORE_DATA_CHECK(len);
6906
6907 bc_octet_7:
6908
6909         /* octet 7 */
6910
6911         item =
6912             proto_tree_add_text(tree,
6913                 tvb, curr_offset, 1,
6914                 "Octet 7");
6915
6916         subtree = proto_item_add_subtree(item, ett_bc_oct_7);
6917
6918         extended = (oct & 0x80) ? FALSE : TRUE;
6919
6920         oct = tvb_get_guint8(tvb, curr_offset);
6921
6922         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6923         proto_tree_add_text(subtree,
6924             tvb, curr_offset, 1,
6925             "%s :  Extension: %s",
6926             a_bigbuf,
6927             extended ? "extended" : "not extended");
6928
6929         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
6930         proto_tree_add_text(subtree,
6931             tvb, curr_offset, 1,
6932             "%s :  Layer 2 Identity: %s",
6933             a_bigbuf,
6934             ((oct & 0x60) == 0x40) ? "Octet identifier" : "Reserved");
6935
6936         switch (oct & 0x1f)
6937         {
6938         case 0x06: str = "Reserved: was allocated in earlier phases of the protocol"; break;
6939         case 0x08: str = "ISO 6429, codeset 0 (DC1/DC3)"; break;
6940         case 0x09: str = "Reserved: was allocated but never used in earlier phases of the protocol"; break;
6941         case 0x0a: str = "Videotex profile 1"; break;
6942         case 0x0c: str = "COPnoFlCt (Character oriented Protocol with no Flow Control mechanism)"; break;
6943         case 0x0d: str = "Reserved: was allocated in earlier phases of the protocol"; break;
6944         default:
6945             str = "Reserved";
6946             break;
6947         }
6948
6949         other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
6950         proto_tree_add_text(subtree,
6951             tvb, curr_offset, 1,
6952             "%s :  User information layer 2 protocol: %s",
6953             a_bigbuf,
6954             str);
6955         break;
6956     }
6957
6958     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
6959
6960     return(curr_offset - offset);
6961 }
6962
6963 /*
6964  * [3] 10.5.4.5a
6965  */
6966 static guint8
6967 de_cc_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
6968 {
6969     guint8      oct;
6970     guint32     curr_offset;
6971
6972     curr_offset = offset;
6973
6974     oct = tvb_get_guint8(tvb, curr_offset);
6975
6976     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
6977
6978     switch ((oct & 0xf0) >> 4)
6979     {
6980     case 0:
6981         proto_tree_add_text(tree,
6982             tvb, curr_offset, 1,
6983             "%s :  Maximum number of supported bearers: 1",
6984             a_bigbuf);
6985         break;
6986
6987     default:
6988         proto_tree_add_text(tree,
6989             tvb, curr_offset, 1,
6990             "%s :  Maximum number of supported bearers: %u",
6991             a_bigbuf,
6992             (oct & 0xf0) >> 4);
6993         break;
6994     }
6995
6996     other_decode_bitfield_value(a_bigbuf, oct, 0x0c, 8);
6997     proto_tree_add_text(tree,
6998         tvb, curr_offset, 1,
6999         "%s :  Spare",
7000         a_bigbuf);
7001
7002     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
7003     proto_tree_add_text(tree,
7004         tvb, curr_offset, 1,
7005         "%s :  PCP: the mobile station %s the Prolonged Clearing Procedure",
7006         a_bigbuf,
7007         (oct & 0x02) ? "supports" : "does not support");
7008
7009     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
7010     proto_tree_add_text(tree,
7011         tvb, curr_offset, 1,
7012         "%s :  DTMF: %s",
7013         a_bigbuf,
7014         (oct & 0x01) ?
7015             "the mobile station supports DTMF as specified in subclause 5.5.7 of TS 24.008" :
7016             "reserved for earlier versions of the protocol");
7017
7018     curr_offset++;
7019
7020     NO_MORE_DATA_CHECK(len);
7021
7022     oct = tvb_get_guint8(tvb, curr_offset);
7023
7024     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
7025     proto_tree_add_text(tree,
7026         tvb, curr_offset, 1,
7027         "%s :  Spare",
7028         a_bigbuf);
7029
7030     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
7031     proto_tree_add_text(tree,
7032         tvb, curr_offset, 1,
7033         "%s :  Maximum number of speech bearers: %u",
7034         a_bigbuf,
7035         oct & 0x0f);
7036
7037     curr_offset++;
7038
7039     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
7040
7041     return(curr_offset - offset);
7042 }
7043
7044 /*
7045  * [3] 10.5.4.6
7046  */
7047 static guint8
7048 de_call_state(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
7049 {
7050     guint8      oct;
7051     guint32     curr_offset;
7052     proto_tree  *subtree;
7053     proto_item  *item;
7054     const gchar *str;
7055
7056     len = len;
7057     curr_offset = offset;
7058
7059     oct = tvb_get_guint8(tvb, curr_offset);
7060
7061     item =
7062         proto_tree_add_text(tree,
7063             tvb, curr_offset, 1,
7064             gsm_dtap_elem_strings[DE_CALL_STATE].strptr);
7065
7066     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CALL_STATE]);
7067
7068     switch ((oct & 0xc0) >> 6)
7069     {
7070     case 0: str = "Coding as specified in ITU-T Rec. Q.931"; break;
7071     case 1: str = "Reserved for other international standards"; break;
7072     case 2: str = "National standard"; break;
7073     default:
7074         str = "Standard defined for the GSM PLMNS";
7075         break;
7076     }
7077
7078     other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
7079     proto_tree_add_text(subtree,
7080         tvb, curr_offset, 1,
7081         "%s :  Coding standard: %s",
7082         a_bigbuf,
7083         str);
7084
7085     switch (oct & 0x3f)
7086     {
7087     case 0x00: str = "UO - null                                 NO - null"; break;
7088     case 0x02: str = "U0.1- MM connection pending               N0.1- MM connection pending"; break;
7089     case 0x22: str = "U0.2- CC prompt present                   N0.2- CC connection pending"; break;
7090     case 0x23: str = "U0.3- Wait for network information        N0.3- Network answer pending"; break;
7091     case 0x24: str = "U0.4- CC-Establishment present            N0.4- CC-Establishment present"; break;
7092     case 0x25: str = "U0.5- CC-Establishment confirmed          N0.5- CC-Establishment confirmed"; break;
7093     case 0x26: str = "U0.6- Recall present                      N0.6- Recall present"; break;
7094     case 0x01: str = "U1 - call initiated                       N1 - call initiated"; break;
7095     case 0x03: str = "U3 - mobile originating call proceeding   N3 - mobile originating call proceeding"; break;
7096     case 0x04: str = "U4 - call delivered                       N4 - call delivered"; break;
7097     case 0x06: str = "U6 - call present                         N6 - call present"; break;
7098     case 0x07: str = "U7 - call received                        N7 - call received"; break;
7099     case 0x08: str = "U8 - connect request                      N8 - connect request"; break;
7100     case 0x09: str = "U9 - mobile terminating call confirmed    N9 - mobile terminating call confirmed"; break;
7101     case 0x0a: str = "U10- active                               N10- active"; break;
7102     case 0x0b: str = "U11- disconnect request"; break;
7103     case 0x0c: str = "U12- disconnect indication                N12-disconnect indication"; break;
7104     case 0x13: str = "U19- release request                      N19- release request"; break;
7105     case 0x1a: str = "U26- mobile originating modify            N26- mobile originating modify"; break;
7106     case 0x1b: str = "U27- mobile terminating modify            N27- mobile terminating modify"; break;
7107     case 0x1c: str = "                                          N28- connect indication"; break;
7108     default:
7109         str = "Unknown";
7110         break;
7111     }
7112
7113     other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
7114     proto_tree_add_text(subtree,
7115         tvb, curr_offset, 1,
7116         "%s :  Call state value: %s",
7117         a_bigbuf,
7118         str);
7119
7120     curr_offset++;
7121
7122     /* no length check possible */
7123
7124     return(curr_offset - offset);
7125 }
7126
7127 static const true_false_string gsm_a_extension_value = {
7128   "No Extension",
7129   "Extension"
7130 };
7131
7132 const value_string gsm_a_type_of_number_values[] = {
7133         {   0x00,       "unknown" },
7134         {   0x01,       "International Number" },
7135         {   0x02,       "National number" },
7136         {   0x03,       "Network Specific Number" },
7137         {   0x04,       "Dedicated access, short code" },
7138         {   0x05,       "Reserved" },
7139         {   0x06,       "Reserved" },
7140         {   0x07,       "Reserved for extension" },
7141         { 0, NULL }
7142 };
7143
7144 const value_string gsm_a_numbering_plan_id_values[] = {
7145         {   0x00,       "unknown" },
7146         {   0x01,       "ISDN/Telephony Numbering (Rec ITU-T E.164)" },
7147         {   0x02,       "spare" },
7148         {   0x03,       "Data Numbering (ITU-T Rec. X.121)" },
7149         {   0x04,       "Telex Numbering (ITU-T Rec. F.69)" },
7150         {   0x08,       "National Numbering" },
7151         {   0x09,       "Private Numbering" },
7152         {       0x0d,   "reserved for CTS (see 3GPP TS 44.056 [91])" },
7153         {   0x0f,       "Reserved for extension" },
7154         { 0, NULL }
7155 };
7156
7157 /*
7158  * [3] 10.5.4.7
7159  */
7160 static guint8
7161 de_cld_party_bcd_num(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
7162 {
7163     guint8      *poctets;
7164     guint32     curr_offset;
7165
7166     curr_offset = offset;
7167
7168     proto_tree_add_item(tree, hf_gsm_a_extension, tvb, curr_offset, 1, FALSE);
7169         proto_tree_add_item(tree, hf_gsm_a_type_of_number , tvb, curr_offset, 1, FALSE);
7170         proto_tree_add_item(tree, hf_gsm_a_numbering_plan_id , tvb, curr_offset, 1, FALSE);
7171
7172     curr_offset++;
7173
7174     NO_MORE_DATA_CHECK(len);
7175
7176     poctets = tvb_get_ephemeral_string(tvb, curr_offset, len - (curr_offset - offset));
7177
7178     my_dgt_tbcd_unpack(a_bigbuf, poctets, len - (curr_offset - offset),
7179         &Dgt_mbcd);
7180
7181     proto_tree_add_string_format(tree, hf_gsm_a_cld_party_bcd_num,
7182         tvb, curr_offset, len - (curr_offset - offset),
7183         a_bigbuf,
7184         "BCD Digits: %s",
7185         a_bigbuf);
7186
7187         if (sccp_assoc && ! sccp_assoc->called_party) {
7188                 sccp_assoc->called_party = se_strdup(a_bigbuf);
7189         }
7190         
7191     curr_offset += len - (curr_offset - offset);
7192
7193     if (add_string)
7194         g_snprintf(add_string, string_len, " - (%s)", a_bigbuf);
7195
7196     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
7197
7198     return(curr_offset - offset);
7199 }
7200
7201 /*
7202  * [3] 10.5.4.8
7203  */
7204 static guint8
7205 de_cld_party_sub_addr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
7206 {
7207     guint8      oct;
7208     guint32     curr_offset;
7209     const gchar *str;
7210
7211     curr_offset = offset;
7212
7213     oct = tvb_get_guint8(tvb, curr_offset);
7214
7215     proto_tree_add_item(tree, hf_gsm_a_extension, tvb, curr_offset, 1, FALSE);
7216
7217     switch ((oct & 0x70) >> 4)
7218     {
7219     case 0: str = "NSAP (X.213/ISO 8348 AD2)"; break;
7220     case 2: str = "User specified"; break;
7221     default:
7222         str = "Reserved";
7223         break;
7224     }
7225
7226     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
7227     proto_tree_add_text(tree,
7228         tvb, curr_offset, 1,
7229         "%s :  Type of subaddress: %s",
7230         a_bigbuf,
7231         str);
7232
7233     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
7234     proto_tree_add_text(tree,
7235         tvb, curr_offset, 1,
7236         "%s :  Odd/Even indicator: %s",
7237         a_bigbuf,
7238         (oct & 0x08) ?
7239             "odd number of address signals" : "even number of address signals");
7240
7241     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
7242     proto_tree_add_text(tree,
7243         tvb, curr_offset, 1,
7244         "%s :  Spare",
7245         a_bigbuf);
7246
7247     curr_offset++;
7248
7249     NO_MORE_DATA_CHECK(len);
7250
7251     proto_tree_add_text(tree,
7252         tvb, curr_offset, len - (curr_offset - offset),
7253         "Subaddress information");
7254
7255     curr_offset += len - (curr_offset - offset);
7256
7257     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
7258
7259     return(curr_offset - offset);
7260 }
7261
7262 /* 3GPP TS 24.008
7263  * [3] 10.5.4.9
7264  */
7265 static guint8
7266 de_clg_party_bcd_num(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
7267 {
7268     guint8      oct;
7269     guint8      *poctets;
7270     guint32     curr_offset;
7271     const gchar *str;
7272
7273     curr_offset = offset;
7274
7275     proto_tree_add_item(tree, hf_gsm_a_extension, tvb, curr_offset, 1, FALSE);
7276         proto_tree_add_item(tree, hf_gsm_a_type_of_number , tvb, curr_offset, 1, FALSE);
7277         proto_tree_add_item(tree, hf_gsm_a_numbering_plan_id , tvb, curr_offset, 1, FALSE);
7278
7279     curr_offset++;
7280
7281     oct = tvb_get_guint8(tvb, curr_offset);
7282
7283     proto_tree_add_item(tree, hf_gsm_a_extension, tvb, curr_offset, 1, FALSE);
7284
7285     switch ((oct & 0x60) >> 5)
7286     {
7287     case 0: str = "Presentation allowed"; break;
7288     case 1: str = "Presentation restricted"; break;
7289     case 2: str = "Number not available due to interworking"; break;
7290     default:
7291         str = "Reserved";
7292         break;
7293     }
7294
7295     other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
7296     proto_tree_add_text(tree,
7297         tvb, curr_offset, 1,
7298         "%s :  Presentation indicator: %s",
7299         a_bigbuf,
7300         str);
7301
7302     other_decode_bitfield_value(a_bigbuf, oct, 0x1c, 8);
7303     proto_tree_add_text(tree,
7304         tvb, curr_offset, 1,
7305         "%s :  Spare",
7306         a_bigbuf);
7307
7308     switch (oct & 0x03)
7309     {
7310     case 0: str = "User-provided, not screened"; break;
7311     case 1: str = "User-provided, verified and passed"; break;
7312     case 2: str = "User-provided, verified and failed"; break;
7313     default:
7314         str = "Network provided";
7315         break;
7316     }
7317
7318     other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
7319     proto_tree_add_text(tree,
7320         tvb, curr_offset, 1,
7321         "%s :  Screening indicator: %s",
7322         a_bigbuf,
7323         str);
7324
7325     curr_offset++;
7326
7327     NO_MORE_DATA_CHECK(len);
7328
7329     poctets = tvb_get_ephemeral_string(tvb, curr_offset, len - (curr_offset - offset));
7330
7331     my_dgt_tbcd_unpack(a_bigbuf, poctets, len - (curr_offset - offset),
7332         &Dgt_mbcd);
7333
7334     proto_tree_add_string_format(tree, hf_gsm_a_clg_party_bcd_num,
7335         tvb, curr_offset, len - (curr_offset - offset),
7336         a_bigbuf,
7337         "BCD Digits: %s",
7338         a_bigbuf);
7339
7340     curr_offset += len - (curr_offset - offset);
7341
7342     if (add_string)
7343         g_snprintf(add_string, string_len, " - (%s)", a_bigbuf);
7344
7345     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
7346
7347     return(curr_offset - offset);
7348 }
7349
7350 /*
7351  * [3] 10.5.4.10
7352  */
7353 static guint8
7354 de_clg_party_sub_addr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
7355 {
7356     guint8      oct;
7357     guint32     curr_offset;
7358     const gchar *str;
7359
7360     curr_offset = offset;
7361
7362     oct = tvb_get_guint8(tvb, curr_offset);
7363
7364     proto_tree_add_item(tree, hf_gsm_a_extension, tvb, curr_offset, 1, FALSE);
7365
7366     switch ((oct & 0x70) >> 4)
7367     {
7368     case 0: str = "NSAP (X.213/ISO 8348 AD2)"; break;
7369     case 2: str = "User specified"; break;
7370     default:
7371         str = "Reserved";
7372         break;
7373     }
7374
7375     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
7376     proto_tree_add_text(tree,
7377         tvb, curr_offset, 1,
7378         "%s :  Type of subaddress: %s",
7379         a_bigbuf,
7380         str);
7381
7382     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
7383     proto_tree_add_text(tree,
7384         tvb, curr_offset, 1,
7385         "%s :  Odd/Even indicator: %s",
7386         a_bigbuf,
7387         (oct & 0x08) ?
7388             "odd number of address signals" : "even number of address signals");
7389
7390     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
7391     proto_tree_add_text(tree,
7392         tvb, curr_offset, 1,
7393         "%s :  Spare",
7394         a_bigbuf);
7395
7396     curr_offset++;
7397
7398     NO_MORE_DATA_CHECK(len);
7399
7400     proto_tree_add_text(tree,
7401         tvb, curr_offset, len - (curr_offset - offset),
7402         "Subaddress information");
7403
7404     curr_offset += len - (curr_offset - offset);
7405
7406     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
7407
7408     return(curr_offset - offset);
7409 }
7410
7411 /*
7412  * [3] 10.5.4.11
7413  */
7414 static guint8
7415 de_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
7416 {
7417     guint8      oct;
7418     guint8      cause;
7419     guint32     curr_offset;
7420     const gchar *str;
7421
7422     curr_offset = offset;
7423
7424     oct = tvb_get_guint8(tvb, curr_offset);
7425
7426     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
7427     proto_tree_add_text(tree,
7428         tvb, curr_offset, 1,
7429         "%s :  Extension: %s",
7430         a_bigbuf,
7431         (oct & 0x80) ? "not extended" : "extended");
7432
7433     switch ((oct & 0x60) >> 5)
7434     {
7435     case 0: str = "Coding as specified in ITU-T Rec. Q.931"; break;
7436     case 1: str = "Reserved for other international standards"; break;
7437     case 2: str = "National standard"; break;
7438     default:
7439         str = "Standard defined for the GSM PLMNS";
7440         break;
7441     }
7442
7443     other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
7444     proto_tree_add_text(tree,
7445         tvb, curr_offset, 1,
7446         "%s :  Coding standard: %s",
7447         a_bigbuf,
7448         str);
7449
7450     other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
7451     proto_tree_add_text(tree,
7452         tvb, curr_offset, 1,
7453         "%s :  Spare",
7454         a_bigbuf);
7455
7456     switch (oct & 0x0f)
7457     {
7458     case 0: str = "User"; break;
7459     case 1: str = "Private network serving the local user"; break;
7460     case 2: str = "Public network serving the local user"; break;
7461     case 3: str = "Transit network"; break;
7462     case 4: str = "Public network serving the remote user"; break;
7463     case 5: str = "Private network serving the remote user"; break;
7464     case 7: str = "International network"; break;
7465     case 10: str = "Network beyond interworking point"; break;
7466     default:
7467         str = "Reserved";
7468         break;
7469     }
7470
7471     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
7472     proto_tree_add_text(tree,
7473         tvb, curr_offset, 1,
7474         "%s :  Location: %s",
7475         a_bigbuf,
7476         str);
7477
7478     curr_offset++;
7479
7480     oct = tvb_get_guint8(tvb, curr_offset);
7481
7482     if (!(oct & 0x80))
7483     {
7484         proto_tree_add_item(tree, hf_gsm_a_extension, tvb, curr_offset, 1, FALSE);
7485
7486         other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
7487         proto_tree_add_text(tree,
7488             tvb, curr_offset, 1,
7489             "%s :  Recommendation",
7490             a_bigbuf);
7491
7492         curr_offset++;
7493
7494         oct = tvb_get_guint8(tvb, curr_offset);
7495     }
7496
7497     proto_tree_add_item(tree, hf_gsm_a_extension, tvb, curr_offset, 1, FALSE);
7498
7499     cause = oct & 0x7f;
7500     switch (cause)
7501     {
7502     case 1: str = "Unassigned (unallocated) number"; break;
7503     case 3: str = "No route to destination"; break;
7504     case 6: str = "Channel unacceptable"; break;
7505     case 8: str = "Operator determined barring"; break;
7506     case 16: str = "Normal call clearing"; break;
7507     case 17: str = "User busy"; break;
7508     case 18: str = "No user responding"; break;
7509     case 19: str = "User alerting, no answer"; break;
7510     case 21: str = "Call rejected"; break;
7511     case 22: str = "Number changed"; break;
7512     case 25: str = "Pre-emption"; break;
7513     case 26: str = "Non selected user clearing"; break;
7514     case 27: str = "Destination out of order"; break;
7515     case 28: str = "Invalid number format (incomplete number)"; break;
7516     case 29: str = "Facility rejected"; break;
7517     case 30: str = "Response to STATUS ENQUIRY"; break;
7518     case 31: str = "Normal, unspecified"; break;
7519     case 34: str = "No circuit/channel available"; break;
7520     case 38: str = "Network out of order"; break;
7521     case 41: str = "Temporary failure"; break;
7522     case 42: str = "Switching equipment congestion"; break;
7523     case 43: str = "Access information discarded"; break;
7524     case 44: str = "requested circuit/channel not available"; break;
7525     case 47: str = "Resources unavailable, unspecified"; break;
7526     case 49: str = "Quality of service unavailable"; break;
7527     case 50: str = "Requested facility not subscribed"; break;
7528     case 55: str = "Incoming calls barred within the CUG"; break;
7529     case 57: str = "Bearer capability not authorized"; break;
7530     case 58: str = "Bearer capability not presently available"; break;
7531     case 63: str = "Service or option not available, unspecified"; break;
7532     case 65: str = "Bearer service not implemented"; break;
7533     case 68: str = "ACM equal to or greater than ACMmax"; break;
7534     case 69: str = "Requested facility not implemented"; break;
7535     case 70: str = "Only restricted digital information bearer capability is available"; break;
7536     case 79: str = "Service or option not implemented, unspecified"; break;
7537     case 81: str = "Invalid transaction identifier value"; break;
7538     case 87: str = "User not member of CUG"; break;
7539     case 88: str = "Incompatible destination"; break;
7540     case 91: str = "Invalid transit network selection"; break;
7541     case 95: str = "Semantically incorrect message"; break;
7542     case 96: str = "Invalid mandatory information"; break;
7543     case 97: str = "Message type non-existent or not implemented"; break;
7544     case 98: str = "Message type not compatible with protocol state"; break;
7545     case 99: str = "Information element non-existent or not implemented"; break;
7546     case 100: str = "Conditional IE error"; break;
7547     case 101: str = "Message not compatible with protocol state"; break;
7548     case 102: str = "Recovery on timer expiry"; break;
7549     case 111: str = "Protocol error, unspecified"; break;
7550     case 127: str = "Interworking, unspecified"; break;
7551     default:
7552         if (cause <= 31) { str = "Treat as Normal, unspecified"; }
7553         else if ((cause >= 32) && (cause <= 47)) { str = "Treat as Resources unavailable, unspecified"; }
7554         else if ((cause >= 48) && (cause <= 63)) { str = "Treat as Service or option not available, unspecified"; }
7555         else if ((cause >= 64) && (cause <= 79)) { str = "Treat as Service or option not implemented, unspecified"; }
7556         else if ((cause >= 80) && (cause <= 95)) { str = "Treat as Semantically incorrect message"; }
7557         else if ((cause >= 96) && (cause <= 111)) { str = "Treat as Protocol error, unspecified"; }
7558         else if ((cause >= 112) && (cause <= 127)) { str = "Treat as Interworking, unspecified"; }
7559         break;
7560     }
7561
7562     other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
7563     proto_tree_add_uint_format(tree, hf_gsm_a_dtap_cause,
7564         tvb, curr_offset, 1, cause,
7565         "%s :  Cause: (%u) %s",
7566         a_bigbuf,
7567         cause,
7568         str);
7569
7570     curr_offset++;
7571
7572     if (add_string)
7573         g_snprintf(add_string, string_len, " - (%u) %s", cause, str);
7574
7575     NO_MORE_DATA_CHECK(len);
7576
7577     proto_tree_add_text(tree,
7578         tvb, curr_offset, len - (curr_offset - offset),
7579         "Diagnostics");
7580
7581     curr_offset += len - (curr_offset - offset);
7582
7583     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
7584
7585     return(curr_offset - offset);
7586 }
7587
7588 /*
7589  * 10.5.4.18 Low layer compatibility 
7590  */
7591 static guint8
7592 de_llc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
7593 {
7594     guint32     curr_offset;
7595
7596     curr_offset = offset;
7597
7598         dissect_q931_bearer_capability_ie(tvb, offset, len, tree);
7599
7600         curr_offset = curr_offset + len;
7601     return(curr_offset - offset);
7602 }
7603
7604 /*
7605  * [6] 3.6
7606  */
7607  static int
7608 dissect_ROS_InvokeIdType(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
7609   offset = dissect_ber_integer(implicit_tag, pinfo, tree, tvb, offset, hf_index,
7610                                   NULL);
7611
7612   return offset;
7613 }
7614 static int dissect_invokeID(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
7615   return dissect_ROS_InvokeIdType(FALSE, tvb, offset, pinfo, tree, hf_ROS_invokeID);
7616 }
7617 static int dissect_linkedID_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
7618   return dissect_ROS_InvokeIdType(TRUE, tvb, offset, pinfo, tree, hf_ROS_linkedID);
7619 }
7620 static int dissect_derivable(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
7621   return dissect_ROS_InvokeIdType(FALSE, tvb, offset, pinfo, tree, hf_ROS_derivable);
7622 }
7623
7624
7625
7626 static int
7627 dissect_ROS_INTEGER(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
7628   offset = dissect_ber_integer(implicit_tag, pinfo, tree, tvb, offset, hf_index,
7629                                   &localValue);
7630
7631   return offset;
7632 }
7633 static int dissect_localValue(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
7634   return dissect_ROS_INTEGER(FALSE, tvb, offset, pinfo, tree, hf_ROS_localValue);
7635 }
7636 static int dissect_privateer_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
7637   return dissect_ROS_INTEGER(TRUE, tvb, offset, pinfo, tree, hf_ROS_privateer);
7638 }
7639
7640
7641
7642 static int
7643 dissect_ROS_OBJECT_IDENTIFIER(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
7644   offset = dissect_ber_object_identifier(implicit_tag, pinfo, tree, tvb, offset, hf_index,
7645                                             NULL);
7646
7647   return offset;
7648 }
7649 static int dissect_globalValue(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
7650   return dissect_ROS_OBJECT_IDENTIFIER(FALSE, tvb, offset, pinfo, tree, hf_ROS_globalValue);
7651 }
7652
7653
7654 static const value_string ROS_OPERATION_vals[] = {
7655   {   0, "localValue" },
7656   {   1, "globalValue" },
7657   { 0, NULL }
7658 };
7659
7660 static const ber_choice_t OPERATION_choice[] = {
7661   {   0, BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_localValue },
7662   {   1, BER_CLASS_UNI, BER_UNI_TAG_OID, BER_FLAGS_NOOWNTAG, dissect_globalValue },
7663   { 0, 0, 0, 0, NULL }
7664 };
7665
7666 static int
7667 dissect_ROS_OPERATION(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
7668   offset = dissect_ber_choice(pinfo, tree, tvb, offset,
7669                               OPERATION_choice, hf_index, ett_ROS_OPERATION, NULL);
7670
7671   return offset;
7672 }
7673 static int dissect_opCode(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
7674   return dissect_ROS_OPERATION(FALSE, tvb, offset, pinfo, tree, hf_ROS_opCode);
7675 }
7676
7677
7678
7679 static int
7680 dissect_ROS_Parameter(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
7681   offset = gsm_ss_dissect(tvb, pinfo, tree, offset, localValue, comp_type_tag);
7682         
7683   return offset;
7684 }
7685 static int dissect_parameter(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
7686   return dissect_ROS_Parameter(FALSE, tvb, offset, pinfo, tree, hf_ROS_parameter);
7687 }
7688
7689 static const ber_sequence_t Invoke_sequence[] = {
7690   { BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_invokeID },
7691   { BER_CLASS_CON, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_linkedID_impl },
7692   { BER_CLASS_UNI, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_opCode },
7693   { BER_CLASS_ANY, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_parameter },
7694   { 0, 0, 0, NULL }
7695 };
7696
7697 static int
7698 dissect_ROS_Invoke(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
7699   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
7700                                 Invoke_sequence, hf_index, ett_ROS_Invoke);
7701
7702   return offset;
7703 }
7704 static int dissect_invoke_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
7705   return dissect_ROS_Invoke(TRUE, tvb, offset, pinfo, tree, hf_ROS_invoke);
7706 }
7707
7708 static const ber_sequence_t T_resultretres_sequence[] = {
7709   { BER_CLASS_UNI, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_opCode },
7710   { BER_CLASS_ANY, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_parameter },
7711   { 0, 0, 0, NULL }
7712 };
7713
7714 static int
7715 dissect_ROS_T_resultretres(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
7716   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
7717                                 T_resultretres_sequence, hf_index, ett_ROS_T_resultretres);
7718
7719   return offset;
7720 }
7721 static int dissect_resultretres(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
7722   return dissect_ROS_T_resultretres(FALSE, tvb, offset, pinfo, tree, hf_ROS_resultretres);
7723 }
7724
7725 static const ber_sequence_t ReturnResult_sequence[] = {
7726   { BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_invokeID },
7727   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_resultretres },
7728   { 0, 0, 0, NULL }
7729 };
7730
7731 static int
7732 dissect_ROS_ReturnResult(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
7733   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
7734                                 ReturnResult_sequence, hf_index, ett_ROS_ReturnResult);
7735
7736   return offset;
7737 }
7738 static int dissect_returnResultLast_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
7739   return dissect_ROS_ReturnResult(TRUE, tvb, offset, pinfo, tree, hf_ROS_returnResultLast);
7740 }
7741
7742
7743
7744 static int
7745 dissect_ROS_INTEGER_M32768_32767(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
7746   offset = dissect_ber_integer(implicit_tag, pinfo, tree, tvb, offset, hf_index,
7747                                   NULL);
7748
7749   return offset;
7750 }
7751 static int dissect_nationaler_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
7752   return dissect_ROS_INTEGER_M32768_32767(TRUE, tvb, offset, pinfo, tree, hf_ROS_nationaler);
7753 }
7754
7755
7756 static const value_string ROS_ErrorCode_vals[] = {
7757   {  19, "nationaler" },
7758   {  20, "privateer" },
7759   { 0, NULL }
7760 };
7761
7762 static const ber_choice_t ErrorCode_choice[] = {
7763   {  19, BER_CLASS_PRI, 19, BER_FLAGS_IMPLTAG, dissect_nationaler_impl },
7764   {  20, BER_CLASS_PRI, 20, BER_FLAGS_IMPLTAG, dissect_privateer_impl },
7765   { 0, 0, 0, 0, NULL }
7766 };
7767
7768 static int
7769 dissect_ROS_ErrorCode(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
7770   offset = dissect_ber_choice(pinfo, tree, tvb, offset,
7771                               ErrorCode_choice, hf_index, ett_ROS_ErrorCode, NULL);
7772
7773   return offset;
7774 }
7775 static int dissect_errorCode(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
7776   return dissect_ROS_ErrorCode(FALSE, tvb, offset, pinfo, tree, hf_ROS_errorCode);
7777 }
7778
7779 static const ber_sequence_t ReturnError_sequence[] = {
7780   { BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_invokeID },
7781   { BER_CLASS_PRI, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_errorCode },
7782   { BER_CLASS_ANY, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_parameter },
7783   { 0, 0, 0, NULL }
7784 };
7785
7786 static int
7787 dissect_ROS_ReturnError(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
7788   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
7789                                 ReturnError_sequence, hf_index, ett_ROS_ReturnError);
7790
7791   return offset;
7792 }
7793 static int dissect_returnError_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
7794   return dissect_ROS_ReturnError(TRUE, tvb, offset, pinfo, tree, hf_ROS_returnError);
7795 }
7796
7797
7798
7799 static int
7800 dissect_ROS_NULL(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
7801   offset = dissect_ber_null(implicit_tag, pinfo, tree, tvb, offset, hf_index);
7802
7803   return offset;
7804 }
7805 static int dissect_not_derivable(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
7806   return dissect_ROS_NULL(FALSE, tvb, offset, pinfo, tree, hf_ROS_not_derivable);
7807 }
7808
7809
7810 static const value_string ROS_T_invokeIDRej_vals[] = {
7811   {   0, "derivable" },
7812   {   1, "not-derivable" },
7813   { 0, NULL }
7814 };
7815
7816 static const ber_choice_t T_invokeIDRej_choice[] = {
7817   {   0, BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_derivable },
7818   {   1, BER_CLASS_UNI, BER_UNI_TAG_NULL, BER_FLAGS_NOOWNTAG, dissect_not_derivable },
7819   { 0, 0, 0, 0, NULL }
7820 };
7821
7822 static int
7823 dissect_ROS_T_invokeIDRej(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
7824   offset = dissect_ber_choice(pinfo, tree, tvb, offset,
7825                               T_invokeIDRej_choice, hf_index, ett_ROS_T_invokeIDRej, NULL);
7826
7827   return offset;
7828 }
7829 static int dissect_invokeIDRej(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
7830   return dissect_ROS_T_invokeIDRej(FALSE, tvb, offset, pinfo, tree, hf_ROS_invokeIDRej);
7831 }
7832
7833
7834 static const value_string ROS_GeneralProblem_vals[] = {
7835   {   0, "unrecognizedComponent" },
7836   {   1, "mistypedComponent" },
7837   {   2, "badlyStructuredComponent" },
7838   { 0, NULL }
7839 };
7840
7841
7842 static int
7843 dissect_ROS_GeneralProblem(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
7844   offset = dissect_ber_integer(implicit_tag, pinfo, tree, tvb, offset, hf_index,
7845                                   NULL);
7846
7847   return offset;
7848 }
7849 static int dissect_generalProblem_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
7850   return dissect_ROS_GeneralProblem(TRUE, tvb, offset, pinfo, tree, hf_ROS_generalProblem);
7851 }
7852
7853
7854 static const value_string ROS_InvokeProblem_vals[] = {
7855   {   0, "duplicateInvokeID" },
7856   {   1, "unrecognizedOperation" },
7857   {   2, "mistypedParameter" },
7858   {   3, "resourceLimitation" },
7859   {   4, "initiatingRelease" },
7860   {   5, "unrecognizedLinkedID" },
7861   {   6, "linkedResponseUnexpected" },
7862   {   7, "unexpectedLinkedOperation" },
7863   { 0, NULL }
7864 };
7865
7866
7867 static int
7868 dissect_ROS_InvokeProblem(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
7869   offset = dissect_ber_integer(implicit_tag, pinfo, tree, tvb, offset, hf_index,
7870                                   NULL);
7871
7872   return offset;
7873 }
7874 static int dissect_invokeProblem_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
7875   return dissect_ROS_InvokeProblem(TRUE, tvb, offset, pinfo, tree, hf_ROS_invokeProblem);
7876 }
7877
7878
7879 static const value_string ROS_ReturnResultProblem_vals[] = {
7880   {   0, "unrecognizedInvokeID" },
7881   {   1, "returnResultUnexpected" },
7882   {   2, "mistypedParameter" },
7883   { 0, NULL }
7884 };
7885
7886
7887 static int
7888 dissect_ROS_ReturnResultProblem(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
7889   offset = dissect_ber_integer(implicit_tag, pinfo, tree, tvb, offset, hf_index,
7890                                   NULL);
7891
7892   return offset;
7893 }
7894 static int dissect_returnResultProblem_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
7895   return dissect_ROS_ReturnResultProblem(TRUE, tvb, offset, pinfo, tree, hf_ROS_returnResultProblem);
7896 }
7897
7898
7899 static const value_string ROS_ReturnErrorProblem_vals[] = {
7900   {   0, "unrecognizedInvokeID" },
7901   {   1, "returnErrorUnexpected" },
7902   {   2, "unrecognizedError" },
7903   {   3, "unexpectedError" },
7904   {   4, "mistypedParameter" },
7905   { 0, NULL }
7906 };
7907
7908
7909 static int
7910 dissect_ROS_ReturnErrorProblem(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
7911   offset = dissect_ber_integer(implicit_tag, pinfo, tree, tvb, offset, hf_index,
7912                                   NULL);
7913
7914   return offset;
7915 }
7916 static int dissect_returnErrorProblem_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
7917   return dissect_ROS_ReturnErrorProblem(TRUE, tvb, offset, pinfo, tree, hf_ROS_returnErrorProblem);
7918 }
7919
7920
7921 static const value_string ROS_T_problem_vals[] = {
7922   {   0, "generalProblem" },
7923   {   1, "invokeProblem" },
7924   {   2, "returnResultProblem" },
7925   {   3, "returnErrorProblem" },
7926   { 0, NULL }
7927 };
7928
7929 static const ber_choice_t T_problem_choice[] = {
7930   {   0, BER_CLASS_CON, 0, BER_FLAGS_IMPLTAG, dissect_generalProblem_impl },
7931   {   1, BER_CLASS_CON, 1, BER_FLAGS_IMPLTAG, dissect_invokeProblem_impl },
7932   {   2, BER_CLASS_CON, 2, BER_FLAGS_IMPLTAG, dissect_returnResultProblem_impl },
7933   {   3, BER_CLASS_CON, 3, BER_FLAGS_IMPLTAG, dissect_returnErrorProblem_impl },
7934   { 0, 0, 0, 0, NULL }
7935 };
7936
7937 static int
7938 dissect_ROS_T_problem(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
7939   offset = dissect_ber_choice(pinfo, tree, tvb, offset,
7940                               T_problem_choice, hf_index, ett_ROS_T_problem, NULL);
7941
7942   return offset;
7943 }
7944 static int dissect_problem(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
7945   return dissect_ROS_T_problem(FALSE, tvb, offset, pinfo, tree, hf_ROS_problem);
7946 }
7947
7948 static const ber_sequence_t Reject_sequence[] = {
7949   { BER_CLASS_UNI, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_invokeIDRej },
7950   { BER_CLASS_CON, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_problem },
7951   { 0, 0, 0, NULL }
7952 };
7953
7954 static int
7955 dissect_ROS_Reject(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
7956   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
7957                                 Reject_sequence, hf_index, ett_ROS_Reject);
7958
7959   return offset;
7960 }
7961 static int dissect_reject_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
7962   return dissect_ROS_Reject(TRUE, tvb, offset, pinfo, tree, hf_ROS_reject);
7963 }
7964
7965
7966 static const value_string ROS_Component_vals[] = {
7967   {   1, "invoke" },
7968   {   2, "returnResultLast" },
7969   {   3, "returnError" },
7970   {   4, "reject" },
7971   { 0, NULL }
7972 };
7973
7974 static const ber_choice_t Component_choice[] = {
7975   {   1, BER_CLASS_CON, 1, BER_FLAGS_IMPLTAG, dissect_invoke_impl },
7976   {   2, BER_CLASS_CON, 2, BER_FLAGS_IMPLTAG, dissect_returnResultLast_impl },
7977   {   3, BER_CLASS_CON, 3, BER_FLAGS_IMPLTAG, dissect_returnError_impl },
7978   {   4, BER_CLASS_CON, 4, BER_FLAGS_IMPLTAG, dissect_reject_impl },
7979   { 0, 0, 0, 0, NULL }
7980 };
7981
7982 static int
7983 dissect_ROS_Component(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
7984
7985   offset = dissect_ber_choice(pinfo, tree, tvb, offset,
7986                               Component_choice, hf_index, ett_ROS_Component, NULL);
7987   /* branch taken will be component type -1 */
7988
7989   return offset;
7990 }
7991
7992
7993 static const value_string ROS_ERROR_vals[] = {
7994   {   0, "localValue" },
7995   {   1, "globalValue" },
7996   { 0, NULL }
7997 };
7998
7999 static const ber_choice_t ERROR_choice[] = {
8000   {   0, BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_localValue },
8001   {   1, BER_CLASS_UNI, BER_UNI_TAG_OID, BER_FLAGS_NOOWNTAG, dissect_globalValue },
8002   { 0, 0, 0, 0, NULL }
8003 };
8004
8005 #if 0
8006 static int
8007 dissect_ROS_ERROR(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
8008   offset = dissect_ber_choice(pinfo, tree, tvb, offset,
8009                               ERROR_choice, hf_index, ett_ROS_ERROR, NULL);
8010
8011   return offset;
8012 }
8013 #endif
8014
8015 static guint8
8016 de_facility(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint fac_len, gchar *add_string _U_, int string_len _U_)
8017 {
8018     guint       saved_offset;
8019         gint8 class;
8020         gboolean pc;
8021         gboolean ind = FALSE;
8022         guint32 component_len = 0;
8023         guint32 header_end_offset;
8024         guint32 header_len;
8025
8026         
8027         saved_offset = offset;
8028         while ( fac_len > (offset - saved_offset)){ 
8029
8030                 /* Get the length of the component there can be more tnan one component in a facility message */
8031           
8032                 header_end_offset = get_ber_identifier(tvb, offset, &class, &pc, &comp_type_tag);
8033                 header_end_offset = get_ber_length(tree, tvb, header_end_offset, &component_len, &ind);
8034                 if (ind){
8035                         proto_tree_add_text(tree, tvb, offset+1, 1,
8036                                 "Indefinte length, ignoring component");
8037                         return (fac_len);
8038                 }
8039                 header_len = header_end_offset - offset;
8040                 component_len = header_len + component_len;
8041                 dissect_ROS_Component(FALSE, tvb, offset, g_pinfo, tree, hf_ROS_component);
8042                 offset = offset + component_len;
8043
8044         } 
8045         return(fac_len);
8046
8047
8048 }
8049
8050 /*
8051  * [3] 10.5.4.17
8052  */
8053 static guint8
8054 de_keypad_facility(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
8055 {
8056     guint8      oct;
8057     guint32     curr_offset;
8058
8059     len = len;
8060     curr_offset = offset;
8061
8062     oct = tvb_get_guint8(tvb, curr_offset);
8063
8064     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
8065     proto_tree_add_text(tree,
8066         tvb, curr_offset, 1,
8067         "%s :  Spare",
8068         a_bigbuf);
8069
8070     other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
8071     proto_tree_add_text(tree,
8072         tvb, curr_offset, 1,
8073         "%s :  Keypad information: %c",
8074         a_bigbuf,
8075         oct & 0x7f);
8076
8077     curr_offset++;
8078
8079     if (add_string)
8080         g_snprintf(add_string, string_len, " - %c", oct & 0x7f);
8081
8082     /* no length check possible */
8083
8084     return(curr_offset - offset);
8085 }
8086
8087 /*
8088  * [3] 10.5.4.21
8089  */
8090 static guint8
8091 de_prog_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
8092 {
8093     guint8      oct;
8094     guint32     curr_offset;
8095     const gchar *str;
8096
8097     len = len;
8098     curr_offset = offset;
8099
8100     oct = tvb_get_guint8(tvb, curr_offset);
8101
8102     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
8103     proto_tree_add_text(tree,
8104         tvb, curr_offset, 1,
8105         "%s :  Extension: %s",
8106         a_bigbuf,
8107         (oct & 0x80) ? "extended" : "not extended");
8108
8109     switch ((oct & 0x60) >> 5)
8110     {
8111     case 0: str = "Coding as specified in ITU-T Rec. Q.931"; break;
8112     case 1: str = "Reserved for other international standards"; break;
8113     case 2: str = "National standard"; break;
8114     default:
8115         str = "Standard defined for the GSM PLMNS";
8116         break;
8117     }
8118
8119     other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
8120     proto_tree_add_text(tree,
8121         tvb, curr_offset, 1,
8122         "%s :  Coding standard: %s",
8123         a_bigbuf,
8124         str);
8125
8126     other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
8127     proto_tree_add_text(tree,
8128         tvb, curr_offset, 1,
8129         "%s :  Spare",
8130         a_bigbuf);
8131
8132     switch (oct & 0x0f)
8133     {
8134     case 0: str = "User"; break;
8135     case 1: str = "Private network serving the local user"; break;
8136     case 2: str = "Public network serving the local user"; break;
8137     case 4: str = "Public network serving the remote user"; break;
8138     case 5: str = "Private network serving the remote user"; break;
8139     case 10: str = "Network beyond interworking point"; break;
8140     default:
8141         str = "Reserved";
8142         break;
8143     }
8144
8145     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
8146     proto_tree_add_text(tree,
8147         tvb, curr_offset, 1,
8148         "%s :  Location: %s",
8149         a_bigbuf,
8150         str);
8151
8152     curr_offset++;
8153
8154     oct = tvb_get_guint8(tvb, curr_offset);
8155
8156     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
8157     proto_tree_add_text(tree,
8158         tvb, curr_offset, 1,
8159         "%s :  Extension: %s",
8160         a_bigbuf,
8161         (oct & 0x80) ? "extended" : "not extended");
8162
8163     switch (oct & 0x7f)
8164     {
8165     case 1: str = "Call is not end-to-end PLMN/ISDN, further call progress information may be available in-band"; break;
8166     case 2: str = "Destination address in non-PLMN/ISDN"; break;
8167     case 3: str = "Origination address in non-PLMN/ISDN"; break;
8168     case 4: str = "Call has returned to the PLMN/ISDN"; break;
8169     case 8: str = "In-band information or appropriate pattern now available"; break;
8170     case 32: str = "Call is end-to-end PLMN/ISDN"; break;
8171     case 64: str = "Queueing"; break;
8172     default:
8173         str = "Unspecific";
8174         break;
8175     }
8176
8177     other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
8178     proto_tree_add_text(tree,
8179         tvb, curr_offset, 1,
8180         "%s :  Progress Description: %s (%d)",
8181         a_bigbuf,
8182         str,
8183         oct & 0x7f);
8184
8185     if (add_string)
8186         g_snprintf(add_string, string_len, " - %d", oct & 0x7f);
8187
8188     curr_offset++;
8189
8190     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
8191
8192     return(curr_offset - offset);
8193 }
8194
8195 /*
8196  * [3] 10.5.4.22
8197  */
8198 static guint8
8199 de_repeat_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
8200 {
8201     guint8      oct;
8202     guint32     curr_offset;
8203     const gchar *str;
8204
8205     len = len;
8206     curr_offset = offset;
8207
8208     oct = tvb_get_guint8(tvb, curr_offset);
8209
8210     switch (oct & 0x0f)
8211     {
8212     case 1: str = "Circular for successive selection 'mode 1 alternate mode 2'"; break;
8213     case 2: str = "Support of fallback  mode 1 preferred, mode 2 selected if setup of mode 1 fails"; break;
8214     case 3: str = "Reserved: was allocated in earlier phases of the protocol"; break;
8215     default:
8216         str = "Reserved";
8217         break;
8218     }
8219
8220     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
8221     proto_tree_add_text(tree,
8222         tvb, curr_offset, 1,
8223         "%s :  %s",
8224         a_bigbuf,
8225         str);
8226
8227     curr_offset++;
8228
8229     /* no length check possible */
8230
8231     return(curr_offset - offset);
8232 }
8233
8234 /*
8235  * [6] 3.7.2
8236  */
8237 static guint8
8238 de_ss_ver_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
8239 {
8240     guint8      oct;
8241     guint32     curr_offset;
8242     const gchar *str;
8243
8244     curr_offset = offset;
8245
8246     oct = tvb_get_guint8(tvb, curr_offset);
8247
8248     switch (oct)
8249     {
8250     case 0: str = "Phase 2 service, ellipsis notation, and phase 2 error handling is supported"; break;
8251     case 1: str = "SS-Protocol version 3 is supported, and phase 2 error handling is supported"; break;
8252     default:
8253         str = "Reserved";
8254         break;
8255     }
8256
8257     proto_tree_add_text(tree,
8258         tvb, curr_offset, 1,
8259         "%s",
8260         str);
8261
8262     curr_offset++;
8263
8264     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
8265
8266     return(curr_offset - offset);
8267 }
8268
8269 /*
8270  * [5] 8.1.4.1 3GPP TS 24.011 version 6.1.0 Release 6
8271  */
8272 static guint8
8273 de_cp_user_data(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
8274 {
8275     guint32     curr_offset;
8276     tvbuff_t    *rp_tvb;
8277
8278     curr_offset = offset;
8279
8280     proto_tree_add_text(tree, tvb, curr_offset, len,
8281         "RPDU (not displayed)");
8282
8283     /*
8284      * dissect the embedded RP message
8285      */
8286     rp_tvb = tvb_new_subset(tvb, curr_offset, len, len);
8287
8288     call_dissector(rp_handle, rp_tvb, g_pinfo, g_tree);
8289
8290     curr_offset += len;
8291
8292     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
8293
8294     return(curr_offset - offset);
8295 }
8296
8297 /*
8298  * [5] 8.1.4.2
8299  */
8300 static guint8
8301 de_cp_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
8302 {
8303     guint8      oct;
8304     guint32     curr_offset;
8305     const gchar *str;
8306
8307     len = len;
8308     curr_offset = offset;
8309
8310     oct = tvb_get_guint8(tvb, curr_offset);
8311
8312     switch (oct)
8313     {
8314     case 17: str = "Network failure"; break;
8315     case 22: str = "Congestion"; break;
8316     case 81: str = "Invalid Transaction Identifier value"; break;
8317     case 95: str = "Semantically incorrect message"; break;
8318     case 96: str = "Invalid mandatory information"; break;
8319     case 97: str = "Message type non-existent or not implemented"; break;
8320     case 98: str = "Message not compatible with the short message protocol state"; break;
8321     case 99: str = "Information element non-existent or not implemented"; break;
8322     case 111: str = "Protocol error, unspecified"; break;
8323     default:
8324         str = "Reserved, treat as Protocol error, unspecified";
8325         break;
8326     }
8327
8328     proto_tree_add_text(tree,
8329         tvb, curr_offset, 1,
8330         "Cause: (%u) %s",
8331         oct,
8332         str);
8333
8334     curr_offset++;
8335
8336     if (add_string)
8337         g_snprintf(add_string, string_len, " - (%u) %s", oct, str);
8338
8339     /* no length check possible */
8340
8341     return(curr_offset - offset);
8342 }
8343
8344 /*
8345  * [5] 8.2.3
8346  */
8347 static guint8
8348 de_rp_message_ref(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
8349 {
8350     guint8      oct;
8351     guint32     curr_offset;
8352
8353     len = len;
8354     curr_offset = offset;
8355
8356     oct = tvb_get_guint8(tvb, curr_offset);
8357
8358     proto_tree_add_text(tree,
8359         tvb, curr_offset, 1,
8360         "RP-Message Reference: 0x%02x (%u)",
8361         oct,
8362         oct);
8363
8364     curr_offset++;
8365
8366     /* no length check possible */
8367
8368     return(curr_offset - offset);
8369 }
8370
8371 /*
8372  * [5] 8.2.5.1
8373  */
8374 static guint8
8375 de_rp_orig_addr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
8376 {
8377     return(de_cld_party_bcd_num(tvb, tree, offset, len, add_string, string_len));
8378 }
8379
8380 /*
8381  * [5] 8.2.5.2
8382  */
8383 static guint8
8384 de_rp_dest_addr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
8385 {
8386     return(de_cld_party_bcd_num(tvb, tree, offset, len, add_string, string_len));
8387 }
8388
8389 /*
8390  * [5] 8.2.5.3
8391  */
8392 static guint8
8393 de_rp_user_data(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
8394 {
8395     guint32     curr_offset;
8396     tvbuff_t    *tpdu_tvb;
8397
8398     curr_offset = offset;
8399
8400     proto_tree_add_text(tree, tvb, curr_offset, len,
8401         "TPDU (not displayed)");
8402
8403     /*
8404      * dissect the embedded TPDU message
8405      */
8406     tpdu_tvb = tvb_new_subset(tvb, curr_offset, len, len);
8407
8408     dissector_try_port(sms_dissector_table, 0, tpdu_tvb, g_pinfo, g_tree);
8409
8410     curr_offset += len;
8411
8412     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
8413
8414     return(curr_offset - offset);
8415 }
8416
8417 /*
8418  * [5] 8.2.5.4
8419  */
8420 static guint8
8421 de_rp_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
8422 {
8423     guint8      oct;
8424     guint32     curr_offset;
8425     const gchar *str;
8426
8427     curr_offset = offset;
8428
8429     oct = tvb_get_guint8(tvb, curr_offset);
8430
8431     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
8432     proto_tree_add_text(tree,
8433         tvb, curr_offset, 1,
8434         "%s :  Extension: %s",
8435         a_bigbuf,
8436         (oct & 0x80) ? "extended" : "not extended");
8437
8438     switch (oct & 0x7f)
8439     {
8440     case 1: str = "Unassigned (unallocated) number"; break;
8441     case 8: str = "Operator determined barring"; break;
8442     case 10: str = "Call barred"; break;
8443     case 11: str = "Reserved"; break;
8444     case 21: str = "Short message transfer rejected"; break;
8445     case 22: str = "Memory capacity exceeded"; break;
8446     case 27: str = "Destination out of order"; break;
8447     case 28: str = "Unidentified subscriber"; break;
8448     case 29: str = "Facility rejected"; break;
8449     case 30: str = "Unknown subscriber"; break;
8450     case 38: str = "Network out of order"; break;
8451     case 41: str = "Temporary failure"; break;
8452     case 42: str = "Congestion"; break;
8453     case 47: str = "Resources unavailable, unspecified"; break;
8454     case 50: str = "Requested facility not subscribed"; break;
8455     case 69: str = "Requested facility not implemented"; break;
8456     case 81: str = "Invalid short message transfer reference value"; break;
8457     case 95: str = "Semantically incorrect message"; break;
8458     case 96: str = "Invalid mandatory information"; break;
8459     case 97: str = "Message type non-existent or not implemented"; break;
8460     case 98: str = "Message not compatible with short message protocol state"; break;
8461     case 99: str = "Information element non-existent or not implemented"; break;
8462     case 111: str = "Protocol error, unspecified"; break;
8463     case 127: str = "Interworking, unspecified"; break;
8464     default:
8465         str = "Reserved";
8466         break;
8467     }
8468
8469     other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
8470     proto_tree_add_text(tree,
8471         tvb, curr_offset, 1,
8472         "%s :  Cause: (%u) %s",
8473         a_bigbuf,
8474         oct & 0x7f,
8475         str);
8476
8477     curr_offset++;
8478
8479     if (add_string)
8480         g_snprintf(add_string, string_len, " - (%u) %s", oct & 0x7f, str);
8481
8482     NO_MORE_DATA_CHECK(len);
8483
8484     proto_tree_add_text(tree,
8485         tvb, curr_offset, len - (curr_offset - offset),
8486         "Diagnostic field");
8487
8488     curr_offset += len - (curr_offset - offset);
8489
8490     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
8491
8492     return(curr_offset - offset);
8493 }
8494
8495 /*
8496  * [7] 10.5.5.1
8497  */
8498 static guint8
8499 de_gmm_attach_res(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
8500 {
8501     guint8      oct;
8502     guint32     curr_offset;
8503     const gchar *str;
8504     
8505     len = len;
8506     curr_offset = offset;
8507
8508     oct = tvb_get_guint8(tvb, curr_offset);
8509
8510     switch(oct&7)
8511     {
8512         case 1: str="GPRS only attached"; break;
8513         case 3: str="Combined GPRS/IMSI attached";      break;
8514         default: str="reserved";
8515     }
8516
8517     proto_tree_add_text(tree,
8518         tvb, curr_offset, 1,
8519         "Attach Result: (%u) %s",
8520         oct&7,
8521         str);
8522
8523     curr_offset++;
8524
8525     /* no length check possible */
8526
8527     return(curr_offset - offset);
8528 }
8529
8530 /*
8531  * [7] 10.5.5.2
8532  */
8533 static guint8
8534 de_gmm_attach_type(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
8535 {
8536     guint8      oct;
8537     guint8      oct_ciph;
8538     guint32     curr_offset;
8539     const gchar *str_follow;
8540     const gchar *str_attach;
8541     proto_item  *tf = NULL;
8542     proto_tree      *tf_tree = NULL;
8543     
8544     len = len;
8545     curr_offset = offset;
8546
8547     oct = tvb_get_guint8(tvb, curr_offset);
8548     oct_ciph = oct>>4;
8549
8550     oct &= 0x0f;
8551
8552     switch(oct&7)
8553     {
8554         case 1: str_attach="GPRS attach"; break;
8555         case 2: str_attach="GPRS attach while IMSI attached"; break;
8556         case 3: str_attach="Combined GPRS/IMSI attach"; break;
8557         default: str_attach="reserved";
8558     }
8559     switch(oct&8)
8560     {
8561         case 8: str_follow="Follow-on request pending"; break;
8562         default: str_follow="No follow-on request pending";
8563     }
8564
8565     tf = proto_tree_add_text(tree,
8566         tvb, curr_offset, 1,
8567         "Attach Type");
8568
8569     tf_tree = proto_item_add_subtree(tf, ett_gmm_attach_type );
8570
8571     proto_tree_add_text(tf_tree,
8572         tvb, curr_offset, 1,
8573         "Type: (%u) %s",
8574         oct&7,
8575         str_attach);
8576     proto_tree_add_text(tf_tree,
8577         tvb, curr_offset, 1,
8578         "Follow: (%u) %s",
8579         (oct>>3)&1,
8580         str_follow);
8581
8582     /* The ciphering key sequence number is added here */
8583     proto_tree_add_text(tree,
8584         tvb, curr_offset, 1,
8585         "Ciphering key sequence number: 0x%02x (%u)",
8586         oct_ciph,
8587         oct_ciph);
8588
8589     curr_offset++;
8590
8591     /* no length check possible */
8592
8593     return(curr_offset - offset);
8594 }
8595
8596 /*
8597  * [7] 10.5.5.3
8598  */
8599 static guint8
8600 de_gmm_ciph_alg(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
8601 {
8602     guint8      oct;
8603     guint32     curr_offset;
8604     const gchar *str;
8605     
8606     len = len;
8607     curr_offset = offset;
8608
8609     oct = tvb_get_guint8(tvb, curr_offset);
8610
8611     switch(oct&7)
8612     {
8613         case 0: str="ciphering not used"; break;
8614         case 1: str="GPRS Encryption Algorithm GEA/1"; break;
8615         case 2: str="GPRS Encryption Algorithm GEA/2"; break;
8616         case 3: str="GPRS Encryption Algorithm GEA/3"; break;
8617         case 4: str="GPRS Encryption Algorithm GEA/4"; break;
8618         case 5: str="GPRS Encryption Algorithm GEA/5"; break;
8619         case 6: str="GPRS Encryption Algorithm GEA/6"; break;
8620         case 7: str="GPRS Encryption Algorithm GEA/7"; break;
8621         default: str="This should never happen";
8622     }
8623
8624     proto_tree_add_text(tree,
8625         tvb, curr_offset, 1,
8626         "Ciphering Algorithm: (%u) %s",
8627         oct&7,
8628         str);
8629
8630     curr_offset++;
8631
8632     /* no length check possible */
8633
8634     return(curr_offset - offset);
8635 }
8636
8637 /*
8638  * [7] 10.5.5.4
8639  */
8640 static guint8
8641 de_gmm_tmsi_stat(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
8642 {
8643     guint8      oct;
8644     guint32     curr_offset;
8645     const gchar *str;
8646     
8647     len = len;
8648     curr_offset = offset;
8649
8650     oct = tvb_get_guint8(tvb, curr_offset);
8651
8652     switch(oct&1)
8653     {
8654         case 0: str="no valid TMSI available"; break;
8655         case 1: str="valid TMSI available"; break;
8656         default: str="This should never happen";
8657     }
8658
8659     proto_tree_add_text(tree,
8660         tvb, curr_offset, 1,
8661         "TMSI Status: (%u) %s",
8662         oct&1,
8663         str);
8664
8665     /* curr_offset++;  - It is encoded in the octed before */
8666
8667     /* no length check possible */
8668
8669     return(curr_offset - offset);
8670 }
8671
8672 /*
8673  * [7] 10.5.5.5
8674  */
8675 static guint8
8676 de_gmm_detach_type(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
8677 {
8678     guint8      oct;
8679     guint32     curr_offset;
8680     const gchar *str;
8681     const gchar *str_power;
8682     proto_item  *tf = NULL;
8683     proto_tree      *tf_tree = NULL;
8684     
8685     len = len;
8686     curr_offset = offset;
8687
8688     oct = tvb_get_guint8(tvb, curr_offset);
8689
8690     switch(oct&7)
8691     {
8692         case 1: str="GPRS detach/re-attach required"; break;
8693         case 2: str="IMSI detach/re-attach not required"; break;
8694         case 3: str="Combined GPRS/IMSI detach/IMSI detach (after VLR failure)"; break;
8695         default: str="Combined GPRS/IMSI detach/re-attach not required";
8696     }
8697
8698     switch(oct&8)
8699     {
8700         case 8: str_power="power switched off"; break;
8701         default: str_power="normal detach"; break;
8702     }
8703
8704     tf = proto_tree_add_text(tree,
8705         tvb, curr_offset, 1,
8706         "Detach Type");
8707
8708     tf_tree = proto_item_add_subtree(tf, ett_gmm_detach_type );
8709
8710     proto_tree_add_text(tf_tree,
8711         tvb, curr_offset, 1,
8712         "Type: (%u) %s",
8713         oct&7,
8714         str);
8715
8716     proto_tree_add_text(tf_tree,
8717         tvb, curr_offset, 1,
8718         "Power: (%u) %s",
8719         (oct>>3)&1,
8720         str_power);
8721
8722     curr_offset++;
8723
8724     /* no length check possible */
8725
8726     return(curr_offset - offset);
8727 }
8728
8729 /*
8730  * [7] 10.5.5.6
8731  * 
8732  * SPLIT on CCCH, octet 3 (bit 4)
8733  * 0 Split pg cycle on CCCH is not supported by the mobile station
8734  * 1 Split pg cycle on CCCH is supported by the mobile station
8735  */
8736 static const true_false_string gsm_a_gmm_split_on_ccch_value  = {
8737   "Split pg cycle on CCCH is supported by the mobile station",
8738   "Split pg cycle on CCCH is not supported by the mobile station"
8739 };
8740
8741 /* non-DRX timer, octet 3
8742  * bit
8743  * 3 2 1
8744  */
8745 static const value_string gsm_a_gmm_non_drx_timer_strings[] = {
8746     { 0x00,     "no non-DRX mode after transfer state" },
8747     { 0x01,     "max. 1 sec non-DRX mode after transfer state" },
8748     { 0x02,     "max. 2 sec non-DRX mode after transfer state" },
8749     { 0x03,     "max. 4 sec non-DRX mode after transfer state" },
8750     { 0x04,     "max. 8 sec non-DRX mode after transfer state" },
8751     { 0x05,     "max. 16 sec non-DRX mode after transfer state" },
8752     { 0x06,     "max. 32 sec non-DRX mode after transfer state" },
8753     { 0x07,     "max. 64 sec non-DRX mode after transfer state" },
8754     { 0, NULL },
8755 };
8756 /*
8757  * CN Specific DRX cycle length coefficient, octet 3
8758  * bit
8759  * 8 7 6 5 Iu mode specific
8760  * 0 0 0 0 CN Specific DRX cycle length coefficient not specified by the MS, ie. the
8761  * system information value 'CN domain specific DRX cycle length' is used.
8762  * (Ref 3GPP TS 25.331)
8763  * 0 1 1 0 CN Specific DRX cycle length coefficient 6
8764  * 0 1 1 1 CN Specific DRX cycle length coefficient 7
8765  * 1 0 0 0 CN Specific DRX cycle length coefficient 8
8766  * 1 0 0 1 CN Specific DRX cycle length coefficient 9
8767  * All other values shall be interpreted as "CN Specific DRX cycle length coefficient not
8768  * specified by the MS " by this version of the protocol.
8769  * NOTE: In Iu mode this field (octet 3 bits 8 to 5) is used, but was spare in earlier
8770  * versions of this protocol.
8771  */
8772 static const value_string gsm_a_gmm_cn_spec_drs_cycle_len_coef_strings[] = {
8773     { 0x00,     "CN Specific DRX cycle length coefficient not specified by the MS" },
8774     { 0x01,     "CN Specific DRX cycle length coefficient not specified by the MS" },
8775     { 0x02,     "CN Specific DRX cycle length coefficient not specified by the MS" },
8776     { 0x03,     "CN Specific DRX cycle length coefficient not specified by the MS" },
8777     { 0x04,     "CN Specific DRX cycle length coefficient not specified by the MS" },
8778     { 0x05,     "CN Specific DRX cycle length coefficient not specified by the MS" },
8779     { 0x06,     "CN Specific DRX cycle length coefficient 6" },
8780     { 0x07,     "CN Specific DRX cycle length coefficient 7" },
8781     { 0x08,     "CN Specific DRX cycle length coefficient 8" },
8782     { 0x09,     "CN Specific DRX cycle length coefficient 9" },
8783     { 0x0a,     "CN Specific DRX cycle length coefficient not specified by the MS" },
8784     { 0x0b,     "CN Specific DRX cycle length coefficient not specified by the MS" },
8785     { 0x0c,     "CN Specific DRX cycle length coefficient not specified by the MS" },
8786     { 0x0d,     "CN Specific DRX cycle length coefficient not specified by the MS" },
8787     { 0x0e,     "CN Specific DRX cycle length coefficient not specified by the MS" },
8788     { 0x0f,     "CN Specific DRX cycle length coefficient not specified by the MS" },
8789     { 0, NULL },
8790 };
8791 guint8
8792 de_gmm_drx_param(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
8793 {
8794     guint8      oct;
8795     guint32     curr_offset;
8796     const gchar *str;
8797     gchar       str_val[3];
8798     proto_item  *tf = NULL;
8799     proto_tree  *tf_tree = NULL;
8800     
8801     len = len;
8802     curr_offset = offset;
8803
8804     tf = proto_tree_add_text(tree,
8805         tvb, curr_offset, 2,
8806         "DRX Parameter");
8807
8808     tf_tree = proto_item_add_subtree(tf, ett_gmm_drx );
8809
8810     oct = tvb_get_guint8(tvb, curr_offset);
8811
8812     switch(oct)
8813     {
8814         case 0: str="704"; break;
8815         case 65: str="71"; break;
8816         case 66: str="72"; break;
8817         case 67: str="74"; break;
8818         case 68: str="75"; break;
8819         case 69: str="77"; break;
8820         case 70: str="79"; break;
8821         case 71: str="80"; break;
8822         case 72: str="83"; break;
8823         case 73: str="86"; break;
8824         case 74: str="88"; break;
8825         case 75: str="90"; break;
8826         case 76: str="92"; break;
8827         case 77: str="96"; break;
8828         case 78: str="101"; break;
8829         case 79: str="103"; break;
8830         case 80: str="107"; break;
8831         case 81: str="112"; break;
8832         case 82: str="116"; break;
8833         case 83: str="118"; break;
8834         case 84: str="128"; break;
8835         case 85: str="141"; break;
8836         case 86: str="144"; break;
8837         case 87: str="150"; break;
8838         case 88: str="160"; break;
8839         case 89: str="171"; break;
8840         case 90: str="176"; break;
8841         case 91: str="192"; break;
8842         case 92: str="214"; break;
8843         case 93: str="224"; break;
8844         case 94: str="235"; break;
8845         case 95: str="256"; break;
8846         case 96: str="288"; break;
8847         case 97: str="320"; break;
8848         case 98: str="352"; break;
8849         default:
8850                 str_val[0]=oct/10+'0';
8851                 str_val[1]=oct%10+'0';
8852                 str_val[2]=0;
8853                 str=str_val;
8854     }
8855
8856     proto_tree_add_text(tf_tree,
8857         tvb, curr_offset, 1,
8858         "Split PG Cycle Code: (%u) %s",
8859         oct,
8860         str);
8861
8862     curr_offset++;
8863         proto_tree_add_item(tf_tree, hf_gsm_a_gmm_cn_spec_drs_cycle_len_coef, tvb, curr_offset, 1, FALSE);
8864         proto_tree_add_item(tf_tree, hf_gsm_a_gmm_split_on_ccch, tvb, curr_offset, 1, FALSE);
8865         proto_tree_add_item(tf_tree, hf_gsm_a_gmm_non_drx_timer, tvb, curr_offset, 1, FALSE);
8866
8867     curr_offset++;
8868
8869     /* no length check possible */
8870
8871     return(curr_offset - offset);
8872 }
8873
8874 /*
8875  * [7] 10.5.5.7
8876  */
8877 static guint8
8878 de_gmm_ftostby(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
8879 {
8880     guint8      oct;
8881     guint32     curr_offset;
8882     const gchar *str;
8883     
8884     len = len;
8885     curr_offset = offset;
8886
8887     oct = tvb_get_guint8(tvb, curr_offset);
8888
8889     switch(oct&7)
8890     {
8891         case 1: str="Force to standby indicated"; break;
8892         default: str="force to standby not indicated";
8893     }
8894
8895     proto_tree_add_text(tree,
8896         tvb, curr_offset, 1,
8897         "Force to Standby: (%u) %s",
8898         oct&7,
8899         str);
8900
8901     curr_offset++;
8902
8903     /* no length check possible */
8904
8905     return(curr_offset - offset);
8906 }
8907
8908 /*
8909  * [7] 10.5.5.7
8910  */
8911 static guint8
8912 de_gmm_ftostby_h(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
8913 {
8914     guint8      oct;
8915     guint32     curr_offset;
8916     const gchar *str;
8917     
8918     len = len;
8919     curr_offset = offset;
8920
8921     oct = tvb_get_guint8(tvb, curr_offset);
8922
8923     /* IMPORTANT - IT'S ASSUMED THAT THE INFORMATION IS IN THE HIGHER NIBBLE */
8924     oct >>= 4;
8925
8926     switch(oct&7)
8927     {
8928         case 1: str="Force to standby indicated"; break;
8929         default: str="force to standby not indicated";
8930     }
8931
8932     proto_tree_add_text(tree,
8933         tvb, curr_offset, 1,
8934         "Force to Standby: (%u) %s",
8935         oct&7,
8936         str);
8937
8938     curr_offset++;
8939
8940     /* no length check possible */
8941
8942     return(curr_offset - offset);
8943 }
8944
8945 /*
8946  * [7] 10.5.5.8
8947  */
8948 static guint8
8949 de_gmm_ptmsi_sig(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
8950 {
8951     guint32     curr_offset;
8952     proto_item  *curr_item;
8953     curr_offset = offset;
8954     curr_item= proto_tree_add_item(tree,hf_gsm_a_ptmsi_sig,tvb,curr_offset,3,FALSE);
8955     proto_item_append_text(curr_item,"%s",add_string ? add_string : "");
8956
8957     curr_offset+=3;
8958
8959     /* no length check possible */
8960
8961     return(curr_offset - offset);
8962 }
8963
8964 /*
8965  * [7] 10.5.5.8a
8966  */
8967 static guint8
8968 de_gmm_ptmsi_sig2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len _U_)
8969 {
8970     guint32     curr_offset;
8971     proto_item  *curr_item;
8972     curr_offset = offset;
8973
8974     curr_item= proto_tree_add_item(tree,hf_gsm_a_ptmsi_sig2,tvb,curr_offset,3,FALSE);
8975     proto_item_append_text(curr_item,"%s",add_string ? add_string : "");
8976     curr_offset+=3;
8977
8978     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
8979
8980     return(curr_offset - offset);
8981 }
8982
8983 /*
8984  * [7] 10.5.5.9
8985  */
8986 static guint8
8987 de_gmm_ident_type2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
8988 {
8989     guint8      oct;
8990     guint32     curr_offset;
8991     const gchar *str;
8992     
8993     len = len;
8994     curr_offset = offset;
8995
8996     oct = tvb_get_guint8(tvb, curr_offset);
8997
8998     switch ( oct&7 )
8999     {
9000         case 2: str="IMEI"; break;
9001         case 3: str="IMEISV"; break;
9002         case 4: str="TMSI"; break;
9003         default: str="IMSI";
9004     }
9005     
9006     proto_tree_add_text(tree,
9007         tvb, curr_offset, 1,
9008         "Identity Type 2: (%u) %s",
9009         oct&7,
9010         str);
9011
9012     curr_offset++;
9013
9014     /* no length check possible */
9015
9016     return(curr_offset - offset);
9017 }
9018
9019 /*
9020  * [7] 10.5.5.10
9021  */
9022 static guint8
9023 de_gmm_imeisv_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
9024 {
9025     guint8      oct;
9026     guint32     curr_offset;
9027     const gchar *str;
9028     
9029     len = len;
9030     curr_offset = offset;
9031
9032     oct = tvb_get_guint8(tvb, curr_offset);
9033
9034     /* IMPORTANT - IT'S ASSUMED THAT THE INFORMATION IS IN THE HIGHER NIBBLE */
9035     oct >>= 4;
9036
9037     switch ( oct&7 )
9038     {
9039         case 1: str="IMEISV requested"; break;
9040         default: str="IMEISV not requested";
9041     }
9042     
9043     proto_tree_add_text(tree,
9044         tvb, curr_offset, 1,
9045         "IMEISV Request: (%u) %s",
9046         oct&7,
9047         str);
9048
9049     curr_offset++;
9050
9051     /* no length check possible */
9052
9053     return(curr_offset - offset);
9054 }
9055
9056 /*
9057  * [7] 10.5.5.11
9058  */
9059 static guint8
9060 de_gmm_rec_npdu_lst(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
9061 {
9062     guint32     curr_offset;
9063     guint       curr_len;
9064     
9065     curr_len = len;
9066     curr_offset = offset;
9067
9068     if ( len == 0 ) return 0;
9069
9070     do
9071     {
9072             guint32     oct;
9073             oct = tvb_get_guint8(tvb, curr_offset);
9074             oct <<=8;
9075             oct |= tvb_get_guint8(tvb, curr_offset+1);
9076             curr_len -= 2;
9077             oct <<=8;
9078
9079             proto_tree_add_text(tree,
9080                 tvb, curr_offset, 2,
9081                 "NSAPI %d: 0x%02x (%u)",
9082                 oct>>20,
9083                 (oct>>12)&0xff,
9084                 (oct>>12)&0xff);
9085             curr_offset+= 2;
9086
9087             if ( curr_len > 2 )
9088             {
9089                     oct |= tvb_get_guint8(tvb, curr_offset+2);
9090                     curr_len--;
9091                     oct <<= 12;
9092
9093                     proto_tree_add_text(tree,
9094                         tvb, curr_offset-1, 2,
9095                         "NSAPI %d: 0x%02x (%u)",
9096                         oct>>20,
9097                         (oct>>12)&0xff,
9098                         (oct>>12)&0xff);
9099                     curr_offset++;
9100             }
9101
9102
9103     } while ( curr_len > 1 );
9104
9105     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
9106
9107     return(curr_offset - offset);
9108 }
9109
9110 /*
9111  * [7] 10.5.5.12
9112  */
9113 guint8
9114 de_gmm_ms_net_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
9115 {
9116     guint8      oct;
9117     guint32     curr_offset;
9118     guint       curr_len;
9119     guint       gea_val;
9120     
9121     gchar answer_gea[2][40]={ "encryption algorithm not available",
9122                         "encryption algorithm available" };
9123     gchar answer_smdch[2][120]={ "Mobile station does not support mobile terminated point to point SMS via dedicated signalling channels",
9124                         "Mobile station supports mobile terminated point to point SMS via dedicated signalling channels" };
9125     gchar answer_smgprs[2][100]={ "Mobile station does not support mobile terminated point to point SMS via GPRS packet data channels",
9126                         "Mobile station supports mobile terminated point to point SMS via GPRS packet data channels" };
9127     gchar answer_ucs2[2][100]={ "the ME has a preference for the default alphabet (defined in 3GPP TS 23.038 [8b]) over UCS2",
9128                         "the ME has no preference between the use of the default alphabet and the use of UCS2" };
9129     
9130     gchar answer_ssid[4][80]={ "default value of phase 1",
9131                         "capability of handling of ellipsis notation and phase 2 error handling",
9132                         "capability of handling of ellipsis notation and phase 2 error handling",
9133                         "capability of handling of ellipsis notation and phase 2 error handling" };
9134
9135     gchar answer_solsa[2][40]={ "The ME does not support SoLSA",
9136                         "The ME supports SoLSA" };
9137                         
9138     gchar answer_rev[2][80]={ "used by a mobile station not supporting R99 or later versions of the protocol",
9139                         "used by a mobile station supporting R99 or later versions of the protocol" };
9140
9141     gchar answer_pfc[2][80]={ "Mobile station does not support BSS packet flow procedures",
9142                         "Mobile station does support BSS packet flow procedures" };
9143
9144     gchar answer_lcs[2][80]={ "LCS value added location request notification capability not supported" ,
9145                         "LCS value added location request notification capability supported" };
9146     
9147     curr_len = len;
9148     curr_offset = offset;
9149
9150     if ( curr_len == 0 ){ EXTRANEOUS_DATA_CHECK(len, curr_offset - offset); return(curr_offset - offset); }
9151     oct = tvb_get_guint8(tvb, curr_offset);
9152     curr_len--;
9153
9154         /* bit 8 */
9155     proto_tree_add_text(tree,
9156         tvb, curr_offset, 1,
9157         "GEA1: (%u) %s",
9158         oct>>7,
9159         answer_gea[oct>>7]);
9160     oct<<=1;
9161
9162         /* bit 7 */
9163     proto_tree_add_text(tree,
9164         tvb, curr_offset, 1,
9165         "SM capabilities via dedicated channels: (%u) %s",
9166         oct>>7,
9167         answer_smdch[oct>>7]);
9168     oct<<=1;
9169
9170         /* bit 6 */
9171     proto_tree_add_text(tree,
9172         tvb, curr_offset, 1,
9173         "SM capabilities via GPRS channels: (%u) %s",
9174         oct>>7,
9175         answer_smgprs[oct>>7]);
9176     oct<<=1;
9177
9178         /* bit 5 */
9179     proto_tree_add_text(tree,
9180         tvb, curr_offset, 1,
9181         "UCS2 support: (%u) %s",
9182         oct>>7,
9183         answer_ucs2[oct>>7]);
9184     oct<<=1;
9185         
9186         /* bit 4 3 */
9187     proto_tree_add_text(tree,
9188         tvb, curr_offset, 1,
9189         "SS Screening Indicator: (%u) %s",
9190         oct>>6,
9191         answer_ssid[oct>>6]);
9192     oct<<=2;
9193
9194         /* bit 2 */
9195     proto_tree_add_text(tree,
9196         tvb, curr_offset, 1,
9197         "SoLSA Capability: (%u) %s",
9198         oct>>7,
9199         answer_solsa[oct>>7]);
9200     oct<<=1;
9201
9202         /* bit 1 */
9203     proto_tree_add_text(tree,
9204         tvb, curr_offset, 1,
9205         "Revision level indicator: (%u) %s",
9206         oct>>7,
9207         answer_rev[oct>>7]);
9208
9209     curr_offset++;
9210
9211     if ( curr_len == 0 ){ EXTRANEOUS_DATA_CHECK(len, curr_offset - offset); return(curr_offset - offset); }
9212     oct = tvb_get_guint8(tvb, curr_offset);
9213     curr_len--;
9214
9215     proto_tree_add_text(tree,
9216         tvb, curr_offset, 1,
9217         "PFC feature mode: (%u) %s",
9218         oct>>7,
9219         answer_pfc[oct>>7]);
9220     oct<<=1;
9221
9222     for( gea_val=2; gea_val<8 ; gea_val++ )
9223     {
9224             proto_tree_add_text(tree,
9225                 tvb, curr_offset, 1,
9226                 "GEA%d: (%u) %s", gea_val,
9227                 oct>>7,
9228                 answer_gea[oct>>7]);
9229             oct<<=1;
9230     }
9231     
9232     proto_tree_add_text(tree,
9233         tvb, curr_offset, 1,
9234         "LCS VA capability:: (%u) %s",
9235         oct>>7,
9236         answer_lcs[oct>>7]);
9237     
9238     curr_offset++;         
9239                    
9240     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
9241
9242     return(curr_offset - offset);
9243 }
9244
9245 /*
9246  * [7] 10.5.5.12a
9247  */
9248 #define GET_DATA                                /* check if we have enough bits left */ \
9249                 if ( curr_bits_length < bits_needed ) \
9250                         continue; \
9251                 /* check if oct has enougth bits */ \
9252                 if ( bits_in_oct < bits_needed ) \
9253                 { \
9254                         guint32 tmp_oct; \
9255                         if ( curr_len == 0 ) \
9256                         { \
9257                                 proto_tree_add_text(tf_tree, \
9258                                 tvb, curr_offset, 1, \
9259                                 "Not enough data available"); \
9260                         } \
9261                         tmp_oct = tvb_get_guint8(tvb, curr_offset); \
9262                         oct |= tmp_oct<<(32-8-bits_in_oct); \
9263                         curr_len--; \
9264                         curr_offset++; \
9265                         if ( bits_in_oct != 0 ) \
9266                                 add_ocetets = 1; \
9267                         else \
9268                                 add_ocetets = 0; \
9269                         bits_in_oct += 8; \
9270                 } \
9271                 else \
9272                         add_ocetets = 0;
9273
9274
9275 guint8
9276 de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
9277 {
9278     guint32     curr_offset;
9279     guint       curr_len;
9280     proto_item  *tf = NULL;
9281     proto_tree      *tf_tree = NULL;
9282     guint32     oct;
9283     guchar      bits_in_oct;
9284     guchar      bits_needed;
9285     guint       bits_length;
9286     guint       add_ocetets;    /* octets which are covered by one element -1 */
9287     guint       curr_bits_length;
9288     guchar      acc_type;
9289     const gchar *str;
9290     gchar       multi_slot_str[64][230] = {
9291         "Not specified", /* 00 */
9292         "Max Rx-Slot/TDMA:1 Max Tx-Slot/TDMA:1 Max-Sum-Slot/TDMA:2 Tta:3 Ttb:2 Tra:4 Trb:2 Type:1", /* 01 */
9293         "Max Rx-Slot/TDMA:2 Max Tx-Slot/TDMA:1 Max-Sum-Slot/TDMA:3 Tta:3 Ttb:2 Tra:3 Trb:1 Type:1", /* 02 */
9294         "Max Rx-Slot/TDMA:2 Max Tx-Slot/TDMA:2 Max-Sum-Slot/TDMA:3 Tta:3 Ttb:2 Tra:3 Trb:1 Type:1", /* 03 */
9295         "Max Rx-Slot/TDMA:3 Max Tx-Slot/TDMA:1 Max-Sum-Slot/TDMA:4 Tta:3 Ttb:1 Tra:3 Trb:1 Type:1", /* 04 */
9296         "Max Rx-Slot/TDMA:2 Max Tx-Slot/TDMA:2 Max-Sum-Slot/TDMA:4 Tta:3 Ttb:1 Tra:3 Trb:1 Type:1", /* 05 */
9297         "Max Rx-Slot/TDMA:3 Max Tx-Slot/TDMA:2 Max-Sum-Slot/TDMA:4 Tta:3 Ttb:1 Tra:3 Trb:1 Type:1", /* 06 */
9298         "Max Rx-Slot/TDMA:3 Max Tx-Slot/TDMA:3 Max-Sum-Slot/TDMA:4 Tta:3 Ttb:1 Tra:3 Trb:1 Type:1", /* 07 */
9299         "Max Rx-Slot/TDMA:4 Max Tx-Slot/TDMA:1 Max-Sum-Slot/TDMA:5 Tta:3 Ttb:1 Tra:2 Trb:1 Type:1", /* 08 */
9300         "Max Rx-Slot/TDMA:3 Max Tx-Slot/TDMA:2 Max-Sum-Slot/TDMA:5 Tta:3 Ttb:1 Tra:2 Trb:1 Type:1", /* 09 */
9301         "Max Rx-Slot/TDMA:4 Max Tx-Slot/TDMA:2 Max-Sum-Slot/TDMA:5 Tta:3 Ttb:1 Tra:2 Trb:1 Type:1", /* 10 */
9302         "Max Rx-Slot/TDMA:4 Max Tx-Slot/TDMA:3 Max-Sum-Slot/TDMA:5 Tta:3 Ttb:1 Tra:2 Trb:1 Type:1", /* 11 */
9303         "Max Rx-Slot/TDMA:4 Max Tx-Slot/TDMA:4 Max-Sum-Slot/TDMA:5 Tta:2 Ttb:1 Tra:2 Trb:1 Type:1", /* 12 */
9304         "Max Rx-Slot/TDMA:3 Max Tx-Slot/TDMA:3 Max-Sum-Slot/TDMA:NA Tta:NA Ttb:a) Tra:3 Trb:a) Type:2 (a: 1 with frequency hopping, 0 otherwise)", /* 13 */
9305         "Max Rx-Slot/TDMA:4 Max Tx-Slot/TDMA:4 Max-Sum-Slot/TDMA:NA Tta:NA Ttb:a) Tra:3 Trb:a) Type:2 (a: 1 with frequency hopping, 0 otherwise)", /* 14 */
9306         "Max Rx-Slot/TDMA:5 Max Tx-Slot/TDMA:5 Max-Sum-Slot/TDMA:NA Tta:NA Ttb:a) Tra:3 Trb:a) Type:2 (a: 1 with frequency hopping, 0 otherwise)", /* 15 */
9307         "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:6 Max-Sum-Slot/TDMA:NA Tta:NA Ttb:a) Tra:2 Trb:a) Type:2 (a: 1 with frequency hopping, 0 otherwise)", /* 16 */
9308         "Max Rx-Slot/TDMA:7 Max Tx-Slot/TDMA:7 Max-Sum-Slot/TDMA:NA Tta:NA Ttb:a) Tra:1 Trb:0 Type:2 (a: 1 with frequency hopping, 0 otherwise)", /* 17 */
9309         "Max Rx-Slot/TDMA:8 Max Tx-Slot/TDMA:8 Max-Sum-Slot/TDMA:NA Tta:NA Ttb:0 Tra:0 Trb:0 Type:2", /* 18 */
9310         "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:2 Max-Sum-Slot/TDMA:NA Tta:3 Ttb:b) Tra:2 Trb:c) Type:1 (b: 1 with frequency hopping or change from Rx to Tx, 0 otherwise; c: 1 with frequency hopping or change from Tx to Rx, 0 otherwise", /* 19 */     
9311         "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:3 Max-Sum-Slot/TDMA:NA Tta:3 Ttb:b) Tra:2 Trb:c) Type:1 (b: 1 with frequency hopping or change from Rx to Tx, 0 otherwise; c: 1 with frequency hopping or change from Tx to Rx, 0 otherwise", /* 20 */
9312         "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:4 Max-Sum-Slot/TDMA:NA Tta:3 Ttb:b) Tra:2 Trb:c) Type:1 (b: 1 with frequency hopping or change from Rx to Tx, 0 otherwise; c: 1 with frequency hopping or change from Tx to Rx, 0 otherwise", /* 21 */
9313         "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:4 Max-Sum-Slot/TDMA:NA Tta:3 Ttb:b) Tra:2 Trb:c) Type:1 (b: 1 with frequency hopping or change from Rx to Tx, 0 otherwise; c: 1 with frequency hopping or change from Tx to Rx, 0 otherwise", /* 22 */
9314         "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:6 Max-Sum-Slot/TDMA:NA Tta:3 Ttb:b) Tra:2 Trb:c) Type:1 (b: 1 with frequency hopping or change from Rx to Tx, 0 otherwise; c: 1 with frequency hopping or change from Tx to Rx, 0 otherwise", /* 23 */
9315         "Max Rx-Slot/TDMA:8 Max Tx-Slot/TDMA:2 Max-Sum-Slot/TDMA:NA Tta:3 Ttb:b) Tra:2 Trb:c) Type:1 (b: 1 with frequency hopping or change from Rx to Tx, 0 otherwise; c: 1 with frequency hopping or change from Tx to Rx, 0 otherwise", /* 24 */
9316         "Max Rx-Slot/TDMA:8 Max Tx-Slot/TDMA:3 Max-Sum-Slot/TDMA:NA Tta:3 Ttb:b) Tra:2 Trb:c) Type:1 (b: 1 with frequency hopping or change from Rx to Tx, 0 otherwise; c: 1 with frequency hopping or change from Tx to Rx, 0 otherwise", /* 25 */
9317         "Max Rx-Slot/TDMA:8 Max Tx-Slot/TDMA:4 Max-Sum-Slot/TDMA:NA Tta:3 Ttb:b) Tra:2 Trb:c) Type:1 (b: 1 with frequency hopping or change from Rx to Tx, 0 otherwise; c: 1 with frequency hopping or change from Tx to Rx, 0 otherwise", /* 26 */
9318         "Max Rx-Slot/TDMA:8 Max Tx-Slot/TDMA:4 Max-Sum-Slot/TDMA:NA Tta:3 Ttb:b) Tra:2 Trb:c) Type:1 (b: 1 with frequency hopping or change from Rx to Tx, 0 otherwise; c: 1 with frequency hopping or change from Tx to Rx, 0 otherwise", /* 27 */
9319         "Max Rx-Slot/TDMA:8 Max Tx-Slot/TDMA:6 Max-Sum-Slot/TDMA:NA Tta:3 Ttb:b) Tra:2 Trb:c) Type:1 (b: 1 with frequency hopping or change from Rx to Tx, 0 otherwise; c: 1 with frequency hopping or change from Tx to Rx, 0 otherwise", /* 28 */
9320         "Max Rx-Slot/TDMA:8 Max Tx-Slot/TDMA:8 Max-Sum-Slot/TDMA:NA Tta:3 Ttb:b) Tra:2 Trb:c) Type:1 (b: 1 with frequency hopping or change from Rx to Tx, 0 otherwise; c: 1 with frequency hopping or change from Tx to Rx, 0 otherwise", /* 29 */
9321         "Max Rx-Slot/TDMA:5 Max Tx-Slot/TDMA:1 Max-Sum-Slot/TDMA:6 Tta:2 Ttb:1 Tra:1 Trb:1 Type:1", /* 30 */
9322         "Max Rx-Slot/TDMA:5 Max Tx-Slot/TDMA:2 Max-Sum-Slot/TDMA:6 Tta:2 Ttb:1 Tra:1 Trb:1 Type:1", /* 31 */
9323         "Max Rx-Slot/TDMA:5 Max Tx-Slot/TDMA:3 Max-Sum-Slot/TDMA:6 Tta:2 Ttb:1 Tra:1 Trb:1 Type:1", /* 32 */
9324         "Max Rx-Slot/TDMA:5 Max Tx-Slot/TDMA:4 Max-Sum-Slot/TDMA:6 Tta:2 Ttb:1 Tra:1 Trb:1 Type:1", /* 33 */
9325         "Max Rx-Slot/TDMA:5 Max Tx-Slot/TDMA:5 Max-Sum-Slot/TDMA:6 Tta:2 Ttb:1 Tra:1 Trb:1 Type:1", /* 34 */
9326         "Max Rx-Slot/TDMA:5 Max Tx-Slot/TDMA:1 Max-Sum-Slot/TDMA:6 Tta:2 Ttb:1 Tra:1+to Trb:1 Type:1 (to: to = 31 symbol periods (this can be provided by a TA offset, i.e. a minimum TA value))", /* 35 */
9327         "Max Rx-Slot/TDMA:5 Max Tx-Slot/TDMA:2 Max-Sum-Slot/TDMA:6 Tta:2 Ttb:1 Tra:1+to Trb:1 Type:1 (to: to = 31 symbol periods (this can be provided by a TA offset, i.e. a minimum TA value))", /* 36 */
9328         "Max Rx-Slot/TDMA:5 Max Tx-Slot/TDMA:3 Max-Sum-Slot/TDMA:6 Tta:2 Ttb:1 Tra:1+to Trb:1 Type:1 (to: to = 31 symbol periods (this can be provided by a TA offset, i.e. a minimum TA value))", /* 37 */
9329         "Max Rx-Slot/TDMA:5 Max Tx-Slot/TDMA:4 Max-Sum-Slot/TDMA:6 Tta:2 Ttb:1 Tra:1+to Trb:1 Type:1 (to: to = 31 symbol periods (this can be provided by a TA offset, i.e. a minimum TA value))", /* 38 */
9330         "Max Rx-Slot/TDMA:5 Max Tx-Slot/TDMA:5 Max-Sum-Slot/TDMA:6 Tta:2 Ttb:1 Tra:1+to Trb:1 Type:1 (to: to = 31 symbol periods (this can be provided by a TA offset, i.e. a minimum TA value))", /* 39 */
9331         "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:1 Max-Sum-Slot/TDMA:7 Tta:1 Ttb:1 Tra:1 Trb:to Type:1 (to: to = 31 symbol periods (this can be provided by a TA offset, i.e. a minimum TA value))", /* 40 */
9332         "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:2 Max-Sum-Slot/TDMA:7 Tta:1 Ttb:1 Tra:1 Trb:to Type:1 (to: to = 31 symbol periods (this can be provided by a TA offset, i.e. a minimum TA value))", /* 41 */
9333         "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:3 Max-Sum-Slot/TDMA:7 Tta:1 Ttb:1 Tra:1 Trb:to Type:1 (to: to = 31 symbol periods (this can be provided by a TA offset, i.e. a minimum TA value))", /* 42 */
9334         "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:4 Max-Sum-Slot/TDMA:7 Tta:1 Ttb:1 Tra:1 Trb:to Type:1 (to: to = 31 symbol periods (this can be provided by a TA offset, i.e. a minimum TA value))", /* 43 */
9335         "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:5 Max-Sum-Slot/TDMA:7 Tta:1 Ttb:1 Tra:1 Trb:to Type:1 (to: to = 31 symbol periods (this can be provided by a TA offset, i.e. a minimum TA value))", /* 44 */
9336         "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:6 Max-Sum-Slot/TDMA:7 Tta:1 Ttb:1 Tra:1 Trb:to Type:1 (to: to = 31 symbol periods (this can be provided by a TA offset, i.e. a minimum TA value))", /* 45 */
9337         "Not specified", /* 46 */
9338         "Not specified", /* 47 */
9339         "Not specified", /* 48 */
9340         "Not specified", /* 49 */
9341         "Not specified", /* 50 */
9342         "Not specified", /* 51 */
9343         "Not specified", /* 52 */
9344         "Not specified", /* 53 */
9345         "Not specified", /* 54 */
9346         "Not specified", /* 55 */
9347         "Not specified", /* 56 */
9348         "Not specified", /* 57 */
9349         "Not specified", /* 58 */
9350         "Not specified", /* 59 */
9351         "Not specified", /* 60 */
9352         "Not specified", /* 61 */
9353         "Not specified", /* 62 */
9354         "Not specified", /* 63 */
9355         };
9356     guint index = 0;
9357     guchar dtm_gprs_mslot = 0;
9358     guchar dtm_egprs_mslot = 4;
9359     gboolean finished = TRUE;
9360     
9361     curr_len = len;
9362     curr_offset = offset;
9363
9364     bits_in_oct = 0;
9365     oct = 0;
9366
9367     do
9368     {
9369         /* check for a new round */
9370         if (( curr_len*8 + bits_in_oct ) < 11 )
9371                 break;
9372
9373         /* now read the first 11 bits */
9374         curr_bits_length = 11;  
9375         /*
9376          *
9377          */
9378         if ( curr_len != len )
9379         {
9380                 bits_needed = 1;
9381                 GET_DATA;
9382
9383                 if (( oct>>(32-bits_needed) ) == 1 )
9384                 {
9385                         curr_bits_length -= bits_needed;
9386                         oct <<= bits_needed;
9387                         bits_in_oct -= bits_needed;
9388                         
9389                         if (( curr_len*8 + bits_in_oct ) < 11 )
9390                                 break;
9391                         curr_bits_length = 11;
9392                 }
9393                 else
9394                 {
9395                         curr_bits_length -= bits_needed;
9396                         oct <<= bits_needed;
9397                         bits_in_oct -= bits_needed;
9398                         break;
9399                 }
9400         }
9401
9402         index++;
9403         tf = proto_tree_add_text(tree,
9404                 tvb, curr_offset, 1,
9405                 "MS RA capability %d",index);
9406
9407         tf_tree = proto_item_add_subtree(tf, ett_gmm_radio_cap );
9408
9409         /*
9410          * Access Technology
9411          */
9412         bits_needed = 4;
9413         GET_DATA;
9414         
9415         acc_type = oct>>(32-bits_needed);
9416         switch ( acc_type )
9417         {
9418                 case 0x00: str="GSM P"; break;
9419                 case 0x01: str="GSM E --note that GSM E covers GSM P"; break;
9420                 case 0x02: str="GSM R --note that GSM R covers GSM E and GSM P"; break;
9421                 case 0x03: str="GSM 1800"; break;
9422                 case 0x04: str="GSM 1900"; break;
9423                 case 0x05: str="GSM 450"; break;
9424                 case 0x06: str="GSM 480"; break;
9425                 case 0x07: str="GSM 850"; break;
9426                 case 0x08: str="GSM 700"; break;
9427                 case 0x0f: str="Indicates the presence of a list of Additional access technologies"; break;
9428                 default: str="unknown";
9429          }
9430
9431         proto_tree_add_text(tf_tree,
9432                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9433                 "Access Technology Type: (%u) %s",acc_type,str);
9434         curr_bits_length -= bits_needed;
9435         oct <<= bits_needed;
9436         bits_in_oct -= bits_needed;
9437         
9438         /*
9439          * get bits_length
9440          */
9441         bits_needed = 7;
9442         GET_DATA;
9443         
9444         bits_length = curr_bits_length = oct>>(32-bits_needed);
9445         proto_tree_add_text(tf_tree,
9446                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9447                 "Length: 0x%02x bits (%u)",bits_length,bits_length);
9448         /* This is already done - length doesn't contain this field
9449          curr_bits_length -= bits_needed;
9450         */
9451         oct <<= bits_needed;
9452         bits_in_oct -= bits_needed;
9453
9454         if ( acc_type == 0x0f )
9455         {
9456                 do 
9457                 {
9458                 /*
9459                  * Additional access technologies:
9460                  */
9461                         finished = TRUE; /* Break out of the loop unless proven unfinished */
9462
9463                         /*
9464                          * Presence bit
9465                          */
9466                         bits_needed = 1;
9467                         GET_DATA;
9468
9469                         /* analyse bits */
9470                         switch ( oct>>(32-bits_needed) )
9471                         {
9472                                 case 0x00: str="Not Present"; finished = TRUE; break;
9473                                 case 0x01: str="Present"; finished = FALSE; break;
9474                                 default: str="This should not happen";
9475                         }
9476
9477                         proto_tree_add_text(tf_tree,
9478                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9479                                 "Presence: (%u) %s",oct>>(32-bits_needed),str);
9480                         curr_bits_length -= bits_needed;
9481                         oct <<= bits_needed;
9482                         bits_in_oct -= bits_needed;
9483
9484                         if (finished)
9485                         {
9486                                 /*
9487                                  * No more valid data, get spare bits if any
9488                                  */
9489                                 while ( curr_bits_length > 0 )
9490                                 {
9491                                         if ( curr_bits_length > 8 )
9492                                                 bits_needed = 8;
9493                                         else
9494                                                 bits_needed = curr_bits_length;
9495                                         GET_DATA;
9496                                         curr_bits_length -= bits_needed;
9497                                         oct <<= bits_needed;
9498                                         bits_in_oct -= bits_needed;
9499                                 }
9500                                 continue;
9501                         }
9502
9503                 /*
9504                  * Access Technology
9505                  */
9506                 bits_needed = 4;
9507                 GET_DATA;
9508         
9509                 acc_type = oct>>(32-bits_needed);
9510                 switch ( acc_type )
9511                 {
9512                         case 0x00: str="GSM P"; break;
9513                         case 0x01: str="GSM E --note that GSM E covers GSM P"; break;
9514                         case 0x02: str="GSM R --note that GSM R covers GSM E and GSM P"; break;
9515                         case 0x03: str="GSM 1800"; break;
9516                         case 0x04: str="GSM 1900"; break;
9517                         case 0x05: str="GSM 450"; break;
9518                         case 0x06: str="GSM 480"; break;
9519                         case 0x07: str="GSM 850"; break;
9520                         case 0x08: str="GSM 700"; break;
9521                         case 0x0f: str="Indicates the presence of a list of Additional access technologies"; break;
9522                         default: str="unknown";
9523                  }
9524
9525                 proto_tree_add_text(tf_tree,
9526                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9527                         "Access Technology Type: (%u) %s",acc_type,str);
9528                 curr_bits_length -= bits_needed;
9529                 oct <<= bits_needed;
9530                 bits_in_oct -= bits_needed;
9531
9532                 /*
9533                  * RF Power
9534                  */
9535                 bits_needed = 3;
9536                 GET_DATA;
9537
9538                 /* analyse bits */
9539                 if ( acc_type == 0x04 ) /* GSM 1900 */
9540                 {
9541                         switch ( oct>>(32-bits_needed) )
9542                         {
9543                                 case 0x01: str="1 W (30 dBm)"; break;
9544                                 case 0x02: str="0,25 W (24 dBm)"; break;
9545                                 case 0x03: str="2 W (33 dBm)"; break;
9546                                 default: str="Not specified";
9547                         }
9548                 }
9549                 else if ( acc_type == 0x03 )
9550                 {
9551                         switch ( oct>>(32-bits_needed) )
9552                         {
9553                                 case 0x01: str="1 W (30 dBm)"; break;
9554                                 case 0x02: str="0,25 W (24 dBm)"; break;
9555                                 case 0x03: str="4 W (36 dBm)"; break;
9556                                 default: str="Not specified";
9557                         }
9558                 }
9559                 else if ( acc_type <= 0x08 )
9560                 {
9561                         switch ( oct>>(32-bits_needed) )
9562                         {
9563                                 case 0x02: str="8 W (39 dBm)"; break;
9564                                 case 0x03: str="5 W (37 dBm)"; break;
9565                                 case 0x04: str="2 W (33 dBm)"; break;
9566                                 case 0x05: str="0,8 W (29 dBm)"; break;
9567                                 default: str="Not specified";
9568                         }
9569                 }
9570                 else
9571                         str="Not specified??";
9572     
9573                 proto_tree_add_text(tf_tree,
9574                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9575                         "RF Power Capability, GMSK Power Class: (%u) %s",oct>>(32-bits_needed),str);
9576                 curr_bits_length -= bits_needed;
9577                 oct <<= bits_needed;
9578                 bits_in_oct -= bits_needed;
9579
9580                 /*
9581                  * 8PSK Power Class
9582                  */
9583                 bits_needed = 2;
9584                 GET_DATA;
9585
9586                 /* analyse bits */
9587                 switch ( oct>>(32-bits_needed) )
9588                 {
9589                         case 0x00: str="8PSK modulation not supported for uplink"; break;
9590                         case 0x01: str="Power class E1"; break;
9591                         case 0x02: str="Power class E2"; break;
9592                         case 0x03: str="Power class E3"; break;
9593                         default: str="This should not happen";
9594                 }
9595     
9596                 proto_tree_add_text(tf_tree,
9597                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9598                         "8PSK Power Class: (%u) %s",oct>>(32-bits_needed),str);
9599                 curr_bits_length -= bits_needed;
9600                 oct <<= bits_needed;
9601                 bits_in_oct -= bits_needed;
9602
9603                 } while (!finished);
9604                 
9605                 /* goto next one */
9606                 continue;
9607         }
9608         /*
9609          * RF Power
9610          */
9611         bits_needed = 3;
9612         GET_DATA;
9613
9614         /* analyse bits */
9615         if ( acc_type == 0x04 ) /* GSM 1900 */
9616         {
9617                 switch ( oct>>(32-bits_needed) )
9618                 {
9619                         case 0x01: str="1 W (30 dBm)"; break;
9620                         case 0x02: str="0,25 W (24 dBm)"; break;
9621                         case 0x03: str="2 W (33 dBm)"; break;
9622                         default: str="Not specified";
9623                 }
9624         }
9625         else if ( acc_type == 0x03 )
9626         {
9627                 switch ( oct>>(32-bits_needed) )
9628                 {
9629                         case 0x01: str="1 W (30 dBm)"; break;
9630                         case 0x02: str="0,25 W (24 dBm)"; break;
9631                         case 0x03: str="4 W (36 dBm)"; break;
9632                         default: str="Not specified";
9633                 }
9634         }
9635         else if ( acc_type <= 0x08 )
9636         {
9637                 switch ( oct>>(32-bits_needed) )
9638                 {
9639                         case 0x02: str="8 W (39 dBm)"; break;
9640                         case 0x03: str="5 W (37 dBm)"; break;
9641                         case 0x04: str="2 W (33 dBm)"; break;
9642                         case 0x05: str="0,8 W (29 dBm)"; break;
9643                         default: str="Not specified";
9644                 }
9645         }
9646         else
9647                 str="Not specified??";
9648     
9649         proto_tree_add_text(tf_tree,
9650                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9651                 "RF Power Capability, GMSK Power Class: (%u) %s",oct>>(32-bits_needed),str);
9652         curr_bits_length -= bits_needed;
9653         oct <<= bits_needed;
9654         bits_in_oct -= bits_needed;
9655
9656         /*
9657          * A5 Bits?
9658          */
9659         bits_needed = 1;
9660         GET_DATA;
9661
9662         /* analyse bits */
9663         if ((oct>>(32-bits_needed))==0)
9664         {
9665                 proto_tree_add_text(tf_tree,
9666                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9667                         "A5 Bits: (%u) same values apply for parameters as in the immediately preceding Access capabilities field within this IE",oct>>(32-bits_needed));
9668                 curr_bits_length -= bits_needed;
9669                 oct <<= bits_needed;
9670                 bits_in_oct -= bits_needed;
9671         }
9672         else
9673         {
9674                 int i;
9675
9676                 proto_tree_add_text(tf_tree,
9677                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9678                         "A5 Bits: (%u) A5 bits follows",oct>>(32-bits_needed));
9679
9680                 curr_bits_length -= bits_needed;
9681                 oct <<= bits_needed;
9682                 bits_in_oct -= bits_needed;
9683                 
9684                 for (i=1; i<= 7 ; i++ )
9685                 {
9686                         /*
9687                          * A5 Bits decoding
9688                          */
9689                         bits_needed = 1;
9690                         GET_DATA;
9691
9692                         /* analyse bits */
9693                         switch ( oct>>(32-bits_needed) )
9694                         {
9695                                 case 0x00: str="encryption algorithm not available"; break;
9696                                 case 0x01: str="encryption algorithm available"; break;
9697                                 default: str="This should not happen";
9698                         }
9699     
9700                         proto_tree_add_text(tf_tree,
9701                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9702                                 "A5/%d: (%u) %s",i,oct>>(32-bits_needed),str);
9703                         curr_bits_length -= bits_needed;
9704                         oct <<= bits_needed;
9705                         bits_in_oct -= bits_needed;
9706                 }
9707         }
9708     
9709         /*
9710          * ES IND
9711          */
9712         bits_needed = 1;
9713         GET_DATA;
9714
9715         /* analyse bits */
9716         switch ( oct>>(32-bits_needed) )
9717         {
9718                 case 0x00: str="controlled early Classmark Sending option is not implemented"; break;
9719                 case 0x01: str="controlled early Classmark Sending option is implemented"; break;
9720                 default: str="This should not happen";
9721         }
9722     
9723         proto_tree_add_text(tf_tree,
9724                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9725                 "Controlled early Classmark Sending: (%u) %s",oct>>(32-bits_needed),str);
9726         curr_bits_length -= bits_needed;
9727         oct <<= bits_needed;
9728         bits_in_oct -= bits_needed;
9729
9730         /*
9731          * PS
9732          */
9733         bits_needed = 1;
9734         GET_DATA;
9735
9736         /* analyse bits */
9737         switch ( oct>>(32-bits_needed) )
9738         {
9739                 case 0x00: str="PS capability not present"; break;
9740                 case 0x01: str="PS capability present"; break;
9741                 default: str="This should not happen";
9742         }
9743     
9744         proto_tree_add_text(tf_tree,
9745                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9746                 "Pseudo Synchronisation: (%u) %s",oct>>(32-bits_needed),str);
9747         curr_bits_length -= bits_needed;
9748         oct <<= bits_needed;
9749         bits_in_oct -= bits_needed;
9750
9751         /*
9752          * VGCS
9753          */
9754         bits_needed = 1;
9755         GET_DATA;
9756
9757         /* analyse bits */
9758         switch ( oct>>(32-bits_needed) )
9759         {
9760                 case 0x00: str="no VGCS capability or no notifications wanted"; break;
9761                 case 0x01: str="VGCS capability and notifications wanted"; break;
9762                 default: str="This should not happen";
9763         }
9764     
9765         proto_tree_add_text(tf_tree,
9766                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9767                 "Voice Group Call Service: (%u) %s",oct>>(32-bits_needed),str);
9768         curr_bits_length -= bits_needed;
9769         oct <<= bits_needed;
9770         bits_in_oct -= bits_needed;
9771
9772         /*
9773          * VBS
9774          */
9775         bits_needed = 1;
9776         GET_DATA;
9777
9778         /* analyse bits */
9779         switch ( oct>>(32-bits_needed) )
9780         {
9781                 case 0x00: str="no VBS capability or no notifications wanted"; break;
9782                 case 0x01: str="VBS capability and notifications wanted"; break;
9783                 default: str="This should not happen";
9784         }
9785     
9786         proto_tree_add_text(tf_tree,
9787                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9788                 "Voice Broadcast Service: (%u) %s",oct>>(32-bits_needed),str);
9789         curr_bits_length -= bits_needed;
9790         oct <<= bits_needed;
9791         bits_in_oct -= bits_needed;
9792
9793         /*
9794          * Multislot capability?
9795          */
9796         bits_needed = 1;
9797         GET_DATA;
9798
9799         /* analyse bits */
9800         if ((oct>>(32-bits_needed))==0)
9801         {
9802                 proto_tree_add_text(tf_tree,
9803                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9804                         "Multislot capability: (%u) same values apply for parameters as in the immediately preceding Access capabilities field within this IE",oct>>(32-bits_needed));
9805                 curr_bits_length -= bits_needed;
9806                 oct <<= bits_needed;
9807                 bits_in_oct -= bits_needed;
9808         }
9809         else
9810         {
9811                 proto_tree_add_text(tf_tree,
9812                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9813                         "Multislot capability: (%u) Multislot capability struct available",oct>>(32-bits_needed));
9814
9815                 curr_bits_length -= bits_needed;
9816                 oct <<= bits_needed;
9817                 bits_in_oct -= bits_needed;
9818
9819                 /*
9820                  * HSCSD multislot class?
9821                  */
9822                 bits_needed = 1;
9823                 GET_DATA;
9824
9825                 /* analyse bits */
9826                 if ((oct>>(32-bits_needed))==0)
9827                 {
9828                         proto_tree_add_text(tf_tree,
9829                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9830                                 "HSCSD multislot class: (%u) Bits are not available",oct>>(32-bits_needed));
9831                         curr_bits_length -= bits_needed;
9832                         oct <<= bits_needed;
9833                         bits_in_oct -= bits_needed;
9834                 }
9835                 else
9836                 {
9837                         curr_bits_length -= bits_needed;
9838                         oct <<= bits_needed;
9839                         bits_in_oct -= bits_needed;
9840
9841                         /*
9842                          * HSCSD multislot class
9843                          */
9844                         bits_needed = 5;
9845                         GET_DATA;
9846
9847                         /* analyse bits */
9848                         proto_tree_add_text(tf_tree,
9849                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9850                                 "HSCSD multislot class: (%u) %s",oct>>(32-bits_needed),multi_slot_str[oct>>(32-bits_needed)]);
9851                         curr_bits_length -= bits_needed;
9852                         oct <<= bits_needed;
9853                         bits_in_oct -= bits_needed;
9854                 }
9855
9856                 /*
9857                  * GPRS multislot class?
9858                  */
9859                 bits_needed = 1;
9860                 GET_DATA;
9861
9862                 /* analyse bits */
9863                 if ((oct>>(32-bits_needed))==0)
9864                 {
9865                         proto_tree_add_text(tf_tree,
9866                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9867                                 "GPRS multislot class: (%u) Bits are not available",oct>>(32-bits_needed));
9868                         curr_bits_length -= bits_needed;
9869                         oct <<= bits_needed;
9870                         bits_in_oct -= bits_needed;
9871                 }
9872                 else
9873                 {
9874                         curr_bits_length -= bits_needed;
9875                         oct <<= bits_needed;
9876                         bits_in_oct -= bits_needed;
9877
9878                         /*
9879                          * GPRS multislot class
9880                          */
9881                         bits_needed = 5;
9882                         GET_DATA;
9883
9884                         /* analyse bits */
9885                         proto_tree_add_text(tf_tree,
9886                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9887                                 "GPRS multislot class: (%u) %s",oct>>(32-bits_needed),multi_slot_str[oct>>(32-bits_needed)]);
9888                         curr_bits_length -= bits_needed;
9889                         oct <<= bits_needed;
9890                         bits_in_oct -= bits_needed;
9891
9892                         /*
9893                          * GPRS Extended Dynamic Allocation Capability
9894                          */
9895                         bits_needed = 1;
9896                         GET_DATA;
9897
9898                         /* analyse bits */
9899                         switch ( oct>>(32-bits_needed) )
9900                         {
9901                                 case 0x00: str="Extended Dynamic Allocation Capability for GPRS is not implemented"; break;
9902                                 case 0x01: str="Extended Dynamic Allocation Capability for GPRS is implemented"; break;
9903                                 default: str="This should not happen";
9904                         }
9905                         proto_tree_add_text(tf_tree,
9906                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9907                                 "GPRS Extended Dynamic Allocation Capability: (%u) %s",oct>>(32-bits_needed),str);
9908                         curr_bits_length -= bits_needed;
9909                         oct <<= bits_needed;
9910                         bits_in_oct -= bits_needed;
9911                 }
9912
9913                 /*
9914                  * SMS/SM values
9915                  */
9916                 bits_needed = 1;
9917                 GET_DATA;
9918
9919                 /* analyse bits */
9920                 if ((oct>>(32-bits_needed))==0)
9921                 {
9922                         proto_tree_add_text(tf_tree,
9923                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9924                                 "SMS/SM values: (%u) Bits are not available",oct>>(32-bits_needed));
9925                         curr_bits_length -= bits_needed;
9926                         oct <<= bits_needed;
9927                         bits_in_oct -= bits_needed;
9928                 }
9929                 else
9930                 {
9931                         curr_bits_length -= bits_needed;
9932                         oct <<= bits_needed;
9933                         bits_in_oct -= bits_needed;
9934
9935                         /*
9936                          * Switch-Measure-Switch value
9937                          */
9938                         bits_needed = 4;
9939                         GET_DATA;
9940
9941                         /* analyse bits */
9942                         proto_tree_add_text(tf_tree,
9943                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9944                                 "Switch-Measure-Switch value: (%u) %d/4 timeslot (~%d microseconds)",
9945                                 oct>>(32-bits_needed),oct>>(32-bits_needed),(oct>>(32-bits_needed))*144);
9946                         curr_bits_length -= bits_needed;
9947                         oct <<= bits_needed;
9948                         bits_in_oct -= bits_needed;
9949
9950                         /*
9951                          * Switch-Measure value
9952                          */
9953                         bits_needed = 4;
9954                         GET_DATA;
9955
9956                         /* analyse bits */
9957                         proto_tree_add_text(tf_tree,
9958                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9959                                 "Switch-Measure value: (%u) %d/4 timeslot (~%d microseconds)",
9960                                 oct>>(32-bits_needed),oct>>(32-bits_needed),(oct>>(32-bits_needed))*144);
9961                         curr_bits_length -= bits_needed;
9962                         oct <<= bits_needed;
9963                         bits_in_oct -= bits_needed;
9964                 }
9965
9966                 /*
9967                  * ECSD multislot class?
9968                  */
9969                 bits_needed = 1;
9970                 GET_DATA;
9971
9972                 /* analyse bits */
9973                 if ((oct>>(32-bits_needed))==0)
9974                 {
9975                         proto_tree_add_text(tf_tree,
9976                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9977                                 "ECSD multislot class: (%u) Bits are not available",oct>>(32-bits_needed));
9978                         curr_bits_length -= bits_needed;
9979                         oct <<= bits_needed;
9980                         bits_in_oct -= bits_needed;
9981                 }
9982                 else
9983                 {
9984                         curr_bits_length -= bits_needed;
9985                         oct <<= bits_needed;
9986                         bits_in_oct -= bits_needed;
9987
9988                         /*
9989                          * ECSD multislot class
9990                          */
9991                         bits_needed = 5;
9992                         GET_DATA;
9993
9994                         /* analyse bits */
9995                         proto_tree_add_text(tf_tree,
9996                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
9997                                 "ECSD multislot class: (%u) %s",oct>>(32-bits_needed),multi_slot_str[oct>>(32-bits_needed)]);
9998                         curr_bits_length -= bits_needed;
9999                         oct <<= bits_needed;
10000                         bits_in_oct -= bits_needed;
10001                 }
10002
10003                 /*
10004                  * EGPRS multislot class?
10005                  */
10006                 bits_needed = 1;
10007                 GET_DATA;
10008
10009                 /* analyse bits */
10010                 if ((oct>>(32-bits_needed))==0)
10011                 {
10012                         proto_tree_add_text(tf_tree,
10013                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10014                                 "EGPRS multislot class: (%u) Bits are not available",oct>>(32-bits_needed));
10015                         curr_bits_length -= bits_needed;
10016                         oct <<= bits_needed;
10017                         bits_in_oct -= bits_needed;
10018                 }
10019                 else
10020                 {
10021                         curr_bits_length -= bits_needed;
10022                         oct <<= bits_needed;
10023                         bits_in_oct -= bits_needed;
10024
10025                         /*
10026                          * EGPRS multislot class
10027                          */
10028                         bits_needed = 5;
10029                         GET_DATA;
10030
10031                         /* analyse bits */
10032                         proto_tree_add_text(tf_tree,
10033                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10034                                 "EGPRS multislot class: (%u) %s",oct>>(32-bits_needed),multi_slot_str[oct>>(32-bits_needed)]);
10035                         curr_bits_length -= bits_needed;
10036                         oct <<= bits_needed;
10037                         bits_in_oct -= bits_needed;
10038
10039                         /*
10040                          * EGPRS Extended Dynamic Allocation Capability
10041                          */
10042                         bits_needed = 1;
10043                         GET_DATA;
10044
10045                         /* analyse bits */
10046                         switch ( oct>>(32-bits_needed) )
10047                         {
10048                                 case 0x00: str="Extended Dynamic Allocation Capability for EGPRS is not implemented"; break;
10049                                 case 0x01: str="Extended Dynamic Allocation Capability for EGPRS is implemented"; break;
10050                                 default: str="This should not happen";
10051                         }
10052                         proto_tree_add_text(tf_tree,
10053                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10054                                 "EGPRS Extended Dynamic Allocation Capability: (%u) %s",oct>>(32-bits_needed),str);
10055                         curr_bits_length -= bits_needed;
10056                         oct <<= bits_needed;
10057                         bits_in_oct -= bits_needed;
10058                 }
10059
10060                 /*
10061                  * DTM GPRS Multi Slot Class ?
10062                 */
10063                 bits_needed = 1;
10064                 GET_DATA;
10065
10066                 /* analyse bits */
10067                 if ((oct>>(32-bits_needed))==0)
10068                 {
10069                         proto_tree_add_text(tf_tree,
10070                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10071                                 "DTM GPRS Multi Slot Class: (%u) Bits are not available",oct>>(32-bits_needed));
10072                         curr_bits_length -= bits_needed;
10073                         oct <<= bits_needed;
10074                         bits_in_oct -= bits_needed;
10075                 }
10076                 else
10077                 {
10078                         curr_bits_length -= bits_needed;
10079                         oct <<= bits_needed;
10080                         bits_in_oct -= bits_needed;
10081
10082                         /*
10083                          * DTM GPRS Multi Slot Class
10084                          */
10085                         bits_needed = 2;
10086                         GET_DATA;
10087
10088                         /* analyse bits */
10089                         dtm_gprs_mslot = oct>>(32-bits_needed);
10090
10091                         switch ( oct>>(32-bits_needed) )
10092                         {
10093                                 case 0: str="Unused. If received, the network shall interpret this as Multislot class 5"; break;
10094                                 case 1: str="Multislot class 5 supported"; break;
10095                                 case 2: str="Multislot class 9 supported"; break;
10096                                 case 3: str="Multislot class 11 supported"; break;
10097                                 default: str="This should not happen";
10098                         }
10099                         
10100                         proto_tree_add_text(tf_tree,
10101                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10102                                 "DTM GPRS Multi Slot Class: (%u) %s",oct>>(32-bits_needed),str);
10103                         curr_bits_length -= bits_needed;
10104                         oct <<= bits_needed;
10105                         bits_in_oct -= bits_needed;
10106
10107                         /*
10108                          * Single Slot DTM
10109                          */
10110                         bits_needed = 1;
10111                         GET_DATA;
10112
10113                         /* analyse bits */
10114                         switch ( oct>>(32-bits_needed) )
10115                         {
10116                                 case 0x00: str="Single Slot DTM not supported"; break;
10117                                 case 0x01: str="Single Slot DTM supported"; break;
10118                                 default: str="This should not happen";
10119                         }
10120                         proto_tree_add_text(tf_tree,
10121                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10122                                 "Single Slot DTM: (%u) %s",oct>>(32-bits_needed),str);
10123                         curr_bits_length -= bits_needed;
10124                         oct <<= bits_needed;
10125                         bits_in_oct -= bits_needed;
10126
10127                         /*
10128                          * DTM EGPRS Multi Slot Class ?
10129                         */
10130                         bits_needed = 1;
10131                         GET_DATA;
10132
10133                         /* analyse bits */
10134                         dtm_egprs_mslot = oct>>(32-bits_needed);
10135
10136                         if ((oct>>(32-bits_needed))==0)
10137                         {
10138                                 proto_tree_add_text(tf_tree,
10139                                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10140                                         "DTM EGPRS Multi Slot Class: (%u) Bits are not available",oct>>(32-bits_needed));
10141                                 curr_bits_length -= bits_needed;
10142                                 oct <<= bits_needed;
10143                                 bits_in_oct -= bits_needed;
10144                         }
10145                         else
10146                         {
10147                                 curr_bits_length -= bits_needed;
10148                                 oct <<= bits_needed;
10149                                 bits_in_oct -= bits_needed;
10150
10151                                 /*
10152                                  * DTM EGPRS Multi Slot Class
10153                                  */
10154                                 bits_needed = 2;
10155                                 GET_DATA;
10156
10157                                 /* analyse bits */
10158                                 switch ( oct>>(32-bits_needed) )
10159                                 {
10160                                         case 0: str="Unused. If received, the network shall interpret this as Multislot class 5"; break;
10161                                         case 1: str="Multislot class 5 supported"; break;
10162                                         case 2: str="Multislot class 9 supported"; break;
10163                                         case 3: str="Multislot class 11 supported"; break;
10164                                         default: str="This should not happen";
10165                                 }
10166                         
10167                                 proto_tree_add_text(tf_tree,
10168                                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10169                                         "DTM EGPRS Multi Slot Class: (%u) %s",oct>>(32-bits_needed),str);
10170                                 curr_bits_length -= bits_needed;
10171                                 oct <<= bits_needed;
10172                                 bits_in_oct -= bits_needed;
10173                         }
10174                 }
10175         }
10176
10177         /*
10178          * 8PSK Power Capability?
10179          */
10180         bits_needed = 1;
10181         GET_DATA;
10182
10183         /* analyse bits */
10184         if ((oct>>(32-bits_needed))==0)
10185         {
10186                 proto_tree_add_text(tf_tree,
10187                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10188                         "8PSK Power Capability: (%u) Bits are not available",oct>>(32-bits_needed));
10189                 curr_bits_length -= bits_needed;
10190                 oct <<= bits_needed;
10191                 bits_in_oct -= bits_needed;
10192         }
10193         else
10194         {
10195                 curr_bits_length -= bits_needed;
10196                 oct <<= bits_needed;
10197                 bits_in_oct -= bits_needed;
10198
10199                 /*
10200                  * 8PSK Power Capability
10201                  */
10202                 bits_needed = 2;
10203                 GET_DATA;
10204
10205                 /* analyse bits */
10206                 switch ( oct>>(32-bits_needed) )
10207                 {
10208                         case 0x00: str="Reserved"; break;
10209                         case 0x01: str="Power class E1"; break;
10210                         case 0x02: str="Power class E2"; break;
10211                         case 0x03: str="Power class E3"; break;
10212                         default: str="This should not happen";
10213                 }
10214     
10215                 proto_tree_add_text(tf_tree,
10216                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10217                         "8PSK Power Capability: (%u) %s",oct>>(32-bits_needed),str);
10218                 curr_bits_length -= bits_needed;
10219                 oct <<= bits_needed;
10220                 bits_in_oct -= bits_needed;
10221         }
10222
10223         /*
10224          * COMPACT Interference Measurement Capability
10225          */
10226         bits_needed = 1;
10227         GET_DATA;
10228
10229         /* analyse bits */
10230         switch ( oct>>(32-bits_needed) )
10231         {
10232                 case 0x00: str="COMPACT Interference Measurement Capability is not implemented"; break;
10233                 case 0x01: str="COMPACT Interference Measurement Capability is implemented"; break;
10234                 default: str="This should not happen";
10235         }
10236     
10237         proto_tree_add_text(tf_tree,
10238                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10239                 "COMPACT Interference Measurement Capability: (%u) %s",oct>>(32-bits_needed),str);
10240         curr_bits_length -= bits_needed;
10241         oct <<= bits_needed;
10242         bits_in_oct -= bits_needed;
10243
10244         /*
10245          * Revision Level Indicator
10246          */
10247         bits_needed = 1;
10248         GET_DATA;
10249
10250         /* analyse bits */
10251         switch ( oct>>(32-bits_needed) )
10252         {
10253                 case 0x00: str="The ME is Release 98 or older"; break;
10254                 case 0x01: str="The ME is Release 99 onwards"; break;
10255                 default: str="This should not happen";
10256         }
10257     
10258         proto_tree_add_text(tf_tree,
10259                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10260                 "Revision Level Indicator: (%u) %s",oct>>(32-bits_needed),str);
10261         curr_bits_length -= bits_needed;
10262         oct <<= bits_needed;
10263         bits_in_oct -= bits_needed;
10264
10265         /*
10266          * UMTS FDD Radio Access Technology Capability
10267          */
10268         bits_needed = 1;
10269         GET_DATA;
10270
10271         /* analyse bits */
10272         switch ( oct>>(32-bits_needed) )
10273         {
10274                 case 0x00: str="UMTS FDD not supported"; break;
10275                 case 0x01: str="UMTS FDD supported"; break;
10276                 default: str="This should not happen";
10277         }
10278     
10279         proto_tree_add_text(tf_tree,
10280                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10281                 "UMTS FDD Radio Access Technology Capability: (%u) %s",oct>>(32-bits_needed),str);
10282         curr_bits_length -= bits_needed;
10283         oct <<= bits_needed;
10284         bits_in_oct -= bits_needed;
10285
10286         /*
10287          * UMTS 3.84 Mcps TDD Radio Access Technology Capability
10288          */
10289         bits_needed = 1;
10290         GET_DATA;
10291
10292         /* analyse bits */
10293         switch ( oct>>(32-bits_needed) )
10294         {
10295                 case 0x00: str="UMTS 3.84 Mcps TDD not supported"; break;
10296                 case 0x01: str="UMTS 3.84 Mcps TDD supported"; break;
10297                 default: str="This should not happen";
10298         }
10299     
10300         proto_tree_add_text(tf_tree,
10301                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10302                 "UMTS 3.84 Mcps TDD Radio Access Technology Capability: (%u) %s",oct>>(32-bits_needed),str);
10303         curr_bits_length -= bits_needed;
10304         oct <<= bits_needed;
10305         bits_in_oct -= bits_needed;
10306
10307         /*
10308          * CDMA 2000 Radio Access Technology Capability
10309          */
10310         bits_needed = 1;
10311         GET_DATA;
10312
10313         /* analyse bits */
10314         switch ( oct>>(32-bits_needed) )
10315         {
10316                 case 0x00: str="CDMA 2000 not supported"; break;
10317                 case 0x01: str="CDMA 2000 supported"; break;
10318                 default: str="This should not happen";
10319         }
10320     
10321         proto_tree_add_text(tf_tree,
10322                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10323                 "CDMA 2000 Radio Access Technology Capability: (%u) %s",oct>>(32-bits_needed),str);
10324         curr_bits_length -= bits_needed;
10325         oct <<= bits_needed;
10326         bits_in_oct -= bits_needed;
10327
10328         /*
10329          * UMTS 1.28 Mcps TDD Radio Access Technology Capability
10330          */
10331         bits_needed = 1;
10332         GET_DATA;
10333
10334         /* analyse bits */
10335         switch ( oct>>(32-bits_needed) )
10336         {
10337                 case 0x00: str="UMTS 1.28 Mcps TDD not supported"; break;
10338                 case 0x01: str="UMTS 1.28 Mcps TDD supported"; break;
10339                 default: str="This should not happen";
10340         }
10341     
10342         proto_tree_add_text(tf_tree,
10343                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10344                 "UMTS 1.28 Mcps TDD Radio Access Technology Capability: (%u) %s",oct>>(32-bits_needed),str);
10345         curr_bits_length -= bits_needed;
10346         oct <<= bits_needed;
10347         bits_in_oct -= bits_needed;
10348
10349         /*
10350          * GERAN Feature Package 1
10351          */
10352         bits_needed = 1;
10353         GET_DATA;
10354
10355         /* analyse bits */
10356         switch ( oct>>(32-bits_needed) )
10357         {
10358                 case 0x00: str="GERAN feature package 1 not supported"; break;
10359                 case 0x01: str="GERAN feature package 1 supported"; break;
10360                 default: str="This should not happen";
10361         }
10362     
10363         proto_tree_add_text(tf_tree,
10364                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10365                 "GERAN Feature Package 1: (%u) %s",oct>>(32-bits_needed),str);
10366         curr_bits_length -= bits_needed;
10367         oct <<= bits_needed;
10368         bits_in_oct -= bits_needed;
10369
10370         /*
10371          * Extended DTM (E)GPRS Multi Slot Class
10372          */
10373         bits_needed = 1;
10374         GET_DATA;
10375
10376         /* analyse bits */
10377         if ((oct>>(32-bits_needed))==0)
10378         {
10379                 proto_tree_add_text(tf_tree,
10380                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10381                         "Extended DTM (E)GPRS Multi Slot Class: (%u) Bits are not available",oct>>(32-bits_needed));
10382                 curr_bits_length -= bits_needed;
10383                 oct <<= bits_needed;
10384                 bits_in_oct -= bits_needed;
10385         }
10386         else
10387         {
10388                 curr_bits_length -= bits_needed;
10389                 oct <<= bits_needed;
10390                 bits_in_oct -= bits_needed;
10391
10392                 /*
10393                  * Extended DTM GPRS Multi Slot Class
10394                  */
10395                 bits_needed = 2;
10396                 GET_DATA;
10397
10398                 /* analyse bits */
10399                 switch ( (oct>>(32-bits_needed))|(dtm_gprs_mslot<<4) )
10400                 {
10401                         case 0x00: str="Unused. If received, it shall be interpreted as Multislot class 5 supported"; break;
10402                         case 0x01: str="Unused. If received, it shall be interpreted as Multislot class 5 supported"; break;
10403                         case 0x02: str="Unused. If received, it shall be interpreted as Multislot class 5 supported"; break;
10404                         case 0x03: str="Unused. If received, it shall be interpreted as Multislot class 5 supported"; break;
10405                         case 0x10: str="Multislot class 5 supported"; break;
10406                         case 0x11: str="Multislot class 6 supported"; break;
10407                         case 0x12: str="Unused. If received, it shall be interpreted as Multislot class 5 supported"; break;
10408                         case 0x13: str="Unused. If received, it shall be interpreted as Multislot class 5 supported"; break;
10409                         case 0x20: str="Multislot class 9 supported"; break;
10410                         case 0x21: str="Multislot class 10 supported"; break;
10411                         case 0x22: str="Unused. If received, it shall be interpreted as Multislot class 9 supported"; break;
10412                         case 0x23: str="Unused. If received, it shall be interpreted as Multislot class 9 supported"; break;
10413                         case 0x30: str="Multislot class 11 supported"; break;
10414                         case 0x31: str="Unused. If received, it shall be interpreted as Multislot class 11 supported"; break;
10415                         case 0x32: str="Unused. If received, it shall be interpreted as Multislot class 11 supported"; break;
10416                         case 0x33: str="Unused. If received, it shall be interpreted as Multislot class 11 supported"; break;
10417                         default: str="This should not happen";
10418                 }
10419     
10420                 proto_tree_add_text(tf_tree,
10421                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10422                         "Extended DTM GPRS Multi Slot Class: (%u) %s",oct>>(32-bits_needed),str);
10423                 curr_bits_length -= bits_needed;
10424                 oct <<= bits_needed;
10425                 bits_in_oct -= bits_needed;
10426
10427                 if ( dtm_egprs_mslot <= 3 )
10428                 {
10429                         /*
10430                          * Extended DTM EGPRS Multi Slot Class
10431                          */
10432                         bits_needed = 2;
10433                         GET_DATA;
10434
10435                         /* analyse bits */
10436                         switch ( (oct>>(32-bits_needed))|(dtm_egprs_mslot<<4) )
10437                         {
10438                                 case 0x00: str="Unused. If received, it shall be interpreted as Multislot class 5 supported"; break;
10439                                 case 0x01: str="Unused. If received, it shall be interpreted as Multislot class 5 supported"; break;
10440                                 case 0x02: str="Unused. If received, it shall be interpreted as Multislot class 5 supported"; break;
10441                                 case 0x03: str="Unused. If received, it shall be interpreted as Multislot class 5 supported"; break;
10442                                 case 0x10: str="Multislot class 5 supported"; break;
10443                                 case 0x11: str="Multislot class 6 supported"; break;
10444                                 case 0x12: str="Unused. If received, it shall be interpreted as Multislot class 5 supported"; break;
10445                                 case 0x13: str="Unused. If received, it shall be interpreted as Multislot class 5 supported"; break;
10446                                 case 0x20: str="Multislot class 9 supported"; break;
10447                                 case 0x21: str="Multislot class 10 supported"; break;
10448                                 case 0x22: str="Unused. If received, it shall be interpreted as Multislot class 9 supported"; break;
10449                                 case 0x23: str="Unused. If received, it shall be interpreted as Multislot class 9 supported"; break;
10450                                 case 0x30: str="Multislot class 11 supported"; break;
10451                                 case 0x31: str="Unused. If received, it shall be interpreted as Multislot class 11 supported"; break;
10452                                 case 0x32: str="Unused. If received, it shall be interpreted as Multislot class 11 supported"; break;
10453                                 case 0x33: str="Unused. If received, it shall be interpreted as Multislot class 11 supported"; break;
10454                                 default: str="This should not happen";
10455                         }
10456     
10457                         proto_tree_add_text(tf_tree,
10458                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10459                                 "Extended DTM EGPRS Multi Slot Class: (%u) %s",oct>>(32-bits_needed),str);
10460                         curr_bits_length -= bits_needed;
10461                         oct <<= bits_needed;
10462                         bits_in_oct -= bits_needed;
10463                 }
10464         }
10465
10466         /*
10467          * Modulation based multislot class support
10468          */
10469         bits_needed = 1;
10470         GET_DATA;
10471
10472         /* analyse bits */
10473         switch ( oct>>(32-bits_needed) )
10474         {
10475                 case 0x00: str="Modulation based multislot class not supported"; break;
10476                 case 0x01: str="Modulation based multislot class supported"; break;
10477                 default: str="This should not happen";
10478         }
10479     
10480         proto_tree_add_text(tf_tree,
10481                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10482                 "Modulation based multislot class support: (%u) %s",oct>>(32-bits_needed),str);
10483         curr_bits_length -= bits_needed;
10484         oct <<= bits_needed;
10485         bits_in_oct -= bits_needed;
10486
10487         /*
10488          * High Multislot Capability
10489          */
10490         bits_needed = 1;
10491         GET_DATA;
10492
10493         /* analyse bits */
10494         if ((oct>>(32-bits_needed))==0)
10495         {
10496                 proto_tree_add_text(tf_tree,
10497                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10498                         "High Multislot Capability: (%u) Bits are not available",oct>>(32-bits_needed));
10499                 curr_bits_length -= bits_needed;
10500                 oct <<= bits_needed;
10501                 bits_in_oct -= bits_needed;
10502         }
10503         else
10504         {
10505                 curr_bits_length -= bits_needed;
10506                 oct <<= bits_needed;
10507                 bits_in_oct -= bits_needed;
10508
10509                 /*
10510                  * High Multislot Capability
10511                  */
10512                 bits_needed = 2;
10513                 GET_DATA;
10514
10515                 /* analyse bits */
10516                 proto_tree_add_text(tf_tree,
10517                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10518                         "High Multislot Capability: 0x%02x (%u) - This field effect all other multislot fields. To understand the value please read TS 24.008 5.6.0 Release 5 Chap 10.5.5.12 Page 406",oct>>(32-bits_needed),oct>>(32-bits_needed));
10519                 curr_bits_length -= bits_needed;
10520                 oct <<= bits_needed;
10521                 bits_in_oct -= bits_needed;
10522
10523         }
10524
10525         /*
10526          * GERAN Iu Mode Capability
10527          */
10528         bits_needed = 1;
10529         GET_DATA;
10530
10531         /* analyse bits */
10532         switch ( oct>>(32-bits_needed) )
10533         {
10534                 case 0x00: str="GERAN Iu mode not supported"; break;
10535                 case 0x01: str="GERAN Iu mode supported"; break;
10536                 default: str="This should not happen";
10537         }
10538     
10539         proto_tree_add_text(tf_tree,
10540                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10541                 "GERAN Iu Mode Capability: (%u) %s",oct>>(32-bits_needed),str);
10542         curr_bits_length -= bits_needed;
10543         oct <<= bits_needed;
10544         bits_in_oct -= bits_needed;
10545
10546         /*
10547          * GMSK/8-PSK Multislot Power Profile
10548          */
10549         bits_needed = 1;
10550         GET_DATA;
10551
10552         /* analyse bits */
10553         if ((oct>>(32-bits_needed))==0)
10554         {
10555                 proto_tree_add_text(tf_tree,
10556                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10557                         "GMSK/8-PSK Multislot Power Profile: (%u) Bits are not available",oct>>(32-bits_needed));
10558                 curr_bits_length -= bits_needed;
10559                 oct <<= bits_needed;
10560                 bits_in_oct -= bits_needed;
10561         }
10562         else
10563         {
10564                 curr_bits_length -= bits_needed;
10565                 oct <<= bits_needed;
10566                 bits_in_oct -= bits_needed;
10567
10568                 /*
10569                  * GMSK Multislot Power Profile
10570                  */
10571                 bits_needed = 2;
10572                 GET_DATA;
10573
10574                 /* analyse bits */
10575                 switch ( oct>>(32-bits_needed) )
10576                 {
10577                         case 0x00: str="GMSK_MULTISLOT_POWER_PROFILE 0"; break;
10578                         case 0x01: str="GMSK_MULTISLOT_POWER_PROFILE 1"; break;
10579                         case 0x02: str="GMSK_MULTISLOT_POWER_PROFILE 2"; break;
10580                         case 0x03: str="GMSK_MULTISLOT_POWER_PROFILE 3"; break;
10581                         default: str="This should not happen";
10582                 }
10583                 
10584                 proto_tree_add_text(tf_tree,
10585                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10586                         "GMSK Multislot Power Profile: (%u) %s",oct>>(32-bits_needed),str);
10587                 curr_bits_length -= bits_needed;
10588                 oct <<= bits_needed;
10589                 bits_in_oct -= bits_needed;
10590
10591                 /*
10592                  * 8-PSK Multislot Power Profile
10593                  */
10594                 bits_needed = 2;
10595                 GET_DATA;
10596
10597                 /* analyse bits */
10598                 switch ( oct>>(32-bits_needed) )
10599                 {
10600                         case 0x00: str="8-PSK_MULTISLOT_POWER_PROFILE 0"; break;
10601                         case 0x01: str="8-PSK_MULTISLOT_POWER_PROFILE 1"; break;
10602                         case 0x02: str="8-PSK_MULTISLOT_POWER_PROFILE 2"; break;
10603                         case 0x03: str="8-PSK_MULTISLOT_POWER_PROFILE 3"; break;
10604                         default: str="This should not happen";
10605                 }
10606                 
10607                 proto_tree_add_text(tf_tree,
10608                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
10609                         "8-PSK Multislot Power Profile: (%u) %s",oct>>(32-bits_needed),str);
10610                 curr_bits_length -= bits_needed;
10611                 oct <<= bits_needed;
10612                 bits_in_oct -= bits_needed;
10613
10614         }
10615
10616         /*
10617          * we are too long ... so jump over it
10618          */
10619         while ( curr_bits_length > 0 )
10620         {
10621                 if ( curr_bits_length > 8 )
10622                         bits_needed = 8;
10623                 else
10624                         bits_needed = curr_bits_length;
10625                 GET_DATA;
10626                 curr_bits_length -= bits_needed;
10627                 oct <<= bits_needed;
10628                 bits_in_oct -= bits_needed;
10629         }        
10630         
10631     } while ( 1 );
10632     
10633     curr_offset+= curr_len;        
10634                    
10635     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
10636
10637     return(curr_offset - offset);
10638 }
10639
10640 /*
10641  * [7] 10.5.5.13
10642  */
10643 static guint8
10644 de_gc_spare(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
10645 {
10646     guint32     curr_offset;
10647     
10648     len = len;
10649     curr_offset = offset;
10650
10651     proto_tree_add_text(tree,
10652         tvb, curr_offset, 1,
10653         "Spare Nibble");
10654
10655     curr_offset++;
10656
10657     /* no length check possible */
10658
10659     return(curr_offset - offset);
10660 }
10661
10662 /*
10663  * [7] 10.5.5.14
10664  */
10665 static guint8
10666 de_gmm_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
10667 {
10668     guint8      oct;
10669     guint32     curr_offset;
10670     const gchar *str;
10671     
10672     len = len;
10673     curr_offset = offset;
10674
10675     oct = tvb_get_guint8(tvb, curr_offset);
10676
10677     switch ( oct )
10678     {
10679         /* additional causes can be found in annex g */
10680         case 0x02: str="IMSI unknown in HLR"; break;
10681         case 0x03: str="Illegal MS"; break;
10682         case 0x04: str="IMSI unknown in VLR"; break;
10683         case 0x05: str="IMEI not accepted"; break;
10684         case 0x06: str="Illegal ME"; break;
10685         case 0x07: str="GPRS services not allowed"; break;
10686         case 0x08: str="GPRS services and non-GPRS services not allowed"; break;
10687         case 0x09: str="MS identity cannot be derived by the network"; break;
10688         case 0x0a: str="Implicitly detached"; break;
10689         case 0x0b: str="PLMN not allowed"; break;
10690         case 0x0c: str="Location Area not allowed"; break;
10691         case 0x0d: str="Roaming not allowed in this location area"; break;
10692         case 0x0e: str="GPRS services not allowed in this PLMN"; break;
10693         case 0x0f: str="No Suitable Cells In Location Area"; break;
10694         case 0x10: str="MSC temporarily not reachable"; break;
10695         case 0x11: str="Network failure"; break;
10696         case 0x14: str="MAC failure"; break;
10697         case 0x15: str="Synch failure"; break;
10698         case 0x16: str="Congestion"; break;
10699         case 0x17: str="GSM authentication unacceptable"; break;
10700         case 0x20: str="Service option not supported"; break;
10701         case 0x21: str="Requested service option not subscribed"; break;
10702         case 0x22: str="Service option temporarily out of order"; break;
10703         case 0x26: str="Call cannot be identified"; break;
10704         case 0x28: str="No PDP context activated"; break;
10705         case 0x30: str="retry upon entry into a new cell"; break;
10706         case 0x31: str="retry upon entry into a new cell"; break;
10707         case 0x32: str="retry upon entry into a new cell"; break;
10708         case 0x33: str="retry upon entry into a new cell"; break;
10709         case 0x34: str="retry upon entry into a new cell"; break;
10710         case 0x35: str="retry upon entry into a new cell"; break;
10711         case 0x36: str="retry upon entry into a new cell"; break;
10712         case 0x37: str="retry upon entry into a new cell"; break;
10713         case 0x38: str="retry upon entry into a new cell"; break;
10714         case 0x39: str="retry upon entry into a new cell"; break;
10715         case 0x3a: str="retry upon entry into a new cell"; break;
10716         case 0x3b: str="retry upon entry into a new cell"; break;
10717         case 0x3c: str="retry upon entry into a new cell"; break;
10718         case 0x3d: str="retry upon entry into a new cell"; break;
10719         case 0x3e: str="retry upon entry into a new cell"; break;
10720         case 0x3f: str="retry upon entry into a new cell"; break;
10721         case 0x5f: str="Semantically incorrect message"; break;
10722         case 0x60: str="Invalid mandatory information"; break;
10723         case 0x61: str="Message type non-existent or not implemented"; break;
10724         case 0x62: str="Message type not compatible with the protocol state"; break;
10725         case 0x63: str="Information element non-existent or not implemented"; break;
10726         case 0x64: str="Conditional IE error"; break;
10727         case 0x65: str="Message not compatible with the protocol state"; break;
10728         case 0x6f: str="Protocol error, unspecified"; break;
10729         default: str="Protocol error, unspecified";
10730     }
10731     
10732     proto_tree_add_text(tree,
10733         tvb, curr_offset, 1,
10734         "gmm Cause: (%u) %s",
10735         oct,
10736         str);
10737
10738     curr_offset++;
10739
10740     /* no length check possible */
10741
10742     return(curr_offset - offset);
10743 }
10744
10745 /*
10746  * [7] 10.5.5.15 Routing area identification
10747  */
10748 guint8
10749 de_gmm_rai(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
10750 {
10751     guint32     mcc;
10752     guint32     mnc;
10753     guint32     lac;
10754     guint32     rac;
10755     guint32     curr_offset;
10756     
10757     len = len;
10758     curr_offset = offset;
10759
10760     mcc = (tvb_get_guint8(tvb, curr_offset) & 0x0f) <<8;
10761         mcc |= (tvb_get_guint8(tvb, curr_offset) & 0xf0);
10762         mcc |= (tvb_get_guint8(tvb, curr_offset+1) & 0x0f);
10763         mnc = (tvb_get_guint8(tvb, curr_offset+2) & 0x0f) <<8;
10764         mnc |= (tvb_get_guint8(tvb, curr_offset+2) & 0xf0);
10765         mnc |= (tvb_get_guint8(tvb, curr_offset+1) & 0xf0) >>4;
10766         if ((mnc&0x000f) == 0x000f) 
10767                  mnc = mnc>>4;
10768
10769     lac = tvb_get_guint8(tvb, curr_offset+3);
10770     lac <<= 8;
10771     lac |= tvb_get_guint8(tvb, curr_offset+4);
10772     rac = tvb_get_guint8(tvb, curr_offset+5);
10773
10774         proto_tree_add_text(tree,
10775                 tvb, curr_offset, 6,
10776                 "Routing area identification: %x-%x-%x-%x",
10777                 mcc,mnc,lac,rac);
10778
10779     curr_offset+=6;
10780
10781     /* no length check possible */
10782
10783     return(curr_offset - offset);
10784 }
10785
10786 /*
10787  * [7] 10.5.5.17
10788  */
10789 static guint8
10790 de_gmm_update_res(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
10791 {
10792     guint8      oct;
10793     guint32     curr_offset;
10794     const gchar *str;
10795     
10796     len = len;
10797     curr_offset = offset;
10798
10799     oct = tvb_get_guint8(tvb, curr_offset);
10800
10801     /* IMPORTANT - IT'S ASSUMED THAT THE INFORMATION IS IN THE HIGHER NIBBLE */
10802     oct >>= 4;
10803
10804     switch(oct&7)
10805     {
10806         case 0: str="RA updated"; break;
10807         case 1: str="combined RA/LA updated";   break;
10808         default: str="reserved";
10809     }
10810
10811     proto_tree_add_text(tree,
10812         tvb, curr_offset, 1,
10813         "Update Result: (%u) %s",
10814         oct&7,
10815         str);
10816
10817     curr_offset++;
10818
10819     /* no length check possible */
10820
10821     return(curr_offset - offset);
10822 }
10823
10824 /*
10825  * [7] 10.5.5.18
10826  */
10827 static guint8
10828 de_gmm_update_type(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
10829 {
10830     guint8      oct;
10831     guint8      oct_ciph;
10832     guint32     curr_offset;
10833     const gchar *str_follow;
10834     const gchar *str_update;
10835     proto_item  *tf = NULL;
10836     proto_tree      *tf_tree = NULL;
10837     
10838     len = len;
10839     curr_offset = offset;
10840
10841     oct = tvb_get_guint8(tvb, curr_offset);
10842     oct_ciph = oct>>4;
10843
10844     oct &= 0x0f;
10845
10846     switch(oct&7)
10847     {
10848         case 0: str_update="RA updating"; break;
10849         case 1: str_update="combined RA/LA updating"; break;
10850         case 2: str_update="combined RA/LA updating with IMSI attach"; break;
10851         case 3: str_update="Periodic updating"; break;
10852         default: str_update="reserved";
10853     }
10854     switch(oct&8)
10855     {
10856         case 8: str_follow="Follow-on request pending"; break;
10857         default: str_follow="No follow-on request pending";
10858     }
10859
10860     tf = proto_tree_add_text(tree,
10861         tvb, curr_offset, 1,
10862         "Update Type");
10863
10864     tf_tree = proto_item_add_subtree(tf, ett_gmm_update_type );
10865
10866     proto_tree_add_text(tf_tree,
10867         tvb, curr_offset, 1,
10868         "Type: (%u) %s",
10869         oct&7,
10870         str_update);
10871     proto_tree_add_text(tf_tree,
10872         tvb, curr_offset, 1,
10873         "Follow: (%u) %s",
10874         (oct>>3)&1,
10875         str_follow);
10876
10877     /* The ciphering key sequence number is added here */
10878     proto_tree_add_text(tree,
10879         tvb, curr_offset, 1,
10880         "Ciphering key sequence number: 0x%02x (%u)",
10881         oct_ciph,
10882         oct_ciph);
10883
10884     curr_offset++;
10885
10886     /* no length check possible */
10887
10888     return(curr_offset - offset);
10889 }
10890
10891 /*
10892  * [7] 10.5.5.19
10893  */
10894 static guint8
10895 de_gmm_ac_ref_nr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
10896 {
10897     guint8      oct;
10898     guint32     curr_offset;
10899     
10900     len = len;
10901     curr_offset = offset;
10902
10903     oct = tvb_get_guint8(tvb, curr_offset);
10904
10905     proto_tree_add_text(tree,
10906         tvb, curr_offset, 1,
10907         "A&C reference number: 0x%02x (%u)",
10908         oct&0xf,
10909         oct&0xf);
10910
10911     curr_offset++;
10912
10913     /* no length check possible */
10914
10915     return(curr_offset - offset);
10916 }
10917
10918 /*
10919  * [7] 10.5.5.19
10920  */
10921 static guint8
10922 de_gmm_ac_ref_nr_h(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
10923 {
10924     guint8      oct;
10925     guint32     curr_offset;
10926     
10927     len = len;
10928     curr_offset = offset;
10929
10930     oct = tvb_get_guint8(tvb, curr_offset);
10931
10932     /* IMPORTANT - IT'S ASSUMED THAT THE INFORMATION IS IN THE HIGHER NIBBLE */
10933     oct >>= 4;
10934
10935     proto_tree_add_text(tree,
10936         tvb, curr_offset, 1,
10937         "A&C reference number: 0x%02x (%u)",
10938         oct,
10939         oct);
10940
10941     curr_offset++;
10942
10943     /* no length check possible */
10944
10945     return(curr_offset - offset);
10946 }
10947
10948 /*
10949  * [8] 10.5.5.20
10950  */
10951 static guint8
10952 de_gmm_service_type(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
10953 {
10954     guint8      oct;
10955     guint8      oct_ciph;
10956     guint32     curr_offset;
10957     const gchar *str;
10958     
10959     len = len;
10960     curr_offset = offset;
10961
10962     oct = tvb_get_guint8(tvb, curr_offset);
10963     oct_ciph = oct;
10964     oct_ciph &= 7;
10965
10966     oct = oct >> 4;
10967
10968     switch ( oct&7 )
10969     {
10970         case 0: str="Signalling"; break;
10971         case 1: str="Data"; break;
10972         case 2: str="Paging Response"; break;
10973         case 3: str="MBMS Notification Response"; break;/* reponse->response*/
10974         default: str="reserved";
10975     }
10976
10977     /* The ciphering key sequence number is added here */
10978     proto_tree_add_text(tree,
10979         tvb, curr_offset, 1,
10980         "Ciphering key sequence number: 0x%02x (%u)",
10981         oct_ciph,
10982         oct_ciph);
10983
10984     proto_tree_add_text(tree,
10985         tvb, curr_offset, 1,
10986         "Service Type: (%u) %s",
10987         oct&7,
10988         str);
10989
10990     curr_offset++;
10991
10992     /* no length check possible */
10993
10994     return(curr_offset - offset);
10995 }
10996
10997 /*
10998  * [7] 10.5.5.21
10999  */
11000 static guint8
11001 de_gmm_cell_notfi(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
11002 {
11003     guint32     curr_offset;
11004
11005     len = len;
11006     curr_offset = offset;
11007
11008     proto_tree_add_text(tree,
11009         tvb, curr_offset, 0,
11010         "Cell Notification");
11011
11012     /* no length check possible */
11013
11014     return(curr_offset - offset);
11015 }
11016
11017 /*
11018  * [7] 10.5.5.22
11019  */
11020 static guint8
11021 de_gmm_ps_lcs_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
11022 {
11023     guint8      oct;
11024     guint32     curr_offset;
11025     
11026     gchar       str_otd[2][40]={ "MS assisted E-OTD not supported",
11027                         "MS assisted E-OTD supported" };
11028     gchar       str_gps[2][40]={ "MS assisted GPS not supported",
11029                         "MS assisted GPS supported" };
11030     
11031     len = len;
11032     curr_offset = offset;
11033
11034     oct = tvb_get_guint8(tvb, curr_offset);
11035
11036     oct <<=3;   /* move away the spare bits */
11037
11038     proto_tree_add_text(tree,
11039         tvb, curr_offset, 1,
11040         "OTD-A: (%u) %s",
11041         oct>>7,
11042         str_otd[oct>>7]);
11043     oct <<=1;
11044     proto_tree_add_text(tree,
11045         tvb, curr_offset, 1,
11046         "OTD-B: (%u) %s",
11047         oct>>7,
11048         str_otd[oct>>7]);
11049     oct <<=1;
11050
11051     proto_tree_add_text(tree,
11052         tvb, curr_offset, 1,
11053         "GPS-A: (%u) %s",
11054         oct>>7,
11055         str_gps[oct>>7]);
11056     oct <<=1;
11057     proto_tree_add_text(tree,
11058         tvb, curr_offset, 1,
11059         "GPS-B: (%u) %s",
11060         oct>>7,
11061         str_gps[oct>>7]);
11062     oct <<=1;
11063     proto_tree_add_text(tree,
11064         tvb, curr_offset, 1,
11065         "GPS-C: (%u) %s",
11066         oct>>7,
11067         str_gps[oct>>7]);
11068
11069     curr_offset++;
11070
11071     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
11072
11073     return(curr_offset - offset);
11074 }
11075
11076 /*
11077  * [7] 10.5.5.23
11078  */
11079 static guint8
11080 de_gmm_net_feat_supp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
11081 {
11082     guint8      oct;
11083     guint32     curr_offset;
11084     const gchar *str;
11085     
11086     len = len;
11087     curr_offset = offset;
11088
11089     oct = tvb_get_guint8(tvb, curr_offset);
11090
11091     switch(oct&8)
11092     {
11093         case 8: str="LCS-MOLR via PS domain not supported"; break;
11094         default: str="LCS-MOLR via PS domain supported";
11095     }
11096
11097     proto_tree_add_text(tree,
11098         tvb, curr_offset, 1,
11099         "Network Feature Support: (%u) %s",
11100         (oct>>3)&1,
11101         str);
11102
11103     curr_offset++;
11104
11105     /* no length check possible */
11106
11107     return(curr_offset - offset);
11108 }
11109
11110 /* [7] 10.5.24 Inter RAT information container */
11111 static guint8
11112 de_gmm_rat_info_container(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
11113 {
11114         guint32 curr_offset;
11115
11116         len = len;
11117     curr_offset = offset;
11118
11119 /* The value part of the Inter RAT information container information element is the INTER RAT HANDOVER INFO as
11120 defined in 3GPP TS 25.331 [23c]. If this field includes padding bits, they are defined in 3GPP TS 25.331 [23c].*/
11121         proto_tree_add_text(tree, tvb, curr_offset, len,"INTER RAT HANDOVER INFO - Not decoded");
11122
11123         return len;
11124
11125 }
11126
11127 /*
11128  * [7] 10.5.7.1
11129  */
11130 static guint8
11131 de_gc_context_stat(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
11132 {
11133     guint8      oct;
11134     guint16     pdp_nr;
11135     guint32     curr_offset;
11136     proto_item  *tf = NULL;
11137     proto_tree      *tf_tree = NULL;
11138
11139     gchar       str[2][20]={ "PDP-INACTIVE", "PDP-ACTIVE" };
11140     
11141     len = len;
11142     curr_offset = offset;
11143
11144     oct = tvb_get_guint8(tvb, curr_offset);
11145
11146     tf = proto_tree_add_text(tree,
11147         tvb, curr_offset, 1,
11148         "PDP Context Status");
11149
11150     tf_tree = proto_item_add_subtree(tf, ett_gmm_context_stat );
11151     
11152     oct = tvb_get_guint8(tvb, curr_offset);
11153
11154     for ( pdp_nr=0;pdp_nr<16; pdp_nr++ )
11155     {
11156             if ( pdp_nr == 8 )
11157             {
11158                 curr_offset++;
11159                 oct = tvb_get_guint8(tvb, curr_offset);
11160             }
11161             proto_tree_add_text(tf_tree,
11162                 tvb, curr_offset, 1,
11163                 "NSAPI %d: (%u) %s",pdp_nr,
11164                 oct&1,
11165                 str[oct&1]);
11166             oct>>=1;
11167     }
11168
11169     curr_offset++;
11170
11171     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
11172
11173     return(curr_offset - offset);
11174 }
11175
11176 /*
11177  * [7] 10.5.7.2
11178  */
11179 static guint8
11180 de_gc_radio_prio(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
11181 {
11182     guint8      oct;
11183     guint32     curr_offset;
11184     const gchar *str;
11185     
11186     len = len;
11187     curr_offset = offset;
11188
11189     oct = tvb_get_guint8(tvb, curr_offset);
11190
11191     switch ( oct&7 )
11192     {
11193         case 1: str="priority level 1 (highest)"; break;
11194         case 2: str="priority level 2"; break;
11195         case 3: str="priority level 3"; break;
11196         case 4: str="priority level 4 (lowest)"; break;
11197         default: str="priority level 4 (lowest)";
11198     }
11199
11200     proto_tree_add_text(tree,
11201         tvb, curr_offset, 1,
11202         "Radio Priority (PDP or SMS): (%u) %s",
11203         oct&7,
11204         str);
11205
11206     curr_offset++;
11207
11208     return(curr_offset - offset);
11209 }
11210
11211 /*
11212  * [7] 10.5.7.3
11213  */
11214 static guint8
11215 de_gc_timer(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
11216 {
11217     guint8      oct;
11218     guint16     val;
11219     guint32     curr_offset;
11220     const gchar *str;
11221     
11222     len = len;
11223     curr_offset = offset;
11224
11225     oct = tvb_get_guint8(tvb, curr_offset);
11226
11227     val = oct&0x1f;
11228
11229     switch(oct>>5)
11230     {
11231         case 0: str="sec"; val*=2; break;
11232         case 1: str="min"; break;
11233         case 2: str="min"; val*=6; break;
11234         case 7:
11235             proto_tree_add_text(tree,
11236                 tvb, curr_offset, 1,
11237                 "GPRS Timer: timer is deactivated");
11238
11239         default: str="min";
11240     }
11241
11242     proto_tree_add_text(tree,
11243         tvb, curr_offset, 1,
11244         "GPRS Timer: (%u) %u %s",
11245         oct, val,
11246         str);
11247
11248     curr_offset++;
11249
11250     /* no length check possible */
11251
11252     return(curr_offset - offset);
11253 }
11254
11255 /*
11256  * [7] 10.5.7.4
11257  */
11258 static guint8
11259 de_gc_timer2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len _U_)
11260 {
11261     guint8      oct;
11262     guint16     val;
11263     guint32     curr_offset;
11264     const gchar *str;
11265     
11266     len = len;
11267     curr_offset = offset;
11268
11269     oct = tvb_get_guint8(tvb, curr_offset);
11270
11271     val = oct&0x1f;
11272
11273     switch(oct>>5)
11274     {
11275         case 0: str="sec"; val*=2; break;
11276         case 1: str="min"; break;
11277         case 2: str="min"; val*=6; break;
11278         case 7:
11279             proto_tree_add_text(tree,
11280                 tvb, curr_offset, 1,
11281                 "GPRS Timer: timer is deactivated");
11282
11283         default: str="min";
11284     }
11285
11286     proto_tree_add_text(tree,
11287         tvb, curr_offset, 1,
11288         "GPRS Timer: (%u) %u %s %s",
11289         oct, val,
11290         str, add_string ? add_string : "");
11291
11292     curr_offset++;
11293
11294     return(curr_offset - offset);
11295 }
11296
11297
11298 /*
11299  * [7] 10.5.7.5
11300  */
11301 static guint8
11302 de_gc_radio_prio2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
11303 {
11304     guint8      oct;
11305     guint32     curr_offset;
11306     const gchar *str;
11307     
11308     len = len;
11309     curr_offset = offset;
11310
11311     oct = tvb_get_guint8(tvb, curr_offset);
11312
11313     /* IMPORTANT - IT'S ASSUMED THAT THE INFORMATION IS IN THE HIGHER NIBBLE */
11314     oct >>= 4;
11315
11316     switch ( oct&7 )
11317     {
11318         case 1: str="priority level 1 (highest)"; break;
11319         case 2: str="priority level 2"; break;
11320         case 3: str="priority level 3"; break;
11321         case 4: str="priority level 4 (lowest)"; break;
11322         default: str="priority level 4 (lowest)";
11323     }
11324
11325     proto_tree_add_text(tree,
11326         tvb, curr_offset, 1,
11327         "Radio Priority (TOM8): (%u) %s",
11328         oct&7,
11329         str);
11330
11331     curr_offset++;
11332
11333     return(curr_offset - offset);
11334 }
11335
11336 /*
11337  * [8] 10.5.7.6 MBMS context status
11338  */
11339 static guint8
11340 de_gc_mbms_context_stat(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
11341 {
11342     guint32     curr_offset;
11343     
11344     len = len;
11345     curr_offset = offset;
11346  
11347         proto_tree_add_text(tree,tvb, curr_offset, len, "MBMS context status - Not decoded");
11348
11349     return(len);
11350 }
11351 /*
11352  * [7] 10.5.6.1
11353  */
11354 #define MAX_APN_LENGTH          50
11355
11356 guint8
11357 de_sm_apn(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len _U_)
11358 {
11359     guint32     curr_offset;
11360     guint       curr_len;
11361     const guint8        *cptr;
11362     guint8      str[MAX_APN_LENGTH+1];
11363
11364     cptr = tvb_get_ptr(tvb, offset, len);
11365
11366     
11367     curr_offset = offset;
11368
11369     /* init buffer and copy it */
11370     memset ( str , 0 , MAX_APN_LENGTH );
11371     memcpy ( str , cptr , len<MAX_APN_LENGTH?len:MAX_APN_LENGTH );
11372
11373     curr_len = 0;
11374     while (( curr_len < len ) && ( curr_len < MAX_APN_LENGTH ))
11375     {
11376         guint step = str[curr_len];
11377         str[curr_len]='.';
11378         curr_len += step+1;
11379     }
11380     
11381     proto_tree_add_text(tree,
11382         tvb, curr_offset, len,
11383         "APN: %s %s", str+1 , add_string ? add_string : "");
11384
11385     curr_offset+= len;
11386
11387     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
11388
11389     return(curr_offset - offset);
11390 }
11391
11392 /*
11393  * [7] 10.5.6.2
11394  */
11395 static guint8
11396 de_sm_nsapi(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len _U_)
11397 {
11398     guint8      oct;
11399     guint32     curr_offset;
11400     
11401     len = len;
11402     curr_offset = offset;
11403
11404     oct = tvb_get_guint8(tvb, curr_offset);
11405
11406     proto_tree_add_text(tree,
11407         tvb, curr_offset, 1,
11408         "NSAPI: 0x%02x (%u) %s",
11409         oct&0x0f, oct&0x0f,add_string ? add_string : "");
11410
11411     curr_offset++;
11412
11413     return(curr_offset - offset);
11414 }
11415
11416 /*
11417  * [7] 10.5.6.3
11418  */
11419 static guint8
11420 de_sm_pco(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
11421 {
11422     guint32     curr_offset;
11423     guint       curr_len;
11424     guchar      oct;
11425     struct e_in6_addr ipv6_addr;
11426     
11427     curr_len = len;
11428     curr_offset = offset;
11429
11430     oct = tvb_get_guint8(tvb, curr_offset);
11431     curr_len--;
11432     curr_offset++;
11433
11434     proto_tree_add_text(tree,tvb, curr_offset, 1, "Ext: 0x%02x (%u)",oct>>7,oct>>7);
11435     proto_tree_add_text(tree,tvb, curr_offset, 1, "Configuration Protocol: PPP (%u)",oct&0x0f);
11436
11437     while ( curr_len > 0 )
11438     {
11439         guchar e_len;
11440         guint16 prot;
11441         tvbuff_t *l3_tvb;
11442         dissector_handle_t handle = NULL;
11443         static packet_info p_info;
11444         
11445         prot = tvb_get_guint8(tvb, curr_offset);
11446         prot <<= 8;
11447         prot |= tvb_get_guint8(tvb, curr_offset+1);
11448         e_len = tvb_get_guint8(tvb, curr_offset+2);
11449         curr_len-=3;
11450         curr_offset+=3;
11451
11452         switch ( prot )
11453         {
11454                 case 0x0001:
11455                 {
11456                     proto_tree_add_text(tree,tvb, curr_offset-3, 2, "Parameter: (%u) P-CSCF Address" , prot );
11457                     proto_tree_add_text(tree,tvb, curr_offset-1, 1, "Length: 0x%02x (%u)", e_len , e_len);
11458
11459                     tvb_get_ipv6(tvb, curr_offset, &ipv6_addr);
11460                     proto_tree_add_text(tree,
11461                         tvb, curr_offset, 16,
11462                         "IPv6: %s", ip6_to_str(&ipv6_addr));
11463                     break;
11464                 }
11465                 case 0x0002:
11466                     proto_tree_add_text(tree,tvb, curr_offset-3, 2, "Parameter: (%u) IM CN Subsystem Signaling Flag" , prot );
11467                     proto_tree_add_text(tree,tvb, curr_offset-1, 1, "Length: 0x%02x (%u)", e_len , e_len);
11468                     break;
11469                 case 0x0003:
11470                 {
11471                     proto_tree_add_text(tree,tvb, curr_offset-3, 2, "Parameter: (%u) DNS Server Address" , prot );
11472                     proto_tree_add_text(tree,tvb, curr_offset-1, 1, "Length: 0x%02x (%u)", e_len , e_len);
11473
11474                     tvb_get_ipv6(tvb, curr_offset, &ipv6_addr);
11475                     proto_tree_add_text(tree,
11476                         tvb, curr_offset, 16,
11477                         "IPv6: %s", ip6_to_str(&ipv6_addr));
11478                     break;
11479                 }
11480                 case 0x0004:
11481                     proto_tree_add_text(tree,tvb, curr_offset-3, 2, "Parameter: (%u) Policy Control rejection code" , prot );
11482                     proto_tree_add_text(tree,tvb, curr_offset-1, 1, "Length: 0x%02x (%u)", e_len , e_len);
11483                     oct = tvb_get_guint8(tvb, curr_offset);
11484                     proto_tree_add_text(tree,tvb, curr_offset, 1, "Reject Code: 0x%02x (%u)", e_len , e_len);
11485                     break;
11486                 default:
11487                         handle = dissector_get_port_handle ( gprs_sm_pco_subdissector_table , prot );
11488                         if ( handle != NULL )
11489                         {
11490                                 proto_tree_add_text(tree,tvb, curr_offset-3, 2, "Protocol: (%u) %s" , 
11491                                         prot , val_to_str(prot, ppp_vals, "Unknown"));
11492                                 proto_tree_add_text(tree,tvb, curr_offset-1, 1, "Length: 0x%02x (%u)", e_len , e_len);
11493                                 /*
11494                                  * dissect the embedded message
11495                                  */
11496                                 l3_tvb = tvb_new_subset(tvb, curr_offset, e_len, e_len);
11497                                 call_dissector(handle, l3_tvb ,  &p_info  , tree );
11498                         }
11499                         else
11500                         {
11501                                 proto_tree_add_text(tree,tvb, curr_offset-3, 2, "Protocol/Parameter: (%u) unknwown" , prot );
11502                                 proto_tree_add_text(tree,tvb, curr_offset-1, 1, "Length: 0x%02x (%u)", e_len , e_len);
11503                                 /*
11504                                 * dissect the embedded DATA message
11505                                 */
11506                                 l3_tvb = tvb_new_subset(tvb, curr_offset, e_len, e_len);
11507                                 call_dissector(data_handle, l3_tvb, &p_info , tree);
11508                         }
11509         }
11510
11511         curr_len-= e_len;
11512         curr_offset+= e_len;
11513     }    
11514     curr_offset+= curr_len;        
11515                    
11516     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
11517
11518     return(curr_offset - offset);
11519 }
11520
11521 /*
11522  * [7] 10.5.6.4
11523  */
11524 static guint8
11525 de_sm_pdp_addr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
11526 {
11527     guint32     curr_offset;
11528     guint       curr_len;
11529     const gchar *str;
11530     guchar      oct;
11531     guchar      oct2;
11532     struct e_in6_addr ipv6_addr;
11533
11534     curr_len = len;
11535     curr_offset = offset;
11536
11537     oct = tvb_get_guint8(tvb, curr_offset);
11538
11539     switch ( oct&0x0f )
11540     {
11541         case 0x00: str="ETSI allocated address"; break;
11542         case 0x01: str="IETF allocated address"; break;
11543         case 0x0f: str="Empty PDP type";
11544         default: str="reserved";
11545     }
11546
11547     proto_tree_add_text(tree,
11548         tvb, curr_offset, 1,
11549         "PDP type organisation: (%u) %s",oct&0x0f,str);
11550
11551     oct2 = tvb_get_guint8(tvb, curr_offset+1);
11552
11553     if (( oct&0x0f ) == 0 )
11554     {
11555             switch ( oct2 )
11556             {
11557                 case 0x00: str="Reserved, used in earlier version of this protocol"; break;
11558                 case 0x01: str="PDP-type PPP"; break;
11559                 default: str="reserved";
11560             }
11561     }
11562     else if (( oct&0x0f) == 1 )
11563     {
11564             switch ( oct2 )
11565             {
11566                 case 0x21: str="IPv4 address"; break;
11567                 case 0x57: str="IPv6 address"; break;
11568                 default: str="IPv4 address";
11569             }
11570     }
11571     else if ((oct2==0) && (( oct&0x0f) == 0x0f ))    
11572             str="Empty"; 
11573     else
11574             str="Not specified";        
11575     
11576     proto_tree_add_text(tree,
11577         tvb, curr_offset+1, 1,
11578         "PDP type number: (%u) %s",oct2,str);
11579
11580     if (( len == 2 ) && (( oct2 == 0x21 ) || ( oct2 == 0x57 )))
11581     {
11582             proto_tree_add_text(tree,
11583                 tvb, curr_offset+1, 1,
11584                 "Dynamic addressing");
11585         
11586             curr_offset+= curr_len;        
11587
11588             EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
11589
11590            return(curr_offset - offset);
11591     }
11592     else if ( len == 2 )
11593     {
11594             proto_tree_add_text(tree,
11595                 tvb, curr_offset+1, 1,
11596                 "No PDP address is included");
11597         
11598             curr_offset+= curr_len;        
11599
11600             EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
11601
11602            return(curr_offset - offset);
11603     }
11604     else if ( len < 2 )
11605     {
11606             proto_tree_add_text(tree,
11607                 tvb, curr_offset+1, 1,
11608                 "Length is bogus - should be >= 2");
11609         
11610             curr_offset+= curr_len;        
11611
11612             EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
11613
11614            return(curr_offset - offset);
11615     }
11616
11617     if ((( oct2 == 0x21 ) && ( len != 6 )) ||
11618        (( oct2 == 0x57 ) && ( len != 18 )))
11619     {
11620             proto_tree_add_text(tree,
11621                 tvb, curr_offset+2, len-2,
11622                 "Can't display address");
11623     }
11624
11625
11626     switch ( oct2 )
11627     {
11628         case 0x21:
11629             if (len-2 != 4) {
11630                 proto_tree_add_text(tree,
11631                     tvb, curr_offset+2, 0,
11632                     "IPv4: length is wrong");
11633             } else {
11634                 proto_tree_add_text(tree,
11635                     tvb, curr_offset+2, len-2,
11636                     "IPv4: %s", ip_to_str(tvb_get_ptr(tvb, offset+2, 4)));
11637             }
11638             break;
11639
11640         case 0x57:
11641             if (len-2 != 16) {
11642                 proto_tree_add_text(tree,
11643                     tvb, curr_offset+2, 0,
11644                     "IPv6: length is wrong");
11645             } else {
11646                 tvb_get_ipv6(tvb, curr_offset+2, &ipv6_addr);
11647                 proto_tree_add_text(tree,
11648                     tvb, curr_offset+2, len-2,
11649                     "IPv6: %s", ip6_to_str(&ipv6_addr));
11650             }
11651             break;
11652     }
11653     
11654     curr_offset+= curr_len;        
11655                    
11656     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
11657
11658     return(curr_offset - offset);
11659 }
11660
11661 /*
11662  * [7] 10.5.6.5
11663  */
11664  /* Delivery of erroneous SDUs, octet 6 (see 3GPP TS 23.107) Bits 3 2 1 */
11665 const value_string gsm_a_qos_del_of_err_sdu_vals[] = {
11666         { 0, "Subscribed delivery of erroneous SDUs/Reserved" },
11667         { 1, "No detect('-')" },
11668         { 2, "Erroneous SDUs are delivered('yes')" },
11669         { 3, "Erroneous SDUs are not delivered('No')" },
11670         { 7, "Reserved" },
11671         { 0, NULL }
11672 };
11673
11674  /* Delivery order, octet 6 (see 3GPP TS 23.107) Bits 5 4 3 */
11675 const value_string gsm_a_qos_del_order_vals[] = {
11676         { 0, "Subscribed delivery order/Reserved" },
11677         { 1, "With delivery order ('yes')" },
11678         { 2, "Without delivery order ('no')" },
11679         { 3, "Reserved" },
11680         { 0, NULL }
11681 };
11682 /* Traffic class, octet 6 (see 3GPP TS 23.107) Bits 8 7 6 */
11683 const value_string gsm_a_qos_traffic_cls_vals[] = {
11684         { 0, "Subscribed traffic class/Reserved" },
11685         { 1, "Conversational class" },
11686         { 2, "Streaming class" },
11687         { 3, "Interactive class" },
11688         { 4, "Background class" },
11689         { 7, "Reserved" },
11690         { 0, NULL }
11691 };
11692
11693 /* Residual Bit Error Rate (BER), octet 10 (see 3GPP TS 23.107) Bits 8 7 6 5 */
11694 const value_string gsm_a_qos_ber_vals[] = {
11695         { 0, "Subscribed residual BER/Reserved" },
11696         { 1, "5*10-2" },
11697         { 2, "1*10-2" },
11698         { 3, "5*10-3" },
11699         { 4, "4*10-3" },
11700         { 5, "1*10-3" },
11701         { 6, "1*10-4" },
11702         { 7, "1*10-5" },
11703         { 8, "1*10-6" },
11704         { 9, "6*10-8" },
11705         { 10, "Reserved" },
11706         { 0, NULL }
11707 };
11708
11709 /* SDU error ratio, octet 10 (see 3GPP TS 23.107) Bits 4 3 2 1 */
11710 const value_string gsm_a_qos_sdu_err_rat_vals[] = {
11711         { 0, "Subscribed SDU error ratio/Reserved" },
11712         { 1, "1*10-2" },
11713         { 2, "7*10-3" },
11714         { 3, "1*10-3" },
11715         { 4, "1*10-4" },
11716         { 5, "1*10-5" },
11717         { 6, "1*10-6" },
11718         { 7, "1*10-1" },
11719         { 15, "Reserved" },
11720         { 0, NULL }
11721 };
11722
11723 /* Traffic handling priority, octet 11 (see 3GPP TS 23.107) Bits 2 1 */
11724 const value_string gsm_a_qos_traff_hdl_pri_vals[] = {
11725         { 0, "Subscribed traffic handling priority/Reserved" },
11726         { 1, "Priority level 1" },
11727         { 2, "Priority level 2" },
11728         { 3, "Priority level 3" },
11729         { 0, NULL }
11730 };
11731
11732  guint8
11733 de_sm_qos(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
11734 {
11735     guint32     curr_offset;
11736     guint       curr_len;
11737     guchar       oct, tmp_oct;
11738     const gchar *str;
11739     
11740     curr_len = len;
11741     curr_offset = offset;
11742
11743     oct = tvb_get_guint8(tvb, curr_offset);
11744
11745     switch ( (oct>>3)&7 )
11746     {
11747         case 0x00: str="Subscribed delay class/reserved"; break;
11748         case 0x01: str="Delay class 1"; break;
11749         case 0x02: str="Delay class 2"; break;
11750         case 0x03: str="Delay class 3"; break;
11751         case 0x04: str="Delay class 4 (best effort)"; break;
11752         case 0x07: str="Reserved"; break;
11753         default: str="Delay class 4 (best effort)";
11754     }
11755
11756     proto_tree_add_text(tree,
11757         tvb, curr_offset, 1,
11758         "Delay class: (%u) %s",(oct>>3)&7,str);
11759
11760     switch ( oct&0x7 )
11761     {
11762         case 0x00: str="Subscribed reliability class/reserved"; break;
11763         case 0x01: str="Acknowledged GTP, LLC, and RLC; Protected data"; break;
11764         case 0x02: str="Unacknowledged GTP; Acknowledged LLC and RLC, Protected data"; break;
11765         case 0x03: str="Unacknowledged GTP and LLC; Acknowledged RLC, Protected data"; break;
11766         case 0x04: str="Unacknowledged GTP, LLC, and RLC, Protected data"; break;
11767         case 0x05: str="Unacknowledged GTP, LLC, and RLC, Unprotected data"; break;
11768         case 0x07: str="Reserved"; break;
11769         default: str="Unacknowledged GTP and LLC; Acknowledged RLC, Protected data";
11770     }
11771
11772     proto_tree_add_text(tree,
11773         tvb, curr_offset, 1,
11774         "Reliability class: (%u) %s",oct&7,str);
11775
11776     curr_offset+= 1;       
11777     curr_len-= 1;
11778     
11779     if ( curr_len == 0 )
11780     {
11781             EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
11782
11783             return(curr_offset - offset);
11784     }
11785
11786     oct = tvb_get_guint8(tvb, curr_offset);
11787
11788     switch ( oct>>4 )
11789     {
11790         case 0x00: str="Subscribed peak throughput/reserved"; break;
11791         case 0x01: str="Up to 1 000 octet/s"; break;
11792         case 0x02: str="Up to 2 000 octet/s"; break;
11793         case 0x03: str="Up to 4 000 octet/s"; break;
11794         case 0x04: str="Up to 8 000 octet/s"; break;
11795         case 0x05: str="Up to 16 000 octet/s"; break;
11796         case 0x06: str="Up to 32 000 octet/s"; break;
11797         case 0x07: str="Up to 64 000 octet/s"; break;
11798         case 0x08: str="Up to 128 000 octet/s"; break;
11799         case 0x09: str="Up to 256 000 octet/s"; break;
11800         case 0x0f: str="Reserved"; break;
11801         default: str="Up to 1 000 octet/s";
11802     }
11803
11804     proto_tree_add_text(tree,
11805         tvb, curr_offset, 1,
11806         "Peak throughput: (%u) %s",oct>>4,str);
11807
11808     switch ( oct&0x7 )
11809     {
11810         case 0x00: str="Subscribed precedence/reserved"; break;
11811         case 0x01: str="High priority"; break;
11812         case 0x02: str="Normal priority"; break;
11813         case 0x03: str="Low priority"; break;
11814         case 0x07: str="Reserved"; break;
11815         default: str="Normal priority";
11816     }
11817
11818     proto_tree_add_text(tree,
11819         tvb, curr_offset, 1,
11820         "Precedence class: (%u) %s",oct&7,str);
11821
11822     curr_offset+= 1;       
11823     curr_len-= 1;
11824     
11825     if ( curr_len == 0 )
11826     {
11827             EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
11828
11829             return(curr_offset - offset);
11830     }
11831
11832     oct = tvb_get_guint8(tvb, curr_offset);
11833
11834     switch ( oct&0x1f )
11835     {
11836         case 0x00: str="Subscribed peak throughput/reserved"; break;
11837         case 0x01: str="100 octet/h"; break;
11838         case 0x02: str="200 octet/h"; break;
11839         case 0x03: str="500 octet/h"; break;
11840         case 0x04: str="1 000 octet/h"; break;
11841         case 0x05: str="2 000 octet/h"; break;
11842         case 0x06: str="5 000 octet/h"; break;
11843         case 0x07: str="10 000 octet/h"; break;
11844         case 0x08: str="20 000 octet/h"; break;
11845         case 0x09: str="50 000 octet/h"; break;
11846         case 0x0a: str="100 000 octet/h"; break;
11847         case 0x0b: str="200 000 octet/h"; break;
11848         case 0x0c: str="500 000 octet/h"; break;
11849         case 0x0d: str="1 000 000 octet/h"; break;
11850         case 0x0e: str="2 000 000 octet/h"; break;
11851         case 0x0f: str="5 000 000 octet/h"; break;
11852         case 0x10: str="10 000 000 octet/h"; break;
11853         case 0x11: str="20 000 000 octet/h"; break;
11854         case 0x12: str="50 000 000 octet/h"; break;
11855         case 0x1e: str="Reserved"; break;
11856         case 0x1f: str="Best effort"; break;
11857         default: str="Best effort";
11858     }
11859
11860     proto_tree_add_text(tree,
11861         tvb, curr_offset, 1,
11862         "Mean throughput: (%u) %s",oct&0x1f,str);
11863
11864     curr_offset+= 1;       
11865     curr_len-= 1;
11866     
11867     if ( curr_len == 0 )
11868     {
11869             EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
11870
11871             return(curr_offset - offset);
11872     }
11873
11874     proto_tree_add_item(tree, hf_gsm_a_qos_traffic_cls, tvb, curr_offset, 1, FALSE);
11875         proto_tree_add_item(tree, hf_gsm_a_qos_del_order, tvb, curr_offset, 1, FALSE);
11876     proto_tree_add_item(tree, hf_gsm_a_qos_del_of_err_sdu, tvb, curr_offset, 1, FALSE);
11877
11878     curr_offset+= 1;       
11879     curr_len-= 1;
11880     
11881     if ( curr_len == 0 )
11882     {
11883             EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
11884
11885             return(curr_offset - offset);
11886     }
11887
11888     oct = tvb_get_guint8(tvb, curr_offset);
11889
11890     switch ( oct )
11891     {
11892         case 0x00: str="Subscribed maximum SDU size/reserved"; break;
11893         case 0x97: str="1502 octets"; break;
11894         case 0x98: str="1510 octets"; break;
11895         case 0x99: str="1520 octets"; break;
11896         case 0xff: str="Reserved"; break;
11897         default: str="Unspecified";
11898     }
11899
11900     if (( oct >= 1 ) && ( oct <= 0x96 ))
11901             proto_tree_add_text(tree,
11902                 tvb, curr_offset, 1,
11903                 "Maximum SDU size: (%u) %u octets",oct,oct*10);
11904     else
11905             proto_tree_add_text(tree,
11906                 tvb, curr_offset, 1,
11907                 "Maximum SDU size: (%u) %s",oct,str);
11908
11909     curr_offset+= 1;       
11910     curr_len-= 1;
11911     
11912     if ( curr_len == 0 )
11913     {
11914             EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
11915
11916             return(curr_offset - offset);
11917     }
11918
11919     oct = tvb_get_guint8(tvb, curr_offset);
11920
11921     switch ( oct )
11922     {
11923         case 0x00: str="Subscribed maximum bit rate for uplink/reserved"; break;
11924         case 0xff: str="0kbps"; break;
11925         default: str="This should not happen - BUG";
11926     }
11927
11928     if (( oct >= 1 ) && ( oct <= 0x3f ))
11929             proto_tree_add_text(tree,
11930                 tvb, curr_offset, 1,
11931                 "Maximum bit rate for uplink: (%u) %ukbps",oct,oct);
11932     else if (( oct >= 0x40 ) && ( oct <= 0x7f ))
11933             proto_tree_add_text(tree,
11934                 tvb, curr_offset, 1,
11935                 "Maximum bit rate for uplink: (%u) %ukbps",oct,(oct-0x40)*8+64); /* - was (oct-0x40)*8  */
11936     else if (( oct >= 0x80 ) && ( oct <= 0xfe ))
11937             proto_tree_add_text(tree,
11938                 tvb, curr_offset, 1,
11939                 "Maximum bit rate for uplink: (%u) %ukbps",oct,(oct-0x80)*64+576); /* - was (oct-0x80)*64 */
11940     else
11941             proto_tree_add_text(tree,
11942                 tvb, curr_offset, 1,
11943                 "Maximum bit rate for uplink: (%u) %s",oct,str);
11944
11945     curr_offset+= 1;       
11946     curr_len-= 1;
11947     
11948     if ( curr_len == 0 )
11949     {
11950             EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
11951
11952             return(curr_offset - offset);
11953     }
11954
11955     oct = tvb_get_guint8(tvb, curr_offset);
11956
11957     switch ( oct )
11958     {
11959         case 0x00: str="Subscribed maximum bit rate for uplink/reserved"; break;
11960         case 0xff: str="0kbps"; break;
11961         default: str="This should not happen - BUG";
11962     }
11963
11964     if (( oct >= 1 ) && ( oct <= 0x3f ))
11965             proto_tree_add_text(tree,
11966                 tvb, curr_offset, 1,
11967                 "Maximum bit rate for downlink: (%u) %ukbps",oct,oct);
11968     else if (( oct >= 0x40 ) && ( oct <= 0x7f ))
11969             proto_tree_add_text(tree,
11970                 tvb, curr_offset, 1,
11971                 "Maximum bit rate for downlink: (%u) %ukbps",oct,(oct-0x40)*8+64);/*same as above*/
11972     else if (( oct >= 0x80 ) && ( oct <= 0xfe ))
11973             proto_tree_add_text(tree,
11974                 tvb, curr_offset, 1,
11975                 "Maximum bit rate for downlink: (%u) %ukbps",oct,(oct-0x80)*64+576);/*same as above*/
11976     else
11977             proto_tree_add_text(tree,
11978                 tvb, curr_offset, 1,
11979                 "Maximum bit rate for downlink: (%u) %s",oct,str);
11980
11981     curr_offset+= 1;       
11982     curr_len-= 1;
11983     
11984     if ( curr_len == 0 )
11985     {
11986             EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
11987
11988             return(curr_offset - offset);
11989     }
11990
11991     proto_tree_add_item(tree, hf_gsm_a_qos_ber, tvb, curr_offset, 1, FALSE);
11992         proto_tree_add_item(tree, hf_gsm_a_qos_sdu_err_rat, tvb, curr_offset, 1, FALSE);
11993
11994     curr_offset+= 1;       
11995     curr_len-= 1;
11996     
11997     if ( curr_len == 0 )
11998     {
11999             EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
12000
12001             return(curr_offset - offset);
12002     }
12003
12004     oct = tvb_get_guint8(tvb, curr_offset);
12005
12006     switch ( oct>>2 )
12007     {
12008         case 0x00: str="Subscribed transfer delay/reserved"; break;
12009         case 0x3f: str="Reserved"; break;
12010         default: str="This should not happen - BUG";
12011     }
12012
12013     tmp_oct = oct>>2;
12014
12015     if (( tmp_oct >= 1 ) && ( tmp_oct <= 0x0f ))
12016             proto_tree_add_text(tree,
12017                 tvb, curr_offset, 1,
12018                 "Transfer Delay: (%u) %ums",oct>>2,(oct>>2)*10);
12019     else if (( tmp_oct >= 0x10 ) && ( tmp_oct <= 0x1f ))
12020             proto_tree_add_text(tree,
12021                 tvb, curr_offset, 1,
12022                 "Transfer Delay: (%u) %ums",oct>>2,((oct>>2)-0x10)*50+200);
12023     else if (( tmp_oct >= 0x20 ) && ( tmp_oct <= 0x3e ))
12024             proto_tree_add_text(tree,
12025                 tvb, curr_offset, 1,
12026                 "Transfer Delay: (%u) %ums",oct>>2,((oct>>2)-0x20)*100+1000);
12027     else
12028             proto_tree_add_text(tree,
12029                 tvb, curr_offset, 1,
12030                 "Transfer Delay: (%u) %s",oct>>2,str);
12031
12032     switch ( oct&0x03 )
12033     {
12034         case 0x00: str="Subscribed traffic handling priority/reserved"; break;
12035         case 0x01: str="Priority level 1"; break;
12036         case 0x02: str="Priority level 2"; break;
12037         case 0x03: str="Priority level 3"; break;
12038         default: str="This should not happen - BUG";
12039     }
12040
12041     proto_tree_add_text(tree,
12042         tvb, curr_offset, 1,
12043         "Traffic Handling priority: (%u) %s",oct&0x03,str);
12044
12045     curr_offset+= 1;       
12046     curr_len-= 1;
12047     
12048     if ( curr_len == 0 )
12049     {
12050             EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
12051
12052             return(curr_offset - offset);
12053     }
12054
12055     oct = tvb_get_guint8(tvb, curr_offset);
12056
12057     switch ( oct )
12058     {
12059         case 0x00: str="Subscribed guaranteed bit rate for uplink/reserved"; break;
12060         case 0xff: str="0kbps"; break;
12061         default: str="This should not happen - BUG";
12062     }
12063
12064     if (( oct >= 1 ) && ( oct <= 0x3f ))
12065             proto_tree_add_text(tree,
12066                 tvb, curr_offset, 1,
12067                 "Guaranteed bit rate for uplink: (%u) %ukbps",oct,oct);
12068     else if (( oct >= 0x40 ) && ( oct <= 0x7f ))
12069             proto_tree_add_text(tree,
12070                 tvb, curr_offset, 1,
12071                 "Guaranteed bit rate for uplink: (%u) %ukbps",oct,(oct-0x40)*8+64);/*same as for max bit rate*/
12072     else if (( oct >= 0x80 ) && ( oct <= 0xfe ))
12073             proto_tree_add_text(tree,
12074                 tvb, curr_offset, 1,
12075                 "Guaranteed bit rate for uplink: (%u) %ukbps",oct,(oct-0x80)*64+576);/*same as for max bit rate*/
12076     else
12077             proto_tree_add_text(tree,
12078                 tvb, curr_offset, 1,
12079                 "Guaranteed bit rate for uplink: (%u) %s",oct,str);
12080
12081     curr_offset+= 1;       
12082     curr_len-= 1;
12083     
12084     if ( curr_len == 0 )
12085     {
12086             EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
12087
12088             return(curr_offset - offset);
12089     }
12090
12091     oct = tvb_get_guint8(tvb, curr_offset);
12092
12093     switch ( oct )
12094     {
12095         case 0x00: str="Subscribed guaranteed bit rate for uplink/reserved"; break;
12096         case 0xff: str="0kbps"; break;
12097         default: str="This should not happen - BUG";
12098     }
12099
12100     if (( oct >= 1 ) && ( oct <= 0x3f ))
12101             proto_tree_add_text(tree,
12102                 tvb, curr_offset, 1,
12103                 "Guaranteed bit rate for downlink: (%u) %ukbps",oct,oct);
12104     else if (( oct >= 0x40 ) && ( oct <= 0x7f ))
12105             proto_tree_add_text(tree,
12106                 tvb, curr_offset, 1,
12107                 "Guaranteed bit rate for downlink: (%u) %ukbps",oct,(oct-0x40)*8+64);/*same as above*/
12108     else if (( oct >= 0x80 ) && ( oct <= 0xfe ))
12109             proto_tree_add_text(tree,
12110                 tvb, curr_offset, 1,
12111                 "Guaranteed bit rate for downlink: (%u) %ukbps",oct,(oct-0x80)*64+576);/*same as above*/
12112     else
12113             proto_tree_add_text(tree,
12114                 tvb, curr_offset, 1,
12115                 "Guaranteed bit rate for downlink: (%u) %s",oct,str);
12116
12117     curr_offset+= 1;       
12118     curr_len-= 1;
12119     
12120     if ( curr_len == 0 )
12121     {
12122             EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
12123
12124             return(curr_offset - offset);
12125     }
12126
12127     oct = tvb_get_guint8(tvb, curr_offset);
12128
12129     switch ( (oct>>4)&1 )
12130     {
12131         case 0x00: str="Not optimised for signalling traffic"; break;
12132         case 0x01: str="Optimised for signalling traffic"; break;
12133         default: str="This should not happen - BUG";
12134     }
12135
12136     proto_tree_add_text(tree,
12137         tvb, curr_offset, 1,
12138         "Signalling Indication: (%u) %s",(oct>>4)&1,str);
12139
12140     switch ( oct&7 )
12141     {
12142         case 0x00: str="unknown"; break;
12143         case 0x01: str="speech"; break;
12144         default: str="unknown";
12145     }
12146
12147     proto_tree_add_text(tree,
12148         tvb, curr_offset, 1,
12149         "Source Statistics Descriptor: (%u) %s",oct&7,str);
12150
12151     curr_offset+= 1;       
12152     curr_len-= 1;
12153     
12154     if ( curr_len == 0 )
12155     {
12156             EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
12157
12158             return(curr_offset - offset);
12159     }
12160
12161
12162     oct = tvb_get_guint8(tvb, curr_offset);
12163
12164     switch ( oct )
12165     {
12166         case 0x00: str="Use the value indicated by the Maximum bit rate for downlink"; break;
12167         default: str="Unspecified";
12168     }
12169
12170     if (( oct >= 1 ) && ( oct <= 0x3f ))
12171             proto_tree_add_text(tree,
12172                 tvb, curr_offset, 1,
12173                 "Maximum bit rate for downlink (extended): (%u) %ukbps",oct,oct*100);
12174     else
12175             proto_tree_add_text(tree,
12176                 tvb, curr_offset, 1,
12177                 "Maximum bit rate for downlink (extended): (%u) %s",oct,str);
12178
12179     curr_offset+= 1;       
12180     curr_len-= 1;
12181     
12182     if ( curr_len == 0 )
12183     {
12184             EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
12185
12186             return(curr_offset - offset);
12187     }
12188
12189     oct = tvb_get_guint8(tvb, curr_offset);
12190
12191     switch ( oct )
12192     {
12193         case 0x00: str="Use the value indicated by the Guaranteed bit rate for downlink"; break;
12194         default: str="Unspecified";
12195     }
12196
12197     if (( oct >= 1 ) && ( oct <= 0x4a ))
12198             proto_tree_add_text(tree,
12199                 tvb, curr_offset, 1,
12200                 "Guaranteed bit rate for downlink (extended): (%u) %ukbps",oct,oct*100);
12201     else
12202             proto_tree_add_text(tree,
12203                 tvb, curr_offset, 1,
12204                 "Guaranteed bit rate for downlink (extended): (%u) %s",oct,str);
12205
12206     curr_offset+= 1;       
12207     curr_len-= 1;
12208     
12209     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
12210
12211     return(curr_offset - offset);
12212 }
12213
12214 /*
12215  * [8] 10.5.6.6 SM cause
12216  */
12217 static guint8
12218 de_sm_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len _U_)
12219 {
12220     guint8      oct;
12221     guint32     curr_offset;
12222     const gchar *str;
12223     
12224     len = len;
12225     curr_offset = offset;
12226
12227     oct = tvb_get_guint8(tvb, curr_offset);
12228
12229     switch ( oct )
12230     {
12231         case 0x08: str="Operator Determined Barring"; break;
12232         case 0x18: str="MBMS bearer capabilities insufficient for the service"; break;
12233         case 0x19: str="LLC or SNDCP failure(GSM only)"; break;
12234         case 0x1a: str="Insufficient resources"; break;
12235         case 0x1b: str="Missing or unknown APN"; break;
12236         case 0x1c: str="Unknown PDP address or PDP type"; break;
12237         case 0x1d: str="User Aauthentication failed"; break;
12238         case 0x1e: str="Activation rejected by GGSN"; break;
12239         case 0x1f: str="Activation rejected, unspecified"; break;
12240         case 0x20: str="Service option not supported"; break;
12241         case 0x21: str="Requested service option not subscribed"; break;
12242         case 0x22: str="Service option temporarily out of order"; break;
12243         case 0x23: str="NSAPI already used (not sent)"; break;
12244         case 0x24: str="Regular deactivation"; break;
12245         case 0x25: str="QoS not accepted"; break;
12246         case 0x26: str="Network failure"; break;
12247         case 0x27: str="Reactivation required"; break;
12248         case 0x28: str="Feature not supported"; break;
12249         case 0x29: str="Semantic error in the TFT operation"; break;
12250         case 0x2a: str="Syntactical error in the TFT operation"; break;
12251         case 0x2b: str="Unknown PDP context"; break;
12252         case 0x2e: str="PDP context without TFT already activated"; break;
12253         case 0x2f: str="Multicast group membership time-out"; break;
12254         case 0x2c: str="Semantic errors in packet filter(s)"; break;
12255         case 0x2d: str="Syntactical errors in packet filter(s)"; break;
12256         case 0x51: str="Invalid transaction identifier value"; break;
12257         case 0x5f: str="Semantically incorrect message"; break;
12258         case 0x60: str="Invalid mandatory information"; break;
12259         case 0x61: str="Message type non-existent or not implemented"; break;
12260         case 0x62: str="Message type not compatible with the protocol state"; break;
12261         case 0x63: str="Information element non-existent or not implemented"; break;
12262         case 0x64: str="Conditional IE error"; break;
12263         case 0x65: str="Message not compatible with the protocol state"; break;
12264         case 0x6f: str="Protocol error, unspecified"; break;
12265         case 0x70: str="APN restriction value incompatible with active PDP context"; break;
12266         default: str="Protocol error, unspecified"; break;
12267     }
12268
12269     proto_tree_add_text(tree,
12270         tvb, curr_offset, 1,
12271         "Cause: (%u) %s %s",
12272         oct, str,add_string ? add_string : "");
12273
12274     curr_offset++;
12275
12276     return(curr_offset - offset);
12277 }
12278
12279 /*
12280  * [7] 10.5.6.7
12281  */
12282 static guint8
12283 de_sm_linked_ti(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
12284 {
12285     guint32     curr_offset;
12286     guint       curr_len;
12287     gchar       oct;
12288
12289     gchar       ti_flag[2][80]={ "The message is sent from the side that originates the TI" ,
12290                         "The message is sent to the side that originates the TI" };
12291     
12292     curr_len = len;
12293     curr_offset = offset;
12294
12295     oct = tvb_get_guint8(tvb, curr_offset);
12296
12297     proto_tree_add_text(tree,
12298         tvb, curr_offset, 1,
12299         "TI flag: (%u) %s",oct>>7,ti_flag[oct>>7]);
12300
12301     if ( curr_len > 1 )
12302     {
12303         oct = tvb_get_guint8(tvb, curr_offset);
12304         
12305         proto_tree_add_text(tree,
12306         tvb, curr_offset, 1,
12307         "TI value: 0x%02x (%u)",oct&0x7f,oct&0x7f);
12308
12309         proto_tree_add_text(tree,
12310         tvb, curr_offset, 1,
12311         "ext: 0x%02x (%u)",oct>>7,oct>>7);
12312
12313     }
12314     else
12315     {
12316         proto_tree_add_text(tree,
12317         tvb, curr_offset, 1,
12318         "TI value: 0x%02x (%u)",(oct>>4)&7,(oct>>4)&7);
12319     }
12320
12321     curr_offset+= curr_len;        
12322                    
12323     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
12324
12325     return(curr_offset - offset);
12326 }
12327
12328 /*
12329  * [7] 10.5.6.9
12330  */
12331 static guint8
12332 de_sm_sapi(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len _U_)
12333 {
12334     guint8      oct;
12335     guint32     curr_offset;
12336     
12337     len = len;
12338     curr_offset = offset;
12339
12340     oct = tvb_get_guint8(tvb, curr_offset);
12341
12342     proto_tree_add_text(tree,
12343         tvb, curr_offset, 1,
12344         "LLC SAPI: 0x%02x (%u) %s",
12345         oct&0x0f, oct&0x0f,add_string ? add_string : "");
12346
12347     curr_offset++;
12348
12349     return(curr_offset - offset);
12350 }
12351
12352 /*
12353  * [7] 10.5.6.10
12354  */
12355 static guint8
12356 de_sm_tear_down(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len _U_)
12357 {
12358     guint8      oct;
12359     guint32     curr_offset;
12360     gchar       str[2][30] = { "tear down not requested" , "tear down requested" };
12361     
12362     len = len;
12363     curr_offset = offset;
12364
12365     oct = tvb_get_guint8(tvb, curr_offset);
12366
12367     proto_tree_add_text(tree,
12368         tvb, curr_offset, 1,
12369         "Tear Down Indicator: (%u) %s %s",
12370         oct&1, str[oct&1],add_string ? add_string : "");
12371
12372     curr_offset++;
12373
12374     return(curr_offset - offset);
12375 }
12376
12377 /*
12378  * [7] 10.5.6.11
12379  */
12380 /* Packet Flow Identifier value (octet 3) */
12381 static const value_string gsm_a_packet_flow_id_vals[] = {
12382         { 0,            "Best Effort"},
12383         { 1,            "Signaling"},
12384         { 2,            "SMS"},
12385         { 3,            "TOM8"},
12386         { 4,            "reserved"},
12387         { 5,            "reserved"},
12388         { 6,            "reserved"},
12389         { 7,            "reserved"},
12390         { 0,    NULL }
12391 };
12392 guint8
12393 de_sm_pflow_id(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
12394 {
12395     guint32     curr_offset;
12396     guint       curr_len;
12397     guchar      oct;
12398     
12399     curr_len = len;
12400     curr_offset = offset;
12401
12402     oct = tvb_get_guint8(tvb, curr_offset);
12403
12404     proto_tree_add_text(tree,
12405         tvb, curr_offset, 1,
12406         "Packet Flow Identifier: (%u) %s",oct&0x7f,
12407                 val_to_str(oct&0x7f, gsm_a_packet_flow_id_vals, "dynamically assigned (%u)"));
12408
12409     curr_offset+= curr_len;        
12410                    
12411     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
12412
12413     return(curr_offset - offset);
12414 }
12415
12416 /*
12417  * [7] 10.5.6.12     TFT - Traffic Flow Template
12418  */
12419 /* TFT operation code (octet 3) */
12420 static const value_string gsm_a_tft_op_code_vals[] = {
12421         { 0,            "Spare"},
12422         { 1,            "Create new TFT"},
12423         { 2,            "Delete existing TFT"},
12424         { 3,            "Add packet filters to existing TFT"},
12425         { 4,            "Replace packet filters in existing TFT"},
12426         { 5,            "Delete packet filters from existing TFT"},
12427         { 6,            "No TFT operation"},
12428         { 7,            "Reserved"},
12429         { 0,    NULL }
12430 };
12431
12432 static const true_false_string gsm_a_tft_e_bit  = {
12433   "parameters list is included",
12434   "parameters list is not included"
12435 };
12436
12437
12438 static guint8
12439 de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
12440 {
12441     guint32     curr_offset;
12442     guint       curr_len;
12443     proto_item  *tf = NULL;
12444     proto_tree      *tf_tree = NULL;
12445     proto_tree  *comp_tree = NULL;
12446     guchar      op_code;
12447     guchar      pkt_fil_count;
12448     guchar      e_bit;
12449     const gchar *str;
12450     guchar      count;
12451     guchar      oct;
12452     gint pf_length;
12453     gint pf_identifier;
12454     gint pack_component_type;
12455     
12456     curr_len = len;
12457     curr_offset = offset;
12458
12459     /*
12460      * parse first octet. It contain TFT operation code, E bit and Number of packet filters
12461      */
12462     oct = tvb_get_guint8(tvb, curr_offset);
12463
12464     op_code = oct>>5;
12465     pkt_fil_count = oct&0x0f;
12466     e_bit = (oct>>4)&1;
12467
12468         proto_tree_add_item(tree,hf_gsm_a_tft_op_code,tvb,curr_offset,1,FALSE);
12469         proto_tree_add_item(tree,hf_gsm_a_tft_e_bit,tvb,curr_offset,1,FALSE);
12470         proto_tree_add_item(tree,hf_gsm_a_tft_pkt_flt,tvb,curr_offset,1,FALSE);
12471
12472     curr_offset++;
12473     curr_len--;
12474
12475     /* Packet filter list dissect */
12476
12477     count = 0;
12478     if ( op_code == 2 )                 /* delete TFT contains no packet filters. so we will jump over it */
12479         count = pkt_fil_count;
12480     while ( count < pkt_fil_count )
12481     {
12482         tf = proto_tree_add_text(tree,
12483                 tvb, curr_offset, 1,
12484                 "Packet filter %d",count);   /* 0-> 7 */
12485
12486         tf_tree = proto_item_add_subtree(tf, ett_sm_tft );
12487
12488         if ( op_code == 5 )  /* Delete packet filters from existing TFT - just a list of identifiers */
12489
12490         {
12491                 if ((curr_offset-offset)<1) { 
12492                         proto_tree_add_text(tf_tree,tvb, curr_offset, 1,"Not enough data");
12493                         return(curr_offset-offset);
12494                 }
12495                 oct = tvb_get_guint8(tvb, curr_offset);
12496                 curr_offset++;
12497                 curr_len--;
12498
12499                 proto_tree_add_text(tf_tree,
12500                         tvb, curr_offset-1, 1,
12501                         "Packet filter identifier: 0x%02x (%u)",oct,oct );              
12502         }
12503         else                            /* create new, Add packet filters or Replace packet filters */
12504         {
12505                 
12506                 if ((curr_offset-offset)<1) { 
12507                         proto_tree_add_text(tf_tree,tvb, curr_offset, 1,"Not enough data"); 
12508                         return(curr_offset-offset);
12509                 }
12510                 pf_identifier = tvb_get_guint8(tvb, curr_offset);
12511                 curr_offset++;
12512                 curr_len--;
12513
12514                 proto_tree_add_text(tf_tree,
12515                         tvb, curr_offset-1, 1,
12516                         "Packet filter identifier: %u (%u)",pf_identifier, pf_identifier);              
12517
12518                 if ((curr_offset-offset)<1) { 
12519                         proto_tree_add_text(tf_tree,tvb, curr_offset, 1,"Not enough data"); 
12520                         return(curr_offset-offset);
12521                 }
12522                 oct = tvb_get_guint8(tvb, curr_offset);
12523                 curr_offset++;
12524                 curr_len--;
12525
12526                 proto_tree_add_text(tf_tree,
12527                         tvb, curr_offset-1, 1,
12528                         "Packet evaluation precedence: 0x%02x (%u)",oct,oct );          
12529
12530                 if ((curr_offset-offset)<1) { proto_tree_add_text(tf_tree,tvb, curr_offset, 1,"Not enough data"); return(curr_offset-offset);}
12531                 pf_length = tvb_get_guint8(tvb, curr_offset);
12532                 curr_offset++;
12533                 curr_len--;
12534
12535                 proto_tree_add_text(tf_tree,
12536                         tvb, curr_offset-1, 1,
12537                         "Packet filter length: 0x%02x (%u)",pf_length,pf_length );              
12538                 /* New tree for component */
12539
12540         /* Dissect Packet filter Component */
12541                 /* while ( filter_len > 1 ) */
12542                 /* packet filter component type identifier: */
12543
12544                 if (pf_length > 0 ){
12545                         if ((curr_offset-offset)<1) {
12546                                 proto_tree_add_text(tf_tree,tvb, curr_offset, 1,"Not enough data"); 
12547                                 return(curr_offset-offset);
12548                         }
12549                         pack_component_type = tvb_get_guint8(tvb, curr_offset);
12550                         curr_offset++;
12551                         curr_len--;
12552
12553                         tf=proto_tree_add_text(tf_tree,tvb, curr_offset-1, 1,"Packet filter component type identifier: ");
12554                 comp_tree = proto_item_add_subtree(tf, ett_sm_tft );
12555                         
12556                         switch ( pack_component_type ){
12557                                 
12558                                 case 0x10: 
12559                                         str="IPv4 source address type";
12560                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_ip4_address,tvb,curr_offset,4,FALSE);
12561                         curr_offset+=4;
12562                         curr_len-=4;
12563                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_ip4_mask,tvb,curr_offset,4,FALSE);
12564                         curr_offset+=4;
12565                         curr_len-=4;
12566                                         break;
12567  
12568         
12569                                 case 0x20: 
12570                                         str="IPv6 source address type"; 
12571                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_ip6_address,tvb,curr_offset,16,FALSE);
12572                                         curr_offset+=16;
12573                                         curr_len-=16;
12574                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_ip6_mask,tvb,curr_offset,16,FALSE);
12575                                         curr_offset+=16;
12576                                         curr_len-=16;
12577                                         break;
12578
12579                                 case 0x30: 
12580                                         str="Protocol identifier/Next header type";
12581                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_protocol_header,tvb,curr_offset,1,FALSE);
12582                                         curr_offset+=1;
12583                                         curr_len-=1;
12584                                         break;
12585
12586                                 case 0x40: 
12587                                         str="Single destination port type";
12588                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_port,tvb,curr_offset,2,FALSE);
12589                                         curr_offset+=2;
12590                                         curr_len-=2;
12591
12592                                 case 0x41: 
12593                                         str="Destination port range type";
12594                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_port_low,tvb,curr_offset,2,FALSE);
12595                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_port_high,tvb,curr_offset,2,FALSE);
12596                                         curr_offset+=4;
12597                                         curr_len-=4;
12598                                         break;
12599
12600                                 case 0x50: 
12601                                         str="Single source port type";
12602                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_port,tvb,curr_offset,2,FALSE);
12603                                         curr_offset+=2;
12604                                         curr_len-=2;
12605                                         break;
12606
12607                                 case 0x51: 
12608                                         str="Source port range type";
12609                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_port_low,tvb,curr_offset,2,FALSE);
12610                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_port_high,tvb,curr_offset,2,FALSE);
12611                                         curr_offset+=4;
12612                                         curr_len-=4;
12613                                         break;
12614
12615                                 case 0x60: 
12616                                         str="Security parameter index type";
12617                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_security,tvb,curr_offset,4,FALSE);
12618                                         curr_offset+=4;
12619                                         curr_len-=4;
12620                                         break;
12621
12622
12623                                 case 0x70: 
12624                                         str="Type of service/Traffic class type";
12625                                         proto_tree_add_item(comp_tree,hf_gsm_a_qos_traffic_cls,tvb,curr_offset,1,FALSE);
12626                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_traffic_mask,tvb,curr_offset,1,FALSE);
12627                                         curr_offset+=2;
12628                                         curr_len-=2;
12629                                         break;
12630
12631                                 case 0x80: 
12632                                         str="Flow label type";
12633                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_traffic_mask,tvb,curr_offset,1,FALSE);
12634                                         curr_offset+=3;
12635                                         curr_len-=3;
12636                                         break;
12637
12638                                 default: 
12639                                         str="not specified";
12640                         }
12641                         proto_item_append_text(tf, "(%u) %s", pack_component_type, str );
12642             count++;
12643                         }
12644                 }
12645         }
12646
12647
12648         /* The parameters list contains a variable number of parameters that might need to be
12649          * transferred in addition to the packet filters. If the parameters list is included, the E
12650          * bit is set to 1; otherwise, the E bit is set to 0.
12651          */
12652          if (e_bit == 1){
12653                  proto_tree_add_text(tf_tree, tvb, curr_offset, 1, "Note: Possible Authorizaton Token/Flow Identifier not decoded yet");
12654          }
12655  return(curr_offset - offset);
12656 }
12657
12658 static guint8 (*bssmap_elem_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len) = {
12659     be_cic,     /* Circuit Identity Code */
12660     NULL,       /* Reserved */
12661     NULL,       /* Resource Available */
12662     be_cause,   /* Cause */
12663     be_cell_id, /* Cell Identifier */
12664     be_prio,    /* Priority */
12665     be_l3_header_info,  /* Layer 3 Header Information */
12666     de_mid,     /* IMSI */
12667     be_tmsi,    /* TMSI */
12668     be_enc_info,        /* Encryption Information */
12669     be_chan_type,       /* Channel Type */
12670     NULL,       /* Periodicity */
12671     NULL,       /* Extended Resource Indicator */
12672     NULL,       /* Number Of MSs */
12673     NULL,       /* Reserved */
12674     NULL,       /* Reserved */
12675     NULL,       /* Reserved */
12676     de_ms_cm_2, /* Classmark Information Type 2 */
12677     NULL,       /* Classmark Information Type 3 */
12678     NULL,       /* Interference Band To Be Used */
12679     de_rr_cause,        /* RR Cause */
12680     NULL,       /* Reserved */
12681     be_l3_info, /* Layer 3 Information */
12682     be_dlci,    /* DLCI */
12683     be_down_dtx_flag,   /* Downlink DTX Flag */
12684     be_cell_id_list,    /* Cell Identifier List */
12685     NULL /* no associated data */,      /* Response Request */
12686     NULL,       /* Resource Indication Method */
12687     de_ms_cm_1, /* Classmark Information Type 1 */
12688     NULL,       /* Circuit Identity Code List */
12689     NULL,       /* Diagnostic */
12690     be_l3_msg,  /* Layer 3 Message Contents */
12691     be_chosen_chan,     /* Chosen Channel */
12692     NULL,       /* Total Resource Accessible */
12693     be_ciph_resp_mode,  /* Cipher Response Mode */
12694     be_cha_needed,      /* Channel Needed */
12695     NULL,       /* Trace Type */
12696     NULL,       /* TriggerID */
12697     NULL,       /* Trace Reference */
12698     NULL,       /* TransactionID */
12699     de_mid,     /* Mobile Identity */
12700     NULL,       /* OMCID */
12701     be_for_ind, /* Forward Indicator */
12702     be_chosen_enc_alg,  /* Chosen Encryption Algorithm */
12703     be_cct_pool,        /* Circuit Pool */
12704     NULL,       /* Circuit Pool List */
12705     NULL,       /* Time Indication */
12706     NULL,       /* Resource Situation */
12707     be_curr_chan_1,     /* Current Channel Type 1 */
12708     be_que_ind, /* Queueing Indicator */
12709     be_speech_ver,      /* Speech Version */
12710     NULL,       /* Assignment Requirement */
12711     NULL /* no associated data */,      /* Talker Flag */
12712     NULL /* no associated data */,      /* Connection Release Requested */
12713     NULL,       /* Group Call Reference */
12714     NULL,       /* eMLPP Priority */
12715     NULL,       /* Configuration Evolution Indication */
12716     NULL /* no decode required */,      /* Old BSS to New BSS Information */
12717     NULL,       /* LSA Identifier */
12718     NULL,       /* LSA Identifier List */
12719     NULL,       /* LSA Information */
12720     NULL,       /* LCS QoS */
12721     NULL,       /* LSA access control suppression */
12722     NULL,       /* LCS Priority */
12723     NULL,       /* Location Type */
12724     NULL,       /* Location Estimate */
12725     NULL,       /* Positioning Data */
12726     NULL,       /* LCS Cause */
12727     NULL,       /* LCS Client Type */
12728     be_apdu,    /* APDU */
12729     NULL,       /* Network Element Identity */
12730     NULL,       /* GPS Assistance Data */
12731     NULL,       /* Deciphering Keys */
12732     NULL,       /* Return Error Request */
12733     NULL,       /* Return Error Cause */
12734     NULL,       /* Segmentation */
12735     NULL,       /* NONE */
12736 };
12737
12738 static guint8 (*dtap_elem_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len) = {
12739     /* Common Information Elements 10.5.1 */
12740     de_cell_id, /* Cell Identity */
12741     NULL /* handled inline */,  /* Ciphering Key Sequence Number */
12742     de_lai,     /* Location Area Identification */
12743     de_mid,     /* Mobile Identity */
12744     de_ms_cm_1, /* Mobile Station Classmark 1 */
12745     de_ms_cm_2, /* Mobile Station Classmark 2 */
12746     NULL,               /* Mobile Station Classmark 3 */
12747     de_d_gb_call_ref,   /* Descriptive group or broadcast call reference */
12748     NULL /* handled inline */,  /* Group Cipher Key Number */
12749     de_pd_sapi, /* PD and SAPI $(CCBS)$ */
12750         /* Pos 10 */
12751     de_prio /* handled inline */,       /* Priority Level */
12752     de_plmn_list,       /* PLMN List */
12753     /* Radio Resource Management  Information Elements 10.5.2, most are from 10.5.1 */
12754 /*
12755  * [3]  10.5.2.1a       BA Range
12756  */
12757         de_rr_cell_ch_dsc,                              /* [3]  10.5.2.1b       Cell Channel Description        */
12758 /* [3]  10.5.2.1c       BA List Pref
12759  * [3]  10.5.2.1d       UTRAN Frequency List
12760  * [3]  10.5.2.1e       Cell selection indicator after release of all TCH and SDCCH IE
12761  */
12762         de_rr_cell_dsc,                                 /* 10.5.2.2   RR Cell Description                               */
12763 /*
12764  * [3]  10.5.2.3        Cell Options (BCCH)     
12765  * [3]  10.5.2.3a       Cell Options (SACCH)
12766  * [3]  10.5.2.4        Cell Selection Parameters
12767  * [3]  10.5.2.4a       (void)
12768  */
12769         de_rr_ch_dsc,                                   /* [3]  10.5.2.5        Channel Description                     */
12770         de_rr_ch_dsc2,                                  /* [3]  10.5.2.5a   RR Channel Description 2    */
12771         de_rr_ch_mode,                                  /* [3]  10.5.2.6        Channel Mode                            */
12772         de_rr_ch_mode2,                                 /* [3]  10.5.2.7        Channel Mode 2                          */
12773 /*
12774  * [3]  10.5.2.7a       UTRAN predefined configuration status information / START-CS / UE CapabilityUTRAN Classmark information element 218
12775  * [3]  10.5.2.7b       (void) */
12776
12777         de_rr_cm_enq_mask,                              /* [3]  10.5.2.7c       Classmark Enquiry Mask          */
12778 /* [3]  10.5.2.7d       GERAN Iu Mode Classmark information element                                             */
12779         de_rr_chnl_needed,                              /* [3]  10.5.2.8        Channel Needed
12780  * [3]  10.5.2.8a       (void)  
12781  * [3]  10.5.2.8b       Channel Request Description 2 */
12782         /* Pos 20 */
12783         de_rr_cip_mode_set,                                     /* [3]  10.5.2.9        Cipher Mode Setting             */
12784 /* [3]  10.5.2.10       Cipher Response
12785  * [3]  10.5.2.11       Control Channel Description
12786  * [3]  10.5.2.11a      DTM Information Details */
12787         de_rr_dyn_arfcn_map,                            /* [3]  10.5.2.11b      Dynamic ARFCN Mapping           */
12788         de_rr_freq_ch_seq,                                      /* [3]  10.5.2.12       Frequency Channel Sequence      */
12789         de_rr_freq_list,                                        /* [3]  10.5.2.13       Frequency List                          */
12790         de_rr_freq_short_list,                          /* [3]  10.5.2.14       Frequency Short List            */
12791         de_rr_freq_short_list2,                         /* [3]  10.5.2.14a      Frequency Short List 2          */
12792 /* [3]  10.5.2.14b      Group Channel Description
12793  * [3]  10.5.2.14c      GPRS Resumption
12794  * [3]  10.5.2.14d      GPRS broadcast information
12795  * [3]  10.5.2.14e      Enhanced DTM CS Release Indication
12796  */
12797         de_rr_ho_ref,                                   /* 10.5.2.15  Handover Reference                                */
12798 /*
12799  * [3] 10.5.2.16 IA Rest Octets
12800  * [3] 10.5.2.17 IAR Rest Octets
12801  * [3] 10.5.2.18 IAX Rest Octets
12802  * [3] 10.5.2.19 L2 Pseudo Length
12803  * [3] 10.5.2.20 Measurement Results
12804  * [3] 10.5.2.20a GPRS Measurement Results
12805  */
12806         de_rr_mob_all,                                  /* [3] 10.5.2.21 Mobile Allocation                              */
12807         de_rr_mob_time_diff,                    /* [3] 10.5.2.21a Mobile Time Difference                */
12808         de_rr_multirate_conf,                   /* [3] 10.5.2.21aa MultiRate configuration              */
12809         /* Pos 30 */
12810         de_rr_mult_all,                                 /* [3] 10.5.2.21b Multislot Allocation                  */
12811 /*
12812  * [3] 10.5.2.21c NC mode
12813  * [3] 10.5.2.22 Neighbour Cell Description
12814  * [3] 10.5.2.22a Neighbour Cell Description 2
12815  * [3] 10.5.2.22b (void)
12816  * [3] 10.5.2.22c NT/N Rest Octets
12817  * [3] 10.5.2.23 P1 Rest Octets
12818  * [3] 10.5.2.24 P2 Rest Octets
12819  * [3] 10.5.2.25 P3 Rest Octets
12820  * [3] 10.5.2.25a Packet Channel Description
12821  * [3] 10.5.2.25b Dedicated mode or TBF
12822  * [3] 10.5.2.25c RR Packet Uplink Assignment
12823  * [3] 10.5.2.25d RR Packet Downlink Assignment
12824  * [3] 10.5.2.26 Page Mode
12825  * [3] 10.5.2.26a (void)
12826  * [3] 10.5.2.26b (void)
12827  * [3] 10.5.2.26c (void)
12828  * [3] 10.5.2.26d (void)
12829  * [3] 10.5.2.27 NCC Permitted
12830  */
12831         de_rr_pow_cmd,                                  /* 10.5.2.28  Power Command                                             */
12832         de_rr_pow_cmd_and_acc_type,             /* 10.5.2.28a Power Command and access type             */
12833 /*
12834  * [3] 10.5.2.29 RACH Control Parameters
12835  * [3] 10.5.2.30 Request Reference
12836  */
12837     de_rr_cause,                                        /* 10.5.2.31  RR Cause                                                  */
12838         de_rr_sync_ind,                                 /* 10.5.2.39  Synchronization Indication                */
12839 /* [3] 10.5.2.32 SI 1 Rest Octets
12840  * [3] 10.5.2.33 SI 2bis Rest Octets 
12841  * [3] 10.5.2.33a SI 2ter Rest Octets
12842  * [3] 10.5.2.33b SI 2quater Rest Octets
12843  * [3] 10.5.2.34 SI 3 Rest Octets
12844  * [3] 10.5.2.35 SI 4 Rest Octets
12845  * [3] 10.5.2.35a SI 6 Rest Octets
12846  * [3] 10.5.2.36 SI 7 Rest Octets
12847  * [3] 10.5.2.37 SI 8 Rest Octets
12848  * [3] 10.5.2.37a SI 9 Rest Octets
12849  * [3] 10.5.2.37b SI 13 Rest Octets
12850  * [3] 10.5.2.37c (void)
12851  * [3] 10.5.2.37d (void)
12852  * [3] 10.5.2.37e SI 16 Rest Octets
12853  * [3] 10.5.2.37f SI 17 Rest Octets
12854  * [3] 10.5.2.37g SI 19 Rest Octets
12855  * [3] 10.5.2.37h SI 18 Rest Octets
12856  * [3] 10.5.2.37i SI 20 Rest Octets */
12857         de_rr_starting_time,                            /* [3] 10.5.2.38 Starting Time                                  */
12858         de_rr_timing_adv,                                       /* [3] 10.5.2.40 Timing Advance                                 */ 
12859         de_rr_time_diff,                                        /* [3] 10.5.2.41 Time Difference                                */
12860         de_rr_tlli,                                                     /* [3] 10.5.2.41a TLLI                                                  */
12861 /*
12862  * [3] 10.5.2.42 TMSI/P-TMSI */
12863         de_rr_vgcs_tar_mode_ind,                        /* [3] 10.5.2.42a VGCS target mode Indication   */
12864         /* Pos 40 */
12865         de_rr_vgcs_cip_par,                                     /* [3] 10.5.2.42b       VGCS Ciphering Parameters       */
12866 /* [3] 10.5.2.43 Wait Indication
12867  * [3] 10.5.2.44 SI10 rest octets $(ASCI)$
12868  * [3] 10.5.2.45 EXTENDED MEASUREMENT RESULTS
12869  * [3] 10.5.2.46 Extended Measurement Frequency List */
12870         de_rr_sus_cau,                                          /* [3] 10.5.2.47 Suspension Cause                               */
12871 /* [3] 10.5.2.48 APDU ID 
12872  * [3] 10.5.2.49 APDU Flags
12873  * [3] 10.5.2.50 APDU Data
12874  * [3] 10.5.2.51 Handover To UTRAN Command
12875  * [3] 10.5.2.52 Handover To cdma2000 Command 
12876  * [3] 10.5.2.53 (void)
12877  * [3] 10.5.2.54 (void)
12878  * [3] 10.5.2.55 (void)
12879  * [3] 10.5.2.56 3G Target Cell
12880 */
12881         de_rr_ded_serv_inf,                                     /* [3] 10.5.2.59        Dedicated Service Information */
12882
12883         /* Mobility Management Information Elements 10.5.3 */
12884     de_auth_param_rand, /* Authentication Parameter RAND */
12885     de_auth_param_autn, /* Authentication Parameter AUTN (UMTS authentication challenge only) */
12886     de_auth_resp_param, /* Authentication Response Parameter */
12887     de_auth_resp_param_ext,     /* Authentication Response Parameter (extension) (UMTS authentication challenge only) */
12888     de_auth_fail_param, /* Authentication Failure Parameter (UMTS authentication challenge only) */
12889     NULL /* handled inline */,  /* CM Service Type */
12890     NULL /* handled inline */,  /* Identity Type */
12891         /* Pos 50 */
12892     NULL /* handled inline */,  /* Location Updating Type */
12893     de_network_name,    /* Network Name */
12894     de_rej_cause,       /* Reject Cause */
12895     NULL /* no associated data */,      /* Follow-on Proceed */
12896     de_time_zone,       /* Time Zone */
12897     de_time_zone_time,  /* Time Zone and Time */
12898     NULL /* no associated data */,      /* CTS Permission */
12899     de_lsa_id,  /* LSA Identifier */
12900     de_day_saving_time, /* Daylight Saving Time */
12901     NULL, /* Emergency Number List */
12902     /* Call Control Information Elements 10.5.4 */
12903         /* Pos 60 */
12904     de_aux_states,      /* Auxiliary States */
12905     de_bearer_cap,      /* Bearer Capability */
12906     de_cc_cap,  /* Call Control Capabilities */
12907     de_call_state,      /* Call State */
12908     de_cld_party_bcd_num,       /* Called Party BCD Number */
12909     de_cld_party_sub_addr,      /* Called Party Subaddress */
12910     de_clg_party_bcd_num,       /* Calling Party BCD Number */
12911     de_clg_party_sub_addr,      /* Calling Party Subaddress */
12912     de_cause,   /* Cause */
12913     NULL /* no associated data */,      /* CLIR Suppression */
12914     NULL /* no associated data */,      /* CLIR Invocation */
12915     NULL /* handled inline */,  /* Congestion Level */
12916     NULL,       /* Connected Number */
12917     NULL,       /* Connected Subaddress */
12918     de_facility,        /* Facility */
12919     NULL,       /* High Layer Compatibility */
12920     de_keypad_facility, /* Keypad Facility */
12921     de_llc,                                                     /* 10.5.4.18 Low layer compatibility */
12922     NULL,       /* More Data */
12923     NULL,       /* Notification Indicator */
12924     de_prog_ind,        /* Progress Indicator */
12925     NULL,       /* Recall type $(CCBS)$ */
12926     NULL,       /* Redirecting Party BCD Number */
12927     NULL,       /* Redirecting Party Subaddress */
12928     de_repeat_ind,      /* Repeat Indicator */
12929     NULL /* no associated data */,      /* Reverse Call Setup Direction */
12930     NULL,       /* SETUP Container $(CCBS)$ */
12931     NULL,       /* Signal */
12932     de_ss_ver_ind,      /* SS Version Indicator */
12933     NULL,       /* User-user */
12934     NULL,       /* Alerting Pattern $(NIA)$ */
12935     NULL,       /* Allowed Actions $(CCBS)$ */
12936     NULL,       /* Stream Identifier */
12937     NULL,       /* Network Call Control Capabilities */
12938     NULL,       /* Cause of No CLI */
12939     NULL,       /* Immediate Modification Indicator */
12940     NULL,       /* Supported Codec List */
12941     NULL,       /* Service Category */
12942     /* GPRS Mobility Management Information Elements 10.5.5 */
12943     de_gmm_attach_res,  /* Attach Result */
12944     de_gmm_attach_type, /* Attach Type */
12945     de_gmm_ciph_alg,    /* Cipher Algorithm */
12946     de_gmm_tmsi_stat,   /* TMSI Status */
12947     de_gmm_detach_type, /* Detach Type */
12948     de_gmm_drx_param,   /* DRX Parameter */
12949     de_gmm_ftostby,     /* Force to Standby */
12950     de_gmm_ftostby_h,   /* Force to Standby - Info is in the high nibble */
12951     de_gmm_ptmsi_sig,   /* P-TMSI Signature */
12952     de_gmm_ptmsi_sig2,  /* P-TMSI Signature 2 */
12953     de_gmm_ident_type2, /* Identity Type 2 */
12954     de_gmm_imeisv_req,  /* IMEISV Request */
12955     de_gmm_rec_npdu_lst,        /* Receive N-PDU Numbers List */
12956     de_gmm_ms_net_cap,  /* MS Network Capability */
12957     de_gmm_ms_radio_acc_cap,    /* MS Radio Access Capability */
12958     de_gmm_cause,       /* GMM Cause */
12959     de_gmm_rai, /* Routing Area Identification */
12960     de_gmm_update_res,  /* Update Result */
12961     de_gmm_update_type, /* Update Type */
12962     de_gmm_ac_ref_nr,   /* A&C Reference Number */
12963     de_gmm_ac_ref_nr_h, /* A&C Reference Numer - Info is in the high nibble */
12964     de_gmm_service_type,        /* Service Type */
12965     de_gmm_cell_notfi,  /* Cell Notification */
12966     de_gmm_ps_lcs_cap,  /* PS LCS Capability */
12967     de_gmm_net_feat_supp,       /* Network Feature Support */
12968         de_gmm_rat_info_container, /* Inter RAT information container */
12969     /* Short Message Service Information Elements [5] 8.1.4 */
12970     de_cp_user_data,    /* CP-User Data */
12971     de_cp_cause,        /* CP-Cause */
12972     /* Short Message Service Information Elements [5] 8.2 */
12973     de_rp_message_ref,  /* RP-Message Reference */
12974     de_rp_orig_addr,    /* RP-Origination Address */
12975     de_rp_dest_addr,    /* RP-Destination Address */
12976     de_rp_user_data,    /* RP-User Data */
12977     de_rp_cause,        /* RP-Cause */
12978     /* Session Management Information Elements 10.5.6 */
12979     de_sm_apn,  /* Access Point Name */
12980     de_sm_nsapi,        /* Network Service Access Point Identifier */
12981     de_sm_pco,  /* Protocol Configuration Options */
12982     de_sm_pdp_addr,     /* Packet Data Protocol Address */
12983     de_sm_qos,  /* Quality Of Service */
12984     de_sm_cause,        /* SM Cause */
12985     de_sm_linked_ti,    /* Linked TI */
12986     de_sm_sapi, /* LLC Service Access Point Identifier */
12987     de_sm_tear_down,    /* Tear Down Indicator */
12988     de_sm_pflow_id,     /* Packet Flow Identifier */
12989     de_sm_tflow_temp,   /* Traffic Flow Template */
12990     /* GPRS Common Information Elements 10.5.7 */
12991     de_gc_context_stat, /* PDP Context Status */
12992     de_gc_radio_prio,   /* Radio Priority */
12993     de_gc_timer,        /* GPRS Timer */
12994     de_gc_timer2,       /* GPRS Timer 2 */
12995     de_gc_radio_prio2,  /* Radio Priority 2 */
12996         de_gc_mbms_context_stat, /* 10.5.7.6 MBMS context status */
12997     de_gc_spare,        /* Spare Nibble */
12998     NULL,       /* NONE */
12999 };
13000
13001 #define SET_ELEM_VARS(SEV_pdu_type, SEV_elem_names, SEV_elem_ett, SEV_elem_funcs) \
13002     switch (SEV_pdu_type) \
13003     { \
13004     case BSSAP_PDU_TYPE_BSSMAP: \
13005         SEV_elem_names = gsm_bssmap_elem_strings; \
13006         SEV_elem_ett = ett_gsm_bssmap_elem; \
13007         SEV_elem_funcs = bssmap_elem_fcn; \
13008         break; \
13009     case BSSAP_PDU_TYPE_DTAP: \
13010         SEV_elem_names = gsm_dtap_elem_strings; \
13011         SEV_elem_ett = ett_gsm_dtap_elem; \
13012         SEV_elem_funcs = dtap_elem_fcn; \
13013         break; \
13014     default: \
13015         proto_tree_add_text(tree, \
13016             tvb, curr_offset, -1, \
13017             "Unknown PDU type (%u)", SEV_pdu_type); \
13018         return(consumed); \
13019     }
13020
13021 /*
13022  * Type Length Value (TLV) element dissector
13023  */
13024 static guint8
13025 elem_tlv(tvbuff_t *tvb, proto_tree *tree, guint8 iei, gint pdu_type, int idx, guint32 offset, guint len, const gchar *name_add)
13026 {
13027     guint8              oct, parm_len;
13028     guint8              consumed;
13029     guint32             curr_offset;
13030     proto_tree          *subtree;
13031     proto_item          *item;
13032     const value_string  *elem_names;
13033     gint                *elem_ett;
13034     guint8 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len);
13035
13036     len = len;
13037     curr_offset = offset;
13038     consumed = 0;
13039
13040     SET_ELEM_VARS(pdu_type, elem_names, elem_ett, elem_funcs);
13041
13042     oct = tvb_get_guint8(tvb, curr_offset);
13043
13044     if (oct == iei)
13045     {
13046         parm_len = tvb_get_guint8(tvb, curr_offset + 1);
13047
13048         item =
13049             proto_tree_add_text(tree,
13050                 tvb, curr_offset, parm_len + 2,
13051                 "%s%s",
13052                 elem_names[idx].strptr,
13053                 (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
13054
13055         subtree = proto_item_add_subtree(item, elem_ett[idx]);
13056
13057         proto_tree_add_uint(subtree,
13058             (BSSAP_PDU_TYPE_BSSMAP == pdu_type) ? hf_gsm_a_bssmap_elem_id : hf_gsm_a_dtap_elem_id, tvb,
13059             curr_offset, 1, oct);
13060
13061         proto_tree_add_uint(subtree, hf_gsm_a_length, tvb,
13062             curr_offset + 1, 1, parm_len);
13063
13064         if (parm_len > 0)
13065         {
13066             if (elem_funcs[idx] == NULL)
13067             {
13068                 proto_tree_add_text(subtree,
13069                     tvb, curr_offset + 2, parm_len,
13070                     "Element Value");
13071
13072                 consumed = parm_len;
13073             }
13074             else
13075             {
13076                 gchar *a_add_string;
13077
13078                 a_add_string=ep_alloc(1024);
13079                 a_add_string[0] = '\0';
13080                 consumed =
13081                     (*elem_funcs[idx])(tvb, subtree, curr_offset + 2,
13082                         parm_len, a_add_string, 1024);
13083
13084                 if (a_add_string[0] != '\0')
13085                 {
13086                     proto_item_append_text(item, "%s", a_add_string);
13087                 }
13088             }
13089         }
13090
13091         consumed += 2;
13092     }
13093
13094     return(consumed);
13095 }
13096
13097 /*
13098  * Type Value (TV) element dissector
13099  *
13100  * Length cannot be used in these functions, big problem if a element dissector
13101  * is not defined for these.
13102  */
13103 static guint8
13104 elem_tv(tvbuff_t *tvb, proto_tree *tree, guint8 iei, gint pdu_type, int idx, guint32 offset, const gchar *name_add)
13105 {
13106     guint8              oct;
13107     guint8              consumed;
13108     guint32             curr_offset;
13109     proto_tree          *subtree;
13110     proto_item          *item;
13111     const value_string  *elem_names;
13112     gint                *elem_ett;
13113     guint8 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len);
13114
13115     curr_offset = offset;
13116     consumed = 0;
13117
13118     SET_ELEM_VARS(pdu_type, elem_names, elem_ett, elem_funcs);
13119
13120     oct = tvb_get_guint8(tvb, curr_offset);
13121
13122     if (oct == iei)
13123     {
13124         item =
13125             proto_tree_add_text(tree,
13126                 tvb, curr_offset, -1,
13127                 "%s%s",
13128                 elem_names[idx].strptr,
13129                 (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
13130
13131         subtree = proto_item_add_subtree(item, elem_ett[idx]);
13132
13133         proto_tree_add_uint(subtree,
13134             (BSSAP_PDU_TYPE_BSSMAP == pdu_type) ? hf_gsm_a_bssmap_elem_id : hf_gsm_a_dtap_elem_id, tvb,
13135             curr_offset, 1, oct);
13136
13137         if (elem_funcs[idx] == NULL)
13138         {
13139             /* BAD THING, CANNOT DETERMINE LENGTH */
13140
13141             proto_tree_add_text(subtree,
13142                 tvb, curr_offset + 1, 1,
13143                 "No element dissector, rest of dissection may be incorrect");
13144
13145             consumed = 1;
13146         }
13147         else
13148         {
13149             gchar *a_add_string;
13150
13151             a_add_string=ep_alloc(1024);
13152             a_add_string[0] = '\0';
13153             consumed = (*elem_funcs[idx])(tvb, subtree, curr_offset + 1, -1, a_add_string, 1024);
13154
13155             if (a_add_string[0] != '\0')
13156             {
13157                 proto_item_append_text(item, "%s", a_add_string);
13158             }
13159         }
13160
13161         consumed++;
13162
13163         proto_item_set_len(item, consumed);
13164     }
13165
13166     return(consumed);
13167 }
13168
13169 /*
13170  * Type Value (TV) element dissector
13171  * Where top half nibble is IEI and bottom half nibble is value.
13172  *
13173  * Length cannot be used in these functions, big problem if a element dissector
13174  * is not defined for these.
13175  */
13176 static guint8
13177 elem_tv_short(tvbuff_t *tvb, proto_tree *tree, guint8 iei, gint pdu_type, int idx, guint32 offset, const gchar *name_add)
13178 {
13179     guint8              oct;
13180     guint8              consumed;
13181     guint32             curr_offset;
13182     proto_tree          *subtree;
13183     proto_item          *item;
13184     const value_string  *elem_names;
13185     gint                *elem_ett;
13186     guint8 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len);
13187
13188     curr_offset = offset;
13189     consumed = 0;
13190
13191     SET_ELEM_VARS(pdu_type, elem_names, elem_ett, elem_funcs);
13192
13193     oct = tvb_get_guint8(tvb, curr_offset);
13194
13195     if ((oct & 0xf0) == (iei & 0xf0))
13196     {
13197         item =
13198             proto_tree_add_text(tree,
13199                 tvb, curr_offset, -1,
13200                 "%s%s",
13201                 elem_names[idx].strptr,
13202                 (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
13203
13204         subtree = proto_item_add_subtree(item, elem_ett[idx]);
13205
13206         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
13207         proto_tree_add_text(subtree,
13208             tvb, curr_offset, 1,
13209             "%s :  Element ID",
13210             a_bigbuf);
13211
13212         if (elem_funcs[idx] == NULL)
13213         {
13214             /* BAD THING, CANNOT DETERMINE LENGTH */
13215
13216             proto_tree_add_text(subtree,
13217                 tvb, curr_offset, 1,
13218                 "No element dissector, rest of dissection may be incorrect");
13219
13220             consumed++;
13221         }
13222         else
13223         {
13224             gchar *a_add_string;
13225
13226             a_add_string=ep_alloc(1024);
13227             a_add_string[0] = '\0';
13228             consumed = (*elem_funcs[idx])(tvb, subtree, curr_offset, -1, a_add_string, 1024);
13229
13230             if (a_add_string[0] != '\0')
13231             {
13232                 proto_item_append_text(item, "%s", a_add_string);
13233             }
13234         }
13235
13236         proto_item_set_len(item, consumed);
13237     }
13238
13239     return(consumed);
13240 }
13241
13242 /*
13243  * Type (T) element dissector
13244  */
13245 static guint8
13246 elem_t(tvbuff_t *tvb, proto_tree *tree, guint8 iei, gint pdu_type, int idx, guint32 offset, const gchar *name_add)
13247 {
13248     guint8              oct;
13249     guint32             curr_offset;
13250     guint8              consumed;
13251     const value_string  *elem_names;
13252     gint                *elem_ett;
13253     guint8 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len);
13254
13255     curr_offset = offset;
13256     consumed = 0;
13257
13258     SET_ELEM_VARS(pdu_type, elem_names, elem_ett, elem_funcs);
13259
13260     oct = tvb_get_guint8(tvb, curr_offset);
13261
13262     if (oct == iei)
13263     {
13264         proto_tree_add_uint_format(tree,
13265             (BSSAP_PDU_TYPE_BSSMAP == pdu_type) ? hf_gsm_a_bssmap_elem_id : hf_gsm_a_dtap_elem_id, tvb,
13266             curr_offset, 1, oct,
13267             "%s%s",
13268             elem_names[idx].strptr,
13269             (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
13270
13271         consumed = 1;
13272     }
13273
13274     return(consumed);
13275 }
13276
13277 /*
13278  * Length Value (LV) element dissector
13279  */
13280 static guint8
13281 elem_lv(tvbuff_t *tvb, proto_tree *tree, gint pdu_type, int idx, guint32 offset, guint len, const gchar *name_add)
13282 {
13283     guint8              parm_len;
13284     guint8              consumed;
13285     guint32             curr_offset;
13286     proto_tree          *subtree;
13287     proto_item          *item;
13288     const value_string  *elem_names;
13289     gint                *elem_ett;
13290     guint8 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len);
13291
13292     len = len;
13293     curr_offset = offset;
13294     consumed = 0;
13295
13296     SET_ELEM_VARS(pdu_type, elem_names, elem_ett, elem_funcs);
13297
13298     parm_len = tvb_get_guint8(tvb, curr_offset);
13299
13300     item =
13301         proto_tree_add_text(tree,
13302             tvb, curr_offset, parm_len + 1,
13303             "%s%s",
13304             elem_names[idx].strptr,
13305             (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
13306
13307     subtree = proto_item_add_subtree(item, elem_ett[idx]);
13308
13309     proto_tree_add_uint(subtree, hf_gsm_a_length, tvb,
13310         curr_offset, 1, parm_len);
13311
13312     if (parm_len > 0)
13313     {
13314         if (elem_funcs[idx] == NULL)
13315         {
13316             proto_tree_add_text(subtree,
13317                 tvb, curr_offset + 1, parm_len,
13318                 "Element Value");
13319
13320             consumed = parm_len;
13321         }
13322         else
13323         {
13324             gchar *a_add_string;
13325
13326             a_add_string=ep_alloc(1024);
13327             a_add_string[0] = '\0';
13328             consumed =
13329                 (*elem_funcs[idx])(tvb, subtree, curr_offset + 1,
13330                     parm_len, a_add_string, 1024);
13331
13332             if (a_add_string[0] != '\0')
13333             {
13334                 proto_item_append_text(item, "%s", a_add_string);
13335             }
13336         }
13337     }
13338
13339     return(consumed + 1);
13340 }
13341
13342 /*
13343  * Value (V) element dissector
13344  *
13345  * Length cannot be used in these functions, big problem if a element dissector
13346  * is not defined for these.
13347  */
13348 static guint8
13349 elem_v(tvbuff_t *tvb, proto_tree *tree, gint pdu_type, int idx, guint32 offset)
13350 {
13351     guint8              consumed;
13352     guint32             curr_offset;
13353     const value_string  *elem_names;
13354     gint                *elem_ett;
13355     guint8 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len);
13356
13357     curr_offset = offset;
13358     consumed = 0;
13359
13360     SET_ELEM_VARS(pdu_type, elem_names, elem_ett, elem_funcs);
13361
13362     if (elem_funcs[idx] == NULL)
13363     {
13364         /* BAD THING, CANNOT DETERMINE LENGTH */
13365
13366         proto_tree_add_text(tree,
13367             tvb, curr_offset, 1,
13368             "No element dissector, rest of dissection may be incorrect");
13369
13370         consumed = 1;
13371     }
13372     else
13373     {
13374         gchar *a_add_string;
13375
13376         a_add_string=ep_alloc(1024);
13377         a_add_string[0] = '\0';
13378         consumed = (*elem_funcs[idx])(tvb, tree, curr_offset, -1, a_add_string, 1024);
13379     }
13380
13381     return(consumed);
13382 }
13383
13384 #define ELEM_MAND_TLV(EMT_iei, EMT_pdu_type, EMT_elem_idx, EMT_elem_name_addition) \
13385 {\
13386     if ((consumed = elem_tlv(tvb, tree, (guint8) EMT_iei, EMT_pdu_type, EMT_elem_idx, curr_offset, curr_len, EMT_elem_name_addition)) > 0) \
13387     { \
13388         curr_offset += consumed; \
13389         curr_len -= consumed; \
13390     } \
13391     else \
13392     { \
13393         proto_tree_add_text(tree, \
13394             tvb, curr_offset, 0, \
13395             "Missing Mandatory element (0x%02x) %s%s, rest of dissection is suspect", \
13396                 EMT_iei, \
13397                 (EMT_pdu_type == BSSAP_PDU_TYPE_BSSMAP) ? \
13398                     gsm_bssmap_elem_strings[EMT_elem_idx].strptr : gsm_dtap_elem_strings[EMT_elem_idx].strptr, \
13399                 (EMT_elem_name_addition == NULL) || (EMT_elem_name_addition[0] == '\0') ? "" : EMT_elem_name_addition \
13400             ); \
13401     } \
13402     if (curr_len <= 0) return; \
13403 }
13404
13405 #define ELEM_OPT_TLV(EOT_iei, EOT_pdu_type, EOT_elem_idx, EOT_elem_name_addition) \
13406 {\
13407     if ((consumed = elem_tlv(tvb, tree, (guint8) EOT_iei, EOT_pdu_type, EOT_elem_idx, curr_offset, curr_len, EOT_elem_name_addition)) > 0) \
13408     { \
13409         curr_offset += consumed; \
13410         curr_len -= consumed; \
13411     } \
13412     if (curr_len <= 0) return; \
13413 }
13414
13415 #define ELEM_MAND_TV(EMT_iei, EMT_pdu_type, EMT_elem_idx, EMT_elem_name_addition) \
13416 {\
13417     if ((consumed = elem_tv(tvb, tree, (guint8) EMT_iei, EMT_pdu_type, EMT_elem_idx, curr_offset, EMT_elem_name_addition)) > 0) \
13418     { \
13419         curr_offset += consumed; \
13420         curr_len -= consumed; \
13421     } \
13422     else \
13423     { \
13424         proto_tree_add_text(tree, \
13425             tvb, curr_offset, 0, \
13426             "Missing Mandatory element (0x%02x) %s%s, rest of dissection is suspect", \
13427                 EMT_iei, \
13428                 (EMT_pdu_type == BSSAP_PDU_TYPE_BSSMAP) ? \
13429                     gsm_bssmap_elem_strings[EMT_elem_idx].strptr : gsm_dtap_elem_strings[EMT_elem_idx].strptr, \
13430                 (EMT_elem_name_addition == NULL) || (EMT_elem_name_addition[0] == '\0') ? "" : EMT_elem_name_addition \
13431             ); \
13432     } \
13433     if (curr_len <= 0) return; \
13434 }
13435
13436 #define ELEM_OPT_TV(EOT_iei, EOT_pdu_type, EOT_elem_idx, EOT_elem_name_addition) \
13437 {\
13438     if ((consumed = elem_tv(tvb, tree, (guint8) EOT_iei, EOT_pdu_type, EOT_elem_idx, curr_offset, EOT_elem_name_addition)) > 0) \
13439     { \
13440         curr_offset += consumed; \
13441         curr_len -= consumed; \
13442     } \
13443     if (curr_len <= 0) return; \
13444 }
13445
13446 #define ELEM_OPT_TV_SHORT(EOT_iei, EOT_pdu_type, EOT_elem_idx, EOT_elem_name_addition) \
13447 {\
13448     if ((consumed = elem_tv_short(tvb, tree, EOT_iei, EOT_pdu_type, EOT_elem_idx, curr_offset, EOT_elem_name_addition)) > 0) \
13449     { \
13450         curr_offset += consumed; \
13451         curr_len -= consumed; \
13452     } \
13453     if (curr_len <= 0) return; \
13454 }
13455
13456 #define ELEM_OPT_T(EOT_iei, EOT_pdu_type, EOT_elem_idx, EOT_elem_name_addition) \
13457 {\
13458     if ((consumed = elem_t(tvb, tree, (guint8) EOT_iei, EOT_pdu_type, EOT_elem_idx, curr_offset, EOT_elem_name_addition)) > 0) \
13459     { \
13460         curr_offset += consumed; \
13461         curr_len -= consumed; \
13462     } \
13463     if (curr_len <= 0) return; \
13464 }
13465
13466 #define ELEM_MAND_LV(EML_pdu_type, EML_elem_idx, EML_elem_name_addition) \
13467 {\
13468     if ((consumed = elem_lv(tvb, tree, EML_pdu_type, EML_elem_idx, curr_offset, curr_len, EML_elem_name_addition)) > 0) \
13469     { \
13470         curr_offset += consumed; \
13471         curr_len -= consumed; \
13472     } \
13473     else \
13474     { \
13475         /* Mandatory, but nothing we can do */ \
13476     } \
13477     if (curr_len <= 0) return; \
13478 }
13479
13480 #define ELEM_MAND_V(EMV_pdu_type, EMV_elem_idx) \
13481 {\
13482     if ((consumed = elem_v(tvb, tree, EMV_pdu_type, EMV_elem_idx, curr_offset)) > 0) \
13483     { \
13484         curr_offset += consumed; \
13485         curr_len -= consumed; \
13486     } \
13487     else \
13488     { \
13489         /* Mandatory, but nothing we can do */ \
13490     } \
13491     if (curr_len <= 0) return; \
13492 }
13493
13494
13495 /* MESSAGE FUNCTIONS */
13496
13497 /*
13498  *  [2] 3.2.1.1
13499  */
13500 static void
13501 bssmap_ass_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
13502 {
13503     guint32     curr_offset;
13504     guint32     consumed;
13505     guint       curr_len;
13506
13507     curr_offset = offset;
13508     curr_len = len;
13509
13510     is_uplink = IS_UPLINK_FALSE;
13511
13512     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CHAN_TYPE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHAN_TYPE, "");
13513
13514     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_L3_HEADER_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_L3_HEADER_INFO, "");
13515
13516     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_PRIO].value, BSSAP_PDU_TYPE_BSSMAP, BE_PRIO, "");
13517
13518     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
13519
13520     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_DOWN_DTX_FLAG].value, BSSAP_PDU_TYPE_BSSMAP, BE_DOWN_DTX_FLAG, "");
13521
13522     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_INT_BAND].value, BSSAP_PDU_TYPE_BSSMAP, BE_INT_BAND, "");
13523
13524     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CM_INFO_2].value, BSSAP_PDU_TYPE_BSSMAP, BE_CM_INFO_2, "");
13525
13526     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_GROUP_CALL_REF].value, BSSAP_PDU_TYPE_BSSMAP, BE_GROUP_CALL_REF, "");
13527
13528     ELEM_OPT_T(gsm_bssmap_elem_strings[BE_TALKER_FLAG].value, BSSAP_PDU_TYPE_BSSMAP, BE_TALKER_FLAG, "");
13529
13530     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_LSA_ACC_CTRL].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_ACC_CTRL, "");
13531
13532     EXTRANEOUS_DATA_CHECK(curr_len, 0);
13533 }
13534
13535 /*
13536  *  [2] 3.2.1.2
13537  */
13538 static void
13539 bssmap_ass_complete(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
13540 {
13541     guint32     curr_offset;
13542     guint32     consumed;
13543     guint       curr_len;
13544
13545     curr_offset = offset;
13546     curr_len = len;
13547
13548     is_uplink = IS_UPLINK_TRUE;
13549
13550     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_RR_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_RR_CAUSE, "");
13551
13552     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
13553
13554     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
13555
13556     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_CHAN].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_CHAN, "");
13557
13558     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_ENC_ALG].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_ENC_ALG, "");
13559
13560     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CCT_POOL].value, BSSAP_PDU_TYPE_BSSMAP, BE_CCT_POOL, "");
13561
13562     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_SPEECH_VER].value, BSSAP_PDU_TYPE_BSSMAP, BE_SPEECH_VER, " (Chosen)");
13563
13564     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_LSA_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_ID, "");
13565
13566     EXTRANEOUS_DATA_CHECK(curr_len, 0);
13567 }
13568
13569 /*
13570  *  [2] 3.2.1.3
13571  */
13572 static void
13573 bssmap_ass_failure(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
13574 {
13575     guint32     curr_offset;
13576     guint32     consumed;
13577     guint       curr_len;
13578
13579     curr_offset = offset;
13580     curr_len = len;
13581
13582     is_uplink = IS_UPLINK_TRUE;
13583
13584     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
13585
13586     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_RR_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_RR_CAUSE, "");
13587
13588     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CCT_POOL].value, BSSAP_PDU_TYPE_BSSMAP, BE_CCT_POOL, "");
13589
13590     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CCT_POOL_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CCT_POOL_LIST, "");
13591
13592     EXTRANEOUS_DATA_CHECK(curr_len, 0);
13593 }
13594
13595 /*
13596  *  [2] 3.2.1.4
13597  */
13598 static void
13599 bssmap_block(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
13600 {
13601     guint32     curr_offset;
13602     guint32     consumed;
13603     guint       curr_len;
13604
13605     curr_offset = offset;
13606     curr_len = len;
13607
13608     is_uplink = IS_UPLINK_TRUE;
13609
13610     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
13611
13612     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
13613
13614     ELEM_OPT_T(gsm_bssmap_elem_strings[BE_CONN_REL_REQ].value, BSSAP_PDU_TYPE_BSSMAP, BE_CONN_REL_REQ, "");
13615
13616     EXTRANEOUS_DATA_CHECK(curr_len, 0);
13617 }
13618
13619 /*
13620  *  [2] 3.2.1.5
13621  */
13622 static void
13623 bssmap_block_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
13624 {
13625     guint32     curr_offset;
13626     guint32     consumed;
13627     guint       curr_len;
13628
13629     curr_offset = offset;
13630     curr_len = len;
13631
13632     is_uplink = IS_UPLINK_TRUE;
13633
13634     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
13635
13636     EXTRANEOUS_DATA_CHECK(curr_len, 0);
13637 }
13638
13639 /*
13640  *  [2] 3.2.1.6
13641  */
13642 static void
13643 bssmap_unblock(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
13644 {
13645     guint32     curr_offset;
13646     guint32     consumed;
13647     guint       curr_len;
13648
13649     curr_offset = offset;
13650     curr_len = len;
13651
13652     is_uplink = IS_UPLINK_TRUE;
13653
13654     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
13655
13656     ELEM_OPT_T(gsm_bssmap_elem_strings[BE_CONN_REL_REQ].value, BSSAP_PDU_TYPE_BSSMAP, BE_CONN_REL_REQ, "");
13657
13658     EXTRANEOUS_DATA_CHECK(curr_len, 0);
13659 }
13660
13661 /*
13662  *  [2] 3.2.1.7
13663  */
13664 static void
13665 bssmap_unblock_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
13666 {
13667     guint32     curr_offset;
13668     guint32     consumed;
13669     guint       curr_len;
13670
13671     curr_offset = offset;
13672     curr_len = len;
13673
13674     is_uplink = IS_UPLINK_TRUE;
13675
13676     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
13677
13678     EXTRANEOUS_DATA_CHECK(curr_len, 0);
13679 }
13680
13681 /*
13682  *  [2] 3.2.1.8
13683  */
13684 static void
13685 bssmap_ho_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
13686 {
13687     guint32     curr_offset;
13688     guint32     consumed;
13689     guint       curr_len;
13690
13691     curr_offset = offset;
13692     curr_len = len;
13693
13694     is_uplink = IS_UPLINK_FALSE;
13695
13696     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CHAN_TYPE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHAN_TYPE, "");
13697
13698     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_ENC_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_ENC_INFO, "");
13699
13700     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CM_INFO_1].value, BSSAP_PDU_TYPE_BSSMAP, BE_CM_INFO_1, "");
13701
13702     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CM_INFO_2].value, BSSAP_PDU_TYPE_BSSMAP, BE_CM_INFO_2, "");
13703
13704     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, " (Serving)");
13705
13706     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_PRIO].value, BSSAP_PDU_TYPE_BSSMAP, BE_PRIO, "");
13707
13708     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
13709
13710     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_DOWN_DTX_FLAG].value, BSSAP_PDU_TYPE_BSSMAP, BE_DOWN_DTX_FLAG, "");
13711
13712     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, " (Target)");
13713
13714     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_INT_BAND].value, BSSAP_PDU_TYPE_BSSMAP, BE_INT_BAND, "");
13715
13716     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
13717
13718     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CM_INFO_3].value, BSSAP_PDU_TYPE_BSSMAP, BE_CM_INFO_3, "");
13719
13720     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CURR_CHAN_1].value, BSSAP_PDU_TYPE_BSSMAP, BE_CURR_CHAN_1, "");
13721
13722     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_SPEECH_VER].value, BSSAP_PDU_TYPE_BSSMAP, BE_SPEECH_VER, " (Used)");
13723
13724     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_GROUP_CALL_REF].value, BSSAP_PDU_TYPE_BSSMAP, BE_GROUP_CALL_REF, "");
13725
13726     ELEM_OPT_T(gsm_bssmap_elem_strings[BE_TALKER_FLAG].value, BSSAP_PDU_TYPE_BSSMAP, BE_TALKER_FLAG, "");
13727
13728     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CONF_EVO_IND].value, BSSAP_PDU_TYPE_BSSMAP, BE_CONF_EVO_IND, "");
13729
13730     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_ENC_ALG].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_ENC_ALG, " (Serving)");
13731
13732     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_OLD2NEW_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_OLD2NEW_INFO, "");
13733
13734     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_LSA_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_INFO, "");
13735
13736     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_LSA_ACC_CTRL].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_ACC_CTRL, "");
13737
13738     EXTRANEOUS_DATA_CHECK(curr_len, 0);
13739 }
13740
13741 /*
13742  *  [2] 3.2.1.9
13743  */
13744 static void
13745 bssmap_ho_reqd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
13746 {
13747     guint32     curr_offset;
13748     guint32     consumed;
13749     guint       curr_len;
13750
13751     curr_offset = offset;
13752     curr_len = len;
13753
13754     is_uplink = IS_UPLINK_TRUE;
13755
13756     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
13757
13758     ELEM_OPT_T(gsm_bssmap_elem_strings[BE_RESP_REQ].value, BSSAP_PDU_TYPE_BSSMAP, BE_RESP_REQ, "");
13759
13760     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID_LIST, " (Preferred)");
13761
13762     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CCT_POOL_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CCT_POOL_LIST, "");
13763
13764     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CURR_CHAN_1].value, BSSAP_PDU_TYPE_BSSMAP, BE_CURR_CHAN_1, "");
13765
13766     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_SPEECH_VER].value, BSSAP_PDU_TYPE_BSSMAP, BE_SPEECH_VER, " (Used)");
13767
13768     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_QUE_IND].value, BSSAP_PDU_TYPE_BSSMAP, BE_QUE_IND, "");
13769
13770     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_OLD2NEW_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_OLD2NEW_INFO, "");
13771
13772     EXTRANEOUS_DATA_CHECK(curr_len, 0);
13773 }
13774
13775 /*
13776  *  [2] 3.2.1.10
13777  */
13778 static void
13779 bssmap_ho_req_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
13780 {
13781     guint32     curr_offset;
13782     guint32     consumed;
13783     guint       curr_len;
13784
13785     curr_offset = offset;
13786     curr_len = len;
13787
13788     is_uplink = IS_UPLINK_TRUE;
13789
13790     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_L3_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_L3_INFO, "");
13791
13792     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_CHAN].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_CHAN, "");
13793
13794     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_ENC_ALG].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_ENC_ALG, "");
13795
13796     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CCT_POOL].value, BSSAP_PDU_TYPE_BSSMAP, BE_CCT_POOL, "");
13797
13798     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_SPEECH_VER].value, BSSAP_PDU_TYPE_BSSMAP, BE_SPEECH_VER, " (Chosen)");
13799
13800     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
13801
13802     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_LSA_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_ID, "");
13803
13804     EXTRANEOUS_DATA_CHECK(curr_len, 0);
13805 }
13806
13807 /*
13808  *  [2] 3.2.1.11
13809  */
13810 static void
13811 bssmap_ho_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
13812 {
13813     guint32     curr_offset;
13814     guint32     consumed;
13815     guint       curr_len;
13816
13817     curr_offset = offset;
13818     curr_len = len;
13819
13820     is_uplink = IS_UPLINK_FALSE;
13821
13822     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_L3_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_L3_INFO, "");
13823
13824     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
13825
13826     EXTRANEOUS_DATA_CHECK(curr_len, 0);
13827 }
13828
13829 /*
13830  *  [2] 3.2.1.12
13831  */
13832 static void
13833 bssmap_ho_complete(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
13834 {
13835     guint32     curr_offset;
13836     guint32     consumed;
13837     guint       curr_len;
13838
13839     curr_offset = offset;
13840     curr_len = len;
13841
13842     is_uplink = IS_UPLINK_TRUE;
13843
13844     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_RR_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_RR_CAUSE, "");
13845
13846     EXTRANEOUS_DATA_CHECK(curr_len, 0);
13847 }
13848
13849 /*
13850  *  [2] 3.2.1.14
13851  */
13852 static void
13853 bssmap_ho_cand_enq(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
13854 {
13855     guint32     curr_offset;
13856     guint32     consumed;
13857     guint       curr_len;
13858
13859     curr_offset = offset;
13860     curr_len = len;
13861
13862     is_uplink = IS_UPLINK_FALSE;
13863
13864     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_NUM_MS].value, BSSAP_PDU_TYPE_BSSMAP, BE_NUM_MS, "");
13865
13866     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID_LIST, "");
13867
13868     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
13869
13870     EXTRANEOUS_DATA_CHECK(curr_len, 0);
13871 }
13872
13873 /*
13874  *  [2] 3.2.1.15
13875  */
13876 static void
13877 bssmap_ho_cand_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
13878 {
13879     guint32     curr_offset;
13880     guint32     consumed;
13881     guint       curr_len;
13882
13883     curr_offset = offset;
13884     curr_len = len;
13885
13886     is_uplink = IS_UPLINK_TRUE;
13887
13888     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_NUM_MS].value, BSSAP_PDU_TYPE_BSSMAP, BE_NUM_MS, "");
13889
13890     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
13891
13892     EXTRANEOUS_DATA_CHECK(curr_len, 0);
13893 }
13894
13895 /*
13896  *  [2] 3.2.1.16
13897  */
13898 static void
13899 bssmap_ho_failure(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
13900 {
13901     guint32     curr_offset;
13902     guint32     consumed;
13903     guint       curr_len;
13904
13905     curr_offset = offset;
13906     curr_len = len;
13907
13908     is_uplink = IS_UPLINK_TRUE;
13909
13910     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
13911
13912     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_RR_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_RR_CAUSE, "");
13913
13914     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CCT_POOL].value, BSSAP_PDU_TYPE_BSSMAP, BE_CCT_POOL, "");
13915
13916     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CCT_POOL_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CCT_POOL_LIST, "");
13917
13918     EXTRANEOUS_DATA_CHECK(curr_len, 0);
13919 }
13920
13921 /*
13922  *  [2] 3.2.1.19
13923  */
13924 static void
13925 bssmap_paging(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
13926 {
13927     guint32     curr_offset;
13928     guint32     consumed;
13929     guint       curr_len;
13930
13931     curr_offset = offset;
13932     curr_len = len;
13933
13934     is_uplink = IS_UPLINK_FALSE;
13935
13936     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_IMSI].value, BSSAP_PDU_TYPE_BSSMAP, BE_IMSI, "");
13937
13938     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_TMSI].value, BSSAP_PDU_TYPE_BSSMAP, BE_TMSI, "");
13939
13940     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID_LIST, "");
13941
13942     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHAN_NEEDED].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHAN_NEEDED, "");
13943
13944     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_EMLPP_PRIO].value, BSSAP_PDU_TYPE_BSSMAP, BE_EMLPP_PRIO, "");
13945
13946     EXTRANEOUS_DATA_CHECK(curr_len, 0);
13947 }
13948
13949 /*
13950  *  [2] 3.2.1.20
13951  */
13952 static void
13953 bssmap_clear_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
13954 {
13955     guint32     curr_offset;
13956     guint32     consumed;
13957     guint       curr_len;
13958
13959     curr_offset = offset;
13960     curr_len = len;
13961
13962     is_uplink = IS_UPLINK_TRUE;
13963
13964     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
13965
13966     EXTRANEOUS_DATA_CHECK(curr_len, 0);
13967 }
13968
13969 /*
13970  *  [2] 3.2.1.21
13971  */
13972 static void
13973 bssmap_clear_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
13974 {
13975     guint32     curr_offset;
13976     guint32     consumed;
13977     guint       curr_len;
13978
13979     curr_offset = offset;
13980     curr_len = len;
13981
13982     is_uplink = IS_UPLINK_FALSE;
13983
13984     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_L3_HEADER_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_L3_HEADER_INFO, "");
13985
13986     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
13987
13988     EXTRANEOUS_DATA_CHECK(curr_len, 0);
13989 }
13990
13991 /*
13992  *  [2] 3.2.1.23
13993  */
13994 static void
13995 bssmap_reset(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
13996 {
13997     guint32     curr_offset;
13998     guint32     consumed;
13999     guint       curr_len;
14000
14001     curr_offset = offset;
14002     curr_len = len;
14003
14004     is_uplink = IS_UPLINK_UNKNOWN;
14005
14006     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
14007
14008     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14009 }
14010
14011 /*
14012  *  [2] 3.2.1.25
14013  */
14014 static void
14015 bssmap_ho_performed(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14016 {
14017     guint32     curr_offset;
14018     guint32     consumed;
14019     guint       curr_len;
14020
14021     curr_offset = offset;
14022     curr_len = len;
14023
14024     is_uplink = IS_UPLINK_TRUE;
14025
14026     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
14027
14028     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
14029
14030     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_CHAN].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_CHAN, "");
14031
14032     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_ENC_ALG].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_ENC_ALG, "");
14033
14034     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_SPEECH_VER].value, BSSAP_PDU_TYPE_BSSMAP, BE_SPEECH_VER, " (Chosen)");
14035
14036     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_LSA_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_ID, "");
14037
14038     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14039 }
14040
14041 /*
14042  *  [2] 3.2.1.26
14043  */
14044 static void
14045 bssmap_overload(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14046 {
14047     guint32     curr_offset;
14048     guint32     consumed;
14049     guint       curr_len;
14050
14051     curr_offset = offset;
14052     curr_len = len;
14053
14054     is_uplink = IS_UPLINK_TRUE;
14055
14056     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
14057
14058     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
14059
14060     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14061 }
14062
14063 /*
14064  *  [2] 3.2.1.29
14065  */
14066 static void
14067 bssmap_cm_upd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14068 {
14069     guint32     curr_offset;
14070     guint32     consumed;
14071     guint       curr_len;
14072
14073     curr_offset = offset;
14074     curr_len = len;
14075
14076     is_uplink = IS_UPLINK_FALSE;
14077
14078     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CM_INFO_2].value, BSSAP_PDU_TYPE_BSSMAP, BE_CM_INFO_2, "");
14079
14080     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CM_INFO_3].value, BSSAP_PDU_TYPE_BSSMAP, BE_CM_INFO_3, "");
14081
14082     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14083 }
14084
14085 /*
14086  *  [2] 3.2.1.30
14087  */
14088 static void
14089 bssmap_ciph_mode_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14090 {
14091     guint32     curr_offset;
14092     guint32     consumed;
14093     guint       curr_len;
14094
14095     curr_offset = offset;
14096     curr_len = len;
14097
14098     is_uplink = IS_UPLINK_FALSE;
14099
14100     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_L3_HEADER_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_L3_HEADER_INFO, "");
14101
14102     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_ENC_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_ENC_INFO, "");
14103
14104     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CIPH_RESP_MODE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIPH_RESP_MODE, "");
14105
14106     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14107 }
14108
14109 /*
14110  *  [2] 3.2.1.31
14111  */
14112 static void
14113 bssmap_ciph_mode_complete(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14114 {
14115     guint32     curr_offset;
14116     guint32     consumed;
14117     guint       curr_len;
14118
14119     curr_offset = offset;
14120     curr_len = len;
14121
14122     is_uplink = IS_UPLINK_TRUE;
14123
14124     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_L3_MSG].value, BSSAP_PDU_TYPE_BSSMAP, BE_L3_MSG, "");
14125
14126     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_ENC_ALG].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_ENC_ALG, "");
14127
14128     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14129 }
14130
14131 /*
14132  * [2] 3.2.1.32
14133  */
14134 static void
14135 bssmap_cl3_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14136 {
14137     guint8      consumed;
14138     guint32     curr_offset;
14139     guint       curr_len;
14140
14141     curr_offset = offset;
14142     curr_len = len;
14143
14144     is_uplink = IS_UPLINK_TRUE;
14145
14146     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
14147
14148     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_L3_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_L3_INFO, "");
14149
14150     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_CHAN].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_CHAN, "");
14151
14152     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_LSA_ID_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_ID_LIST, "");
14153
14154     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_APDU].value, BSSAP_PDU_TYPE_BSSMAP, BE_APDU, "");
14155
14156     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14157 }
14158
14159 /*
14160  * [2] 3.2.1.34
14161  */
14162 static void
14163 bssmap_sapi_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14164 {
14165     guint8      consumed;
14166     guint32     curr_offset;
14167     guint       curr_len;
14168
14169     curr_offset = offset;
14170     curr_len = len;
14171
14172     is_uplink = IS_UPLINK_TRUE;
14173
14174     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_DLCI].value, BSSAP_PDU_TYPE_BSSMAP, BE_DLCI, "");
14175
14176     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
14177
14178     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14179 }
14180
14181 /*
14182  *  [2] 3.2.1.37
14183  */
14184 static void
14185 bssmap_ho_reqd_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14186 {
14187     guint32     curr_offset;
14188     guint32     consumed;
14189     guint       curr_len;
14190
14191     curr_offset = offset;
14192     curr_len = len;
14193
14194     is_uplink = IS_UPLINK_FALSE;
14195
14196     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
14197
14198     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14199 }
14200
14201 /*
14202  *  [2] 3.2.1.38
14203  */
14204 static void
14205 bssmap_reset_cct(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14206 {
14207     guint32     curr_offset;
14208     guint32     consumed;
14209     guint       curr_len;
14210
14211     curr_offset = offset;
14212     curr_len = len;
14213
14214     is_uplink = IS_UPLINK_TRUE;
14215
14216     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
14217
14218     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
14219
14220     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14221 }
14222
14223 /*
14224  *  [2] 3.2.1.39
14225  */
14226 static void
14227 bssmap_reset_cct_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14228 {
14229     guint32     curr_offset;
14230     guint32     consumed;
14231     guint       curr_len;
14232
14233     curr_offset = offset;
14234     curr_len = len;
14235
14236     is_uplink = IS_UPLINK_TRUE;
14237
14238     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
14239
14240     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14241 }
14242
14243 /*
14244  *  [2] 3.2.1.41
14245  */
14246 static void
14247 bssmap_cct_group_block(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14248 {
14249     guint32     curr_offset;
14250     guint32     consumed;
14251     guint       curr_len;
14252
14253     curr_offset = offset;
14254     curr_len = len;
14255
14256     is_uplink = IS_UPLINK_TRUE;
14257
14258     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
14259
14260     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
14261
14262     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC_LIST, "");
14263
14264     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14265 }
14266
14267 /*
14268  *  [2] 3.2.1.42
14269  */
14270 static void
14271 bssmap_cct_group_block_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14272 {
14273     guint32     curr_offset;
14274     guint32     consumed;
14275     guint       curr_len;
14276
14277     curr_offset = offset;
14278     curr_len = len;
14279
14280     is_uplink = IS_UPLINK_TRUE;
14281
14282     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
14283
14284     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC_LIST, "");
14285
14286     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14287 }
14288
14289 /*
14290  *  [2] 3.2.1.43
14291  */
14292 static void
14293 bssmap_cct_group_unblock(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14294 {
14295     guint32     curr_offset;
14296     guint32     consumed;
14297     guint       curr_len;
14298
14299     curr_offset = offset;
14300     curr_len = len;
14301
14302     is_uplink = IS_UPLINK_TRUE;
14303
14304     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
14305
14306     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC_LIST, "");
14307
14308     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14309 }
14310
14311 /*
14312  *  [2] 3.2.1.44
14313  */
14314 static void
14315 bssmap_cct_group_unblock_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14316 {
14317     guint32     curr_offset;
14318     guint32     consumed;
14319     guint       curr_len;
14320
14321     curr_offset = offset;
14322     curr_len = len;
14323
14324     is_uplink = IS_UPLINK_TRUE;
14325
14326     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
14327
14328     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC_LIST, "");
14329
14330     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14331 }
14332
14333 /*
14334  *  [2] 3.2.1.45
14335  */
14336 static void
14337 bssmap_confusion(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14338 {
14339     guint32     curr_offset;
14340     guint32     consumed;
14341     guint       curr_len;
14342
14343     curr_offset = offset;
14344     curr_len = len;
14345
14346     is_uplink = IS_UPLINK_TRUE;
14347
14348     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
14349
14350     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_DIAG].value, BSSAP_PDU_TYPE_BSSMAP, BE_DIAG, "");
14351
14352     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14353 }
14354
14355 /*
14356  *  [2] 3.2.1.47
14357  */
14358 static void
14359 bssmap_unequipped_cct(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14360 {
14361     guint32     curr_offset;
14362     guint32     consumed;
14363     guint       curr_len;
14364
14365     curr_offset = offset;
14366     curr_len = len;
14367
14368     is_uplink = IS_UPLINK_TRUE;
14369
14370     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
14371
14372     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CIC_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC_LIST, "");
14373
14374     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14375 }
14376
14377 /*
14378  *  [2] 3.2.1.48
14379  */
14380 static void
14381 bssmap_ciph_mode_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14382 {
14383     guint32     curr_offset;
14384     guint32     consumed;
14385     guint       curr_len;
14386
14387     curr_offset = offset;
14388     curr_len = len;
14389
14390     is_uplink = IS_UPLINK_TRUE;
14391
14392     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
14393
14394     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14395 }
14396
14397 /*
14398  *  [2] 3.2.1.49
14399  */
14400 static void
14401 bssmap_load_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14402 {
14403     guint32     curr_offset;
14404     guint32     consumed;
14405     guint       curr_len;
14406
14407     curr_offset = offset;
14408     curr_len = len;
14409
14410     is_uplink = IS_UPLINK_TRUE;
14411
14412     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_TIME_IND].value, BSSAP_PDU_TYPE_BSSMAP, BE_TIME_IND, "");
14413
14414     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
14415
14416     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID_LIST, " (Target)");
14417
14418     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_RES_SIT].value, BSSAP_PDU_TYPE_BSSMAP, BE_RES_SIT, "");
14419
14420     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
14421
14422     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14423 }
14424
14425 /*
14426  *  [2] 3.2.1.66
14427  */
14428 static void
14429 bssmap_change_cct(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14430 {
14431     guint32     curr_offset;
14432     guint32     consumed;
14433     guint       curr_len;
14434
14435     curr_offset = offset;
14436     curr_len = len;
14437
14438     is_uplink = IS_UPLINK_FALSE;
14439
14440     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
14441
14442     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14443 }
14444
14445 /*
14446  *  [2] 3.2.1.67
14447  */
14448 static void
14449 bssmap_change_cct_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14450 {
14451     guint32     curr_offset;
14452     guint32     consumed;
14453     guint       curr_len;
14454
14455     curr_offset = offset;
14456     curr_len = len;
14457
14458     is_uplink = IS_UPLINK_TRUE;
14459
14460     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
14461
14462     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14463 }
14464
14465 /*
14466  *  [2] 3.2.1.68
14467  */
14468 static void
14469 bssmap_common_id(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14470 {
14471     guint32     curr_offset;
14472     guint32     consumed;
14473     guint       curr_len;
14474
14475     curr_offset = offset;
14476     curr_len = len;
14477
14478     is_uplink = IS_UPLINK_FALSE;
14479
14480     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_IMSI].value, BSSAP_PDU_TYPE_BSSMAP, BE_IMSI, "");
14481
14482     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14483 }
14484
14485 /*
14486  *  [2] 3.2.1.69
14487  */
14488 static void
14489 bssmap_lsa_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14490 {
14491     guint32     curr_offset;
14492     guint32     consumed;
14493     guint       curr_len;
14494
14495     curr_offset = offset;
14496     curr_len = len;
14497
14498     is_uplink = IS_UPLINK_FALSE;
14499
14500     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_LSA_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_INFO, "");
14501
14502     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14503 }
14504
14505 /*
14506  *  [2] 3.2.1.70
14507  */
14508 static void
14509 bssmap_conn_oriented(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14510 {
14511     guint32     curr_offset;
14512     guint32     consumed;
14513     guint       curr_len;
14514
14515     curr_offset = offset;
14516     curr_len = len;
14517
14518     is_uplink = IS_UPLINK_FALSE;
14519
14520     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_APDU].value, BSSAP_PDU_TYPE_BSSMAP, BE_APDU, "");
14521
14522     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_SEG].value, BSSAP_PDU_TYPE_BSSMAP, BE_SEG, "");
14523
14524     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14525 }
14526
14527
14528 #define NUM_GSM_BSSMAP_MSG (sizeof(gsm_a_bssmap_msg_strings)/sizeof(value_string))
14529 static gint ett_gsm_bssmap_msg[NUM_GSM_BSSMAP_MSG];
14530 static void (*bssmap_msg_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
14531     bssmap_ass_req,     /* Assignment Request */
14532     bssmap_ass_complete,        /* Assignment Complete */
14533     bssmap_ass_failure, /* Assignment Failure */
14534     bssmap_ho_req,      /* Handover Request */
14535     bssmap_ho_reqd,     /* Handover Required */
14536     bssmap_ho_req_ack,  /* Handover Request Acknowledge */
14537     bssmap_ho_cmd,      /* Handover Command */
14538     bssmap_ho_complete, /* Handover Complete */
14539     NULL /* no associated data */,      /* Handover Succeeded */
14540     bssmap_ho_failure,  /* Handover Failure */
14541     bssmap_ho_performed,        /* Handover Performed */
14542     bssmap_ho_cand_enq, /* Handover Candidate Enquire */
14543     bssmap_ho_cand_resp,        /* Handover Candidate Response */
14544     bssmap_ho_reqd_rej, /* Handover Required Reject */
14545     NULL /* no associated data */,      /* Handover Detect */
14546     bssmap_clear_cmd,   /* Clear Command */
14547     NULL /* no associated data */,      /* Clear Complete */
14548     bssmap_clear_req,   /* Clear Request */
14549     NULL,       /* Reserved */
14550     NULL,       /* Reserved */
14551     bssmap_sapi_rej,    /* SAPI 'n' Reject */
14552     bssmap_confusion,   /* Confusion */
14553     NULL,       /* Suspend */
14554     NULL,       /* Resume */
14555     bssmap_conn_oriented,       /* Connection Oriented Information */
14556     NULL,       /* Perform Location Request */
14557     bssmap_lsa_info,    /* LSA Information */
14558     NULL,       /* Perform Location Response */
14559     NULL,       /* Perform Location Abort */
14560     bssmap_common_id,   /* Common Id */
14561     bssmap_reset,       /* Reset */
14562     NULL /* no associated data */,      /* Reset Acknowledge */
14563     bssmap_overload,    /* Overload */
14564     NULL,       /* Reserved */
14565     bssmap_reset_cct,   /* Reset Circuit */
14566     bssmap_reset_cct_ack,       /* Reset Circuit Acknowledge */
14567     NULL,       /* MSC Invoke Trace */
14568     NULL,       /* BSS Invoke Trace */
14569     NULL,       /* Connectionless Information */
14570     bssmap_block,       /* Block */
14571     bssmap_block_ack,   /* Blocking Acknowledge */
14572     bssmap_unblock,     /* Unblock */
14573     bssmap_unblock_ack, /* Unblocking Acknowledge */
14574     bssmap_cct_group_block,     /* Circuit Group Block */
14575     bssmap_cct_group_block_ack, /* Circuit Group Blocking Acknowledge */
14576     bssmap_cct_group_unblock,   /* Circuit Group Unblock */
14577     bssmap_cct_group_unblock_ack,       /* Circuit Group Unblocking Acknowledge */
14578     bssmap_unequipped_cct,      /* Unequipped Circuit */
14579     bssmap_change_cct,  /* Change Circuit */
14580     bssmap_change_cct_ack,      /* Change Circuit Acknowledge */
14581     NULL,       /* Resource Request */
14582     NULL,       /* Resource Indication */
14583     bssmap_paging,      /* Paging */
14584     bssmap_ciph_mode_cmd,       /* Cipher Mode Command */
14585     bssmap_cm_upd,      /* Classmark Update */
14586     bssmap_ciph_mode_complete,  /* Cipher Mode Complete */
14587     NULL /* no associated data */,      /* Queuing Indication */
14588     bssmap_cl3_info,    /* Complete Layer 3 Information */
14589     NULL /* no associated data */,      /* Classmark Request */
14590     bssmap_ciph_mode_rej,       /* Cipher Mode Reject */
14591     bssmap_load_ind,    /* Load Indication */
14592     NULL,       /* VGCS/VBS Setup */
14593     NULL,       /* VGCS/VBS Setup Ack */
14594     NULL,       /* VGCS/VBS Setup Refuse */
14595     NULL,       /* VGCS/VBS Assignment Request */
14596     NULL,       /* VGCS/VBS Assignment Result */
14597     NULL,       /* VGCS/VBS Assignment Failure */
14598     NULL,       /* VGCS/VBS Queuing Indication */
14599     NULL,       /* Uplink Request */
14600     NULL,       /* Uplink Request Acknowledge */
14601     NULL,       /* Uplink Request Confirmation */
14602     NULL,       /* Uplink Release Indication */
14603     NULL,       /* Uplink Reject Command */
14604     NULL,       /* Uplink Release Command */
14605     NULL,       /* Uplink Seized Command */
14606     NULL,       /* NONE */
14607 };
14608
14609 /*
14610  * [4] 9.2.2
14611  */
14612 static void
14613 dtap_mm_auth_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14614 {
14615     guint32     curr_offset;
14616     guint32     consumed;
14617     guint       curr_len;
14618     guint8      oct;
14619     proto_tree  *subtree;
14620     proto_item  *item;
14621
14622     curr_offset = offset;
14623     curr_len = len;
14624
14625     is_uplink = IS_UPLINK_FALSE;
14626
14627     /*
14628      * special dissection for Cipher Key Sequence Number
14629      */
14630     oct = tvb_get_guint8(tvb, curr_offset);
14631
14632     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
14633     proto_tree_add_text(tree,
14634         tvb, curr_offset, 1,
14635         "%s :  Spare",
14636         a_bigbuf);
14637
14638     item =
14639         proto_tree_add_text(tree,
14640             tvb, curr_offset, 1,
14641             gsm_dtap_elem_strings[DE_CIPH_KEY_SEQ_NUM].strptr);
14642
14643     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CIPH_KEY_SEQ_NUM]);
14644
14645     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
14646     proto_tree_add_text(subtree,
14647         tvb, curr_offset, 1,
14648         "%s :  Spare",
14649         a_bigbuf);
14650
14651     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
14652
14653     switch (oct & 0x07)
14654     {
14655     case 0x07:
14656         proto_tree_add_text(subtree,
14657             tvb, curr_offset, 1,
14658             "%s :  Ciphering Key Sequence Number: No key is available",
14659             a_bigbuf);
14660         break;
14661
14662     default:
14663         proto_tree_add_text(subtree,
14664             tvb, curr_offset, 1,
14665             "%s :  Ciphering Key Sequence Number: %u",
14666             a_bigbuf,
14667             oct & 0x07);
14668         break;
14669     }
14670
14671     curr_offset++;
14672     curr_len--;
14673
14674     if (curr_len <= 0) return;
14675
14676     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_AUTH_PARAM_RAND);
14677
14678     ELEM_OPT_TLV(0x20, BSSAP_PDU_TYPE_DTAP, DE_AUTH_PARAM_AUTN, "");
14679
14680     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14681 }
14682
14683 /*
14684  * [4] 9.2.3
14685  */
14686 static void
14687 dtap_mm_auth_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14688 {
14689     guint32     curr_offset;
14690     guint32     consumed;
14691     guint       curr_len;
14692
14693     curr_offset = offset;
14694     curr_len = len;
14695
14696     is_uplink = IS_UPLINK_TRUE;
14697
14698     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_AUTH_RESP_PARAM);
14699
14700     ELEM_OPT_TLV(0x21, BSSAP_PDU_TYPE_DTAP, DE_AUTH_RESP_PARAM_EXT, "");
14701
14702     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14703 }
14704
14705 /*
14706  * [4] 9.2.3a
14707  */
14708 static void
14709 dtap_mm_auth_fail(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14710 {
14711     guint32     curr_offset;
14712     guint32     consumed;
14713     guint       curr_len;
14714
14715     curr_offset = offset;
14716     curr_len = len;
14717
14718     is_uplink = IS_UPLINK_TRUE;
14719
14720     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_REJ_CAUSE);
14721
14722     ELEM_OPT_TLV(0x22, BSSAP_PDU_TYPE_DTAP, DE_AUTH_FAIL_PARAM, "");
14723
14724     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14725 }
14726
14727 /*
14728  * [3] 9.2.4
14729  */
14730 static void
14731 dtap_mm_cm_reestab_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14732 {
14733     guint32     curr_offset;
14734     guint32     consumed;
14735     guint       curr_len;
14736     guint8      oct;
14737     proto_tree  *subtree;
14738     proto_item  *item;
14739
14740     curr_offset = offset;
14741     curr_len = len;
14742
14743     is_uplink = IS_UPLINK_TRUE;
14744
14745     /*
14746      * special dissection for Cipher Key Sequence Number
14747      */
14748     oct = tvb_get_guint8(tvb, curr_offset);
14749
14750     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
14751     proto_tree_add_text(tree,
14752         tvb, curr_offset, 1,
14753         "%s :  Spare",
14754         a_bigbuf);
14755
14756     item =
14757         proto_tree_add_text(tree,
14758             tvb, curr_offset, 1,
14759             gsm_dtap_elem_strings[DE_CIPH_KEY_SEQ_NUM].strptr);
14760
14761     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CIPH_KEY_SEQ_NUM]);
14762
14763     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
14764     proto_tree_add_text(subtree,
14765         tvb, curr_offset, 1,
14766         "%s :  Spare",
14767         a_bigbuf);
14768
14769     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
14770
14771     switch (oct & 0x07)
14772     {
14773     case 0x07:
14774         proto_tree_add_text(subtree,
14775             tvb, curr_offset, 1,
14776             "%s :  Ciphering Key Sequence Number: No key is available",
14777             a_bigbuf);
14778         break;
14779
14780     default:
14781         proto_tree_add_text(subtree,
14782             tvb, curr_offset, 1,
14783             "%s :  Ciphering Key Sequence Number: %u",
14784             a_bigbuf,
14785             oct & 0x07);
14786         break;
14787     }
14788
14789     curr_offset++;
14790     curr_len--;
14791
14792     if (curr_len <= 0) return;
14793
14794     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MS_CM_2, "");
14795
14796     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID, "");
14797
14798     ELEM_OPT_TV(0x13, BSSAP_PDU_TYPE_DTAP, DE_LAI, "");
14799
14800     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14801 }
14802
14803 /*
14804  * [3] 9.2.5a
14805  */
14806 static void
14807 dtap_mm_cm_srvc_prompt(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14808 {
14809     guint32     curr_offset;
14810     guint32     consumed;
14811     guint       curr_len;
14812
14813     curr_offset = offset;
14814     curr_len = len;
14815
14816     is_uplink = IS_UPLINK_FALSE;
14817
14818     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_PD_SAPI);
14819
14820     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14821 }
14822
14823 /*
14824  * [4] 9.2.6
14825  */
14826 static void
14827 dtap_mm_cm_srvc_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14828 {
14829     guint32     curr_offset;
14830     guint32     consumed;
14831     guint       curr_len;
14832
14833     curr_offset = offset;
14834     curr_len = len;
14835
14836     is_uplink = IS_UPLINK_FALSE;
14837
14838     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_REJ_CAUSE);
14839
14840     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14841 }
14842
14843 /*
14844  * [4] 9.2.8
14845  */
14846 static void
14847 dtap_mm_abort(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14848 {
14849     guint32     curr_offset;
14850     guint32     consumed;
14851     guint       curr_len;
14852
14853     curr_offset = offset;
14854     curr_len = len;
14855
14856     is_uplink = IS_UPLINK_FALSE;
14857
14858     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_REJ_CAUSE);
14859
14860     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14861 }
14862
14863 /*
14864  * [3] 9.2.9
14865  */
14866 static void
14867 dtap_mm_cm_srvc_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14868 {
14869     guint32     curr_offset;
14870     guint32     consumed;
14871     guint       curr_len;
14872     guint8      oct;
14873     proto_tree  *subtree;
14874     proto_item  *item;
14875     const gchar *str;
14876
14877     curr_offset = offset;
14878     curr_len = len;
14879
14880     is_uplink = IS_UPLINK_TRUE;
14881
14882     /*
14883      * special dissection for CM Service Type
14884      */
14885     oct = tvb_get_guint8(tvb, curr_offset);
14886
14887     item =
14888         proto_tree_add_text(tree,
14889             tvb, curr_offset, 1,
14890             gsm_dtap_elem_strings[DE_CIPH_KEY_SEQ_NUM].strptr);
14891
14892     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CIPH_KEY_SEQ_NUM]);
14893
14894     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
14895     proto_tree_add_text(subtree,
14896         tvb, curr_offset, 1,
14897         "%s :  Spare",
14898         a_bigbuf);
14899
14900     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
14901
14902     switch ((oct & 0x70) >> 4)
14903     {
14904     case 0x07:
14905         proto_tree_add_text(subtree,
14906             tvb, curr_offset, 1,
14907             "%s :  Ciphering Key Sequence Number: No key is available",
14908             a_bigbuf);
14909         break;
14910
14911     default:
14912         proto_tree_add_text(subtree,
14913             tvb, curr_offset, 1,
14914             "%s :  Ciphering Key Sequence Number: %u",
14915             a_bigbuf,
14916             (oct & 0x70) >> 4);
14917         break;
14918     }
14919
14920     item =
14921         proto_tree_add_text(tree,
14922             tvb, curr_offset, 1,
14923             gsm_dtap_elem_strings[DE_CM_SRVC_TYPE].strptr);
14924
14925     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CM_SRVC_TYPE]);
14926
14927     switch (oct & 0x0f)
14928     {
14929     case 0x01: str = "Mobile originating call establishment or packet mode connection establishment"; break;
14930     case 0x02: str = "Emergency call establishment"; break;
14931     case 0x04: str = "Short message service"; break;
14932     case 0x08: str = "Supplementary service activation"; break;
14933     case 0x09: str = "Voice group call establishment"; break;
14934     case 0x0a: str = "Voice broadcast call establishment"; break;
14935     case 0x0b: str = "Location Services"; break;
14936     default:
14937         str = "Reserved";
14938         break;
14939     }
14940
14941     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
14942     proto_tree_add_text(subtree,
14943         tvb, curr_offset, 1,
14944         "%s :  Service Type: (%u) %s",
14945         a_bigbuf,
14946         oct & 0x0f,
14947         str);
14948
14949     curr_offset++;
14950     curr_len--;
14951
14952     if (curr_len <= 0) return;
14953
14954     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MS_CM_2, "");
14955
14956     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID, "");
14957
14958     ELEM_OPT_TV_SHORT(0x80, BSSAP_PDU_TYPE_DTAP, DE_PRIO, "");
14959
14960     EXTRANEOUS_DATA_CHECK(curr_len, 0);
14961 }
14962
14963 /*
14964  * [3] 9.2.10
14965  */
14966 static void
14967 dtap_mm_id_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
14968 {
14969     guint8      oct;
14970     guint32     curr_offset;
14971     guint       curr_len;
14972     proto_tree  *subtree;
14973     proto_item  *item;
14974     const gchar *str;
14975
14976     curr_offset = offset;
14977     curr_len = len;
14978
14979     is_uplink = IS_UPLINK_FALSE;
14980
14981     /*
14982      * special dissection for Identity Type
14983      */
14984     oct = tvb_get_guint8(tvb, curr_offset);
14985
14986     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
14987     proto_tree_add_text(tree,
14988         tvb, curr_offset, 1,
14989         "%s :  Spare",
14990         a_bigbuf);
14991
14992     item =
14993         proto_tree_add_text(tree,
14994             tvb, curr_offset, 1,
14995             gsm_dtap_elem_strings[DE_ID_TYPE].strptr);
14996
14997     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_ID_TYPE]);
14998
14999     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
15000     proto_tree_add_text(subtree,
15001         tvb, curr_offset, 1,
15002         "%s :  Spare",
15003         a_bigbuf);
15004
15005     switch (oct & 0x07)
15006     {
15007     case 1: str = "IMSI"; break;
15008     case 2: str = "IMEI"; break;
15009     case 3: str = "IMEISV"; break;
15010     case 4: str = "TMSI"; break;
15011     default:
15012         str = "Reserved";
15013         break;
15014     }
15015
15016     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
15017     proto_tree_add_text(subtree,
15018         tvb, curr_offset, 1,
15019         "%s :  Type of identity: %s",
15020         a_bigbuf,
15021         str);
15022
15023     curr_offset++;
15024     curr_len--;
15025
15026     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15027 }
15028
15029 /*
15030  * [3] 9.2.11
15031  */
15032 static void
15033 dtap_mm_id_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15034 {
15035     guint32     curr_offset;
15036     guint32     consumed;
15037     guint       curr_len;
15038
15039     curr_offset = offset;
15040     curr_len = len;
15041
15042     is_uplink = IS_UPLINK_TRUE;
15043
15044     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID, "");
15045
15046     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15047 }
15048
15049 /*
15050  * [3] 9.2.12
15051  */
15052 static void
15053 dtap_mm_imsi_det_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15054 {
15055     guint32     curr_offset;
15056     guint32     consumed;
15057     guint       curr_len;
15058
15059     curr_offset = offset;
15060     curr_len = len;
15061
15062     is_uplink = IS_UPLINK_TRUE;
15063
15064     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_MS_CM_1);
15065
15066     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID, "");
15067
15068     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15069 }
15070
15071 /*
15072  * [3] 9.2.13
15073  */
15074 static void
15075 dtap_mm_loc_upd_acc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15076 {
15077     guint32     curr_offset;
15078     guint32     consumed;
15079     guint       curr_len;
15080
15081     curr_offset = offset;
15082     curr_len = len;
15083
15084     is_uplink = IS_UPLINK_FALSE;
15085
15086     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_LAI);
15087
15088     ELEM_OPT_TLV(0x17, BSSAP_PDU_TYPE_DTAP, DE_MID, "");
15089
15090     ELEM_OPT_T(0xa1, BSSAP_PDU_TYPE_DTAP, DE_FOP, "");
15091
15092     ELEM_OPT_T(0xa2, BSSAP_PDU_TYPE_DTAP, DE_CTS_PERM, "");
15093
15094     ELEM_OPT_TLV(0x4a, BSSAP_PDU_TYPE_DTAP, DE_PLMN_LIST, " Equivalent");
15095
15096     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15097 }
15098
15099 /*
15100  * [3] 9.2.14
15101  */
15102 static void
15103 dtap_mm_loc_upd_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15104 {
15105     guint32     curr_offset;
15106     guint32     consumed;
15107     guint       curr_len;
15108
15109     curr_offset = offset;
15110     curr_len = len;
15111
15112     is_uplink = IS_UPLINK_FALSE;
15113
15114     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_REJ_CAUSE);
15115
15116     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15117 }
15118
15119 /*
15120  * [3] 9.2.15
15121  */
15122 static void
15123 dtap_mm_loc_upd_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15124 {
15125     guint32     curr_offset;
15126     guint32     consumed;
15127     guint       curr_len;
15128     guint8      oct;
15129     proto_tree  *subtree;
15130     proto_item  *item;
15131     const gchar *str;
15132
15133     curr_offset = offset;
15134     curr_len = len;
15135
15136     is_uplink = IS_UPLINK_TRUE;
15137
15138     /*
15139      * special dissection for Location Updating Type
15140      */
15141     oct = tvb_get_guint8(tvb, curr_offset);
15142
15143     item =
15144         proto_tree_add_text(tree,
15145             tvb, curr_offset, 1,
15146             gsm_dtap_elem_strings[DE_CIPH_KEY_SEQ_NUM].strptr);
15147
15148     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CIPH_KEY_SEQ_NUM]);
15149
15150     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
15151     proto_tree_add_text(subtree,
15152         tvb, curr_offset, 1,
15153         "%s :  Spare",
15154         a_bigbuf);
15155
15156     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
15157
15158     switch ((oct & 0x70) >> 4)
15159     {
15160     case 0x07:
15161         proto_tree_add_text(subtree,
15162             tvb, curr_offset, 1,
15163             "%s :  Ciphering Key Sequence Number: No key is available",
15164             a_bigbuf);
15165         break;
15166
15167     default:
15168         proto_tree_add_text(subtree,
15169             tvb, curr_offset, 1,
15170             "%s :  Ciphering Key Sequence Number: %u",
15171             a_bigbuf,
15172             (oct & 0x70) >> 4);
15173         break;
15174     }
15175
15176     item =
15177         proto_tree_add_text(tree,
15178             tvb, curr_offset, 1,
15179             gsm_dtap_elem_strings[DE_LOC_UPD_TYPE].strptr);
15180
15181     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_LOC_UPD_TYPE]);
15182
15183     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
15184     proto_tree_add_text(subtree,
15185         tvb, curr_offset, 1,
15186         "%s :  Follow-On Request (FOR): %s",
15187         a_bigbuf,
15188         (oct & 0x08) ? "Follow-on request pending" : "No follow-on request pending");
15189
15190     other_decode_bitfield_value(a_bigbuf, oct, 0x04, 8);
15191     proto_tree_add_text(subtree,
15192         tvb, curr_offset, 1,
15193         "%s :  Spare",
15194         a_bigbuf);
15195
15196     switch (oct & 0x03)
15197     {
15198     case 0: str = "Normal"; break;
15199     case 1: str = "Periodic"; break;
15200     case 2: str = "IMSI attach"; break;
15201     default:
15202         str = "Reserved";
15203         break;
15204     }
15205
15206     other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
15207     proto_tree_add_text(subtree,
15208         tvb, curr_offset, 1,
15209         "%s :  Updating Type: %s",
15210         a_bigbuf,
15211         str);
15212
15213     proto_item_append_text(item, " - %s", str);
15214
15215     curr_offset++;
15216     curr_len--;
15217
15218     if (curr_len <= 0) return;
15219
15220     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_LAI);
15221
15222     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_MS_CM_1);
15223
15224     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID, "");
15225
15226     ELEM_OPT_TLV(0x33, BSSAP_PDU_TYPE_DTAP, DE_MS_CM_2, "");
15227
15228     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15229 }
15230
15231 /*
15232  * [4] 9.1.15a
15233  */
15234 void
15235 dtap_mm_mm_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15236 {
15237     guint32     curr_offset;
15238     guint32     consumed;
15239     guint       curr_len;
15240
15241     curr_offset = offset;
15242     curr_len = len;
15243
15244     is_uplink = IS_UPLINK_TRUE;
15245
15246     ELEM_OPT_TLV(0x43, BSSAP_PDU_TYPE_DTAP, DE_NETWORK_NAME, " - Full Name");
15247
15248     ELEM_OPT_TLV(0x45, BSSAP_PDU_TYPE_DTAP, DE_NETWORK_NAME, " - Short Name");
15249
15250     ELEM_OPT_TV(0x46, BSSAP_PDU_TYPE_DTAP, DE_TIME_ZONE, " - Local");
15251
15252     ELEM_OPT_TV(0x47, BSSAP_PDU_TYPE_DTAP, DE_TIME_ZONE_TIME, " - Universal Time and Local Time Zone");
15253
15254     ELEM_OPT_TLV(0x48, BSSAP_PDU_TYPE_DTAP, DE_LSA_ID, "");
15255
15256     ELEM_OPT_TLV(0x49, BSSAP_PDU_TYPE_DTAP, DE_DAY_SAVING_TIME, "");
15257
15258     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15259 }
15260
15261 /*
15262  * [4] 9.1.16
15263  */
15264 static void
15265 dtap_mm_mm_status(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15266 {
15267     guint32     curr_offset;
15268     guint32     consumed;
15269     guint       curr_len;
15270
15271     curr_offset = offset;
15272     curr_len = len;
15273
15274     is_uplink = IS_UPLINK_TRUE;
15275
15276     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_REJ_CAUSE);
15277
15278     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15279 }
15280
15281 /*
15282  * [3] 9.2.17
15283  */
15284 static void
15285 dtap_mm_tmsi_realloc_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15286 {
15287     guint32     curr_offset;
15288     guint32     consumed;
15289     guint       curr_len;
15290
15291     curr_offset = offset;
15292     curr_len = len;
15293
15294     is_uplink = IS_UPLINK_FALSE;
15295
15296     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_LAI);
15297
15298     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID, "");
15299
15300     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15301 }
15302 /* 3GPP TS 24.008 version 4.7.0 Release 4
15303  * [3] 9.1.15
15304  */
15305 void
15306 dtap_rr_ho_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15307 {
15308     guint32     curr_offset;
15309     guint32     consumed;
15310     guint       curr_len;
15311     curr_offset = offset;
15312     curr_len = len;
15313
15314         /* Mandatory Elemets
15315          * Cell description 10.5.2.2 
15316          */
15317         ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RR_CELL_DSC);
15318
15319         /* Description of the first channel,after time
15320          * Channel Description 2 10.5.2.5a
15321          */
15322         ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RR_CH_DSC2);
15323
15324         /* Handover Reference 10.5.2.15 */
15325         ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RR_HO_REF);
15326
15327         /* Power Command and Access type 10.5.2.28a */
15328         ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RR_POW_CMD_AND_ACC_TYPE);
15329
15330         /* optional elements */
15331
15332         /* Synchronization Indication 10.5.2.39 */
15333         ELEM_OPT_TV_SHORT(0xD0,BSSAP_PDU_TYPE_DTAP, DE_RR_SYNC_IND,"");
15334
15335         /* Frequency Short List 10.5.2.14 */
15336         ELEM_OPT_TV(0x02,BSSAP_PDU_TYPE_DTAP, DE_RR_FREQ_SHORT_LIST," - Frequency Short List, after time");
15337
15338         /* Frequency List 10.5.2.13 */
15339         ELEM_OPT_TLV(0x05, BSSAP_PDU_TYPE_DTAP, DE_RR_FREQ_LIST, " - Frequency List, after time");
15340
15341         /* Cell Channel Description 10.5.2.1b */
15342         ELEM_OPT_TV(0x62,BSSAP_PDU_TYPE_DTAP, DE_RR_CELL_CH_DSC, "");
15343
15344         /* Multislot Allocation 10.5.2.21b */
15345         ELEM_OPT_TLV(0x10,BSSAP_PDU_TYPE_DTAP, DE_RR_MULT_ALL, "");
15346
15347         /* Mode of the First Channel(Channel Set 1)) Channel Mode 10.5.2.6*/
15348         ELEM_OPT_TV(0x63,BSSAP_PDU_TYPE_DTAP, DE_RR_CH_MODE, " - Mode of the First Channel(Channel Set 1))");
15349
15350         /* Mode of Channel Set 2 Channel Mode 10.5.2.6*/
15351         ELEM_OPT_TV(0x11,BSSAP_PDU_TYPE_DTAP, DE_RR_CH_MODE, " - Mode of Channel Set 2");
15352
15353         /* Mode of Channel Set 3 Channel Mode 10.5.2.6*/        
15354         ELEM_OPT_TV(0x13,BSSAP_PDU_TYPE_DTAP, DE_RR_CH_MODE, " - Mode of Channel Set 3");
15355
15356         /* Mode of Channel Set 4 Channel Mode 10.5.2.6*/
15357         ELEM_OPT_TV(0x14,BSSAP_PDU_TYPE_DTAP, DE_RR_CH_MODE, " - Mode of Channel Set 4");
15358
15359         /* Mode of Channel Set 5 Channel Mode 10.5.2.6*/
15360         ELEM_OPT_TV(0x15,BSSAP_PDU_TYPE_DTAP, DE_RR_CH_MODE, " - Mode of Channel Set 5");
15361
15362         /* Mode of Channel Set 6 Channel Mode 10.5.2.6*/
15363         ELEM_OPT_TV(0x16,BSSAP_PDU_TYPE_DTAP, DE_RR_CH_MODE, " - Mode of Channel Set 6");
15364
15365         /* Mode of Channel Set 7 Channel Mode 10.5.2.6*/
15366         ELEM_OPT_TV(0x17,BSSAP_PDU_TYPE_DTAP, DE_RR_CH_MODE, " - Mode of Channel Set 7");
15367
15368         /* Mode of Channel Set 8 Channel Mode 10.5.2.6*/
15369         ELEM_OPT_TV(0x18,BSSAP_PDU_TYPE_DTAP, DE_RR_CH_MODE, " - Mode of Channel Set 8");
15370
15371         /* Description of the Second Channel, after time, Channel Description 10.5.2.5 */
15372         ELEM_OPT_TV(0x64,BSSAP_PDU_TYPE_DTAP, DE_RR_CH_DSC, " - Description of the Second Channel, after time");
15373
15374         /* Mode of the Second Channel, Channel Mode 2 10.5.2.7 */
15375         ELEM_OPT_TV(0x66,BSSAP_PDU_TYPE_DTAP, DE_RR_CH_MODE2, " - Mode of the Second Channel");
15376
15377         /* Frequency Channel Sequence, after time, Frequency Channel Sequence 10.5.2.12 */
15378         ELEM_OPT_TV(0x69,BSSAP_PDU_TYPE_DTAP, DE_RR_FREQ_CH_SEQ, " - Frequency Channel Sequence, after time");
15379
15380         /* Mobile Allocation, after time, Mobile Allocation 10.5.2.21 */
15381         ELEM_OPT_TLV(0x72,BSSAP_PDU_TYPE_DTAP, DE_RR_MOB_ALL, " - Mobile Allocation, after time");
15382         
15383         /* Starting Time 10.5.2.38 */
15384         ELEM_OPT_TV(0x7C,BSSAP_PDU_TYPE_DTAP, DE_RR_STARTING_TIME, "");
15385
15386         /* Real Time Difference, Time Difference 10.5.2.41 */
15387         ELEM_OPT_TV(0x7B,BSSAP_PDU_TYPE_DTAP, DE_RR_TIME_DIFF, " - Real Time Difference");
15388
15389         /* Timing Advance, Timing Advance 10.5.2.40 */
15390         ELEM_OPT_TV(0x7D,BSSAP_PDU_TYPE_DTAP, DE_RR_TIMING_ADV, "");
15391
15392         /* Frequency Short List, before time, Frequency Short List 10.5.2.14 */
15393         ELEM_OPT_TLV(0x19,BSSAP_PDU_TYPE_DTAP, DE_RR_FREQ_SHORT_LIST, " - Frequency Short List, before time");
15394
15395         /* Frequency List, before time, Frequency List 10.5.2.13 */
15396         ELEM_OPT_TV(0x12,BSSAP_PDU_TYPE_DTAP, DE_RR_FREQ_LIST, " - Frequency List, before time");
15397
15398         /* Description of the First Channel, before time,       Channel Description 2 10.5.2.5a*/
15399         ELEM_OPT_TV(0x1c,BSSAP_PDU_TYPE_DTAP, DE_RR_CH_DSC2, " - Description of the First Channel, before time");
15400
15401         /* Description of the Second Channel, before time,      Channel Description 10.5.2.5*/
15402         ELEM_OPT_TV(0x1d,BSSAP_PDU_TYPE_DTAP, DE_RR_CH_DSC, " - Description of the Second Channel, before time");
15403
15404         /* Frequency channel sequence before time,      Frequency channel sequence 10.5.2.12*/
15405         ELEM_OPT_TV(0x1e,BSSAP_PDU_TYPE_DTAP, DE_RR_FREQ_CH_SEQ, " - Frequency channel sequence before time");
15406
15407         /* Mobile Allocation, before time,      Mobile Allocation 10.5.2.21*/
15408         ELEM_OPT_TLV(0x21,BSSAP_PDU_TYPE_DTAP, DE_RR_MOB_ALL, " - Mobile Allocation, before time");
15409
15410         /* Cipher Mode Setting, Cipher Mode Setting 10.5.2.9*/
15411         ELEM_OPT_TV_SHORT(0x90,BSSAP_PDU_TYPE_DTAP, DE_RR_CIP_MODE_SET, "");
15412
15413         /* VGCS target mode Indication, VGCS target mode Indication 10.5.2.42a*/
15414         ELEM_OPT_TLV(0x01,BSSAP_PDU_TYPE_DTAP, DE_RR_VGCS_TAR_MODE_IND, "");
15415
15416         /* Multi-Rate configuration,    MultiRate configuration 10.5.2.21aa*/
15417         ELEM_OPT_TLV(0x03,BSSAP_PDU_TYPE_DTAP, DE_RR_MULTIRATE_CONF, "");
15418
15419         /* Dynamic ARFCN Mapping,       Dynamic ARFCN Mapping 10.5.2.11b*/
15420         ELEM_OPT_TLV(0x76,BSSAP_PDU_TYPE_DTAP, DE_RR_DYN_ARFCN_MAP, "");
15421
15422         /* VGCS Ciphering Parameters,   VGCS Ciphering Parameters 10.5.2.42b*/
15423         ELEM_OPT_TLV(0x04,BSSAP_PDU_TYPE_DTAP, DE_RR_VGCS_CIP_PAR, "");
15424
15425         /* Dedicated Service Information,       Dedicated Service Information 10.5.2.59*/
15426         ELEM_OPT_TV(0x51,BSSAP_PDU_TYPE_DTAP, DE_RR_DED_SERV_INF, "");
15427
15428         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
15429
15430 }
15431 /*
15432  * [4] 9.1.25
15433  */
15434 static void
15435 dtap_rr_paging_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15436 {
15437     guint32     curr_offset;
15438     guint32     consumed;
15439     guint       curr_len;
15440     guint8      oct;
15441     proto_tree  *subtree;
15442     proto_item  *item;
15443
15444     curr_offset = offset;
15445     curr_len = len;
15446
15447     is_uplink = IS_UPLINK_TRUE;
15448
15449     /*
15450      * special dissection for Cipher Key Sequence Number
15451      */
15452     oct = tvb_get_guint8(tvb, curr_offset);
15453
15454     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
15455     proto_tree_add_text(tree,
15456         tvb, curr_offset, 1,
15457         "%s :  Spare",
15458         a_bigbuf);
15459
15460     item =
15461         proto_tree_add_text(tree,
15462             tvb, curr_offset, 1,
15463             gsm_dtap_elem_strings[DE_CIPH_KEY_SEQ_NUM].strptr);
15464
15465     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CIPH_KEY_SEQ_NUM]);
15466
15467     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
15468     proto_tree_add_text(subtree,
15469         tvb, curr_offset, 1,
15470         "%s :  Spare",
15471         a_bigbuf);
15472
15473     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
15474
15475     switch (oct & 0x07)
15476     {
15477     case 0x07:
15478         proto_tree_add_text(subtree,
15479             tvb, curr_offset, 1,
15480             "%s :  Ciphering Key Sequence Number: No key is available",
15481             a_bigbuf);
15482         break;
15483
15484     default:
15485         proto_tree_add_text(subtree,
15486             tvb, curr_offset, 1,
15487             "%s :  Ciphering Key Sequence Number: %u",
15488             a_bigbuf,
15489             oct & 0x07);
15490         break;
15491     }
15492
15493     curr_offset++;
15494     curr_len--;
15495
15496     if (curr_len <= 0) return;
15497
15498     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MS_CM_2, "");
15499
15500     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID, "");
15501
15502     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15503 }
15504
15505 /*
15506  * [4] 9.1.29
15507  */
15508 static void
15509 dtap_rr_rr_status(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15510 {
15511     guint32     curr_offset;
15512     guint32     consumed;
15513     guint       curr_len;
15514
15515     curr_offset = offset;
15516     curr_len = len;
15517
15518     is_uplink = IS_UPLINK_TRUE;
15519
15520     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RR_CAUSE);
15521
15522     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15523 }
15524
15525 /*
15526  * [4] 9.3.1
15527  */
15528 static void
15529 dtap_cc_alerting(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15530 {
15531     guint32     curr_offset;
15532     guint32     consumed;
15533     guint       curr_len;
15534
15535     curr_offset = offset;
15536     curr_len = len;
15537
15538     is_uplink = IS_UPLINK_TRUE;
15539
15540     ELEM_OPT_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
15541
15542     ELEM_OPT_TLV(0x1e, BSSAP_PDU_TYPE_DTAP, DE_PROG_IND, "");
15543
15544     ELEM_OPT_TLV(0x7e, BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
15545
15546     /* uplink only */
15547
15548     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
15549
15550     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15551 }
15552
15553 /*
15554  * [4] 9.3.2
15555  */
15556 static void
15557 dtap_cc_call_conf(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15558 {
15559     guint32     curr_offset;
15560     guint32     consumed;
15561     guint       curr_len;
15562
15563     curr_offset = offset;
15564     curr_len = len;
15565
15566     is_uplink = IS_UPLINK_TRUE;
15567
15568     ELEM_OPT_TV_SHORT(0xd0, BSSAP_PDU_TYPE_DTAP, DE_REPEAT_IND, " BC repeat indicator");
15569
15570     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 1");
15571
15572     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 2");
15573
15574     ELEM_OPT_TLV(0x08, BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
15575
15576     ELEM_OPT_TLV(0x15, BSSAP_PDU_TYPE_DTAP, DE_CC_CAP, "");
15577
15578     ELEM_OPT_TLV(0x2d, BSSAP_PDU_TYPE_DTAP, DE_SI, "");
15579
15580     ELEM_OPT_TLV(0x40, BSSAP_PDU_TYPE_DTAP, DE_SUP_CODEC_LIST, "");
15581
15582     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15583 }
15584
15585 /*
15586  * [4] 9.3.3
15587  */
15588 static void
15589 dtap_cc_call_proceed(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15590 {
15591     guint32     curr_offset;
15592     guint32     consumed;
15593     guint       curr_len;
15594
15595     curr_offset = offset;
15596     curr_len = len;
15597
15598     is_uplink = IS_UPLINK_FALSE;
15599
15600     ELEM_OPT_TV_SHORT(0xd0, BSSAP_PDU_TYPE_DTAP, DE_REPEAT_IND, " BC repeat indicator");
15601
15602     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 1");
15603
15604     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 2");
15605
15606     ELEM_OPT_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
15607
15608     ELEM_OPT_TLV(0x1e, BSSAP_PDU_TYPE_DTAP, DE_PROG_IND, "");
15609
15610     ELEM_OPT_TV_SHORT(0x80, BSSAP_PDU_TYPE_DTAP, DE_PRIO, "");
15611
15612     ELEM_OPT_TLV(0x2f, BSSAP_PDU_TYPE_DTAP, DE_NET_CC_CAP, "");
15613
15614     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15615 }
15616
15617 /*
15618  * [4] 9.3.4
15619  */
15620 static void
15621 dtap_cc_congestion_control(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15622 {
15623     guint32     curr_offset;
15624     guint32     consumed;
15625     guint       curr_len;
15626     guint8      oct;
15627     proto_tree  *subtree;
15628     proto_item  *item;
15629     const gchar *str;
15630
15631     curr_offset = offset;
15632     curr_len = len;
15633
15634     is_uplink = IS_UPLINK_FALSE;
15635
15636     /*
15637      * special dissection for Congestion Level
15638      */
15639     oct = tvb_get_guint8(tvb, curr_offset);
15640
15641     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
15642     proto_tree_add_text(tree,
15643         tvb, curr_offset, 1,
15644         "%s :  Spare",
15645         a_bigbuf);
15646
15647     item =
15648         proto_tree_add_text(tree,
15649             tvb, curr_offset, 1,
15650             gsm_dtap_elem_strings[DE_CONGESTION].strptr);
15651
15652     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CONGESTION]);
15653
15654     switch (oct & 0x0f)
15655     {
15656     case 0: str = "Receiver ready"; break;
15657     case 15: str = "Receiver not ready"; break;
15658     default:
15659         str = "Reserved";
15660         break;
15661     }
15662
15663     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
15664     proto_tree_add_text(subtree,
15665         tvb, curr_offset, 1,
15666         "%s :  Congestion level: %s",
15667         a_bigbuf,
15668         str);
15669
15670     curr_offset++;
15671     curr_len--;
15672
15673     if (curr_len <= 0) return;
15674
15675     ELEM_OPT_TLV(0x08, BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
15676
15677     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15678 }
15679
15680 /*
15681  * [4] 9.3.5
15682  */
15683 static void
15684 dtap_cc_connect(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15685 {
15686     guint32     curr_offset;
15687     guint32     consumed;
15688     guint       curr_len;
15689
15690     curr_offset = offset;
15691     curr_len = len;
15692
15693     is_uplink = IS_UPLINK_TRUE;
15694
15695     ELEM_OPT_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
15696
15697     ELEM_OPT_TLV(0x1e, BSSAP_PDU_TYPE_DTAP, DE_PROG_IND, "");
15698
15699     ELEM_OPT_TLV(0x4c, BSSAP_PDU_TYPE_DTAP, DE_CONN_NUM, "");
15700
15701     ELEM_OPT_TLV(0x4d, BSSAP_PDU_TYPE_DTAP, DE_CONN_SUB_ADDR, "");
15702
15703     ELEM_OPT_TLV(0x7e, BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
15704
15705     /* uplink only */
15706
15707     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
15708
15709     ELEM_OPT_TLV(0x2d, BSSAP_PDU_TYPE_DTAP, DE_SI, "");
15710
15711     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15712 }
15713
15714 /*
15715  * [4] 9.3.7
15716  */
15717 static void
15718 dtap_cc_disconnect(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15719 {
15720     guint32     curr_offset;
15721     guint32     consumed;
15722     guint       curr_len;
15723
15724     curr_offset = offset;
15725     curr_len = len;
15726
15727     is_uplink = IS_UPLINK_TRUE;
15728
15729     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
15730
15731     ELEM_OPT_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
15732
15733     ELEM_OPT_TLV(0x1e, BSSAP_PDU_TYPE_DTAP, DE_PROG_IND, "");
15734
15735     ELEM_OPT_TLV(0x7e, BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
15736
15737     ELEM_OPT_TLV(0x7b, BSSAP_PDU_TYPE_DTAP, DE_ALLOWED_ACTIONS, "");
15738
15739     /* uplink only */
15740
15741     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
15742
15743     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15744 }
15745
15746 /*
15747  * [4] 9.3.8
15748  */
15749 static void
15750 dtap_cc_emerg_setup(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15751 {
15752     guint32     curr_offset;
15753     guint32     consumed;
15754     guint       curr_len;
15755
15756     curr_offset = offset;
15757     curr_len = len;
15758
15759     is_uplink = IS_UPLINK_TRUE;
15760
15761     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, "");
15762
15763     ELEM_OPT_TLV(0x2d, BSSAP_PDU_TYPE_DTAP, DE_SI, "");
15764
15765     ELEM_OPT_TLV(0x40, BSSAP_PDU_TYPE_DTAP, DE_SUP_CODEC_LIST, "");
15766
15767     ELEM_OPT_TLV(0x2e, BSSAP_PDU_TYPE_DTAP, DE_SRVC_CAT, " Emergency");
15768
15769     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15770 }
15771
15772 /*
15773  * [4] 9.3.9
15774  */
15775 static void
15776 dtap_cc_facility(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15777 {
15778     guint32     curr_offset;
15779     guint32     consumed;
15780     guint       curr_len;
15781
15782     curr_offset = offset;
15783     curr_len = len;
15784
15785     is_uplink = IS_UPLINK_TRUE;
15786
15787     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
15788
15789     /* uplink only */
15790
15791     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
15792
15793     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15794 }
15795
15796 /*
15797  * [4] 9.3.12
15798  */
15799 static void
15800 dtap_cc_hold_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15801 {
15802     guint32     curr_offset;
15803     guint32     consumed;
15804     guint       curr_len;
15805
15806     curr_offset = offset;
15807     curr_len = len;
15808
15809     is_uplink = IS_UPLINK_FALSE;
15810
15811     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
15812
15813     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15814 }
15815
15816 /*
15817  * [4] 9.3.13
15818  */
15819 static void
15820 dtap_cc_modify(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15821 {
15822     guint32     curr_offset;
15823     guint32     consumed;
15824     guint       curr_len;
15825
15826     curr_offset = offset;
15827     curr_len = len;
15828
15829     is_uplink = IS_UPLINK_TRUE;
15830
15831     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, "");
15832
15833     ELEM_OPT_TLV(0x7c, BSSAP_PDU_TYPE_DTAP, DE_LLC, "");
15834
15835     ELEM_OPT_TLV(0x7d, BSSAP_PDU_TYPE_DTAP, DE_HLC, "");
15836
15837     ELEM_OPT_T(0xa3, BSSAP_PDU_TYPE_DTAP, DE_REV_CALL_SETUP_DIR, "");
15838
15839     ELEM_OPT_T(0xa4, BSSAP_PDU_TYPE_DTAP, DE_IMM_MOD_IND, "");
15840
15841     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15842 }
15843
15844 /*
15845  * [4] 9.3.14
15846  */
15847 static void
15848 dtap_cc_modify_complete(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15849 {
15850     guint32     curr_offset;
15851     guint32     consumed;
15852     guint       curr_len;
15853
15854     curr_offset = offset;
15855     curr_len = len;
15856
15857     is_uplink = IS_UPLINK_TRUE;
15858
15859     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, "");
15860
15861     ELEM_OPT_TLV(0x7c, BSSAP_PDU_TYPE_DTAP, DE_LLC, "");
15862
15863     ELEM_OPT_TLV(0x7d, BSSAP_PDU_TYPE_DTAP, DE_HLC, "");
15864
15865     ELEM_OPT_T(0xa3, BSSAP_PDU_TYPE_DTAP, DE_REV_CALL_SETUP_DIR, "");
15866
15867     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15868 }
15869
15870 /*
15871  * [4] 9.3.15
15872  */
15873 static void
15874 dtap_cc_modify_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15875 {
15876     guint32     curr_offset;
15877     guint32     consumed;
15878     guint       curr_len;
15879
15880     curr_offset = offset;
15881     curr_len = len;
15882
15883     is_uplink = IS_UPLINK_FALSE;
15884
15885     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, "");
15886
15887     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
15888
15889     ELEM_OPT_TLV(0x7c, BSSAP_PDU_TYPE_DTAP, DE_LLC, "");
15890
15891     ELEM_OPT_TLV(0x7d, BSSAP_PDU_TYPE_DTAP, DE_HLC, "");
15892
15893     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15894 }
15895
15896 /*
15897  * [4] 9.3.16
15898  */
15899 static void
15900 dtap_cc_notify(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15901 {
15902     guint32     curr_offset;
15903     guint32     consumed;
15904     guint       curr_len;
15905
15906     curr_offset = offset;
15907     curr_len = len;
15908
15909     is_uplink = IS_UPLINK_FALSE;
15910
15911     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_NOT_IND);
15912
15913     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15914 }
15915
15916 /*
15917  * [4] 9.3.17
15918  */
15919 static void
15920 dtap_cc_progress(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15921 {
15922     guint32     curr_offset;
15923     guint32     consumed;
15924     guint       curr_len;
15925
15926     curr_offset = offset;
15927     curr_len = len;
15928
15929     is_uplink = IS_UPLINK_FALSE;
15930
15931     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_PROG_IND, "");
15932
15933     ELEM_OPT_TLV(0x7e, BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
15934
15935     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15936 }
15937
15938 /*
15939  * [4] 9.3.17a
15940  */
15941 static void
15942 dtap_cc_cc_est(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15943 {
15944     guint32     curr_offset;
15945     guint32     consumed;
15946     guint       curr_len;
15947
15948     curr_offset = offset;
15949     curr_len = len;
15950
15951     is_uplink = IS_UPLINK_FALSE;
15952
15953     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_SETUP_CONTAINER, "");
15954
15955     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15956 }
15957
15958 /*
15959  * [4] 9.3.17b
15960  */
15961 static void
15962 dtap_cc_cc_est_conf(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15963 {
15964     guint32     curr_offset;
15965     guint32     consumed;
15966     guint       curr_len;
15967
15968     curr_offset = offset;
15969     curr_len = len;
15970
15971     is_uplink = IS_UPLINK_TRUE;
15972
15973     ELEM_OPT_TV_SHORT(0xd0, BSSAP_PDU_TYPE_DTAP, DE_REPEAT_IND, " Repeat indicator");
15974
15975     ELEM_MAND_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 1");
15976
15977     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 2");
15978
15979     ELEM_OPT_TLV(0x08, BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
15980
15981     ELEM_OPT_TLV(0x40, BSSAP_PDU_TYPE_DTAP, DE_SUP_CODEC_LIST, "");
15982
15983     EXTRANEOUS_DATA_CHECK(curr_len, 0);
15984 }
15985
15986 /*
15987  * [4] 9.3.18
15988  */
15989 static void
15990 dtap_cc_release(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
15991 {
15992     guint32     curr_offset;
15993     guint32     consumed;
15994     guint       curr_len;
15995
15996     curr_offset = offset;
15997     curr_len = len;
15998
15999     is_uplink = IS_UPLINK_TRUE;
16000
16001     ELEM_OPT_TLV(0x08, BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
16002
16003     ELEM_OPT_TLV(0x08, BSSAP_PDU_TYPE_DTAP, DE_CAUSE, " 2");
16004
16005     ELEM_OPT_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
16006
16007     ELEM_OPT_TLV(0x7e, BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
16008
16009     /* uplink only */
16010
16011     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
16012
16013     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16014 }
16015
16016 /*
16017  * [4] 9.3.18a
16018  */
16019 static void
16020 dtap_cc_recall(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16021 {
16022     guint32     curr_offset;
16023     guint32     consumed;
16024     guint       curr_len;
16025
16026     curr_offset = offset;
16027     curr_len = len;
16028
16029     is_uplink = IS_UPLINK_FALSE;
16030
16031     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RECALL_TYPE);
16032
16033     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
16034
16035     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16036 }
16037
16038 /*
16039  * [4] 9.3.19
16040  */
16041 static void
16042 dtap_cc_release_complete(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16043 {
16044     guint32     curr_offset;
16045     guint32     consumed;
16046     guint       curr_len;
16047
16048     curr_offset = offset;
16049     curr_len = len;
16050
16051     is_uplink = IS_UPLINK_FALSE;
16052
16053     ELEM_OPT_TLV(0x08, BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
16054
16055     ELEM_OPT_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
16056
16057     ELEM_OPT_TLV(0x7e, BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
16058
16059     /* uplink only */
16060
16061     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
16062
16063     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16064 }
16065
16066 /*
16067  * [4] 9.3.22
16068  */
16069 static void
16070 dtap_cc_retrieve_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16071 {
16072     guint32     curr_offset;
16073     guint32     consumed;
16074     guint       curr_len;
16075
16076     curr_offset = offset;
16077     curr_len = len;
16078
16079     is_uplink = IS_UPLINK_FALSE;
16080
16081     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
16082
16083     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16084 }
16085
16086 /*
16087  * [4] 9.3.23
16088  * 3GPP TS 24.008 version 7.5.0 Release 7
16089  */
16090 static void
16091 dtap_cc_setup(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16092 {
16093     guint32     curr_offset;
16094     guint32     consumed;
16095     guint       curr_len;
16096
16097     curr_offset = offset;
16098     curr_len = len;
16099
16100     is_uplink = IS_UPLINK_TRUE;
16101
16102     ELEM_OPT_TV_SHORT(0xd0, BSSAP_PDU_TYPE_DTAP, DE_REPEAT_IND, " BC repeat indicator");
16103
16104     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 1");
16105
16106     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 2");
16107
16108     ELEM_OPT_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
16109
16110     ELEM_OPT_TLV(0x1e, BSSAP_PDU_TYPE_DTAP, DE_PROG_IND, "");
16111
16112     ELEM_OPT_TV(0x34, BSSAP_PDU_TYPE_DTAP, DE_SIGNAL, "");
16113
16114     ELEM_OPT_TLV(0x5c, BSSAP_PDU_TYPE_DTAP, DE_CLG_PARTY_BCD_NUM, "");
16115
16116     ELEM_OPT_TLV(0x5d, BSSAP_PDU_TYPE_DTAP, DE_CLG_PARTY_SUB_ADDR, "");
16117
16118     ELEM_OPT_TLV(0x5e, BSSAP_PDU_TYPE_DTAP, DE_CLD_PARTY_BCD_NUM, "");
16119
16120     ELEM_OPT_TLV(0x6d, BSSAP_PDU_TYPE_DTAP, DE_CLD_PARTY_SUB_ADDR, "");
16121
16122     ELEM_OPT_TLV(0x74, BSSAP_PDU_TYPE_DTAP, DE_RED_PARTY_BCD_NUM, "");
16123
16124     ELEM_OPT_TLV(0x75, BSSAP_PDU_TYPE_DTAP, DE_RED_PARTY_SUB_ADDR, "");
16125
16126     ELEM_OPT_TV_SHORT(0xd0, BSSAP_PDU_TYPE_DTAP, DE_REPEAT_IND, " LLC repeat indicator");
16127
16128     ELEM_OPT_TLV(0x7c, BSSAP_PDU_TYPE_DTAP, DE_LLC, " 1");
16129
16130     ELEM_OPT_TLV(0x7c, BSSAP_PDU_TYPE_DTAP, DE_LLC, " 2");
16131
16132     ELEM_OPT_TV_SHORT(0xd0, BSSAP_PDU_TYPE_DTAP, DE_REPEAT_IND, " HLC repeat indicator");
16133
16134     ELEM_OPT_TLV(0x7d, BSSAP_PDU_TYPE_DTAP, DE_HLC, " 1");
16135
16136     ELEM_OPT_TLV(0x7d, BSSAP_PDU_TYPE_DTAP, DE_HLC, " 2");
16137
16138     ELEM_OPT_TLV(0x7e, BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
16139
16140     /* downlink only */
16141
16142     ELEM_OPT_TV_SHORT(0x80, BSSAP_PDU_TYPE_DTAP, DE_PRIO, "");
16143
16144     ELEM_OPT_TLV(0x19, BSSAP_PDU_TYPE_DTAP, DE_ALERT_PATTERN, "");
16145
16146     ELEM_OPT_TLV(0x2f, BSSAP_PDU_TYPE_DTAP, DE_NET_CC_CAP, "");
16147
16148     ELEM_OPT_TLV(0x3a, BSSAP_PDU_TYPE_DTAP, DE_CAUSE_NO_CLI, "");
16149
16150         /* Backup bearer capability O TLV 3-15 10.5.4.4a */
16151         ELEM_OPT_TLV(0x41, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, "");
16152
16153     /* uplink only */
16154
16155     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
16156
16157     ELEM_OPT_T(0xa1, BSSAP_PDU_TYPE_DTAP, DE_CLIR_SUP, "");
16158
16159     ELEM_OPT_T(0xa2, BSSAP_PDU_TYPE_DTAP, DE_CLIR_INV, "");
16160
16161     ELEM_OPT_TLV(0x15, BSSAP_PDU_TYPE_DTAP, DE_CC_CAP, "");
16162
16163     ELEM_OPT_TLV(0x1d, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, " $(CCBS)$ (advanced recall alignment)");
16164
16165     ELEM_OPT_TLV(0x1b, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, " (recall alignment Not essential) $(CCBS)$");
16166
16167     ELEM_OPT_TLV(0x2d, BSSAP_PDU_TYPE_DTAP, DE_SI, "");
16168
16169     ELEM_OPT_TLV(0x40, BSSAP_PDU_TYPE_DTAP, DE_SUP_CODEC_LIST, "");
16170
16171         /*A3 Redial Redial O T 1 10.5.4.34 
16172          * TODO add this element 
16173          * ELEM_OPT_T(0xA3, BSSAP_PDU_TYPE_DTAP, DE_REDIAL, "");
16174          */
16175
16176     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16177 }
16178
16179 /*
16180  * [4] 9.3.23a
16181  */
16182 static void
16183 dtap_cc_start_cc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16184 {
16185     guint32     curr_offset;
16186     guint32     consumed;
16187     guint       curr_len;
16188
16189     curr_offset = offset;
16190     curr_len = len;
16191
16192     is_uplink = IS_UPLINK_FALSE;
16193
16194     ELEM_OPT_TLV(0x15, BSSAP_PDU_TYPE_DTAP, DE_CC_CAP, "");
16195
16196     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16197 }
16198
16199 /*
16200  * [4] 9.3.24
16201  */
16202 static void
16203 dtap_cc_start_dtmf(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16204 {
16205     guint32     curr_offset;
16206     guint32     consumed;
16207     guint       curr_len;
16208
16209     curr_offset = offset;
16210     curr_len = len;
16211
16212     is_uplink = IS_UPLINK_TRUE;
16213
16214     ELEM_MAND_TV(0x2c, BSSAP_PDU_TYPE_DTAP, DE_KEYPAD_FACILITY, "");
16215
16216     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16217 }
16218
16219 /*
16220  * [4] 9.3.25
16221  */
16222 static void
16223 dtap_cc_start_dtmf_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16224 {
16225     guint32     curr_offset;
16226     guint32     consumed;
16227     guint       curr_len;
16228
16229     curr_offset = offset;
16230     curr_len = len;
16231
16232     is_uplink = IS_UPLINK_FALSE;
16233
16234     ELEM_MAND_TV(0x2c, BSSAP_PDU_TYPE_DTAP, DE_KEYPAD_FACILITY, "");
16235
16236     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16237 }
16238
16239 /*
16240  * [4] 9.3.26
16241  */
16242 static void
16243 dtap_cc_start_dtmf_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16244 {
16245     guint32     curr_offset;
16246     guint32     consumed;
16247     guint       curr_len;
16248
16249     curr_offset = offset;
16250     curr_len = len;
16251
16252     is_uplink = IS_UPLINK_FALSE;
16253
16254     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
16255
16256     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16257 }
16258
16259 /*
16260  * [4] 9.3.27
16261  */
16262 static void
16263 dtap_cc_status(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16264 {
16265     guint32     curr_offset;
16266     guint32     consumed;
16267     guint       curr_len;
16268
16269     curr_offset = offset;
16270     curr_len = len;
16271
16272     is_uplink = IS_UPLINK_FALSE;
16273
16274     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
16275
16276     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_CALL_STATE);
16277
16278     ELEM_OPT_TLV(0x24, BSSAP_PDU_TYPE_DTAP, DE_AUX_STATES, "");
16279
16280     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16281 }
16282
16283 /*
16284  * [4] 9.3.31
16285  */
16286 static void
16287 dtap_cc_user_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16288 {
16289     guint32     curr_offset;
16290     guint32     consumed;
16291     guint       curr_len;
16292
16293     curr_offset = offset;
16294     curr_len = len;
16295
16296     is_uplink = IS_UPLINK_TRUE;
16297
16298     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
16299
16300     ELEM_OPT_T(0xa0, BSSAP_PDU_TYPE_DTAP, DE_MORE_DATA, "");
16301
16302     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16303 }
16304
16305 /*
16306  * [6] 2.4.2
16307  */
16308 static void
16309 dtap_ss_register(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16310 {
16311     guint32     curr_offset;
16312     guint32     consumed;
16313     guint       curr_len;
16314
16315     curr_offset = offset;
16316     curr_len = len;
16317
16318     is_uplink = IS_UPLINK_TRUE;
16319
16320     ELEM_MAND_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
16321
16322     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
16323
16324     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16325 }
16326
16327 /*
16328  * [5] 7.2.1
16329  */
16330 static void
16331 dtap_sms_cp_data(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16332 {
16333     guint32     curr_offset;
16334     guint32     consumed;
16335     guint       curr_len;
16336
16337     curr_offset = offset;
16338     curr_len = len;
16339
16340     is_uplink = IS_UPLINK_TRUE;
16341
16342     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_CP_USER_DATA, "");
16343
16344     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16345 }
16346
16347 /*
16348  * [5] 7.2.3
16349  */
16350 static void
16351 dtap_sms_cp_error(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16352 {
16353     guint32     curr_offset;
16354     guint32     consumed;
16355     guint       curr_len;
16356
16357     curr_offset = offset;
16358     curr_len = len;
16359
16360     is_uplink = IS_UPLINK_TRUE;
16361
16362     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_CP_CAUSE);
16363
16364     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16365 }
16366
16367 /*
16368  * [5] 7.3.1.1
16369  */
16370 static void
16371 rp_data_n_ms(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16372 {
16373     guint32     curr_offset;
16374     guint32     consumed;
16375     guint       curr_len;
16376
16377     curr_offset = offset;
16378     curr_len = len;
16379
16380     is_uplink = IS_UPLINK_FALSE;
16381     g_pinfo->p2p_dir = P2P_DIR_SENT;
16382
16383     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RP_MESSAGE_REF);
16384
16385     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_ORIG_ADDR, "");
16386
16387     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_DEST_ADDR, "");
16388
16389     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_USER_DATA, "");
16390
16391     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16392 }
16393
16394 /*
16395  * [5] 7.3.1.2
16396  */
16397 static void
16398 rp_data_ms_n(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16399 {
16400     guint32     curr_offset;
16401     guint32     consumed;
16402     guint       curr_len;
16403
16404     curr_offset = offset;
16405     curr_len = len;
16406
16407     is_uplink = IS_UPLINK_TRUE;
16408     g_pinfo->p2p_dir = P2P_DIR_RECV;
16409
16410     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RP_MESSAGE_REF);
16411
16412     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_ORIG_ADDR, "");
16413
16414     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_DEST_ADDR, "");
16415
16416     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_USER_DATA, "");
16417
16418     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16419 }
16420
16421 /*
16422  * [5] 7.3.2
16423  */
16424 static void
16425 rp_smma(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16426 {
16427     guint32     curr_offset;
16428     guint32     consumed;
16429     guint       curr_len;
16430
16431     curr_offset = offset;
16432     curr_len = len;
16433
16434     is_uplink = IS_UPLINK_TRUE;
16435
16436     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RP_MESSAGE_REF);
16437
16438     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16439 }
16440
16441 /*
16442  * [5] 7.3.3
16443  */
16444 static void
16445 rp_ack_n_ms(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16446 {
16447     guint32     curr_offset;
16448     guint32     consumed;
16449     guint       curr_len;
16450
16451     curr_offset = offset;
16452     curr_len = len;
16453
16454     is_uplink = IS_UPLINK_FALSE;
16455     g_pinfo->p2p_dir = P2P_DIR_SENT;
16456
16457     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RP_MESSAGE_REF);
16458
16459     ELEM_OPT_TLV(0x41, BSSAP_PDU_TYPE_DTAP, DE_RP_USER_DATA, "");
16460
16461     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16462 }
16463
16464 /*
16465  * [5] 7.3.3
16466  */
16467 static void
16468 rp_ack_ms_n(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16469 {
16470     guint32     curr_offset;
16471     guint32     consumed;
16472     guint       curr_len;
16473
16474     curr_offset = offset;
16475     curr_len = len;
16476
16477     is_uplink = IS_UPLINK_TRUE;
16478     g_pinfo->p2p_dir = P2P_DIR_RECV;
16479
16480     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RP_MESSAGE_REF);
16481
16482     ELEM_OPT_TLV(0x41, BSSAP_PDU_TYPE_DTAP, DE_RP_USER_DATA, "");
16483
16484     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16485 }
16486
16487 /*
16488  * [5] 7.3.4
16489  */
16490 static void
16491 rp_error_n_ms(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16492 {
16493     guint32     curr_offset;
16494     guint32     consumed;
16495     guint       curr_len;
16496
16497     curr_offset = offset;
16498     curr_len = len;
16499
16500     is_uplink = IS_UPLINK_FALSE;
16501     g_pinfo->p2p_dir = P2P_DIR_SENT;
16502
16503     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RP_MESSAGE_REF);
16504
16505     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_CAUSE, "");
16506
16507     ELEM_OPT_TLV(0x41, BSSAP_PDU_TYPE_DTAP, DE_RP_USER_DATA, "");
16508
16509     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16510 }
16511
16512 /*
16513  * [5] 7.3.4
16514  */
16515 static void
16516 rp_error_ms_n(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16517 {
16518     guint32     curr_offset;
16519     guint32     consumed;
16520     guint       curr_len;
16521
16522     curr_offset = offset;
16523     curr_len = len;
16524
16525     is_uplink = IS_UPLINK_TRUE;
16526     g_pinfo->p2p_dir = P2P_DIR_RECV;
16527
16528     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RP_MESSAGE_REF);
16529
16530     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_CAUSE, "");
16531
16532     ELEM_OPT_TLV(0x41, BSSAP_PDU_TYPE_DTAP, DE_RP_USER_DATA, "");
16533
16534     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16535 }
16536
16537 /*
16538  * [7] 9.4.1
16539  */
16540 static void
16541 dtap_gmm_attach_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16542 {
16543     guint32     curr_offset;
16544     guint32     consumed;
16545     guint       curr_len;
16546
16547     curr_offset = offset;
16548     curr_len = len;
16549
16550     is_uplink = IS_UPLINK_TRUE;
16551     g_pinfo->p2p_dir = P2P_DIR_RECV;
16552
16553     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MS_NET_CAP, "");
16554     
16555     /* Included in attach type
16556     
16557     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_CIPH_KEY_SEQ_NUM );
16558     curr_offset--;
16559     curr_len++;
16560     */
16561     
16562     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_ATTACH_TYPE );
16563     
16564     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_DRX_PARAM );
16565     
16566     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID , "" );
16567     
16568     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RAI );
16569     
16570     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MS_RAD_ACC_CAP , "" );
16571
16572     ELEM_OPT_TV( 0x19 , BSSAP_PDU_TYPE_DTAP, DE_P_TMSI_SIG, " - Old P-TMSI Signature");
16573     
16574     ELEM_OPT_TV( 0x17 , BSSAP_PDU_TYPE_DTAP, DE_GPRS_TIMER , " - Ready Timer" );
16575     
16576     ELEM_OPT_TV_SHORT( 0x90 , BSSAP_PDU_TYPE_DTAP, DE_TMSI_STAT , "" );
16577
16578     ELEM_OPT_TLV( 0x33 , BSSAP_PDU_TYPE_DTAP, DE_PS_LCS_CAP , "" );
16579
16580     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16581 }
16582
16583 /*
16584  * [7] 9.4.2
16585  */
16586 static void
16587 dtap_gmm_attach_acc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16588 {
16589     guint32     curr_offset;
16590     guint32     consumed;
16591     guint       curr_len;
16592
16593     curr_offset = offset;
16594     curr_len = len;
16595
16596     is_uplink = IS_UPLINK_FALSE;
16597     g_pinfo->p2p_dir = P2P_DIR_SENT;
16598
16599     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_FORCE_TO_STAND_H );
16600     curr_len++;
16601     curr_offset--;    
16602
16603     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_ATTACH_RES );
16604     
16605     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_GPRS_TIMER );
16606     
16607     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RAD_PRIO_2 );
16608     curr_len++;
16609     curr_offset--;
16610     
16611     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RAD_PRIO );
16612     
16613     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RAI );
16614     
16615     ELEM_OPT_TV( 0x19 , BSSAP_PDU_TYPE_DTAP, DE_P_TMSI_SIG, "" );
16616     
16617     ELEM_OPT_TV( 0x17 , BSSAP_PDU_TYPE_DTAP, DE_GPRS_TIMER , " - Negotiated Ready Timer" );
16618     
16619     ELEM_OPT_TLV( 0x18 , BSSAP_PDU_TYPE_DTAP, DE_MID , " - Allocated P-TMSI" );
16620     
16621     ELEM_OPT_TLV( 0x23 , BSSAP_PDU_TYPE_DTAP, DE_MID , "" );
16622     
16623     ELEM_OPT_TV( 0x25 , BSSAP_PDU_TYPE_DTAP, DE_GMM_CAUSE , "" );
16624     
16625     ELEM_OPT_TLV( 0x2A , BSSAP_PDU_TYPE_DTAP, DE_GPRS_TIMER_2 , " - T3302" );
16626     
16627     ELEM_OPT_T( 0x8C , BSSAP_PDU_TYPE_DTAP, DE_CELL_NOT , "" );
16628     
16629     ELEM_OPT_TLV( 0x4A , BSSAP_PDU_TYPE_DTAP, DE_PLMN_LIST , "" );
16630
16631     ELEM_OPT_TV_SHORT( 0xB0 , BSSAP_PDU_TYPE_DTAP, DE_NET_FEAT_SUP , "" );
16632     
16633     ELEM_OPT_TLV( 0x34 , BSSAP_PDU_TYPE_DTAP, DE_EMERGENCY_NUM_LIST , "" );
16634
16635     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16636 }
16637
16638 /*
16639  * [7] 9.4.3
16640  */
16641 static void
16642 dtap_gmm_attach_com(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16643 {
16644
16645     guint32     curr_offset;
16646 /*    guint32   consumed; */
16647     guint       curr_len;
16648
16649     curr_offset = offset;
16650     curr_len = len;
16651
16652     is_uplink = IS_UPLINK_TRUE;
16653     g_pinfo->p2p_dir = P2P_DIR_RECV;
16654
16655     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16656 }
16657
16658 /*
16659  * [7] 9.4.4
16660  */
16661 static void
16662 dtap_gmm_attach_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16663 {
16664     guint32     curr_offset;
16665     guint32     consumed;
16666     guint       curr_len;
16667
16668     curr_offset = offset;
16669     curr_len = len;
16670
16671     is_uplink = IS_UPLINK_FALSE;
16672     g_pinfo->p2p_dir = P2P_DIR_SENT;
16673
16674     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_GMM_CAUSE );
16675
16676     ELEM_OPT_TLV( 0x2A , BSSAP_PDU_TYPE_DTAP, DE_GPRS_TIMER_2 , " - T3302" );
16677
16678     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16679 }
16680
16681 /*
16682  * [7] 9.4.5
16683  */
16684 static void
16685 dtap_gmm_detach_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16686 {
16687     guint32     curr_offset;
16688     guint32     consumed;
16689     guint       curr_len;
16690
16691     curr_offset = offset;
16692     curr_len = len;
16693
16694     is_uplink = IS_UPLINK_FALSE;
16695     g_pinfo->p2p_dir = P2P_DIR_SENT;
16696
16697     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_FORCE_TO_STAND_H );
16698     /* Force to standy might be wrong - To decode it correct, we need the direction */
16699     curr_len++;
16700     curr_offset--;
16701     
16702     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_DETACH_TYPE );
16703     
16704     ELEM_OPT_TV( 0x25 , BSSAP_PDU_TYPE_DTAP, DE_GMM_CAUSE , "" );
16705     
16706     ELEM_OPT_TLV( 0x18 , BSSAP_PDU_TYPE_DTAP, DE_MID , " - P-TMSI" );
16707
16708     ELEM_OPT_TLV( 0x19 , BSSAP_PDU_TYPE_DTAP, DE_P_TMSI_SIG , "" );
16709     
16710     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16711 }
16712
16713 /*
16714  * [7] 9.4.6
16715  */
16716 static void
16717 dtap_gmm_detach_acc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16718 {
16719     guint32     curr_offset;
16720     guint32     consumed;
16721     guint       curr_len;
16722
16723     curr_offset = offset;
16724     curr_len = len;
16725
16726     is_uplink = IS_UPLINK_TRUE;
16727     g_pinfo->p2p_dir = P2P_DIR_RECV;
16728
16729     if ( curr_len != 0 )
16730     {
16731         ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_SPARE_NIBBLE );
16732         curr_len++;
16733         curr_offset--;
16734         
16735         ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_FORCE_TO_STAND );
16736     }
16737
16738     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16739 }
16740
16741 /*
16742  * [7] 9.4.7
16743  */
16744 static void
16745 dtap_gmm_ptmsi_realloc_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16746 {
16747     guint32     curr_offset;
16748     guint32     consumed;
16749     guint       curr_len;
16750
16751     curr_offset = offset;
16752     curr_len = len;
16753
16754     is_uplink = IS_UPLINK_FALSE;
16755     g_pinfo->p2p_dir = P2P_DIR_SENT;
16756
16757     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID , " - Allocated P-TMSI" );
16758
16759     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RAI );
16760
16761     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_SPARE_NIBBLE );
16762     curr_len++;
16763     curr_offset--;
16764     
16765     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_FORCE_TO_STAND );
16766
16767     ELEM_OPT_TV( 0x19 , BSSAP_PDU_TYPE_DTAP, DE_MID , " - P-TMSI Signature" );    
16768
16769     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16770 }
16771
16772 /*
16773  * [7] 9.4.8
16774  */
16775 static void
16776 dtap_gmm_ptmsi_realloc_com(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16777 {
16778     guint32     curr_offset;
16779 /*    guint32   consumed; */
16780     guint       curr_len;
16781
16782     curr_offset = offset;
16783     curr_len = len;
16784
16785     is_uplink = IS_UPLINK_TRUE;
16786     g_pinfo->p2p_dir = P2P_DIR_RECV;
16787
16788     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16789 }
16790
16791 /*
16792  * [7] 9.4.9
16793  */
16794 static void
16795 dtap_gmm_auth_ciph_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16796 {
16797     guint32     curr_offset;
16798     guint32     consumed;
16799     guint       curr_len;
16800     guint8      oct;
16801     
16802     curr_offset = offset;
16803     curr_len = len;
16804
16805     is_uplink = IS_UPLINK_FALSE;
16806     g_pinfo->p2p_dir = P2P_DIR_SENT;
16807
16808     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_IMEISV_REQ );
16809     curr_offset--;
16810     curr_len++;
16811     
16812     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_CIPH_ALG );
16813     
16814     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_AC_REF_NUM_H );
16815     curr_offset--;
16816     curr_len++;
16817     
16818     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_FORCE_TO_STAND );
16819     
16820     ELEM_OPT_TV( 0x21 , BSSAP_PDU_TYPE_DTAP, DE_AUTH_PARAM_RAND , "" );
16821
16822 #if 0    
16823     ELEM_OPT_TV_SHORT( 0x08 , BSSAP_PDU_TYPE_DTAP, DE_CIPH_KEY_SEQ_NUM , "" );
16824 #else
16825     if ( curr_len > 0 )
16826     {
16827             oct = tvb_get_guint8(tvb, curr_offset);
16828             if (( oct & 0xf0 ) == 0x80 )
16829             {
16830                 /* The ciphering key sequence number is added here */
16831                 proto_tree_add_text(tree,
16832                         tvb, curr_offset, 1,
16833                         "Ciphering key sequence number: 0x%02x (%u)",
16834                         oct&7,
16835                         oct&7);
16836                 curr_offset++;
16837                 curr_len--;
16838             }
16839     }
16840 #endif
16841
16842     if ( curr_len == 0  )
16843     {
16844         EXTRANEOUS_DATA_CHECK(curr_len, 0);
16845         return;
16846     }
16847         
16848     ELEM_OPT_TLV( 0x28 , BSSAP_PDU_TYPE_DTAP, DE_AUTH_PARAM_AUTN , "" );
16849
16850     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16851 }
16852
16853 /*
16854  * [7] 9.4.10
16855  */
16856 static void
16857 dtap_gmm_auth_ciph_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16858 {
16859     guint32     curr_offset;
16860     guint32     consumed;
16861     guint       curr_len;
16862
16863     curr_offset = offset;
16864     curr_len = len;
16865
16866     is_uplink = IS_UPLINK_TRUE;
16867     g_pinfo->p2p_dir = P2P_DIR_RECV;
16868
16869     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_SPARE_NIBBLE );
16870     curr_offset--;
16871     curr_len++;
16872     
16873     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_AC_REF_NUM );
16874     
16875     ELEM_OPT_TV( 0x22 , BSSAP_PDU_TYPE_DTAP, DE_AUTH_RESP_PARAM , "" );
16876     
16877     ELEM_OPT_TLV( 0x23 , BSSAP_PDU_TYPE_DTAP, DE_MID , " - IMEISV" );
16878     
16879     ELEM_OPT_TLV( 0x29 , BSSAP_PDU_TYPE_DTAP, DE_AUTH_RESP_PARAM_EXT , "" );
16880
16881     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16882 }
16883
16884 /*
16885  * [7] 9.4.11
16886  */
16887 static void
16888 dtap_gmm_auth_ciph_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16889 {
16890     guint32     curr_offset;
16891 /*    guint32   consumed; */
16892     guint       curr_len;
16893
16894     curr_offset = offset;
16895     curr_len = len;
16896
16897     is_uplink = IS_UPLINK_FALSE;
16898     g_pinfo->p2p_dir = P2P_DIR_SENT;
16899
16900     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16901 }
16902
16903 /*
16904  * [7] 9.4.10a
16905  */
16906 static void
16907 dtap_gmm_auth_ciph_fail(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16908 {
16909     guint32     curr_offset;
16910     guint32     consumed;
16911     guint       curr_len;
16912
16913     curr_offset = offset;
16914     curr_len = len;
16915
16916     is_uplink = IS_UPLINK_TRUE;
16917     g_pinfo->p2p_dir = P2P_DIR_RECV;
16918
16919     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_GMM_CAUSE );
16920     
16921     ELEM_OPT_TLV( 0x30 , BSSAP_PDU_TYPE_DTAP, DE_AUTH_FAIL_PARAM , "" );
16922
16923     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16924 }
16925
16926 /*
16927  * [7] 9.4.12
16928  */
16929 static void
16930 dtap_gmm_ident_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16931 {
16932     guint32     curr_offset;
16933     guint       curr_len;
16934
16935     curr_offset = offset;
16936     curr_len = len;
16937
16938     is_uplink = IS_UPLINK_FALSE;
16939     g_pinfo->p2p_dir = P2P_DIR_SENT;
16940
16941 /*  If the half octect that are about to get decoded is the LAST in the octetstream, the macro will call return BEFORE we get a chance to fix the index. The end result will be that the first half-octet will be decoded but not the last. */
16942 /*    ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_ID_TYPE_2 );
16943     curr_offset--;
16944     curr_len++;
16945     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_FORCE_TO_STAND_H );*/
16946     
16947     elem_v(tvb, tree, BSSAP_PDU_TYPE_DTAP, DE_FORCE_TO_STAND_H, curr_offset);
16948     elem_v(tvb, tree, BSSAP_PDU_TYPE_DTAP, DE_ID_TYPE_2, curr_offset);
16949
16950     curr_offset+=1;
16951     curr_len-=1;
16952
16953     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16954 }
16955
16956 /*
16957  * [7] 9.4.13
16958  */
16959 static void
16960 dtap_gmm_ident_res(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16961 {
16962     guint32     curr_offset;
16963     guint32     consumed;
16964     guint       curr_len;
16965
16966     curr_offset = offset;
16967     curr_len = len;
16968
16969     is_uplink = IS_UPLINK_TRUE;
16970     g_pinfo->p2p_dir = P2P_DIR_RECV;
16971
16972     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID , "" );
16973
16974     EXTRANEOUS_DATA_CHECK(curr_len, 0);
16975 }
16976
16977 /*
16978  * [7] 9.4.14
16979  */
16980 static void
16981 dtap_gmm_rau_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
16982 {
16983     guint32     curr_offset;
16984     guint32     consumed;
16985     guint       curr_len;
16986
16987     curr_offset = offset;
16988     curr_len = len;
16989
16990     is_uplink = IS_UPLINK_TRUE;
16991     g_pinfo->p2p_dir = P2P_DIR_RECV;
16992
16993     /* is included in update type
16994     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_CIPH_KEY_SEQ_NUM );
16995     curr_offset--;
16996     curr_len++;
16997     
16998     */
16999     
17000     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_UPD_TYPE );
17001     
17002     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RAI );
17003     
17004     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MS_RAD_ACC_CAP , "" );
17005     
17006     ELEM_OPT_TV( 0x19 , BSSAP_PDU_TYPE_DTAP, DE_P_TMSI_SIG , " - Old P-TMSI Signature" ); 
17007     
17008     ELEM_OPT_TV( 0x17 , BSSAP_PDU_TYPE_DTAP, DE_GPRS_TIMER , " - Requested Ready Timer" );
17009
17010     ELEM_OPT_TV( 0x27 , BSSAP_PDU_TYPE_DTAP, DE_DRX_PARAM , "" );
17011     
17012     ELEM_OPT_TV_SHORT( 0x90 , BSSAP_PDU_TYPE_DTAP, DE_TMSI_STAT , "" );
17013     
17014     ELEM_OPT_TLV( 0x18 , BSSAP_PDU_TYPE_DTAP, DE_MID , " - P-TMSI" );
17015     
17016     ELEM_OPT_TLV( 0x31 , BSSAP_PDU_TYPE_DTAP, DE_MS_NET_CAP , "" );
17017     
17018     ELEM_OPT_TLV( 0x32 , BSSAP_PDU_TYPE_DTAP, DE_PDP_CONTEXT_STAT , "" );
17019     
17020     ELEM_OPT_TLV( 0x33 , BSSAP_PDU_TYPE_DTAP, DE_PS_LCS_CAP , "" );
17021     
17022     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17023 }
17024
17025 /*
17026  * [7] 9.4.15
17027  */
17028 static void
17029 dtap_gmm_rau_acc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17030 {
17031     guint32     curr_offset;
17032     guint32     consumed;
17033     guint       curr_len;
17034
17035     curr_offset = offset;
17036     curr_len = len;
17037
17038     is_uplink = IS_UPLINK_FALSE;
17039     g_pinfo->p2p_dir = P2P_DIR_SENT;
17040
17041     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_UPD_RES );
17042     curr_offset--;
17043     curr_len++;
17044     
17045     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_FORCE_TO_STAND );
17046     
17047     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_GPRS_TIMER );
17048     
17049     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RAI );
17050     
17051     ELEM_OPT_TV( 0x19 , BSSAP_PDU_TYPE_DTAP, DE_P_TMSI_SIG , "" ); 
17052     
17053     ELEM_OPT_TLV( 0x18 , BSSAP_PDU_TYPE_DTAP, DE_MID , " - Allocated P-TMSI");
17054     
17055     ELEM_OPT_TLV( 0x23 , BSSAP_PDU_TYPE_DTAP, DE_MID , "" );
17056     
17057     ELEM_OPT_TLV( 0x26 , BSSAP_PDU_TYPE_DTAP, DE_REC_N_PDU_NUM_LIST , "" );
17058     
17059     ELEM_OPT_TV( 0x17 , BSSAP_PDU_TYPE_DTAP, DE_GPRS_TIMER , " - Negotiated Ready Timer" );
17060     
17061     ELEM_OPT_TV( 0x25 , BSSAP_PDU_TYPE_DTAP, DE_GMM_CAUSE , "" );
17062     
17063     ELEM_OPT_TLV( 0x2A , BSSAP_PDU_TYPE_DTAP, DE_GPRS_TIMER_2 , " - T3302" );
17064     
17065     ELEM_OPT_T( 0x8C , BSSAP_PDU_TYPE_DTAP, DE_CELL_NOT , "" );
17066     
17067     ELEM_OPT_TLV( 0x4A , BSSAP_PDU_TYPE_DTAP, DE_PLMN_LIST , "" );
17068     
17069     ELEM_OPT_TLV( 0x32 , BSSAP_PDU_TYPE_DTAP, DE_PDP_CONTEXT_STAT , "" );
17070     
17071     ELEM_OPT_TV_SHORT ( 0xB0 , BSSAP_PDU_TYPE_DTAP, DE_NET_FEAT_SUP , "" );
17072     
17073     ELEM_OPT_TLV( 0x34 , BSSAP_PDU_TYPE_DTAP, DE_EMERGENCY_NUM_LIST , "" );
17074
17075     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17076 }
17077
17078 /*
17079  * [7] 9.4.16
17080  */
17081 static void
17082 dtap_gmm_rau_com(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17083 {
17084     guint32     curr_offset;
17085     guint32     consumed;
17086     guint       curr_len;
17087
17088     curr_offset = offset;
17089     curr_len = len;
17090
17091     is_uplink = IS_UPLINK_TRUE;
17092     g_pinfo->p2p_dir = P2P_DIR_RECV;
17093         /* [7] 10.5.5.11 */
17094     ELEM_OPT_TLV( 0x26 , BSSAP_PDU_TYPE_DTAP, DE_REC_N_PDU_NUM_LIST , "" );
17095         /* Inter RAT information container 10.5.5.24 TS 24.008 version 6.8.0 Release 6 */
17096         /*TO DO: Implement */
17097         ELEM_OPT_TLV( 0x27 , BSSAP_PDU_TYPE_DTAP, DE_RAT_INFO_CONTAINER , "" );
17098     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17099 }
17100
17101 /*
17102  * [7] 9.4.17
17103  */
17104 static void
17105 dtap_gmm_rau_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17106 {
17107     guint32     curr_offset;
17108     guint32     consumed;
17109     guint       curr_len;
17110
17111     curr_offset = offset;
17112     curr_len = len;
17113
17114     is_uplink = IS_UPLINK_FALSE;
17115     g_pinfo->p2p_dir = P2P_DIR_SENT;
17116
17117     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_GMM_CAUSE );
17118     
17119     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_SPARE_NIBBLE );
17120     curr_offset--;
17121     curr_len++;
17122     
17123     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_FORCE_TO_STAND );
17124     
17125     ELEM_OPT_TLV( 0x26 , BSSAP_PDU_TYPE_DTAP, DE_GPRS_TIMER_2 , " - T3302" );
17126
17127     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17128 }
17129
17130 /*
17131  * [7] 9.4.18
17132  */
17133 static void
17134 dtap_gmm_status(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17135 {
17136     guint32     curr_offset;
17137     guint32     consumed;
17138     guint       curr_len;
17139
17140     curr_offset = offset;
17141     curr_len = len;
17142
17143      is_uplink = IS_UPLINK_UNKNOWN;
17144     g_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
17145
17146     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_GMM_CAUSE );
17147
17148     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17149 }
17150
17151 /*
17152  * [8] 9.4.19 GMM Information
17153  */
17154 static void
17155 dtap_gmm_information(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17156 {
17157     guint32     curr_offset;
17158     guint32     consumed;
17159     guint       curr_len;
17160
17161     curr_offset = offset;
17162     curr_len = len;
17163
17164     is_uplink = IS_UPLINK_FALSE;
17165     g_pinfo->p2p_dir = P2P_DIR_SENT;
17166
17167     ELEM_OPT_TLV( 0x43 , BSSAP_PDU_TYPE_DTAP, DE_NETWORK_NAME , " - Full Name" );
17168     
17169     ELEM_OPT_TLV( 0x45 , BSSAP_PDU_TYPE_DTAP, DE_NETWORK_NAME , " - Short Name" );
17170     
17171     ELEM_OPT_TV( 0x46 , BSSAP_PDU_TYPE_DTAP, DE_TIME_ZONE , "" );
17172     
17173     ELEM_OPT_TV( 0x47 , BSSAP_PDU_TYPE_DTAP, DE_TIME_ZONE_TIME , "" );
17174     
17175     ELEM_OPT_TLV( 0x48 , BSSAP_PDU_TYPE_DTAP, DE_LSA_ID , "" );
17176     
17177     ELEM_OPT_TLV( 0x49 , BSSAP_PDU_TYPE_DTAP, DE_DAY_SAVING_TIME , "" );
17178
17179     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17180 }
17181
17182 /*
17183  * [7] 9.4.20
17184  */
17185 static void
17186 dtap_gmm_service_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17187 {
17188     guint32     curr_offset;
17189     guint32     consumed;
17190     guint       curr_len;
17191
17192     curr_offset = offset;
17193     curr_len = len;
17194
17195     is_uplink = IS_UPLINK_TRUE;
17196     g_pinfo->p2p_dir = P2P_DIR_RECV;
17197
17198     /* Is included in SRVC TYPE
17199     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_CIPH_KEY_SEQ_NUM );
17200     curr_offset--;
17201     curr_len++;
17202     */
17203     
17204     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_SRVC_TYPE );
17205     
17206         /* P-TMSI Mobile station identity 10.5.1.4 M LV 6 */
17207     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID, "");
17208     
17209     ELEM_OPT_TLV( 0x32 , BSSAP_PDU_TYPE_DTAP, DE_PDP_CONTEXT_STAT , "" );
17210
17211         /* MBMS context status 10.5.7.6 TLV 2 - 18 */
17212         ELEM_OPT_TLV( 0x35 , BSSAP_PDU_TYPE_DTAP, DE_MBMS_CTX_STATUS , "" );
17213
17214     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17215 }
17216
17217 /*
17218  * [7] 9.4.21
17219  */
17220 static void
17221 dtap_gmm_service_acc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17222 {
17223     guint32     curr_offset;
17224     guint32     consumed;
17225     guint       curr_len;
17226
17227     curr_offset = offset;
17228     curr_len = len;
17229
17230     is_uplink = IS_UPLINK_FALSE;
17231     g_pinfo->p2p_dir = P2P_DIR_SENT;
17232
17233     ELEM_OPT_TLV( 0x32 , BSSAP_PDU_TYPE_DTAP, DE_PDP_CONTEXT_STAT , "" );
17234
17235         /* MBMS context status 10.5.7.6 TLV 2 - 18 */
17236         ELEM_OPT_TLV( 0x35 , BSSAP_PDU_TYPE_DTAP, DE_MBMS_CTX_STATUS , "" );
17237
17238     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17239 }
17240
17241 /*
17242  * [7] 9.4.22
17243  */
17244 static void
17245 dtap_gmm_service_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17246 {
17247     guint32     curr_offset;
17248     guint32     consumed;
17249     guint       curr_len;
17250
17251     curr_offset = offset;
17252     curr_len = len;
17253
17254     is_uplink = IS_UPLINK_FALSE;
17255     g_pinfo->p2p_dir = P2P_DIR_SENT;
17256
17257     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_GMM_CAUSE );
17258
17259     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17260 }
17261
17262 /*
17263  * [8] 9.5.1 Activate PDP context request
17264  */
17265 static void
17266 dtap_sm_act_pdp_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17267 {
17268     guint32     curr_offset;
17269     guint32     consumed;
17270     guint       curr_len;
17271
17272     curr_offset = offset;
17273     curr_len = len;
17274
17275     is_uplink = IS_UPLINK_UNKNOWN;
17276     g_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
17277
17278     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_NET_SAPI );
17279
17280     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_LLC_SAPI );
17281
17282     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_QOS , " - Requested QoS" );
17283
17284     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_PD_PRO_ADDR , " - Requested PDP address" );
17285
17286     ELEM_OPT_TLV( 0x28 , BSSAP_PDU_TYPE_DTAP, DE_ACC_POINT_NAME , "" );
17287
17288     ELEM_OPT_TLV( 0x27 , BSSAP_PDU_TYPE_DTAP, DE_PRO_CONF_OPT , "" );
17289
17290     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17291 }
17292
17293 /*
17294  * [8] 9.5.2 Activate PDP context accept
17295  */
17296 static void
17297 dtap_sm_act_pdp_acc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17298 {
17299     guint32     curr_offset;
17300     guint32     consumed;
17301     guint       curr_len;
17302
17303     curr_offset = offset;
17304     curr_len = len;
17305
17306     is_uplink = IS_UPLINK_UNKNOWN;
17307     g_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
17308
17309     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_LLC_SAPI );
17310
17311     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_QOS , " - Negotiated QoS" );
17312
17313 #if 0   
17314     /* This is done automatically */
17315     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_SPARE );
17316     curr_offset--;
17317     curr_len++;
17318 #endif
17319
17320     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RAD_PRIO );
17321
17322     ELEM_OPT_TLV( 0x2B , BSSAP_PDU_TYPE_DTAP, DE_PD_PRO_ADDR , "" );
17323
17324     ELEM_OPT_TLV( 0x27 , BSSAP_PDU_TYPE_DTAP, DE_PRO_CONF_OPT , "" );
17325
17326     ELEM_OPT_TLV( 0x34 , BSSAP_PDU_TYPE_DTAP, DE_PACKET_FLOW_ID , "" );
17327
17328     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17329 }
17330
17331 /*
17332  * [8] 9.5.3 Activate PDP context reject
17333  */
17334 static void
17335 dtap_sm_act_pdp_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17336 {
17337     guint32     curr_offset;
17338     guint32     consumed;
17339     guint       curr_len;
17340
17341     curr_offset = offset;
17342     curr_len = len;
17343
17344     is_uplink = IS_UPLINK_UNKNOWN;
17345     g_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
17346
17347     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_SM_CAUSE );
17348
17349     ELEM_OPT_TLV( 0x27 , BSSAP_PDU_TYPE_DTAP, DE_PRO_CONF_OPT , "" );
17350
17351     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17352 }
17353
17354 /*
17355  * [8] 9.5.4 Activate Secondary PDP Context Request
17356  */
17357 static void
17358 dtap_sm_act_sec_pdp_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17359 {
17360     guint32     curr_offset;
17361     guint32     consumed;
17362     guint       curr_len;
17363
17364     curr_offset = offset;
17365     curr_len = len;
17366
17367     is_uplink = IS_UPLINK_UNKNOWN;
17368     g_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
17369
17370     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_NET_SAPI );
17371
17372     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_LLC_SAPI );
17373
17374     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_QOS , " - Requested QoS" );
17375
17376     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_LINKED_TI , "" );
17377
17378         /* 3GPP TS 24.008 version 6.8.0 Release 6, 36 TFT Traffic Flow Template 10.5.6.12 O TLV 3-257 */
17379     ELEM_OPT_TLV( 0x36 , BSSAP_PDU_TYPE_DTAP, DE_TRAFFIC_FLOW_TEMPLATE , "" );
17380
17381     ELEM_OPT_TLV( 0x27 , BSSAP_PDU_TYPE_DTAP, DE_PRO_CONF_OPT , "" );
17382
17383     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17384 }
17385
17386 /*
17387  * [7] 9.5.5
17388  */
17389 static void
17390 dtap_sm_act_sec_pdp_acc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17391 {
17392     guint32     curr_offset;
17393     guint32     consumed;
17394     guint       curr_len;
17395
17396     curr_offset = offset;
17397     curr_len = len;
17398
17399     is_uplink = IS_UPLINK_UNKNOWN;
17400     g_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
17401
17402     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_LLC_SAPI );
17403
17404     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_QOS , " - Negotiated QoS" );
17405
17406     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RAD_PRIO);
17407
17408 #if 0   
17409     /* This is done automatically */
17410     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_SPARE );
17411     curr_offset--;
17412     curr_len++;
17413 #endif
17414
17415     ELEM_OPT_TLV( 0x34 , BSSAP_PDU_TYPE_DTAP, DE_PACKET_FLOW_ID , "" );
17416
17417     ELEM_OPT_TLV( 0x27 , BSSAP_PDU_TYPE_DTAP, DE_PRO_CONF_OPT , "" );
17418
17419     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17420 }
17421
17422 /*
17423  * [8] 9.5.6 Activate Secondary PDP Context Reject
17424  */
17425 static void
17426 dtap_sm_act_sec_pdp_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17427 {
17428     guint32     curr_offset;
17429     guint32     consumed;
17430     guint       curr_len;
17431
17432     curr_offset = offset;
17433     curr_len = len;
17434
17435     is_uplink = IS_UPLINK_UNKNOWN;
17436     g_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
17437
17438     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_SM_CAUSE );
17439
17440     ELEM_OPT_TLV( 0x27 , BSSAP_PDU_TYPE_DTAP, DE_PRO_CONF_OPT , "" );
17441
17442     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17443 }
17444
17445 /*
17446  * [8] 9.5.7 Request PDP context activation
17447  */
17448 static void
17449 dtap_sm_req_pdp_act(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17450 {
17451     guint32     curr_offset;
17452     guint32     consumed;
17453     guint       curr_len;
17454
17455     curr_offset = offset;
17456     curr_len = len;
17457
17458     is_uplink = IS_UPLINK_UNKNOWN;
17459     g_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
17460
17461     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_PD_PRO_ADDR , " - Offered PDP address" );
17462
17463     ELEM_OPT_TLV( 0x28 , BSSAP_PDU_TYPE_DTAP, DE_ACC_POINT_NAME , "" );
17464
17465     ELEM_OPT_TLV( 0x27 , BSSAP_PDU_TYPE_DTAP, DE_PRO_CONF_OPT , "" );
17466
17467     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17468 }
17469
17470 /*
17471  * [8] 9.5.8 Request PDP context activation reject
17472  */
17473 static void
17474 dtap_sm_req_pdp_act_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17475 {
17476     guint32     curr_offset;
17477     guint32     consumed;
17478     guint       curr_len;
17479
17480     curr_offset = offset;
17481     curr_len = len;
17482
17483     is_uplink = IS_UPLINK_UNKNOWN;
17484     g_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
17485
17486     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_SM_CAUSE );
17487
17488     ELEM_OPT_TLV( 0x27 , BSSAP_PDU_TYPE_DTAP, DE_PRO_CONF_OPT , "" );
17489
17490     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17491 }
17492
17493 /*
17494  * [8] 9.5.9 Modify PDP context request (Network to MS direction)
17495  */
17496 static void
17497 dtap_sm_mod_pdp_req_net(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17498 {
17499     guint32     curr_offset;
17500     guint32     consumed;
17501     guint       curr_len;
17502
17503     curr_offset = offset;
17504     curr_len = len;
17505
17506     is_uplink = IS_UPLINK_UNKNOWN;
17507     g_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
17508
17509         ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP,DE_RAD_PRIO);
17510 #if 0   
17511     /* This is done automatically */
17512     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_SPARE );
17513     curr_offset--;
17514     curr_len++;
17515 #endif
17516
17517     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_LLC_SAPI );
17518
17519     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_QOS , " - New QoS" );
17520
17521     ELEM_OPT_TLV( 0x2B , BSSAP_PDU_TYPE_DTAP, DE_PD_PRO_ADDR , "" );
17522
17523     ELEM_OPT_TLV( 0x34 , BSSAP_PDU_TYPE_DTAP, DE_PACKET_FLOW_ID , "" );
17524
17525     ELEM_OPT_TLV( 0x27 , BSSAP_PDU_TYPE_DTAP, DE_PRO_CONF_OPT , "" );
17526
17527     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17528 }
17529
17530 /*
17531  * [8] 9.5.10 Modify PDP context request (MS to network direction)
17532  */
17533 static void
17534 dtap_sm_mod_pdp_req_ms(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17535 {
17536     guint32     curr_offset;
17537     guint32     consumed;
17538     guint       curr_len;
17539
17540     curr_offset = offset;
17541     curr_len = len;
17542
17543     is_uplink = IS_UPLINK_UNKNOWN;
17544     g_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
17545
17546     ELEM_OPT_TV( 0x32 , BSSAP_PDU_TYPE_DTAP, DE_LLC_SAPI , " - Requested LLC SAPI" );
17547
17548     ELEM_OPT_TLV( 0x30 , BSSAP_PDU_TYPE_DTAP, DE_QOS , " - Requested new QoS" );
17549
17550     ELEM_OPT_TLV( 0x31 , BSSAP_PDU_TYPE_DTAP, DE_TRAFFIC_FLOW_TEMPLATE , " - New TFT" );
17551
17552     ELEM_OPT_TLV( 0x27 , BSSAP_PDU_TYPE_DTAP, DE_PRO_CONF_OPT , "" );
17553
17554     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17555 }
17556
17557 /*
17558  * [8] 9.5.11 Modify PDP context accept (MS to network direction)
17559  */
17560 static void
17561 dtap_sm_mod_pdp_acc_ms(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17562 {
17563     guint32     curr_offset;
17564     guint32     consumed;
17565     guint       curr_len;
17566
17567     curr_offset = offset;
17568     curr_len = len;
17569
17570     is_uplink = IS_UPLINK_UNKNOWN;
17571     g_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
17572
17573     ELEM_OPT_TLV( 0x27 , BSSAP_PDU_TYPE_DTAP, DE_PRO_CONF_OPT , "" );
17574
17575     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17576 }
17577
17578 /*
17579  * [8] 9.5.12 Modify PDP context accept (Network to MS direction)
17580  */
17581 static void
17582 dtap_sm_mod_pdp_acc_net(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17583 {
17584     guint32     curr_offset;
17585     guint32     consumed;
17586     guint       curr_len;
17587
17588     curr_offset = offset;
17589     curr_len = len;
17590
17591     is_uplink = IS_UPLINK_UNKNOWN;
17592     g_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
17593
17594     ELEM_OPT_TLV( 0x30 , BSSAP_PDU_TYPE_DTAP, DE_QOS , " - Negotiated QoS" );
17595
17596     ELEM_OPT_TV( 0x32 , BSSAP_PDU_TYPE_DTAP, DE_LLC_SAPI , " - Negotiated LLC SAPI" );
17597
17598     ELEM_OPT_TV_SHORT ( 0x80 , BSSAP_PDU_TYPE_DTAP , DE_RAD_PRIO , " - New radio priority" );
17599
17600     ELEM_OPT_TLV( 0x34 , BSSAP_PDU_TYPE_DTAP, DE_PACKET_FLOW_ID , "" );
17601
17602     ELEM_OPT_TLV( 0x27 , BSSAP_PDU_TYPE_DTAP, DE_PRO_CONF_OPT , "" );
17603
17604     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17605 }
17606
17607 /*
17608  * [8] 9.5.13 Modify PDP Context Reject
17609  */
17610 static void
17611 dtap_sm_mod_pdp_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17612 {
17613     guint32     curr_offset;
17614     guint32     consumed;
17615     guint       curr_len;
17616
17617     curr_offset = offset;
17618     curr_len = len;
17619
17620     is_uplink = IS_UPLINK_UNKNOWN;
17621     g_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
17622
17623     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_SM_CAUSE );
17624
17625     ELEM_OPT_TLV( 0x27 , BSSAP_PDU_TYPE_DTAP, DE_PRO_CONF_OPT , "" );
17626
17627     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17628 }
17629
17630 /*
17631  * [8] 9.5.14 Deactivate PDP context request
17632  */
17633 static void
17634 dtap_sm_deact_pdp_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17635 {
17636     guint32     curr_offset;
17637     guint32     consumed;
17638     guint       curr_len;
17639
17640     curr_offset = offset;
17641     curr_len = len;
17642
17643     is_uplink = IS_UPLINK_UNKNOWN;
17644     g_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
17645
17646     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_SM_CAUSE );
17647
17648     ELEM_OPT_TV_SHORT( 0x90 , BSSAP_PDU_TYPE_DTAP , DE_TEAR_DOWN_IND , "" );
17649
17650     ELEM_OPT_TLV( 0x27 , BSSAP_PDU_TYPE_DTAP, DE_PRO_CONF_OPT , "" );
17651
17652         /* MBMS context status 10.5.7.6 TLV 2 - 18 */
17653         ELEM_OPT_TLV( 0x35 , BSSAP_PDU_TYPE_DTAP, DE_MBMS_CTX_STATUS , "" );
17654
17655     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17656 }
17657
17658
17659 /*
17660  * [8] 9.5.15 Deactivate PDP context accept
17661  */
17662 static void
17663 dtap_sm_deact_pdp_acc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17664 {
17665     guint32     curr_offset;
17666     guint32     consumed;
17667     guint       curr_len;
17668
17669     curr_offset = offset;
17670     curr_len = len;
17671
17672      is_uplink = IS_UPLINK_UNKNOWN;
17673     g_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
17674
17675     ELEM_OPT_TLV( 0x27 , BSSAP_PDU_TYPE_DTAP, DE_PRO_CONF_OPT , "" );
17676
17677         /* MBMS context status 10.5.7.6 TLV 2 - 18 */
17678         ELEM_OPT_TLV( 0x35 , BSSAP_PDU_TYPE_DTAP, DE_MBMS_CTX_STATUS , "" );
17679
17680     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17681 }
17682
17683 /*
17684  * [8] 9.5.21 SM Status
17685  */
17686 static void
17687 dtap_sm_status(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
17688 {
17689     guint32     curr_offset;
17690     guint32     consumed;
17691     guint       curr_len;
17692
17693     curr_offset = offset;
17694     curr_len = len;
17695
17696      is_uplink = IS_UPLINK_UNKNOWN;
17697     g_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
17698
17699     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_SM_CAUSE );
17700
17701     EXTRANEOUS_DATA_CHECK(curr_len, 0);
17702 }
17703
17704 /*
17705  * [8] 9.5.22 Activate MBMS Context Request
17706  */
17707
17708         /* Requested MBMS NSAPI Enhanced Network service access point identifier 10.5.6.15 M V */
17709         /* Requested LLC SAPI LLC service access point identifier 10.5.6.9 M V 1 */
17710         /* Supported MBMS bearer capabilities MBMS bearer capabilities 10.5.6.14 M LV 2 - 3 */
17711         /* Requested multicast address Packet data protocol address 10.5.6.4 M LV 3 - 19 */
17712         /* Access point name Access point name 10.5.6.1 M LV 2 - 101 */
17713         /* 35 MBMS protocol configuration options MBMS protocol configuration options 10.5.6.15 O TLV 3 - 253 */
17714
17715 /*
17716  * [8] 9.5.23 Activate MBMS Context Accept
17717  */
17718
17719 /*
17720  * [8] 9.5.24 Activate MBMS Context Reject
17721  */
17722
17723 /*
17724  * [8] 9.5.25 Request MBMS Context Activation
17725  */
17726
17727 /*
17728  * [8] 9.5.26 Request MBMS Context Activation Reject
17729  */
17730
17731 #define NUM_GSM_DTAP_MSG_MM (sizeof(gsm_a_dtap_msg_mm_strings)/sizeof(value_string))
17732 static gint ett_gsm_dtap_msg_mm[NUM_GSM_DTAP_MSG_MM];
17733 static void (*dtap_msg_mm_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
17734     dtap_mm_imsi_det_ind,       /* IMSI Detach Indication */
17735     dtap_mm_loc_upd_acc,        /* Location Updating Accept */
17736     dtap_mm_loc_upd_rej,        /* Location Updating Reject */
17737     dtap_mm_loc_upd_req,        /* Location Updating Request */
17738     NULL /* no associated data */,      /* Authentication Reject */
17739     dtap_mm_auth_req,   /* Authentication Request */
17740     dtap_mm_auth_resp,  /* Authentication Response */
17741     dtap_mm_auth_fail,  /* Authentication Failure */
17742     dtap_mm_id_req,     /* Identity Request */
17743     dtap_mm_id_resp,    /* Identity Response */
17744     dtap_mm_tmsi_realloc_cmd,   /* TMSI Reallocation Command */
17745     NULL /* no associated data */,      /* TMSI Reallocation Complete */
17746     NULL /* no associated data */,      /* CM Service Accept */
17747     dtap_mm_cm_srvc_rej,        /* CM Service Reject */
17748     NULL /* no associated data */,      /* CM Service Abort */
17749     dtap_mm_cm_srvc_req,        /* CM Service Request */
17750     dtap_mm_cm_srvc_prompt,     /* CM Service Prompt */
17751     NULL,       /* Reserved: was allocated in earlier phases of the protocol */
17752     dtap_mm_cm_reestab_req,     /* CM Re-establishment Request */
17753     dtap_mm_abort,      /* Abort */
17754     NULL /* no associated data */,      /* MM Null */
17755     dtap_mm_mm_status,  /* MM Status */
17756     dtap_mm_mm_info,    /* MM Information */
17757     NULL,       /* NONE */
17758 };
17759
17760 #define NUM_GSM_DTAP_MSG_RR (sizeof(gsm_a_dtap_msg_rr_strings)/sizeof(value_string))
17761 static gint ett_gsm_dtap_msg_rr[NUM_GSM_DTAP_MSG_RR];
17762 static void (*dtap_msg_rr_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
17763     NULL,       /* RR Initialisation Request */
17764     NULL,       /* Additional Assignment */
17765     NULL,       /* Immediate Assignment */
17766     NULL,       /* Immediate Assignment Extended */
17767     NULL,       /* Immediate Assignment Reject */
17768
17769     NULL,       /* DTM Assignment Failure */
17770     NULL,       /* DTM Reject */
17771     NULL,       /* DTM Request */
17772     NULL,       /* Main DCCH Assignment Command */
17773     NULL,       /* Packet Assignment Command */
17774
17775     NULL,       /* Ciphering Mode Command */
17776     NULL,       /* Ciphering Mode Complete */
17777
17778     NULL,       /* Configuration Change Command */
17779     NULL,       /* Configuration Change Ack. */
17780     NULL,       /* Configuration Change Reject */
17781
17782     NULL,       /* Assignment Command */
17783     NULL,       /* Assignment Complete */
17784     NULL,       /* Assignment Failure */
17785     dtap_rr_ho_cmd,     /* Handover Command */
17786     NULL,       /* Handover Complete */
17787     NULL,       /* Handover Failure */
17788     NULL,       /* Physical Information */
17789     NULL,       /* DTM Assignment Command */
17790
17791     NULL,       /* RR-cell Change Order */
17792     NULL,       /* PDCH Assignment Command */
17793
17794     NULL,       /* Channel Release */
17795     NULL,       /* Partial Release */
17796     NULL,       /* Partial Release Complete */
17797
17798     NULL,       /* Paging Request Type 1 */
17799     NULL,       /* Paging Request Type 2 */
17800     NULL,       /* Paging Request Type 3 */
17801     dtap_rr_paging_resp,        /* Paging Response */
17802     NULL,       /* Notification/NCH */
17803     NULL,       /* Reserved */
17804     NULL,       /* Notification/Response */
17805
17806     NULL,       /* Reserved */
17807
17808     NULL,       /* Utran Classmark Change  */
17809     NULL,       /* UE RAB Preconfiguration */
17810     NULL,       /* cdma2000 Classmark Change */
17811     NULL,       /* Inter System to UTRAN Handover Command */
17812     NULL,       /* Inter System to cdma2000 Handover Command */
17813
17814     NULL,       /* System Information Type 8 */
17815     NULL,       /* System Information Type 1 */
17816     NULL,       /* System Information Type 2 */
17817     NULL,       /* System Information Type 3 */
17818     NULL,       /* System Information Type 4 */
17819     NULL,       /* System Information Type 5 */
17820     NULL,       /* System Information Type 6 */
17821     NULL,       /* System Information Type 7 */
17822
17823     NULL,       /* System Information Type 2bis */
17824     NULL,       /* System Information Type 2ter */
17825     NULL,       /* System Information Type 2quater */
17826     NULL,       /* System Information Type 5bis */
17827     NULL,       /* System Information Type 5ter */
17828     NULL,       /* System Information Type 9 */
17829     NULL,       /* System Information Type 13 */
17830
17831     NULL,       /* System Information Type 16 */
17832     NULL,       /* System Information Type 17 */
17833
17834     NULL,       /* System Information Type 18 */
17835     NULL,       /* System Information Type 19 */
17836     NULL,       /* System Information Type 20 */
17837
17838     NULL,       /* Channel Mode Modify */
17839     dtap_rr_rr_status,  /* RR Status */
17840     NULL,       /* Channel Mode Modify Acknowledge */
17841     NULL,       /* Frequency Redefinition */
17842     NULL,       /* Measurement Report */
17843     NULL,       /* Classmark Change */
17844     NULL,       /* Classmark Enquiry */
17845     NULL,       /* Extended Measurement Report */
17846     NULL,       /* Extended Measurement Order */
17847     NULL,       /* GPRS Suspension Request */
17848
17849     NULL,       /* VGCS Uplink Grant */
17850     NULL,       /* Uplink Release */
17851     NULL,       /* Reserved */
17852     NULL,       /* Uplink Busy */
17853     NULL,       /* Talker Indication */
17854
17855     NULL,       /* UTRAN Classmark Change/Handover To UTRAN Command */  /* spec conflict */
17856
17857     NULL,       /* Application Information */
17858
17859     NULL,       /* NONE */
17860 };
17861
17862 #define NUM_GSM_DTAP_MSG_CC (sizeof(gsm_a_dtap_msg_cc_strings)/sizeof(value_string))
17863 static gint ett_gsm_dtap_msg_cc[NUM_GSM_DTAP_MSG_CC];
17864 static void (*dtap_msg_cc_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
17865     dtap_cc_alerting,   /* Alerting */
17866     dtap_cc_call_conf,  /* Call Confirmed */
17867     dtap_cc_call_proceed,       /* Call Proceeding */
17868     dtap_cc_connect,    /* Connect */
17869     NULL /* no associated data */,      /* Connect Acknowledge */
17870     dtap_cc_emerg_setup,        /* Emergency Setup */
17871     dtap_cc_progress,   /* Progress */
17872     dtap_cc_cc_est,     /* CC-Establishment */
17873     dtap_cc_cc_est_conf,        /* CC-Establishment Confirmed */
17874     dtap_cc_recall,     /* Recall */
17875     dtap_cc_start_cc,   /* Start CC */
17876     dtap_cc_setup,      /* Setup */
17877     dtap_cc_modify,     /* Modify */
17878     dtap_cc_modify_complete,    /* Modify Complete */
17879     dtap_cc_modify_rej, /* Modify Reject */
17880     dtap_cc_user_info,  /* User Information */
17881     NULL /* no associated data */,      /* Hold */
17882     NULL /* no associated data */,      /* Hold Acknowledge */
17883     dtap_cc_hold_rej,   /* Hold Reject */
17884     NULL /* no associated data */,      /* Retrieve */
17885     NULL /* no associated data */,      /* Retrieve Acknowledge */
17886     dtap_cc_retrieve_rej,       /* Retrieve Reject */
17887     dtap_cc_disconnect, /* Disconnect */
17888     dtap_cc_release,    /* Release */
17889     dtap_cc_release_complete,   /* Release Complete */
17890     dtap_cc_congestion_control, /* Congestion Control */
17891     dtap_cc_notify,     /* Notify */
17892     dtap_cc_status,     /* Status */
17893     NULL /* no associated data */,      /* Status Enquiry */
17894     dtap_cc_start_dtmf, /* Start DTMF */
17895     NULL /* no associated data */,      /* Stop DTMF */
17896     NULL /* no associated data */,      /* Stop DTMF Acknowledge */
17897     dtap_cc_start_dtmf_ack,     /* Start DTMF Acknowledge */
17898     dtap_cc_start_dtmf_rej,     /* Start DTMF Reject */
17899     dtap_cc_facility,   /* Facility */
17900     NULL,       /* NONE */
17901 };
17902
17903 #define NUM_GSM_DTAP_MSG_GMM (sizeof(gsm_a_dtap_msg_gmm_strings)/sizeof(value_string))
17904 static gint ett_gsm_dtap_msg_gmm[NUM_GSM_DTAP_MSG_GMM];
17905 static void (*dtap_msg_gmm_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
17906     dtap_gmm_attach_req,                /* Attach Request */
17907     dtap_gmm_attach_acc,                /* Attach Accept */
17908     dtap_gmm_attach_com,                /* Attach Complete */
17909     dtap_gmm_attach_rej,                /* Attach Reject */
17910     dtap_gmm_detach_req,                /* Detach Request */
17911     dtap_gmm_detach_acc,                /* Detach Accept */
17912     dtap_gmm_rau_req,                   /* Routing Area Update Request */
17913     dtap_gmm_rau_acc,                   /* Routing Area Update Accept */
17914     dtap_gmm_rau_com,                   /* Routing Area Update Complete */
17915     dtap_gmm_rau_rej,                   /* Routing Area Update Reject */
17916     dtap_gmm_service_req,               /* Service Request */
17917     dtap_gmm_service_acc,               /* Service Accept */
17918     dtap_gmm_service_rej,               /* Service Reject */
17919     dtap_gmm_ptmsi_realloc_cmd, /* P-TMSI Reallocation Command */
17920     dtap_gmm_ptmsi_realloc_com, /* P-TMSI Reallocation Complete */
17921     dtap_gmm_auth_ciph_req,             /* Authentication and Ciphering Req */
17922     dtap_gmm_auth_ciph_resp,    /* Authentication and Ciphering Resp */
17923     dtap_gmm_auth_ciph_rej,             /* Authentication and Ciphering Rej */
17924     dtap_gmm_auth_ciph_fail,    /* Authentication and Ciphering Failure */
17925     dtap_gmm_ident_req,                 /* Identity Request */
17926     dtap_gmm_ident_res,                 /* Identity Response */
17927     dtap_gmm_status,                    /* GMM Status */
17928     dtap_gmm_information,               /* GMM Information */
17929     NULL,       /* NONE */
17930 };
17931
17932 #define NUM_GSM_DTAP_MSG_SMS (sizeof(gsm_a_dtap_msg_sms_strings)/sizeof(value_string))
17933 static gint ett_gsm_dtap_msg_sms[NUM_GSM_DTAP_MSG_SMS];
17934 static void (*dtap_msg_sms_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
17935     dtap_sms_cp_data,   /* CP-DATA */
17936     NULL /* no associated data */,      /* CP-ACK */
17937     dtap_sms_cp_error,  /* CP-ERROR */
17938     NULL,       /* NONE */
17939 };
17940
17941 #define NUM_GSM_DTAP_MSG_SM (sizeof(gsm_a_dtap_msg_sm_strings)/sizeof(value_string))
17942 static gint ett_gsm_dtap_msg_sm[NUM_GSM_DTAP_MSG_SM];
17943 static void (*dtap_msg_sm_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
17944     dtap_sm_act_pdp_req,                /* Activate PDP Context Request */
17945     dtap_sm_act_pdp_acc,                /* Activate PDP Context Accept */
17946     dtap_sm_act_pdp_rej,                /* Activate PDP Context Reject */
17947     dtap_sm_req_pdp_act,                /* Request PDP Context Activation */
17948     dtap_sm_req_pdp_act_rej,    /* Request PDP Context Activation rej. */
17949     dtap_sm_deact_pdp_req,              /* Deactivate PDP Context Request */
17950     dtap_sm_deact_pdp_acc,              /* Deactivate PDP Context Accept */
17951     dtap_sm_mod_pdp_req_net,    /* Modify PDP Context Request(Network to MS direction) */
17952     dtap_sm_mod_pdp_acc_ms,             /* Modify PDP Context Accept (MS to network direction) */
17953     dtap_sm_mod_pdp_req_ms,             /* Modify PDP Context Request(MS to network direction) */
17954     dtap_sm_mod_pdp_acc_net,    /* Modify PDP Context Accept (Network to MS direction) */
17955     dtap_sm_mod_pdp_rej,                /* Modify PDP Context Reject */
17956     dtap_sm_act_sec_pdp_req,    /* Activate Secondary PDP Context Request */
17957     dtap_sm_act_sec_pdp_acc,    /* Activate Secondary PDP Context Accept */
17958     dtap_sm_act_sec_pdp_rej,    /* Activate Secondary PDP Context Reject */
17959     NULL,                                               /* Reserved: was allocated in earlier phases of the protocol */
17960     NULL,                                               /* Reserved: was allocated in earlier phases of the protocol */
17961     NULL,                                               /* Reserved: was allocated in earlier phases of the protocol */
17962     NULL,                                               /* Reserved: was allocated in earlier phases of the protocol */
17963     NULL,                                               /* Reserved: was allocated in earlier phases of the protocol */
17964     dtap_sm_status,                             /* SM Status */
17965                                                                 /* Activate MBMS Context Request */
17966                                                                 /* Activate MBMS Context Accept */
17967                                                                 /* Activate MBMS Context Reject */
17968                                                                 /* Request MBMS Context Activation */
17969                                                                 /* Request MBMS Context Activation Reject */
17970     NULL,       /* NONE */
17971 };
17972
17973 #define NUM_GSM_DTAP_MSG_SS (sizeof(gsm_a_dtap_msg_ss_strings)/sizeof(value_string))
17974 static gint ett_gsm_dtap_msg_ss[NUM_GSM_DTAP_MSG_SS];
17975 static void (*dtap_msg_ss_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
17976     dtap_cc_release_complete,   /* Release Complete */
17977     dtap_cc_facility,   /* Facility */
17978     dtap_ss_register,   /* Register */
17979     NULL,       /* NONE */
17980 };
17981
17982 #define NUM_GSM_RP_MSG (sizeof(gsm_rp_msg_strings)/sizeof(value_string))
17983 static gint ett_gsm_rp_msg[NUM_GSM_RP_MSG];
17984 static void (*rp_msg_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
17985     rp_data_ms_n,       /* RP-DATA (MS to Network) */
17986     rp_data_n_ms,       /* RP-DATA (Network to MS */
17987     rp_ack_ms_n,        /* RP-ACK (MS to Network) */
17988     rp_ack_n_ms,        /* RP-ACK (Network to MS) */
17989     rp_error_ms_n,      /* RP-ERROR (MS to Network) */
17990     rp_error_n_ms,      /* RP-ERROR (Network to MS) */
17991     rp_smma,    /* RP-SMMA (MS to Network) */
17992     NULL,       /* NONE */
17993 };
17994
17995 /* GENERIC DISSECTOR FUNCTIONS */
17996
17997 static void
17998 dissect_rp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
17999 {
18000     guint8      oct;
18001     guint32     offset, saved_offset;
18002     guint32     len;
18003     gint        idx;
18004     proto_item  *rp_item = NULL;
18005     proto_tree  *rp_tree = NULL;
18006     const gchar *str;
18007
18008
18009     if (check_col(pinfo->cinfo, COL_INFO))
18010     {
18011         col_append_str(pinfo->cinfo, COL_INFO, "(RP) ");
18012     }
18013
18014     /*
18015      * In the interest of speed, if "tree" is NULL, don't do any work
18016      * not necessary to generate protocol tree items.
18017      */
18018     if (!tree)
18019     {
18020         return;
18021     }
18022
18023     offset = 0;
18024     saved_offset = offset;
18025
18026     g_pinfo = pinfo;
18027     g_tree = tree;
18028
18029     len = tvb_length(tvb);
18030
18031     /*
18032      * add RP message name
18033      */
18034     oct = tvb_get_guint8(tvb, offset++);
18035
18036     str = match_strval_idx((guint32) oct, gsm_rp_msg_strings, &idx);
18037
18038     /*
18039      * create the protocol tree
18040      */
18041     if (str == NULL)
18042     {
18043         rp_item =
18044             proto_tree_add_protocol_format(tree, proto_a_rp, tvb, 0, len,
18045                 "GSM A-I/F RP - Unknown RP Message Type (0x%02x)",
18046                 oct);
18047
18048         rp_tree = proto_item_add_subtree(rp_item, ett_rp_msg);
18049     }
18050     else
18051     {
18052         rp_item =
18053             proto_tree_add_protocol_format(tree, proto_a_rp, tvb, 0, -1,
18054                 "GSM A-I/F RP - %s",
18055                 str);
18056
18057         rp_tree = proto_item_add_subtree(rp_item, ett_gsm_rp_msg[idx]);
18058
18059         if (check_col(pinfo->cinfo, COL_INFO))
18060         {
18061             col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", str);
18062         }
18063     }
18064
18065     /*
18066      * add RP message name
18067      */
18068     proto_tree_add_uint_format(rp_tree, hf_gsm_a_rp_msg_type,
18069                 tvb, saved_offset, 1, oct, "Message Type %s", str ? str : "(Unknown)");
18070
18071     if (str == NULL) return;
18072
18073     if ((len - offset) <= 0) return;
18074
18075     /*
18076      * decode elements
18077      */
18078     if (rp_msg_fcn[idx] == NULL)
18079     {
18080         proto_tree_add_text(rp_tree,
18081             tvb, offset, len - offset,
18082             "Message Elements");
18083     }
18084     else
18085     {
18086         (*rp_msg_fcn[idx])(tvb, rp_tree, offset, len - offset);
18087     }
18088 }
18089
18090
18091 void
18092 dissect_bssmap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
18093 {
18094     static gsm_a_tap_rec_t      tap_rec[4];
18095     static gsm_a_tap_rec_t      *tap_p;
18096     static int                  tap_current=0;
18097     guint8      oct;
18098     guint32     offset, saved_offset;
18099     guint32     len;
18100     gint        idx;
18101     proto_item  *bssmap_item = NULL;
18102     proto_tree  *bssmap_tree = NULL;
18103     const gchar *str;
18104         
18105
18106         sccp_msg = pinfo->sccp_info;
18107         
18108         if (sccp_msg && sccp_msg->assoc) {
18109                 sccp_assoc = sccp_msg->assoc;
18110         } else {
18111                 sccp_assoc = NULL;
18112                 sccp_msg = NULL;
18113         }
18114         
18115     if (check_col(pinfo->cinfo, COL_INFO))
18116     {
18117         col_append_str(pinfo->cinfo, COL_INFO, "(BSSMAP) ");
18118     }
18119
18120     /*
18121      * set tap record pointer
18122      */
18123     tap_current++;
18124     if (tap_current == 4)
18125     {
18126         tap_current = 0;
18127     }
18128     tap_p = &tap_rec[tap_current];
18129
18130
18131     offset = 0;
18132     saved_offset = offset;
18133
18134     g_pinfo = pinfo;
18135     g_tree = tree;
18136
18137     len = tvb_length(tvb);
18138
18139     /*
18140      * add BSSMAP message name
18141      */
18142     oct = tvb_get_guint8(tvb, offset++);
18143
18144     str = match_strval_idx((guint32) oct, gsm_a_bssmap_msg_strings, &idx);
18145
18146         if (sccp_msg && !sccp_msg->label) {
18147                 sccp_msg->label = se_strdup(val_to_str((guint32) oct, gsm_a_bssmap_msg_strings, "BSSMAP (0x%02x)"));
18148         }
18149         
18150     /*
18151      * create the protocol tree
18152      */
18153     if (str == NULL)
18154     {
18155         bssmap_item =
18156             proto_tree_add_protocol_format(tree, proto_a_bssmap, tvb, 0, len,
18157                 "GSM A-I/F BSSMAP - Unknown BSSMAP Message Type (0x%02x)",
18158                 oct);
18159
18160         bssmap_tree = proto_item_add_subtree(bssmap_item, ett_bssmap_msg);
18161     }
18162     else
18163     {
18164         bssmap_item =
18165             proto_tree_add_protocol_format(tree, proto_a_bssmap, tvb, 0, -1,
18166                 "GSM A-I/F BSSMAP - %s",
18167                 str);
18168
18169         bssmap_tree = proto_item_add_subtree(bssmap_item, ett_gsm_bssmap_msg[idx]);
18170
18171         if (check_col(pinfo->cinfo, COL_INFO))
18172         {
18173             col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", str);
18174         }
18175
18176     /*
18177      * add BSSMAP message name
18178      */
18179     proto_tree_add_uint_format(bssmap_tree, hf_gsm_a_bssmap_msg_type,
18180         tvb, saved_offset, 1, oct, "Message Type %s",str);
18181     }
18182
18183     tap_p->pdu_type = BSSAP_PDU_TYPE_BSSMAP;
18184     tap_p->message_type = oct;
18185
18186     tap_queue_packet(gsm_a_tap, pinfo, tap_p);
18187
18188     if (str == NULL) return;
18189
18190     if ((len - offset) <= 0) return;
18191
18192     /*
18193      * decode elements
18194      */
18195     if (bssmap_msg_fcn[idx] == NULL)
18196     {
18197         proto_tree_add_text(bssmap_tree,
18198             tvb, offset, len - offset,
18199             "Message Elements");
18200     }
18201     else
18202     {
18203         (*bssmap_msg_fcn[idx])(tvb, bssmap_tree, offset, len - offset);
18204     }
18205 }
18206
18207
18208 static void
18209 dissect_dtap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
18210 {
18211     static gsm_a_tap_rec_t      tap_rec[4];
18212     static gsm_a_tap_rec_t      *tap_p;
18213     static int                  tap_current=0;
18214     void                        (*msg_fcn)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len);
18215     guint8                      oct;
18216     guint8                      pd;
18217     guint32                     offset;
18218     guint32                     len;
18219     guint32                     oct_1, oct_2;
18220     gint                        idx;
18221     proto_item                  *dtap_item = NULL;
18222     proto_tree                  *dtap_tree = NULL;
18223     proto_item                  *oct_1_item = NULL;
18224     proto_tree                  *pd_tree = NULL;
18225     const gchar                 *msg_str;
18226     gint                        ett_tree;
18227     gint                        ti;
18228     int                         hf_idx;
18229     gboolean                    nsd;
18230
18231
18232     len = tvb_length(tvb);
18233
18234     if (len < 2)
18235     {
18236         /*
18237          * too short to be DTAP
18238          */
18239         call_dissector(data_handle, tvb, pinfo, tree);
18240         return;
18241     }
18242
18243     if (check_col(pinfo->cinfo, COL_INFO))
18244     {
18245         col_append_str(pinfo->cinfo, COL_INFO, "(DTAP) ");
18246     }
18247
18248     /*
18249      * set tap record pointer
18250      */
18251     tap_current++;
18252     if (tap_current == 4)
18253     {
18254         tap_current = 0;
18255     }
18256     tap_p = &tap_rec[tap_current];
18257
18258
18259     offset = 0;
18260     oct_2 = 0;
18261
18262     g_pinfo = pinfo;
18263     g_tree = tree;
18264
18265     /*
18266      * get protocol discriminator
18267      */
18268     oct_1 = tvb_get_guint8(tvb, offset++);
18269
18270     if ((((oct_1 & DTAP_TI_MASK) >> 4) & DTAP_TIE_PRES_MASK) == DTAP_TIE_PRES_MASK)
18271     {
18272         /*
18273          * eventhough we don't know if a TI should be in the message yet
18274          * we rely on the TI/SKIP indicator to be 0 to avoid taking this
18275          * octet
18276          */
18277         oct_2 = tvb_get_guint8(tvb, offset++);
18278     }
18279
18280     oct = tvb_get_guint8(tvb, offset);
18281
18282     pd = oct_1 & DTAP_PD_MASK;
18283     ti = -1;
18284     msg_str = NULL;
18285     ett_tree = -1;
18286     hf_idx = -1;
18287     msg_fcn = NULL;
18288     nsd = FALSE;
18289     if (check_col(pinfo->cinfo, COL_INFO))
18290     {
18291         col_append_fstr(pinfo->cinfo, COL_INFO, "(%s) ",val_to_str(pd,gsm_a_pd_short_str_vals,"unknown"));
18292     }
18293
18294     /*
18295      * octet 1
18296      */
18297     switch (pd)
18298     {
18299     case 3:
18300         msg_str = match_strval_idx((guint32) (oct & DTAP_CC_IEI_MASK), gsm_a_dtap_msg_cc_strings, &idx);
18301         ett_tree = ett_gsm_dtap_msg_cc[idx];
18302         hf_idx = hf_gsm_a_dtap_msg_cc_type;
18303         msg_fcn = dtap_msg_cc_fcn[idx];
18304         ti = (oct_1 & DTAP_TI_MASK) >> 4;
18305         nsd = TRUE;
18306         break;
18307
18308     case 5:
18309         msg_str = match_strval_idx((guint32) (oct & DTAP_MM_IEI_MASK), gsm_a_dtap_msg_mm_strings, &idx);
18310         ett_tree = ett_gsm_dtap_msg_mm[idx];
18311         hf_idx = hf_gsm_a_dtap_msg_mm_type;
18312         msg_fcn = dtap_msg_mm_fcn[idx];
18313         nsd = TRUE;
18314         break;
18315
18316     case 6:
18317         msg_str = match_strval_idx((guint32) (oct & DTAP_RR_IEI_MASK), gsm_a_dtap_msg_rr_strings, &idx);
18318         ett_tree = ett_gsm_dtap_msg_rr[idx];
18319         hf_idx = hf_gsm_a_dtap_msg_rr_type;
18320         msg_fcn = dtap_msg_rr_fcn[idx];
18321         break;
18322
18323     case 8:
18324         msg_str = match_strval_idx((guint32) (oct & DTAP_GMM_IEI_MASK), gsm_a_dtap_msg_gmm_strings, &idx);
18325         ett_tree = ett_gsm_dtap_msg_gmm[idx];
18326         hf_idx = hf_gsm_a_dtap_msg_gmm_type;
18327         msg_fcn = dtap_msg_gmm_fcn[idx];
18328         break;
18329
18330     case 9:
18331         msg_str = match_strval_idx((guint32) (oct & DTAP_SMS_IEI_MASK), gsm_a_dtap_msg_sms_strings, &idx);
18332         ett_tree = ett_gsm_dtap_msg_sms[idx];
18333         hf_idx = hf_gsm_a_dtap_msg_sms_type;
18334         msg_fcn = dtap_msg_sms_fcn[idx];
18335         ti = (oct_1 & DTAP_TI_MASK) >> 4;
18336         break;
18337
18338     case 10:
18339         msg_str = match_strval_idx((guint32) (oct & DTAP_SM_IEI_MASK), gsm_a_dtap_msg_sm_strings, &idx);
18340         ett_tree = ett_gsm_dtap_msg_sm[idx];
18341         hf_idx = hf_gsm_a_dtap_msg_sm_type;
18342         msg_fcn = dtap_msg_sm_fcn[idx];
18343         ti = (oct_1 & DTAP_TI_MASK) >> 4;
18344         break;
18345
18346     case 11:
18347         msg_str = match_strval_idx((guint32) (oct & DTAP_SS_IEI_MASK), gsm_a_dtap_msg_ss_strings, &idx);
18348         ett_tree = ett_gsm_dtap_msg_ss[idx];
18349         hf_idx = hf_gsm_a_dtap_msg_ss_type;
18350         msg_fcn = dtap_msg_ss_fcn[idx];
18351         ti = (oct_1 & DTAP_TI_MASK) >> 4;
18352         nsd = TRUE;
18353         break;
18354
18355     default:
18356     /* 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 */
18357     return;
18358         break;
18359     }
18360
18361         sccp_msg = pinfo->sccp_info;
18362         
18363         if (sccp_msg && sccp_msg->assoc) {
18364                 sccp_assoc = sccp_msg->assoc;
18365         } else {
18366                 sccp_assoc = NULL;
18367                 sccp_msg = NULL;
18368         }
18369         
18370     /*
18371      * create the protocol tree
18372      */
18373     if (msg_str == NULL)
18374     {
18375         dtap_item =
18376             proto_tree_add_protocol_format(tree, proto_a_dtap, tvb, 0, len,
18377                 "GSM A-I/F DTAP - Unknown DTAP Message Type (0x%02x)",
18378                 oct);
18379
18380         dtap_tree = proto_item_add_subtree(dtap_item, ett_dtap_msg);
18381         
18382         if (sccp_msg && !sccp_msg->label) {
18383                 sccp_msg->label = se_strdup_printf("DTAP (0x%02x)",oct);
18384         }
18385         
18386         
18387     }
18388     else
18389     {
18390         dtap_item =
18391             proto_tree_add_protocol_format(tree, proto_a_dtap, tvb, 0, -1,
18392                 "GSM A-I/F DTAP - %s",
18393                 msg_str);
18394
18395         dtap_tree = proto_item_add_subtree(dtap_item, ett_tree);
18396
18397         if (sccp_msg && !sccp_msg->label) {
18398                 sccp_msg->label = se_strdup(msg_str);
18399         }
18400
18401         if (check_col(pinfo->cinfo, COL_INFO))
18402         {
18403             col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", msg_str);
18404         }
18405     }
18406
18407     oct_1_item =
18408         proto_tree_add_text(dtap_tree,
18409             tvb, 0, 1,
18410             "Protocol Discriminator: %s",
18411             val_to_str(pd, protocol_discriminator_vals, "Unknown (%u)"));
18412
18413     pd_tree = proto_item_add_subtree(oct_1_item, ett_dtap_oct_1);
18414
18415     if (ti == -1)
18416     {
18417         proto_tree_add_item(pd_tree, hf_gsm_a_skip_ind, tvb, 0, 1, FALSE);
18418     }
18419     else
18420     {
18421         other_decode_bitfield_value(a_bigbuf, oct_1, 0x80, 8);
18422         proto_tree_add_text(pd_tree,
18423             tvb, 0, 1,
18424             "%s :  TI flag: %s",
18425             a_bigbuf,
18426             ((oct_1 & 0x80) ?  "allocated by receiver" : "allocated by sender"));
18427
18428         if ((ti & DTAP_TIE_PRES_MASK) == DTAP_TIE_PRES_MASK)
18429         {
18430             /* ti is extended to next octet */
18431
18432             other_decode_bitfield_value(a_bigbuf, oct_1, 0x70, 8);
18433             proto_tree_add_text(pd_tree,
18434                 tvb, 0, 1,
18435                 "%s :  TIO: The TI value is given by the TIE in octet 2",
18436                 a_bigbuf);
18437         }
18438         else
18439         {
18440             other_decode_bitfield_value(a_bigbuf, oct_1, 0x70, 8);
18441             proto_tree_add_text(pd_tree,
18442                 tvb, 0, 1,
18443                 "%s :  TIO: %u",
18444                 a_bigbuf,
18445                 ti & DTAP_TIE_PRES_MASK);
18446         }
18447     }
18448
18449     proto_tree_add_item(pd_tree, hf_gsm_a_L3_protocol_discriminator, tvb, 0, 1, FALSE);
18450
18451     if ((ti != -1) &&
18452         (ti & DTAP_TIE_PRES_MASK) == DTAP_TIE_PRES_MASK)
18453     {
18454         proto_tree_add_item(tree, hf_gsm_a_extension, tvb, 1, 1, FALSE);
18455
18456         other_decode_bitfield_value(a_bigbuf, oct_2, DTAP_TIE_MASK, 8);
18457         proto_tree_add_text(pd_tree,
18458             tvb, 1, 1,
18459             "%s :  TIE: %u",
18460             a_bigbuf,
18461             oct_2 & DTAP_TIE_MASK);
18462     }
18463
18464     /*
18465      * N(SD)
18466      */
18467     if ((pinfo->p2p_dir == P2P_DIR_RECV) &&
18468         nsd)
18469     {
18470         /* XXX */
18471     }
18472
18473     /*
18474      * add DTAP message name
18475      */
18476     proto_tree_add_uint_format(dtap_tree, hf_idx,
18477         tvb, offset, 1, oct,
18478         "Message Type %s",msg_str ? msg_str : "(Unknown)");
18479
18480     offset++;
18481
18482     tap_p->pdu_type = BSSAP_PDU_TYPE_DTAP;
18483     tap_p->message_type = (nsd ? (oct & 0x3f) : oct);
18484     tap_p->protocol_disc = pd;
18485
18486     tap_queue_packet(gsm_a_tap, pinfo, tap_p);
18487
18488     if (msg_str == NULL) return;
18489
18490     if ((len - offset) <= 0) return;
18491
18492     /*
18493      * decode elements
18494      */
18495     if (msg_fcn == NULL)
18496     {
18497         proto_tree_add_text(dtap_tree,
18498             tvb, offset, len - offset,
18499             "Message Elements");
18500     }
18501     else
18502     {
18503         (*msg_fcn)(tvb, dtap_tree, offset, len - offset);
18504     }
18505 }
18506
18507
18508 /* Register the protocol with Wireshark */
18509 void
18510 proto_register_gsm_a(void)
18511 {
18512     guint               i;
18513     guint               last_offset;
18514
18515     /* Setup list of header fields */
18516
18517     static hf_register_info hf[] =
18518     {
18519         { &hf_gsm_a_bssmap_msg_type,
18520             { "BSSMAP Message Type",    "gsm_a.bssmap_msgtype",
18521             FT_UINT8, BASE_HEX, VALS(gsm_a_bssmap_msg_strings), 0x0,
18522             "", HFILL }
18523         },
18524         { &hf_gsm_a_dtap_msg_mm_type,
18525             { "DTAP Mobility Management Message Type",  "gsm_a.dtap_msg_mm_type",
18526             FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_mm_strings), 0x0,
18527             "", HFILL }
18528         },
18529         { &hf_gsm_a_dtap_msg_rr_type,
18530             { "DTAP Radio Resources Management Message Type",   "gsm_a.dtap_msg_rr_type",
18531             FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_rr_strings), 0x0,
18532             "", HFILL }
18533         },
18534         { &hf_gsm_a_dtap_msg_cc_type,
18535             { "DTAP Call Control Message Type", "gsm_a.dtap_msg_cc_type",
18536             FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_cc_strings), 0x0,
18537             "", HFILL }
18538         },
18539         { &hf_gsm_a_dtap_msg_gmm_type,
18540             { "DTAP GPRS Mobility Management Message Type",     "gsm_a.dtap_msg_gmm_type",
18541             FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_gmm_strings), 0x0,
18542             "", HFILL }
18543         },
18544         { &hf_gsm_a_dtap_msg_sms_type,
18545             { "DTAP Short Message Service Message Type",        "gsm_a.dtap_msg_sms_type",
18546             FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_sms_strings), 0x0,
18547             "", HFILL }
18548         },
18549         { &hf_gsm_a_dtap_msg_sm_type,
18550             { "DTAP GPRS Session Management Message Type",      "gsm_a.dtap_msg_sm_type",
18551             FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_sm_strings), 0x0,
18552             "", HFILL }
18553         },
18554         { &hf_gsm_a_dtap_msg_ss_type,
18555             { "DTAP Non call Supplementary Service Message Type",       "gsm_a.dtap_msg_ss_type",
18556             FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_ss_strings), 0x0,
18557             "", HFILL }
18558         },
18559         { &hf_gsm_a_rp_msg_type,
18560             { "RP Message Type",        "gsm_a.rp_msg_type",
18561             FT_UINT8, BASE_HEX, VALS(gsm_rp_msg_strings), 0x0,
18562             "", HFILL }
18563         },
18564         { &hf_gsm_a_bssmap_elem_id,
18565             { "Element ID",     "gsm_a_bssmap.elem_id",
18566             FT_UINT8, BASE_DEC, NULL, 0,
18567             "", HFILL }
18568         },
18569         { &hf_gsm_a_dtap_elem_id,
18570             { "Element ID",     "gsm_a_dtap.elem_id",
18571             FT_UINT8, BASE_DEC, NULL, 0,
18572             "", HFILL }
18573         },
18574         { &hf_gsm_a_length,
18575             { "Length",         "gsm_a.len",
18576             FT_UINT8, BASE_DEC, NULL, 0,
18577             "", HFILL }
18578         },
18579         { &hf_gsm_a_none,
18580             { "Sub tree",       "gsm_a.none",
18581             FT_NONE, 0, 0, 0,
18582             "", HFILL }
18583         },
18584         { &hf_gsm_a_imsi,
18585             { "IMSI",   "gsm_a.imsi",
18586             FT_STRING, BASE_DEC, 0, 0,
18587             "", HFILL }
18588         },
18589         { &hf_gsm_a_tmsi,
18590             { "TMSI/P-TMSI",    "gsm_a.tmsi",
18591             FT_UINT32, BASE_HEX, 0, 0x0,
18592             "", HFILL }
18593         },
18594         { &hf_gsm_a_imei,
18595             { "IMEI",   "gsm_a.imei",
18596             FT_STRING, BASE_DEC, 0, 0,
18597             "", HFILL }
18598         },
18599         { &hf_gsm_a_imeisv,
18600             { "IMEISV", "gsm_a.imeisv",
18601             FT_STRING, BASE_DEC, 0, 0,
18602             "", HFILL }
18603         },
18604         { &hf_gsm_a_cld_party_bcd_num,
18605             { "Called Party BCD Number",        "gsm_a.cld_party_bcd_num",
18606             FT_STRING, BASE_DEC, 0, 0,
18607             "", HFILL }
18608         },
18609         { &hf_gsm_a_clg_party_bcd_num,
18610             { "Calling Party BCD Number",       "gsm_a.clg_party_bcd_num",
18611             FT_STRING, BASE_DEC, 0, 0,
18612             "", HFILL }
18613         },
18614         { &hf_gsm_a_cell_ci,
18615             { "Cell CI",        "gsm_a.cell_ci",
18616             FT_UINT16, BASE_HEX_DEC, 0, 0x0,
18617             "", HFILL }
18618         },
18619         { &hf_gsm_a_cell_lac,
18620             { "Cell LAC",       "gsm_a.cell_lac",
18621             FT_UINT16, BASE_HEX_DEC, 0, 0x0,
18622             "", HFILL }
18623         },
18624         { &hf_gsm_a_dlci_cc,
18625             { "Control Channel", "bssap.dlci.cc",
18626             FT_UINT8, BASE_HEX, VALS(bssap_cc_values), 0xc0,
18627             "", HFILL}
18628         },
18629         { &hf_gsm_a_dlci_spare,
18630             { "Spare", "bssap.dlci.spare",
18631             FT_UINT8, BASE_HEX, NULL, 0x38,
18632             "", HFILL}
18633         },
18634         { &hf_gsm_a_dlci_sapi,
18635             { "SAPI", "bssap.dlci.sapi",
18636             FT_UINT8, BASE_HEX, VALS(bssap_sapi_values), 0x07,
18637             "", HFILL}
18638         },
18639         { &hf_gsm_a_bssmap_cause,
18640             { "BSSMAP Cause",   "gsm_a_bssmap.cause",
18641             FT_UINT8, BASE_HEX, 0, 0x0,
18642             "", HFILL }
18643         },
18644         { &hf_gsm_a_dtap_cause,
18645             { "DTAP Cause",     "gsm_a_dtap.cause",
18646             FT_UINT8, BASE_HEX, 0, 0x0,
18647             "", HFILL }
18648         },
18649         { &hf_gsm_a_MSC_rev,
18650                 { "Revision Level","gsm_a.MSC2_rev",
18651                 FT_UINT8,BASE_DEC,  VALS(gsm_a_msc_rev_vals), 0x60,          
18652                 "Revision level", HFILL }
18653         },
18654         { &hf_gsm_a_ES_IND,
18655                 { "ES IND","gsm_a.MSC2_rev",
18656                 FT_UINT8,BASE_DEC,  VALS(ES_IND_vals), 0x10,          
18657                         "ES IND", HFILL }
18658         },
18659     { &hf_gsm_a_qos_traffic_cls,
18660       { "Traffic class", "gsm_a.qos.traffic_cls",
18661         FT_UINT8, BASE_DEC, VALS(gsm_a_qos_traffic_cls_vals), 0xe0,
18662         "Traffic class", HFILL }},
18663     { &hf_gsm_a_qos_del_order,
18664       { "Delivery order", "gsm_a.qos.del_order",
18665         FT_UINT8, BASE_DEC, VALS(gsm_a_qos_traffic_cls_vals), 0x18,
18666         "Delivery order", HFILL }},
18667     { &hf_gsm_a_qos_del_of_err_sdu,
18668       { "Delivery of erroneous SDUs", "gsm_a.qos.del_of_err_sdu",
18669         FT_UINT8, BASE_DEC, VALS(gsm_a_qos_del_of_err_sdu_vals), 0x03,
18670         "Delivery of erroneous SDUs", HFILL }},
18671     { &hf_gsm_a_qos_ber,
18672       { "Residual Bit Error Rate (BER)", "gsm_a.qos.ber",
18673         FT_UINT8, BASE_DEC, VALS(gsm_a_qos_ber_vals), 0xf0,
18674         "Residual Bit Error Rate (BER)", HFILL }},
18675     { &hf_gsm_a_qos_sdu_err_rat,
18676       { "SDU error ratio", "gsm_a.qos.sdu_err_rat",
18677         FT_UINT8, BASE_DEC, VALS(gsm_a_qos_sdu_err_rat_vals), 0x0f,
18678         "SDU error ratio", HFILL }},
18679     { &hf_gsm_a_qos_traff_hdl_pri,
18680       { "Traffic handling priority", "gsm_a.qos.traff_hdl_pri",
18681         FT_UINT8, BASE_DEC, VALS(gsm_a_qos_traff_hdl_pri_vals), 0x03,
18682         "Traffic handling priority", HFILL }},
18683         { &hf_gsm_a_A5_1_algorithm_sup,
18684                 { "A5/1 algorithm supported","gsm_a.MSC2_rev",
18685                 FT_UINT8,BASE_DEC,  VALS(A5_1_algorithm_sup_vals), 0x08,          
18686                 "A5/1 algorithm supported ", HFILL }
18687         },
18688         { &hf_gsm_a_RF_power_capability,
18689                 { "RF Power Capability","gsm_a.MSC2_rev",
18690                 FT_UINT8,BASE_DEC,  VALS(RF_power_capability_vals), 0x07,          
18691                 "RF Power Capability", HFILL }
18692         },
18693         { &hf_gsm_a_ps_sup_cap,
18694                 { "PS capability (pseudo-synchronization capability)","gsm_a.ps_sup_cap",
18695                 FT_UINT8,BASE_DEC,  VALS(ps_sup_cap_vals), 0x40,          
18696                 "PS capability (pseudo-synchronization capability)", HFILL }
18697         },
18698         { &hf_gsm_a_SS_screening_indicator,
18699                 { "SS Screening Indicator","gsm_a.SS_screening_indicator",
18700                 FT_UINT8,BASE_DEC,  VALS(SS_screening_indicator_vals), 0x30,          
18701                 "SS Screening Indicator", HFILL }
18702         },
18703         { &hf_gsm_a_SM_capability,
18704                 { "SM capability (MT SMS pt to pt capability)","gsm_a.SM_cap",
18705                 FT_UINT8,BASE_DEC,  VALS(SM_capability_vals), 0x08,          
18706                 "SM capability (MT SMS pt to pt capability)", HFILL }
18707         },
18708         { &hf_gsm_a_VBS_notification_rec,
18709                 { "VBS notification reception ","gsm_a.VBS_notification_rec",
18710                 FT_UINT8,BASE_DEC,  VALS(VBS_notification_rec_vals), 0x04,          
18711                 "VBS notification reception ", HFILL }
18712         },
18713         { &hf_gsm_a_VGCS_notification_rec,
18714                 { "VGCS notification reception ","gsm_a.VGCS_notification_rec",
18715                 FT_UINT8,BASE_DEC,  VALS(VGCS_notification_rec_vals), 0x02,          
18716                 "VGCS notification reception", HFILL }
18717         },
18718         { &hf_gsm_a_FC_frequency_cap,
18719                 { "FC Frequency Capability","gsm_a.FC_frequency_cap",
18720                 FT_UINT8,BASE_DEC,  VALS(FC_frequency_cap_vals), 0x01,          
18721                 "FC Frequency Capability", HFILL }
18722         },
18723         { &hf_gsm_a_CM3,
18724                 { "CM3","gsm_a.CM3",
18725                 FT_UINT8,BASE_DEC,  VALS(CM3_vals), 0x80,          
18726                 "CM3", HFILL }
18727         },
18728         { &hf_gsm_a_LCS_VA_cap,
18729                 { "LCS VA capability (LCS value added location request notification capability) ","gsm_a.LCS_VA_cap",
18730                 FT_UINT8,BASE_DEC,  VALS(LCS_VA_cap_vals), 0x20,          
18731                 "LCS VA capability (LCS value added location request notification capability) ", HFILL }
18732         },
18733         { &hf_gsm_a_UCS2_treatment,
18734                 { "UCS2 treatment ","gsm_a.UCS2_treatment",
18735                 FT_UINT8,BASE_DEC,  VALS(UCS2_treatment_vals), 0x10,          
18736                 "UCS2 treatment ", HFILL }
18737         },
18738         { &hf_gsm_a_SoLSA,
18739                 { "SoLSA","gsm_a.SoLSA",
18740                 FT_UINT8,BASE_DEC,  VALS(SoLSA_vals), 0x08,          
18741                 "SoLSA", HFILL }
18742         },
18743         { &hf_gsm_a_CMSP,
18744                 { "CMSP: CM Service Prompt","gsm_a.CMSP",
18745                 FT_UINT8,BASE_DEC,  VALS(CMSP_vals), 0x04,          
18746                 "CMSP: CM Service Prompt", HFILL }
18747         },
18748         { &hf_gsm_a_A5_3_algorithm_sup,
18749                 { "A5/3 algorithm supported","gsm_a.A5_3_algorithm_sup",
18750                 FT_UINT8,BASE_DEC,  VALS(A5_3_algorithm_sup_vals), 0x02,          
18751                 "A5/3 algorithm supported", HFILL }
18752         },
18753         { &hf_gsm_a_A5_2_algorithm_sup,
18754                 { "A5/2 algorithm supported","gsm_a.A5_2_algorithm_sup",
18755                 FT_UINT8,BASE_DEC,  VALS(A5_2_algorithm_sup_vals), 0x01,          
18756                 "A5/2 algorithm supported", HFILL }
18757         },
18758         { &hf_gsm_a_mobile_identity_type,
18759                 { "Mobile Identity Type","gsm_a.ie.mobileid.type",
18760                 FT_UINT8, BASE_DEC, VALS(mobile_identity_type_vals), 0x07,          
18761                 "Mobile Identity Type", HFILL }
18762         },
18763         { &hf_gsm_a_odd_even_ind,
18764                 { "Odd/even indication","gsm_a.oddevenind",
18765                 FT_UINT8, BASE_DEC, oddevenind_vals, 0x08,          
18766                 "Mobile Identity", HFILL }
18767         },
18768         { &hf_gsm_a_L3_protocol_discriminator,
18769                 { "Protocol discriminator","gsm_a.L3_protocol_discriminator",
18770                 FT_UINT8,BASE_DEC,  VALS(protocol_discriminator_vals), 0x0f,          
18771                 "Protocol discriminator", HFILL }
18772         },
18773         { &hf_gsm_a_skip_ind,
18774                 { "Skip Indicator",           "gsm_a.skip.ind",
18775                 FT_UINT8, BASE_DEC, NULL, 0xf0,          
18776                 "Skip Indicator", HFILL }
18777         },
18778         { &hf_gsm_a_bcc,
18779                 { "BCC","gsm_a.bcc",
18780                 FT_UINT8,BASE_DEC,  NULL, 0x07,          
18781                 "BCC", HFILL }
18782         },
18783         { &hf_gsm_a_ncc,
18784                 { "NCC","gsm_a.ncc",
18785                 FT_UINT8,BASE_DEC,  NULL, 0x38,          
18786                 "NCC", HFILL }
18787         },
18788         { &hf_gsm_a_bcch_arfcn,
18789                 { "BCCH ARFCN(RF channel number)","gsm_a.bcch_arfcn",
18790                 FT_UINT16,BASE_DEC,  NULL, 0x0,          
18791                 "BCCH ARFCN", HFILL }
18792         },
18793         { &hf_gsm_a_rr_ho_ref_val,
18794                 { "Handover reference value","gsm_a.rr.ho_ref_val",
18795                 FT_UINT8,BASE_DEC,  NULL, 0x0,          
18796                 "Handover reference value", HFILL }
18797         },
18798         { &hf_gsm_a_b7spare,
18799                 { "Spare","gsm_a.spareb7",
18800                 FT_UINT8,BASE_DEC,  NULL, 0x40,
18801                 "Spare", HFILL }
18802         },
18803         { &hf_gsm_a_b8spare,
18804                 { "Spare","gsm_a.spareb8",
18805                 FT_UINT8,BASE_DEC,  NULL, 0x80,          
18806                 "Spare", HFILL }
18807         },
18808         { &hf_gsm_a_rr_pow_cmd_atc,
18809                 { "Spare","gsm_a.rr.pow_cmd_atc",
18810                 FT_BOOLEAN,8,  TFS(&gsm_a_rr_pow_cmd_atc_value), 0x80,          
18811                 "Spare", HFILL }
18812         },
18813         { &hf_gsm_a_rr_pow_cmd_epc,
18814                 { "EPC_mode","gsm_a.rr.pow_cmd_epc",
18815                 FT_BOOLEAN,8,  TFS(&gsm_a_rr_pow_cmd_epc_value), 0x40,          
18816                 "EPC_mode", HFILL }
18817         },
18818         { &hf_gsm_a_rr_pow_cmd_fpcepc,
18819                 { "FPC_EPC","gsm_a.rr.pow_cmd_fpcepc",
18820                 FT_BOOLEAN,8,  TFS(&gsm_a_rr_pow_cmd_fpcepc_value), 0x20,          
18821                 "FPC_EPC", HFILL }
18822         },
18823         { &hf_gsm_a_rr_pow_cmd_powlev,
18824                 { "POWER LEVEL","sm_a.rr.pow_cmd_pow",
18825                 FT_UINT8,BASE_DEC,  NULL, 0x1f,          
18826                 "POWER LEVEL", HFILL }
18827         },
18828         { &hf_gsm_a_rr_sync_ind_nci,
18829                 { "Normal cell indication(NCI)","gsm_a.rr.sync_ind_nci",
18830                 FT_BOOLEAN,8,  TFS(&gsm_a_rr_sync_ind_nci_value), 0x08,          
18831                 "Normal cell indication(NCI)", HFILL }
18832         },
18833         { &hf_gsm_a_rr_sync_ind_rot,
18834                 { "Report Observed Time Difference(ROT)","gsm_a.rr.sync_ind_rot",
18835                 FT_BOOLEAN,8,  TFS(&sm_a_rr_sync_ind_rot_value), 0x04,          
18836                 "Report Observed Time Difference(ROT)", HFILL }
18837         },
18838         { &hf_gsm_a_rr_sync_ind_si,
18839                 { "Synchronization indication(SI)","gsm_a.rr_sync_ind_si",
18840                 FT_UINT8,BASE_DEC,  VALS(gsm_a_rr_sync_ind_si_vals), 0x03,          
18841                 "Synchronization indication(SI)", HFILL }
18842         },
18843         { &hf_gsm_a_rr_format_id,
18844                 { "Format Identifier","gsm_a.rr_format_id",
18845                 FT_UINT8,BASE_HEX,  VALS(gsm_a_rr_freq_list_format_id_vals), 0xce,          
18846                 "Format Identifier", HFILL }
18847         },
18848         { &hf_gsm_a_rr_channel_mode,
18849                 { "Channel Mode","gsm_a.rr.channel_mode",
18850                 FT_UINT8,BASE_DEC,  VALS(gsm_a_rr_channel_mode_vals), 0x0,          
18851                 "Channel Mode", HFILL }
18852         },
18853         { &hf_gsm_a_rr_channel_mode2,
18854                 { "Channel Mode 2","gsm_a.rr.channel_mode2",
18855                 FT_UINT8,BASE_DEC,  VALS(gsm_a_rr_channel_mode2_vals), 0x0,          
18856                 "Channel Mode 2", HFILL }
18857         },
18858         { &hf_gsm_a_rr_sc,
18859                 { "SC","gsm_a.rr.SC",
18860                 FT_UINT8,BASE_DEC,  VALS(gsm_a_rr_sc_vals), 0x1,          
18861                 "SC", HFILL }
18862         },
18863         { &hf_gsm_a_algorithm_id,
18864                 { "Algorithm identifier","gsm_a.algorithm_identifier",
18865                 FT_UINT8,BASE_DEC,  VALS(gsm_a_algorithm_identifier_vals), 0xe,          
18866                 "Algorithm_identifier", HFILL }
18867         },
18868
18869         { &hf_gsm_a_rr_multirate_speech_ver,
18870                 { "Multirate speech version","gsm_a.rr.multirate_speech_ver",
18871                 FT_UINT8,BASE_DEC,  VALS(multirate_speech_ver_vals), 0xe0,          
18872                 "Multirate speech version", HFILL }
18873         },
18874         { &hf_gsm_a_rr_NCSB,
18875                 { "NSCB: Noise Suppression Control Bit","gsm_a.rr.NCSB",
18876                 FT_UINT8,BASE_DEC,  VALS(NSCB_vals), 0x10,          
18877                 "NSCB: Noise Suppression Control Bit", HFILL }
18878         },
18879         { &hf_gsm_a_rr_ICMI,
18880                 { "ICMI: Initial Codec Mode Indicator","gsm_a.rr.ICMI",
18881                 FT_UINT8,BASE_DEC,  VALS(ICMI_vals), 0x8,          
18882                 "ICMI: Initial Codec Mode Indicator", HFILL }
18883         },
18884         { &hf_gsm_a_rr_start_mode,
18885                 { "Start Mode","gsm_a.rr.start_mode",
18886                 FT_UINT8,BASE_DEC,  NULL, 0x3,          
18887                 "Start Mode", HFILL }
18888         },
18889         { &hf_gsm_a_rr_timing_adv,
18890                 { "Timing advance value","gsm_a.rr.timing_adv",
18891                 FT_UINT8,BASE_DEC,  NULL, 0x0,          
18892                 "Timing advance value", HFILL }
18893         },
18894         { &hf_gsm_a_rr_time_diff,
18895                 { "Time difference value","gsm_a.rr.time_diff",
18896                 FT_UINT8,BASE_DEC,  NULL, 0x0,          
18897                 "Time difference value", HFILL }
18898         },
18899         { &hf_gsm_a_rr_tlli,
18900                 { "TLLI","gsm_a.rr.tlli",
18901                 FT_UINT32,BASE_HEX,  NULL, 0x0,          
18902                 "TLLI", HFILL }
18903         },
18904         { &hf_gsm_a_rr_target_mode,
18905                 { "Target mode","gsm_a.rr.target_mode",
18906                 FT_UINT8,BASE_DEC,  NULL, 0xc0,          
18907                 "Target mode", HFILL }
18908         },
18909         { &hf_gsm_a_rr_group_cipher_key_number,
18910                 { "Group cipher key number","gsm_a.rr.Group_cipher_key_number",
18911                 FT_UINT8,BASE_DEC,  NULL, 0x3c,          
18912                 "Group cipher key number", HFILL }
18913         },
18914         { &hf_gsm_a_rr_last_segment,
18915                 { "Last Segment","gsm_a.rr.last_segment",
18916                 FT_BOOLEAN,8,  TFS(&gsm_a_rr_last_segment_value), 0x01,          
18917                 "Last Segment", HFILL }
18918         },
18919         { &hf_gsm_a_gmm_split_on_ccch,
18920                 { "SPLIT on CCCH","gsm_a.gmm.split_on_ccch",
18921                 FT_BOOLEAN,8,  TFS(&gsm_a_gmm_split_on_ccch_value), 0x08,          
18922                 "SPLIT on CCCH", HFILL }
18923         },
18924         { &hf_gsm_a_gmm_non_drx_timer,
18925                 { "Non-DRX timer","gsm_a.gmm.non_drx_timer",
18926                 FT_UINT8,BASE_DEC,  VALS(gsm_a_gmm_non_drx_timer_strings), 0x07,          
18927                 "Non-DRX timer", HFILL }
18928         },
18929         { &hf_gsm_a_gmm_cn_spec_drs_cycle_len_coef,
18930                 { "CN Specific DRX cycle length coefficient","gsm_a.gmm.cn_spec_drs_cycle_len_coef",
18931                 FT_UINT8,BASE_DEC,  VALS(gsm_a_gmm_cn_spec_drs_cycle_len_coef_strings), 0xf0,          
18932                 "CN Specific DRX cycle length coefficient", HFILL }
18933         },
18934         { &hf_gsm_a_rr_RR_cause,
18935                 { "RR cause value","gsm_a.rr.RRcause",
18936                 FT_UINT8,BASE_DEC,  VALS(gsm_a_rr_RR_cause_vals), 0x0,          
18937                 "RR cause value", HFILL }
18938                 },
18939         { &hf_gsm_a_be_cell_id_disc,
18940                 { "Cell identification discriminator","gsm_a.be.cell_id_disc",
18941                 FT_UINT8,BASE_DEC,  VALS(gsm_a_rr_cell_id_disc_vals), 0x0f,          
18942                 "Cell identificationdiscriminator", HFILL }
18943         },
18944         { &hf_gsm_a_be_rnc_id,
18945                 { "RNC-ID","gsm_a.be.rnc_id",
18946                 FT_UINT16,BASE_DEC,  NULL, 0x0,          
18947                 "RNC-ID", HFILL }
18948         },
18949         { &hf_gsm_a_rr_cm_cng_msg_req, 
18950                 { "CLASSMARK CHANGE","gsm_a.rr_cm_cng_msg_req",
18951                 FT_BOOLEAN,8,  TFS(&gsm_a_msg_req_value), 0x80,          
18952                 "CLASSMARK CHANGE ", HFILL }
18953         },
18954         { &hf_gsm_a_rr_utran_cm_cng_msg_req,
18955                 { "UTRAN CLASSMARK CHANGE","gsm_a.rr_utran_cm_cng_msg_req",
18956                 FT_UINT8,BASE_DEC,  VALS(gsm_a_rr_utran_cm_cng_msg_req_vals), 0x70,          
18957                 "UTRAN CLASSMARK CHANGE", HFILL }
18958         },
18959         { &hf_gsm_a_rr_cdma200_cm_cng_msg_req,
18960                 { "CDMA2000 CLASSMARK CHANGE ","gsm_a.rr_cdma200_cm_cng_msg_req",
18961                 FT_BOOLEAN,8,  TFS(&gsm_a_msg_req_value), 0x08,          
18962                 "CDMA2000 CLASSMARK CHANGE ", HFILL }
18963         },
18964         { &hf_gsm_a_rr_geran_iu_cm_cng_msg_req,
18965                 { "GERAN IU MODE CLASSMARK CHANGE","gsm_a.rr_geran_iu_cm_cng_msg_req",
18966                 FT_BOOLEAN,8,  TFS(&gsm_a_msg_req_value), 0x04,          
18967                 "GERAN IU MODE CLASSMARK CHANGE", HFILL }
18968         },
18969         { &hf_gsm_a_rr_chnl_needed_ch1,
18970                 { "Channel 1","gsm_a.rr_chnl_needed_ch1",
18971                 FT_UINT8,BASE_DEC,  VALS(gsm_a_rr_channel_needed_vals), 0x03,          
18972                 "Channel 1", HFILL }
18973         },
18974         { &hf_gsm_a_rr_chnl_needed_ch2,
18975                 { "Channel 2","gsm_a.rr_chnl_needed_ch1",
18976                 FT_UINT8,BASE_DEC,  VALS(gsm_a_rr_channel_needed_vals), 0x0c,          
18977                 "Channel 2", HFILL }
18978         },
18979         { &hf_gsm_a_rr_suspension_cause,
18980                 { "Suspension cause value","gsm_a.rr.suspension_cause",
18981                 FT_UINT8,BASE_DEC,  VALS(gsm_a_rr_suspension_cause_vals), 0x0,          
18982                 "Suspension cause value", HFILL }
18983         },
18984     { &hf_ROS_component,
18985       { "component", "ROS.component",
18986         FT_UINT8, BASE_DEC, VALS(ROS_Component_vals), 0,
18987         "Component", HFILL }},
18988     { &hf_ROS_invoke,
18989       { "invoke", "ROS.invoke",
18990         FT_NONE, BASE_NONE, NULL, 0,
18991         "Component/invoke", HFILL }},
18992     { &hf_ROS_returnResultLast,
18993       { "returnResultLast", "ROS.returnResultLast",
18994         FT_NONE, BASE_NONE, NULL, 0,
18995         "Component/returnResultLast", HFILL }},
18996     { &hf_ROS_returnError,
18997       { "returnError", "ROS.returnError",
18998         FT_NONE, BASE_NONE, NULL, 0,
18999         "Component/returnError", HFILL }},
19000     { &hf_ROS_reject,
19001       { "reject", "ROS.reject",
19002         FT_NONE, BASE_NONE, NULL, 0,
19003         "Component/reject", HFILL }},
19004     { &hf_ROS_invokeID,
19005       { "invokeID", "ROS.invokeID",
19006         FT_UINT32, BASE_DEC, NULL, 0,
19007         "", HFILL }},
19008     { &hf_ROS_linkedID,
19009       { "linkedID", "ROS.linkedID",
19010         FT_UINT32, BASE_DEC, NULL, 0,
19011         "Invoke/linkedID", HFILL }},
19012     { &hf_ROS_opCode,
19013       { "opCode", "ROS.opCode",
19014         FT_UINT32, BASE_DEC, VALS(ROS_OPERATION_vals), 0,
19015         "", HFILL }},
19016     { &hf_ROS_parameter,
19017       { "parameter", "ROS.parameter",
19018         FT_NONE, BASE_NONE, NULL, 0,
19019         "", HFILL }},
19020     { &hf_ROS_resultretres,
19021       { "resultretres", "ROS.resultretres",
19022         FT_NONE, BASE_NONE, NULL, 0,
19023         "ReturnResult/resultretres", HFILL }},
19024     { &hf_ROS_errorCode,
19025       { "errorCode", "ROS.errorCode",
19026         FT_UINT32, BASE_DEC, VALS(ROS_ErrorCode_vals), 0,
19027         "ReturnError/errorCode", HFILL }},
19028     { &hf_ROS_invokeIDRej,
19029       { "invokeIDRej", "ROS.invokeIDRej",
19030         FT_UINT32, BASE_DEC, VALS(ROS_T_invokeIDRej_vals), 0,
19031         "Reject/invokeIDRej", HFILL }},
19032     { &hf_ROS_derivable,
19033       { "derivable", "ROS.derivable",
19034         FT_UINT32, BASE_DEC, NULL, 0,
19035         "Reject/invokeIDRej/derivable", HFILL }},
19036     { &hf_ROS_not_derivable,
19037       { "not-derivable", "ROS.not_derivable",
19038         FT_NONE, BASE_NONE, NULL, 0,
19039         "Reject/invokeIDRej/not-derivable", HFILL }},
19040     { &hf_ROS_problem,
19041       { "problem", "ROS.problem",
19042         FT_UINT32, BASE_DEC, VALS(ROS_T_problem_vals), 0,
19043         "Reject/problem", HFILL }},
19044     { &hf_ROS_generalProblem,
19045       { "generalProblem", "ROS.generalProblem",
19046         FT_INT32, BASE_DEC, VALS(ROS_GeneralProblem_vals), 0,
19047         "Reject/problem/generalProblem", HFILL }},
19048     { &hf_ROS_invokeProblem,
19049       { "invokeProblem", "ROS.invokeProblem",
19050         FT_INT32, BASE_DEC, VALS(ROS_InvokeProblem_vals), 0,
19051         "Reject/problem/invokeProblem", HFILL }},
19052     { &hf_ROS_returnResultProblem,
19053       { "returnResultProblem", "ROS.returnResultProblem",
19054         FT_INT32, BASE_DEC, VALS(ROS_ReturnResultProblem_vals), 0,
19055         "Reject/problem/returnResultProblem", HFILL }},
19056     { &hf_ROS_returnErrorProblem,
19057       { "returnErrorProblem", "ROS.returnErrorProblem",
19058         FT_INT32, BASE_DEC, VALS(ROS_ReturnErrorProblem_vals), 0,
19059         "Reject/problem/returnErrorProblem", HFILL }},
19060     { &hf_ROS_localValue,
19061       { "localValue", "ROS.localValue",
19062         FT_INT32, BASE_DEC, VALS(gsm_ss_opr_code_strings), 0,
19063         "", HFILL }},
19064     { &hf_ROS_globalValue,
19065       { "globalValue", "ROS.globalValue",
19066         FT_STRING, BASE_NONE, NULL, 0,
19067         "", HFILL }},
19068     { &hf_ROS_nationaler,
19069       { "nationaler", "ROS.nationaler",
19070         FT_UINT32, BASE_DEC, NULL, 0,
19071         "ErrorCode/nationaler", HFILL }},
19072     { &hf_ROS_privateer,
19073       { "privateer", "ROS.privateer",
19074         FT_INT32, BASE_DEC, NULL, 0,
19075         "ErrorCode/privateer", HFILL }},
19076         { &hf_gsm_a_rr_set_of_amr_codec_modes_v1_b8,
19077       { "12,2 kbit/s codec rate", "gsm_a.rr.set_of_amr_codec_modes_v1b8",
19078                 FT_BOOLEAN,8,  TFS(&gsm_a_rr_set_of_amr_codec_modes), 0x80,          
19079                 "12,2 kbit/s codec rate", HFILL }
19080         },
19081         { &hf_gsm_a_rr_set_of_amr_codec_modes_v1_b7,
19082       { "10,2 kbit/s codec rate", "gsm_a.rr.set_of_amr_codec_modes_v1b7",
19083                 FT_BOOLEAN,8,  TFS(&gsm_a_rr_set_of_amr_codec_modes), 0x40,          
19084                 "10,2 kbit/s codec rate", HFILL }
19085         },
19086         { &hf_gsm_a_rr_set_of_amr_codec_modes_v1_b6,
19087       { "7,95 kbit/s codec rate", "gsm_a.rr.set_of_amr_codec_modes_v1b6",
19088                 FT_BOOLEAN,8,  TFS(&gsm_a_rr_set_of_amr_codec_modes), 0x20,          
19089                 "7,95 kbit/s codec rate", HFILL }
19090         },
19091         { &hf_gsm_a_rr_set_of_amr_codec_modes_v1_b5,
19092       { "7,40 kbit/s codec rate", "gsm_a.rr.set_of_amr_codec_modes_v1b5",
19093                 FT_BOOLEAN,8,  TFS(&gsm_a_rr_set_of_amr_codec_modes), 0x10,          
19094                 "7,40 kbit/s codec rate", HFILL }
19095         },
19096         { &hf_gsm_a_rr_set_of_amr_codec_modes_v1_b4,
19097       { "6,70 kbit/s codec rate", "gsm_a.rr.set_of_amr_codec_modes_v1b4",
19098                 FT_BOOLEAN,8,  TFS(&gsm_a_rr_set_of_amr_codec_modes), 0x08,          
19099                 "6,70 kbit/s codec rate", HFILL }
19100         },
19101         { &hf_gsm_a_rr_set_of_amr_codec_modes_v1_b3,
19102       { "5,90 kbit/s codec rate", "gsm_a.rr.set_of_amr_codec_modes_v1b3",
19103                 FT_BOOLEAN,8,  TFS(&gsm_a_rr_set_of_amr_codec_modes), 0x04,          
19104                 "5,90 kbit/s codec rate", HFILL }
19105         },
19106         { &hf_gsm_a_rr_set_of_amr_codec_modes_v1_b2,
19107       { "5,15 kbit/s codec rate", "gsm_a.rr.set_of_amr_codec_modes_v1b2",
19108                 FT_BOOLEAN,8,  TFS(&gsm_a_rr_set_of_amr_codec_modes), 0x02,          
19109                 "5,15 kbit/s codec rate", HFILL }
19110         },
19111         { &hf_gsm_a_rr_set_of_amr_codec_modes_v1_b1,
19112       { "4,75 kbit/s codec rate", "gsm_a.rr.set_of_amr_codec_modes_v1b1",
19113                 FT_BOOLEAN,8,  TFS(&gsm_a_rr_set_of_amr_codec_modes), 0x01,          
19114                 "4,75 kbit/s codec rate", HFILL }
19115         },
19116         { &hf_gsm_a_rr_set_of_amr_codec_modes_v2_b5,
19117       { "23,85 kbit/s codec rate", "gsm_a.rr.set_of_amr_codec_modes_v2b5",
19118                 FT_BOOLEAN,8,  TFS(&gsm_a_rr_set_of_amr_codec_modes), 0x10,          
19119                 "23,85 kbit/s codec rate", HFILL }
19120         },
19121         { &hf_gsm_a_rr_set_of_amr_codec_modes_v2_b4,
19122       { "15,85 kbit/s codec rate", "gsm_a.rr.set_of_amr_codec_modes_v2b4",
19123                 FT_BOOLEAN,8,  TFS(&gsm_a_rr_set_of_amr_codec_modes), 0x08,          
19124                 "15,85 kbit/s codec rate", HFILL }
19125         },
19126         { &hf_gsm_a_rr_set_of_amr_codec_modes_v2_b3,
19127       { "12,65 kbit/s codec rate", "gsm_a.rr.set_of_amr_codec_modes_v2b3",
19128                 FT_BOOLEAN,8,  TFS(&gsm_a_rr_set_of_amr_codec_modes), 0x04,          
19129                 "12,65 kbit/s codec rate", HFILL }
19130         },
19131         { &hf_gsm_a_rr_set_of_amr_codec_modes_v2_b2,
19132       { "8,85 kbit/s codec rate", "gsm_a.rr.set_of_amr_codec_modes_v2b2",
19133                 FT_BOOLEAN,8,  TFS(&gsm_a_rr_set_of_amr_codec_modes), 0x02,          
19134                 "8,85 kbit/s codec rate", HFILL }
19135         },
19136         { &hf_gsm_a_rr_set_of_amr_codec_modes_v2_b1,
19137       { "6,60 kbit/s codec rate", "gsm_a.rr.set_of_amr_codec_modes_v2b1",
19138                 FT_BOOLEAN,8,  TFS(&gsm_a_rr_set_of_amr_codec_modes), 0x01,          
19139                 "6,60 kbit/s codec rate", HFILL }
19140         },
19141        { &hf_gsm_a_extension,
19142       { "Extension", "gsm_a.extension",
19143         FT_BOOLEAN, 8, TFS(&gsm_a_extension_value), 0x80,
19144         "Extension", HFILL }},
19145        { &hf_gsm_a_type_of_number,
19146       { "Type of number", "gsm_a.type_of_number",
19147         FT_UINT8, BASE_HEX, VALS(gsm_a_type_of_number_values), 0x70,
19148         "Type of number", HFILL }},
19149        { &hf_gsm_a_numbering_plan_id,
19150       { "Numbering plan identification", "gsm_a.numbering_plan_id",
19151         FT_UINT8, BASE_HEX, VALS(gsm_a_numbering_plan_id_values), 0x0f,
19152         "Numbering plan identification", HFILL }},
19153         { &hf_gsm_a_tft_op_code,
19154                 { "TFT operation code", "gsm_a.tft.op_code", 
19155                 FT_UINT8, BASE_DEC, VALS(gsm_a_tft_op_code_vals), 0xe0,
19156                 "TFT operation code", HFILL }
19157         },
19158         { &hf_gsm_a_tft_e_bit,
19159                 { "E bit","gsm_a.tft.e_bit",
19160                 FT_BOOLEAN,8,  TFS(&gsm_a_tft_e_bit), 0x10,          
19161                 "E bit", HFILL }
19162         },
19163         { &hf_gsm_a_tft_pkt_flt,
19164                 { "Number of packet filters", "gsm_a.tft.pkt_flt", 
19165                 FT_UINT8, BASE_DEC, NULL, 0x0f,
19166                 "Number of packet filters", HFILL }
19167         },
19168
19169        { &hf_gsm_a_tft_ip4_address,
19170       { "IPv4 adress", "gsm_a.tft.ip4_address", FT_IPv4, BASE_NONE, NULL, 0x0,
19171                 "IPv4 address", HFILL }},
19172         { &hf_gsm_a_tft_ip4_mask,
19173       { "IPv4 address mask", "gsm_a.tft.ip4_mask", FT_IPv4, BASE_NONE, NULL, 0x0,
19174                 "IPv4 address mask", HFILL }},
19175         { &hf_gsm_a_tft_ip6_address,
19176       { "IPv6 adress", "gsm_a.tft.ip6_address", FT_IPv6, BASE_NONE, NULL, 0x0,
19177                 "IPv6 address", HFILL }},
19178         { &hf_gsm_a_tft_ip6_mask,
19179         { "IPv6 adress mask", "gsm_a.tft.ip6_mask", FT_IPv6, BASE_NONE, NULL, 0x0,
19180                 "IPv6 address mask", HFILL }},
19181         { &hf_gsm_a_tft_protocol_header,
19182         { "Protocol/header", "gsm_a.tft.protocol_header", FT_UINT8, BASE_HEX, NULL, 0x0,
19183                 "Protocol/header", HFILL }},
19184         { &hf_gsm_a_tft_port,
19185         { "Port", "gsm_a.tft.port", FT_UINT16, BASE_DEC, NULL, 0x0,
19186                 "Port", HFILL }},
19187         { &hf_gsm_a_tft_port_low,
19188         { "Low limit port", "gsm_a.tft.port_low", FT_UINT16, BASE_DEC, NULL, 0x0,
19189                 "Low limit port", HFILL }},
19190         { &hf_gsm_a_tft_port_high,
19191         { "High limit port", "gsm_a.tft.port_high", FT_UINT16, BASE_DEC, NULL, 0x0,
19192                 "High limit port", HFILL }},
19193         { &hf_gsm_a_tft_security,
19194         { "IPSec security parameter index", "gsm_a.tft.security", FT_UINT32, BASE_HEX, NULL, 0x0,
19195                 "IPSec security parameter index", HFILL }},
19196         { &hf_gsm_a_tft_traffic_mask,
19197         { "Mask field", "gsm_a.tft.traffic_mask", FT_UINT8, BASE_HEX, NULL, 0x0,
19198                 "Mask field", HFILL }},
19199         { &hf_gsm_a_tft_flow,
19200         { "IPv6 flow label", "gsm_a.tft.flow", FT_UINT24, BASE_HEX, NULL, 0x0FFFFF,
19201                 "IPv6 flow label", HFILL }},
19202
19203         { &hf_gsm_a_ptmsi_sig,
19204         { "P-TMSI Signature", "gsm_a.ptmsi_sig", FT_UINT24, BASE_HEX, NULL, 0x0,
19205                 "P-TMSI Signature", HFILL }},
19206         { &hf_gsm_a_ptmsi_sig2,
19207         { "P-TMSI Signature 2", "gsm_a.ptmsi_sig2", FT_UINT24, BASE_HEX, NULL, 0x0,
19208                 "P-TMSI Signature 2", HFILL }},
19209
19210         { &hf_gsm_a_apdu_protocol_id,
19211                 { "Protocol ID", "gsm_a.apdu_protocol_id", 
19212                 FT_UINT8, BASE_DEC, VALS(gsm_a_apdu_protocol_id_strings), 0x0,
19213                 "APDU embedded protocol id", HFILL }
19214         },
19215         { &hf_gsm_a_lsa_id,
19216                 { "LSA Identifier", "gsm_a.lsa_id", 
19217                 FT_UINT24, BASE_HEX, NULL, 0x0,
19218                 "LSA Identifier", HFILL }
19219         },
19220     };
19221
19222     /* Setup protocol subtree array */
19223 #define NUM_INDIVIDUAL_ELEMS    50
19224     static gint *ett[NUM_INDIVIDUAL_ELEMS + NUM_GSM_BSSMAP_MSG +
19225                         NUM_GSM_DTAP_MSG_MM + NUM_GSM_DTAP_MSG_RR + NUM_GSM_DTAP_MSG_CC +
19226                         NUM_GSM_DTAP_MSG_GMM + NUM_GSM_DTAP_MSG_SMS +
19227                         NUM_GSM_DTAP_MSG_SM + NUM_GSM_DTAP_MSG_SS + NUM_GSM_RP_MSG +
19228                         NUM_GSM_BSSMAP_ELEM + NUM_GSM_DTAP_ELEM];
19229
19230     ett[0] = &ett_bssmap_msg;
19231     ett[1] = &ett_dtap_msg;
19232     ett[2] = &ett_rp_msg;
19233     ett[3] = &ett_elems;
19234     ett[4] = &ett_elem;
19235     ett[5] = &ett_dtap_oct_1;
19236     ett[6] = &ett_cm_srvc_type;
19237     ett[7] = &ett_gsm_enc_info;
19238     ett[8] = &ett_cell_list;
19239     ett[9] = &ett_dlci;
19240     ett[10] = &ett_bc_oct_3a;
19241     ett[11] = &ett_bc_oct_4;
19242     ett[12] = &ett_bc_oct_5;
19243     ett[13] = &ett_bc_oct_5a;
19244     ett[14] = &ett_bc_oct_5b;
19245     ett[15] = &ett_bc_oct_6;
19246     ett[16] = &ett_bc_oct_6a;
19247     ett[17] = &ett_bc_oct_6b;
19248     ett[18] = &ett_bc_oct_6c;
19249     ett[19] = &ett_bc_oct_6d;
19250     ett[20] = &ett_bc_oct_6e;
19251     ett[21] = &ett_bc_oct_6f;
19252     ett[22] = &ett_bc_oct_6g;
19253     ett[23] = &ett_bc_oct_7;
19254
19255     ett[24] = &ett_tc_component;
19256     ett[25] = &ett_tc_invoke_id;
19257     ett[26] = &ett_tc_linked_id;
19258     ett[27] = &ett_tc_opr_code;
19259     ett[28] = &ett_tc_err_code;
19260     ett[29] = &ett_tc_prob_code;
19261     ett[30] = &ett_tc_sequence;
19262     
19263     ett[31] = &ett_gmm_drx;
19264     ett[32] = &ett_gmm_detach_type;
19265     ett[33] = &ett_gmm_attach_type;
19266     ett[34] = &ett_gmm_context_stat;
19267     ett[35] = &ett_gmm_update_type;
19268     ett[36] = &ett_gmm_radio_cap;
19269
19270     ett[37] = &ett_sm_tft;
19271
19272     ett[38] = &ett_ros,
19273     ett[39] = &ett_ROS_Component,
19274     ett[40] = &ett_ROS_Invoke,
19275     ett[41] = &ett_ROS_ReturnResult,
19276     ett[42] = &ett_ROS_T_resultretres,
19277     ett[43] = &ett_ROS_ReturnError,
19278     ett[44] = &ett_ROS_Reject,
19279     ett[45] = &ett_ROS_T_invokeIDRej,
19280     ett[46] = &ett_ROS_T_problem,
19281     ett[47] = &ett_ROS_OPERATION,
19282     ett[48] = &ett_ROS_ERROR,
19283     ett[49] = &ett_ROS_ErrorCode,
19284
19285     last_offset = NUM_INDIVIDUAL_ELEMS;
19286
19287     for (i=0; i < NUM_GSM_BSSMAP_MSG; i++, last_offset++)
19288     {
19289         ett_gsm_bssmap_msg[i] = -1;
19290         ett[last_offset] = &ett_gsm_bssmap_msg[i];
19291     }
19292
19293     for (i=0; i < NUM_GSM_DTAP_MSG_MM; i++, last_offset++)
19294     {
19295         ett_gsm_dtap_msg_mm[i] = -1;
19296         ett[last_offset] = &ett_gsm_dtap_msg_mm[i];
19297     }
19298
19299     for (i=0; i < NUM_GSM_DTAP_MSG_RR; i++, last_offset++)
19300     {
19301         ett_gsm_dtap_msg_rr[i] = -1;
19302         ett[last_offset] = &ett_gsm_dtap_msg_rr[i];
19303     }
19304
19305     for (i=0; i < NUM_GSM_DTAP_MSG_CC; i++, last_offset++)
19306     {
19307         ett_gsm_dtap_msg_cc[i] = -1;
19308         ett[last_offset] = &ett_gsm_dtap_msg_cc[i];
19309     }
19310
19311     for (i=0; i < NUM_GSM_DTAP_MSG_GMM; i++, last_offset++)
19312     {
19313         ett_gsm_dtap_msg_gmm[i] = -1;
19314         ett[last_offset] = &ett_gsm_dtap_msg_gmm[i];
19315     }
19316
19317     for (i=0; i < NUM_GSM_DTAP_MSG_SMS; i++, last_offset++)
19318     {
19319         ett_gsm_dtap_msg_sms[i] = -1;
19320         ett[last_offset] = &ett_gsm_dtap_msg_sms[i];
19321     }
19322
19323     for (i=0; i < NUM_GSM_DTAP_MSG_SM; i++, last_offset++)
19324     {
19325         ett_gsm_dtap_msg_sm[i] = -1;
19326         ett[last_offset] = &ett_gsm_dtap_msg_sm[i];
19327     }
19328
19329     for (i=0; i < NUM_GSM_DTAP_MSG_SS; i++, last_offset++)
19330     {
19331         ett_gsm_dtap_msg_ss[i] = -1;
19332         ett[last_offset] = &ett_gsm_dtap_msg_ss[i];
19333     }
19334
19335     for (i=0; i < NUM_GSM_RP_MSG; i++, last_offset++)
19336     {
19337         ett_gsm_rp_msg[i] = -1;
19338         ett[last_offset] = &ett_gsm_rp_msg[i];
19339     }
19340
19341     for (i=0; i < NUM_GSM_BSSMAP_ELEM; i++, last_offset++)
19342     {
19343         ett_gsm_bssmap_elem[i] = -1;
19344         ett[last_offset] = &ett_gsm_bssmap_elem[i];
19345     }
19346
19347     for (i=0; i < NUM_GSM_DTAP_ELEM; i++, last_offset++)
19348     {
19349         ett_gsm_dtap_elem[i] = -1;
19350         ett[last_offset] = &ett_gsm_dtap_elem[i];
19351     }
19352
19353
19354     /* Register the protocol name and description */
19355
19356     proto_a_bssmap =
19357         proto_register_protocol("GSM A-I/F BSSMAP", "GSM BSSMAP", "gsm_a_bssmap");
19358
19359     proto_register_field_array(proto_a_bssmap, hf, array_length(hf));
19360
19361     proto_a_dtap =
19362         proto_register_protocol("GSM A-I/F DTAP", "GSM DTAP", "gsm_a_dtap");
19363
19364     proto_a_rp =
19365         proto_register_protocol("GSM A-I/F RP", "GSM RP", "gsm_a_rp");
19366
19367     sms_dissector_table =
19368         register_dissector_table("gsm_a.sms_tpdu", "GSM SMS TPDU",
19369         FT_UINT8, BASE_DEC);
19370
19371     proto_register_subtree_array(ett, array_length(ett));
19372
19373     /* subdissector code */
19374     gprs_sm_pco_subdissector_table = register_dissector_table("sm_pco.protocol",
19375         "GPRS SM PCO PPP protocol", FT_UINT16, BASE_HEX);
19376
19377     gsm_a_tap = register_tap("gsm_a");
19378         
19379         register_dissector("gsm_a_dtap", dissect_dtap, proto_a_dtap);
19380         register_dissector("gsm_a_rp", dissect_rp, proto_a_rp);
19381         register_dissector("gsm_a_bssmap", dissect_bssmap, proto_a_bssmap);
19382 }
19383
19384
19385 void
19386 proto_reg_handoff_gsm_a(void)
19387 {
19388
19389     bssmap_handle = create_dissector_handle(dissect_bssmap, proto_a_bssmap);
19390     dtap_handle = find_dissector("gsm_a_dtap");
19391     rp_handle = create_dissector_handle(dissect_rp, proto_a_rp);
19392
19393     dissector_add("bssap.pdu_type",  BSSAP_PDU_TYPE_BSSMAP, bssmap_handle);
19394     dissector_add("bssap.pdu_type",  BSSAP_PDU_TYPE_DTAP, dtap_handle);
19395     dissector_add("ranap.nas_pdu",  BSSAP_PDU_TYPE_DTAP, dtap_handle);
19396     dissector_add("llcgprs.sapi", 1 , dtap_handle);
19397     data_handle = find_dissector("data");
19398 }
19399