From Thomas Anders fix some memory leaks
[obnox/wireshark/wip.git] / 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  * Title                3GPP                    Other
8  *
9  *   Reference [1]
10  *   Mobile radio interface signalling layer 3;
11  *   General Aspects
12  *   (3GPP TS 24.007 version 3.9.0 Release 1999)
13  *
14  *   Reference [2]
15  *   Mobile-services Switching Centre - Base Station System
16  *   (MSC - BSS) interface;
17  *   Layer 3 specification
18  *   (GSM 08.08 version 7.7.0 Release 1998)     TS 100 590 v7.7.0
19  *
20  *   Reference [3]
21  *   Mobile radio interface Layer 3 specification;
22  *   Core network protocols;
23  *   Stage 3
24  *   (3GPP TS 24.008 version 4.7.0 Release 4)
25  *
26  *   Reference [4]
27  *   Mobile radio interface layer 3 specification;
28  *   Radio Resource Control Protocol
29  *   (GSM 04.18 version 8.4.1 Release 1999)
30  *
31  *   Reference [5]
32  *   Point-to-Point (PP) Short Message Service (SMS)
33  *   support on mobile radio interface
34  *   (3GPP TS 24.011 version 4.1.1 Release 4)
35  *
36  *   Reference [6]
37  *   Mobile radio Layer 3 supplementary service specification;
38  *   Formats and coding
39  *   (3GPP TS 24.080 version 4.3.0 Release 4)
40  *
41  * $Id: packet-gsm_a.c,v 1.13 2004/04/21 05:53:55 guy Exp $
42  *
43  * Ethereal - Network traffic analyzer
44  * By Gerald Combs <gerald@ethereal.com>
45  * Copyright 1998 Gerald Combs
46  *
47  * This program is free software; you can redistribute it and/or
48  * modify it under the terms of the GNU General Public License
49  * as published by the Free Software Foundation; either version 2
50  * of the License, or (at your option) any later version.
51  *
52  * This program is distributed in the hope that it will be useful,
53  * but WITHOUT ANY WARRANTY; without even the implied warranty of
54  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
55  * GNU General Public License for more details.
56  *
57  * You should have received a copy of the GNU General Public License
58  * along with this program; if not, write to the Free Software
59  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
60  */
61
62 #ifdef HAVE_CONFIG_H
63 # include "config.h"
64 #endif
65
66 #include <stdio.h>
67 #include <stdlib.h>
68
69 #include <string.h>
70
71 #include "epan/packet.h"
72 #include "prefs.h"
73 #include "tap.h"
74 #include "asn1.h"
75
76 #include "packet-tcap.h"
77 #include "packet-bssap.h"
78 #include "packet-gsm_ss.h"
79 #include "packet-gsm_a.h"
80
81 /* PROTOTYPES/FORWARDS */
82
83 const value_string gsm_a_bssmap_msg_strings[] = {
84     { 0x01,     "Assignment Request" },
85     { 0x02,     "Assignment Complete" },
86     { 0x03,     "Assignment Failure" },
87     { 0x10,     "Handover Request" },
88     { 0x11,     "Handover Required" },
89     { 0x12,     "Handover Request Acknowledge" },
90     { 0x13,     "Handover Command" },
91     { 0x14,     "Handover Complete" },
92     { 0x15,     "Handover Succeeded" },
93     { 0x16,     "Handover Failure" },
94     { 0x17,     "Handover Performed" },
95     { 0x18,     "Handover Candidate Enquire" },
96     { 0x19,     "Handover Candidate Response" },
97     { 0x1a,     "Handover Required Reject" },
98     { 0x1b,     "Handover Detect" },
99     { 0x20,     "Clear Command" },
100     { 0x21,     "Clear Complete" },
101     { 0x22,     "Clear Request" },
102     { 0x23,     "Reserved" },
103     { 0x24,     "Reserved" },
104     { 0x25,     "SAPI 'n' Reject" },
105     { 0x26,     "Confusion" },
106     { 0x28,     "Suspend" },
107     { 0x29,     "Resume" },
108     { 0x2a,     "Connection Oriented Information" },
109     { 0x2b,     "Perform Location Request" },
110     { 0x2c,     "LSA Information" },
111     { 0x2d,     "Perform Location Response" },
112     { 0x2e,     "Perform Location Abort" },
113     { 0x30,     "Reset" },
114     { 0x31,     "Reset Acknowledge" },
115     { 0x32,     "Overload" },
116     { 0x33,     "Reserved" },
117     { 0x34,     "Reset Circuit" },
118     { 0x35,     "Reset Circuit Acknowledge" },
119     { 0x36,     "MSC Invoke Trace" },
120     { 0x37,     "BSS Invoke Trace" },
121     { 0x3a,     "Connectionless Information" },
122     { 0x40,     "Block" },
123     { 0x41,     "Blocking Acknowledge" },
124     { 0x42,     "Unblock" },
125     { 0x43,     "Unblocking Acknowledge" },
126     { 0x44,     "Circuit Group Block" },
127     { 0x45,     "Circuit Group Blocking Acknowledge" },
128     { 0x46,     "Circuit Group Unblock" },
129     { 0x47,     "Circuit Group Unblocking Acknowledge" },
130     { 0x48,     "Unequipped Circuit" },
131     { 0x4e,     "Change Circuit" },
132     { 0x4f,     "Change Circuit Acknowledge" },
133     { 0x50,     "Resource Request" },
134     { 0x51,     "Resource Indication" },
135     { 0x52,     "Paging" },
136     { 0x53,     "Cipher Mode Command" },
137     { 0x54,     "Classmark Update" },
138     { 0x55,     "Cipher Mode Complete" },
139     { 0x56,     "Queuing Indication" },
140     { 0x57,     "Complete Layer 3 Information" },
141     { 0x58,     "Classmark Request" },
142     { 0x59,     "Cipher Mode Reject" },
143     { 0x5a,     "Load Indication" },
144     { 0x04,     "VGCS/VBS Setup" },
145     { 0x05,     "VGCS/VBS Setup Ack" },
146     { 0x06,     "VGCS/VBS Setup Refuse" },
147     { 0x07,     "VGCS/VBS Assignment Request" },
148     { 0x1c,     "VGCS/VBS Assignment Result" },
149     { 0x1d,     "VGCS/VBS Assignment Failure" },
150     { 0x1e,     "VGCS/VBS Queuing Indication" },
151     { 0x1f,     "Uplink Request" },
152     { 0x27,     "Uplink Request Acknowledge" },
153     { 0x49,     "Uplink Request Confirmation" },
154     { 0x4a,     "Uplink Release Indication" },
155     { 0x4b,     "Uplink Reject Command" },
156     { 0x4c,     "Uplink Release Command" },
157     { 0x4d,     "Uplink Seized Command" },
158     { 0, NULL },
159 };
160
161 const value_string gsm_a_dtap_msg_mm_strings[] = {
162     { 0x01,     "IMSI Detach Indication" },
163     { 0x02,     "Location Updating Accept" },
164     { 0x04,     "Location Updating Reject" },
165     { 0x08,     "Location Updating Request" },
166     { 0x11,     "Authentication Reject" },
167     { 0x12,     "Authentication Request" },
168     { 0x14,     "Authentication Response" },
169     { 0x1c,     "Authentication Failure" },
170     { 0x18,     "Identity Request" },
171     { 0x19,     "Identity Response" },
172     { 0x1a,     "TMSI Reallocation Command" },
173     { 0x1b,     "TMSI Reallocation Complete" },
174     { 0x21,     "CM Service Accept" },
175     { 0x22,     "CM Service Reject" },
176     { 0x23,     "CM Service Abort" },
177     { 0x24,     "CM Service Request" },
178     { 0x25,     "CM Service Prompt" },
179     { 0x26,     "Reserved: was allocated in earlier phases of the protocol" },
180     { 0x28,     "CM Re-establishment Request" },
181     { 0x29,     "Abort" },
182     { 0x30,     "MM Null" },
183     { 0x31,     "MM Status" },
184     { 0x32,     "MM Information" },
185     { 0, NULL },
186 };
187
188 const value_string gsm_a_dtap_msg_rr_strings[] = {
189     { 0x3c,     "RR Initialisation Request" },
190     { 0x3b,     "Additional Assignment" },
191     { 0x3f,     "Immediate Assignment" },
192     { 0x39,     "Immediate Assignment Extended" },
193     { 0x3a,     "Immediate Assignment Reject" },
194
195     { 0x48,     "DTM Assignment Failure" },
196     { 0x49,     "DTM Reject" },
197     { 0x4a,     "DTM Request" },
198     { 0x4b,     "Main DCCH Assignment Command" },
199     { 0x4c,     "Packet Assignment Command" },
200
201     { 0x35,     "Ciphering Mode Command" },
202     { 0x32,     "Ciphering Mode Complete" },
203
204     { 0x30,     "Configuration Change Command" },
205     { 0x31,     "Configuration Change Ack." },
206     { 0x33,     "Configuration Change Reject" },
207
208     { 0x2e,     "Assignment Command" },
209     { 0x29,     "Assignment Complete" },
210     { 0x2f,     "Assignment Failure" },
211     { 0x2b,     "Handover Command" },
212     { 0x2c,     "Handover Complete" },
213     { 0x28,     "Handover Failure" },
214     { 0x2d,     "Physical Information" },
215     { 0x4d,     "DTM Assignment Command" },
216
217     { 0x08,     "RR-cell Change Order" },
218     { 0x23,     "PDCH Assignment Command" },
219
220     { 0x0d,     "Channel Release" },
221     { 0x0a,     "Partial Release" },
222     { 0x0f,     "Partial Release Complete" },
223
224     { 0x21,     "Paging Request Type 1" },
225     { 0x22,     "Paging Request Type 2" },
226     { 0x24,     "Paging Request Type 3" },
227     { 0x27,     "Paging Response" },
228     { 0x20,     "Notification/NCH" },
229     { 0x25,     "Reserved" },
230     { 0x26,     "Notification/Response" },
231
232     { 0x0b,     "Reserved" },
233
234 /*    { 0xc0,   "Utran Classmark Change" }, CONFLICTS WITH Handover To UTRAN Command */
235     { 0xc1,     "UE RAB Preconfiguration" },
236     { 0xc2,     "cdma2000 Classmark Change" },
237
238     { 0x18,     "System Information Type 8" },
239     { 0x19,     "System Information Type 1" },
240     { 0x1a,     "System Information Type 2" },
241     { 0x1b,     "System Information Type 3" },
242     { 0x1c,     "System Information Type 4" },
243     { 0x1d,     "System Information Type 5" },
244     { 0x1e,     "System Information Type 6" },
245     { 0x1f,     "System Information Type 7" },
246
247     { 0x02,     "System Information Type 2bis" },
248     { 0x03,     "System Information Type 2ter" },
249     { 0x07,     "System Information Type 2quater" },
250     { 0x05,     "System Information Type 5bis" },
251     { 0x06,     "System Information Type 5ter" },
252     { 0x04,     "System Information Type 9" },
253     { 0x00,     "System Information Type 13" },
254
255     { 0x3d,     "System Information Type 16" },
256     { 0x3e,     "System Information Type 17" },
257
258     { 0x40,     "System Information Type 18" },
259     { 0x41,     "System Information Type 19" },
260     { 0x42,     "System Information Type 20" },
261
262     { 0x10,     "Channel Mode Modify" },
263     { 0x12,     "RR Status" },
264     { 0x17,     "Channel Mode Modify Acknowledge" },
265     { 0x14,     "Frequency Redefinition" },
266     { 0x15,     "Measurement Report" },
267     { 0x16,     "Classmark Change" },
268     { 0x13,     "Classmark Enquiry" },
269     { 0x36,     "Extended Measurement Report" },
270     { 0x37,     "Extended Measurement Order" },
271     { 0x34,     "GPRS Suspension Request" },
272
273     { 0x09,     "VGCS Uplink Grant" },
274     { 0x0e,     "Uplink Release" },
275     { 0x0c,     "Reserved" },
276     { 0x2a,     "Uplink Busy" },
277     { 0x11,     "Talker Indication" },
278
279     { 0xc0,     "UTRAN Classmark Change/Handover To UTRAN Command" },   /* spec conflict */
280
281     { 0x38,     "Application Information" },
282
283     { 0, NULL },
284 };
285
286 const value_string gsm_a_dtap_msg_cc_strings[] = {
287     { 0x01,     "Alerting" },
288     { 0x08,     "Call Confirmed" },
289     { 0x02,     "Call Proceeding" },
290     { 0x07,     "Connect" },
291     { 0x0f,     "Connect Acknowledge" },
292     { 0x0e,     "Emergency Setup" },
293     { 0x03,     "Progress" },
294     { 0x04,     "CC-Establishment" },
295     { 0x06,     "CC-Establishment Confirmed" },
296     { 0x0b,     "Recall" },
297     { 0x09,     "Start CC" },
298     { 0x05,     "Setup" },
299     { 0x17,     "Modify" },
300     { 0x1f,     "Modify Complete" },
301     { 0x13,     "Modify Reject" },
302     { 0x10,     "User Information" },
303     { 0x18,     "Hold" },
304     { 0x19,     "Hold Acknowledge" },
305     { 0x1a,     "Hold Reject" },
306     { 0x1c,     "Retrieve" },
307     { 0x1d,     "Retrieve Acknowledge" },
308     { 0x1e,     "Retrieve Reject" },
309     { 0x25,     "Disconnect" },
310     { 0x2d,     "Release" },
311     { 0x2a,     "Release Complete" },
312     { 0x39,     "Congestion Control" },
313     { 0x3e,     "Notify" },
314     { 0x3d,     "Status" },
315     { 0x34,     "Status Enquiry" },
316     { 0x35,     "Start DTMF" },
317     { 0x31,     "Stop DTMF" },
318     { 0x32,     "Stop DTMF Acknowledge" },
319     { 0x36,     "Start DTMF Acknowledge" },
320     { 0x37,     "Start DTMF Reject" },
321     { 0x3a,     "Facility" },
322     { 0, NULL },
323 };
324
325 const value_string gsm_a_dtap_msg_gmm_strings[] = {
326     { 0x01,     "Attach Request" },
327     { 0x02,     "Attach Accept" },
328     { 0x03,     "Attach Complete" },
329     { 0x04,     "Attach Reject" },
330     { 0x05,     "Detach Request" },
331     { 0x06,     "Detach Accept" },
332     { 0x08,     "Routing Area Update Request" },
333     { 0x09,     "Routing Area Update Accept" },
334     { 0x0a,     "Routing Area Update Complete" },
335     { 0x0b,     "Routing Area Update Reject" },
336     { 0x0c,     "Service Request" },
337     { 0x0d,     "Service Accept" },
338     { 0x0e,     "Service Reject" },
339     { 0x10,     "P-TMSI Reallocation Command" },
340     { 0x11,     "P-TMSI Reallocation Complete" },
341     { 0x12,     "Authentication and Ciphering Req" },
342     { 0x13,     "Authentication and Ciphering Resp" },
343     { 0x14,     "Authentication and Ciphering Rej" },
344     { 0x1c,     "Authentication and Ciphering Failure" },
345     { 0x15,     "Identity Request" },
346     { 0x16,     "Identity Response" },
347     { 0x20,     "GMM Status" },
348     { 0x21,     "GMM Information" },
349     { 0, NULL },
350 };
351
352 const value_string gsm_a_dtap_msg_sms_strings[] = {
353     { 0x01,     "CP-DATA" },
354     { 0x04,     "CP-ACK" },
355     { 0x10,     "CP-ERROR" },
356     { 0, NULL },
357 };
358
359 const value_string gsm_a_dtap_msg_sm_strings[] = {
360     { 0x41,     "Activate PDP Context Request" },
361     { 0x42,     "Activate PDP Context Accept" },
362     { 0x43,     "Activate PDP Context Reject" },
363     { 0x44,     "Request PDP Context Activation" },
364     { 0x45,     "Request PDP Context Activation rej." },
365     { 0x46,     "Deactivate PDP Context Request" },
366     { 0x47,     "Deactivate PDP Context Accept" },
367     { 0x48,     "Modify PDP Context Request(Network to MS direction)" },
368     { 0x49,     "Modify PDP Context Accept (MS to network direction)" },
369     { 0x4a,     "Modify PDP Context Request(MS to network direction)" },
370     { 0x4b,     "Modify PDP Context Accept (Network to MS direction)" },
371     { 0x4c,     "Modify PDP Context Reject" },
372     { 0x4d,     "Activate Secondary PDP Context Request" },
373     { 0x4e,     "Activate Secondary PDP Context Accept" },
374     { 0x4f,     "Activate Secondary PDP Context Reject" },
375     { 0x50,     "Reserved: was allocated in earlier phases of the protocol" },
376     { 0x51,     "Reserved: was allocated in earlier phases of the protocol" },
377     { 0x52,     "Reserved: was allocated in earlier phases of the protocol" },
378     { 0x53,     "Reserved: was allocated in earlier phases of the protocol" },
379     { 0x54,     "Reserved: was allocated in earlier phases of the protocol" },
380     { 0x55,     "SM Status" },
381     { 0, NULL },
382 };
383
384 const value_string gsm_a_dtap_msg_ss_strings[] = {
385     { 0x2a,     "Release Complete" },
386     { 0x3a,     "Facility" },
387     { 0x3b,     "Register" },
388     { 0, NULL },
389 };
390
391 static const value_string gsm_rp_msg_strings[] = {
392     { 0x00,     "RP-DATA (MS to Network)" },
393     { 0x01,     "RP-DATA (Network to MS)" },
394     { 0x02,     "RP-ACK (MS to Network)" },
395     { 0x03,     "RP-ACK (Network to MS)" },
396     { 0x04,     "RP-ERROR (MS to Network)" },
397     { 0x05,     "RP-ERROR (Network to MS)" },
398     { 0x06,     "RP-SMMA (MS to Network)" },
399     { 0, NULL },
400 };
401
402 static const value_string gsm_bssmap_elem_strings[] = {
403     { 0x01,     "Circuit Identity Code" },
404     { 0x02,     "Reserved" },
405     { 0x03,     "Resource Available" },
406     { 0x04,     "Cause" },
407     { 0x05,     "Cell Identifier" },
408     { 0x06,     "Priority" },
409     { 0x07,     "Layer 3 Header Information" },
410     { 0x08,     "IMSI" },
411     { 0x09,     "TMSI" },
412     { 0x0a,     "Encryption Information" },
413     { 0x0b,     "Channel Type" },
414     { 0x0c,     "Periodicity" },
415     { 0x0d,     "Extended Resource Indicator" },
416     { 0x0e,     "Number Of MSs" },
417     { 0x0f,     "Reserved" },
418     { 0x10,     "Reserved" },
419     { 0x11,     "Reserved" },
420     { 0x12,     "Classmark Information Type 2" },
421     { 0x13,     "Classmark Information Type 3" },
422     { 0x14,     "Interference Band To Be Used" },
423     { 0x15,     "RR Cause" },
424     { 0x16,     "Reserved" },
425     { 0x17,     "Layer 3 Information" },
426     { 0x18,     "DLCI" },
427     { 0x19,     "Downlink DTX Flag" },
428     { 0x1a,     "Cell Identifier List" },
429     { 0x1b,     "Response Request" },
430     { 0x1c,     "Resource Indication Method" },
431     { 0x1d,     "Classmark Information Type 1" },
432     { 0x1e,     "Circuit Identity Code List" },
433     { 0x1f,     "Diagnostic" },
434     { 0x20,     "Layer 3 Message Contents" },
435     { 0x21,     "Chosen Channel" },
436     { 0x22,     "Total Resource Accessible" },
437     { 0x23,     "Cipher Response Mode" },
438     { 0x24,     "Channel Needed" },
439     { 0x25,     "Trace Type" },
440     { 0x26,     "TriggerID" },
441     { 0x27,     "Trace Reference" },
442     { 0x28,     "TransactionID" },
443     { 0x29,     "Mobile Identity" },
444     { 0x2a,     "OMCID" },
445     { 0x2b,     "Forward Indicator" },
446     { 0x2c,     "Chosen Encryption Algorithm" },
447     { 0x2d,     "Circuit Pool" },
448     { 0x2e,     "Circuit Pool List" },
449     { 0x2f,     "Time Indication" },
450     { 0x30,     "Resource Situation" },
451     { 0x31,     "Current Channel Type 1" },
452     { 0x32,     "Queueing Indicator" },
453     { 0x40,     "Speech Version" },
454     { 0x33,     "Assignment Requirement" },
455     { 0x35,     "Talker Flag" },
456     { 0x36,     "Connection Release Requested" },
457     { 0x37,     "Group Call Reference" },
458     { 0x38,     "eMLPP Priority" },
459     { 0x39,     "Configuration Evolution Indication" },
460     { 0x3a,     "Old BSS to New BSS Information" },
461     { 0x3b,     "LSA Identifier" },
462     { 0x3c,     "LSA Identifier List" },
463     { 0x3d,     "LSA Information" },
464     { 0x3e,     "LCS QoS" },
465     { 0x3f,     "LSA access control suppression" },
466     { 0x43,     "LCS Priority" },
467     { 0x44,     "Location Type" },
468     { 0x45,     "Location Estimate" },
469     { 0x46,     "Positioning Data" },
470     { 0x47,     "LCS Cause" },
471     { 0x48,     "LCS Client Type" },
472     { 0x49,     "APDU" },
473     { 0x4a,     "Network Element Identity" },
474     { 0x4b,     "GPS Assistance Data" },
475     { 0x4c,     "Deciphering Keys" },
476     { 0x4d,     "Return Error Request" },
477     { 0x4e,     "Return Error Cause" },
478     { 0x4f,     "Segmentation" },
479     { 0, NULL },
480 };
481
482 static const value_string gsm_dtap_elem_strings[] = {
483     /* Common Information Elements 10.5.1 */
484     { 0x00,     "Cell Identity" },
485     { 0x00,     "Ciphering Key Sequence Number" },
486     { 0x00,     "Location Area Identification" },
487     { 0x00,     "Mobile Identity" },
488     { 0x00,     "Mobile Station Classmark 1" },
489     { 0x00,     "Mobile Station Classmark 2" },
490     { 0x00,     "Mobile Station Classmark 3" },
491     { 0x00,     "Descriptive group or broadcast call reference" },
492     { 0x00,     "Group Cipher Key Number" },
493     { 0x00,     "PD and SAPI $(CCBS)$" },
494     { 0x00,     "Priority Level" },
495     { 0x00,     "PLMN List" },
496     /* Radio Resource Management Information Elements 10.5.2, most are from 10.5.1 */
497     { 0x00,     "RR Cause" },
498     /* Mobility Management Information Elements 10.5.3 */
499     { 0x00,     "Authentication Parameter RAND" },
500     { 0x00,     "Authentication Parameter AUTN (UMTS authentication challenge only)" },
501     { 0x00,     "Authentication Response Parameter" },
502     { 0x00,     "Authentication Response Parameter (extension) (UMTS authentication challenge only)" },
503     { 0x00,     "Authentication Failure Parameter (UMTS authentication challenge only)" },
504     { 0x00,     "CM Service Type" },
505     { 0x00,     "Identity Type" },
506     { 0x00,     "Location Updating Type" },
507     { 0x00,     "Network Name" },
508     { 0x00,     "Reject Cause" },
509     { 0x00,     "Follow-on Proceed" },
510     { 0x00,     "Time Zone" },
511     { 0x00,     "Time Zone and Time" },
512     { 0x00,     "CTS Permission" },
513     { 0x00,     "LSA Identifier" },
514     { 0x00,     "Daylight Saving Time" },
515     /* Call Control Information Elements 10.5.4 */
516     { 0x00,     "Auxiliary States" },
517     { 0x00,     "Bearer Capability" },
518     { 0x00,     "Call Control Capabilities" },
519     { 0x00,     "Call State" },
520     { 0x00,     "Called Party BCD Number" },
521     { 0x00,     "Called Party Subaddress" },
522     { 0x00,     "Calling Party BCD Number" },
523     { 0x00,     "Calling Party Subaddress" },
524     { 0x00,     "Cause" },
525     { 0x00,     "CLIR Suppression" },
526     { 0x00,     "CLIR Invocation" },
527     { 0x00,     "Congestion Level" },
528     { 0x00,     "Connected Number" },
529     { 0x00,     "Connected Subaddress" },
530     { 0x00,     "Facility" },
531     { 0x00,     "High Layer Compatibility" },
532     { 0x00,     "Keypad Facility" },
533     { 0x00,     "Low Layer Compatibility" },
534     { 0x00,     "More Data" },
535     { 0x00,     "Notification Indicator" },
536     { 0x00,     "Progress Indicator" },
537     { 0x00,     "Recall type $(CCBS)$" },
538     { 0x00,     "Redirecting Party BCD Number" },
539     { 0x00,     "Redirecting Party Subaddress" },
540     { 0x00,     "Repeat Indicator" },
541     { 0x00,     "Reverse Call Setup Direction" },
542     { 0x00,     "SETUP Container $(CCBS)$" },
543     { 0x00,     "Signal" },
544     { 0x00,     "SS Version Indicator" },
545     { 0x00,     "User-user" },
546     { 0x00,     "Alerting Pattern $(NIA)$" },
547     { 0x00,     "Allowed Actions $(CCBS)$" },
548     { 0x00,     "Stream Identifier" },
549     { 0x00,     "Network Call Control Capabilities" },
550     { 0x00,     "Cause of No CLI" },
551     { 0x00,     "Immediate Modification Indicator" },
552     { 0x00,     "Supported Codec List" },
553     { 0x00,     "Service Category" },
554     /* GPRS Mobility Management Information Elements 10.5.5 */
555     { 0x00,     "Attach Result" },
556     { 0x00,     "Attach Type" },
557     { 0x00,     "TMSI Status" },
558     { 0x00,     "Detach Type" },
559     { 0x00,     "DRX Parameter" },
560     { 0x00,     "Force to Standby" },
561     { 0x00,     "P-TMSI Signature" },
562     { 0x00,     "P-TMSI Signature 2" },
563     { 0x00,     "Identity Type 2" },
564     { 0x00,     "IMEISV Request" },
565     { 0x00,     "Receive N-PDU Numbers List" },
566     { 0x00,     "MS Network Capability" },
567     { 0x00,     "MS Radio Access Capability" },
568     { 0x00,     "GMM Cause" },
569     { 0x00,     "Routing Area Identification" },
570     { 0x00,     "Update Result" },
571     { 0x00,     "A&C Reference Number" },
572     { 0x00,     "Service Type" },
573     { 0x00,     "Cell Notification" },
574     { 0x00,     "Network Feature Support" },
575     /* Short Message Service Information Elements [5] 8.1.4 */
576     { 0x00,     "CP-User Data" },
577     { 0x00,     "CP-Cause" },
578     /* Short Message Service Information Elements [5] 8.2 */
579     { 0x00,     "RP-Message Reference" },
580     { 0x00,     "RP-Origination Address" },
581     { 0x00,     "RP-Destination Address" },
582     { 0x00,     "RP-User Data" },
583     { 0x00,     "RP-Cause" },
584     /* Session Management Information Elements 10.5.6 */
585     { 0x00,     "Access Point Name" },
586     { 0x00,     "Network Service Access Point Identifier" },
587     { 0x00,     "Protocol Configuration Options" },
588     { 0x00,     "Packet Data Protocol Address" },
589     { 0x00,     "Quality Of Service" },
590     { 0x00,     "SM Cause" },
591     { 0x00,     "Linked TI" },
592     { 0x00,     "LLC Service Access Point Identifier" },
593     { 0x00,     "Tear Down Indicator" },
594     { 0x00,     "Packet Flow Identifier" },
595     { 0x00,     "Traffic Flow Template" },
596     /* GPRS Common Information Elements 10.5.7 */
597     { 0x00,     "PDP Context Status" },
598     { 0x00,     "Radio Priority" },
599     { 0x00,     "GPRS Timer" },
600     { 0x00,     "GPRS Timer 2" },
601     { 0, NULL },
602 };
603
604 const gchar *gsm_a_pd_str[] = {
605     "Group Call Control",
606     "Broadcast Call Control",
607     "Reserved: was allocated in earlier phases of the protocol",
608     "Call Control; call related SS messages",
609     "GPRS Transparent Transport Protocol (GTTP)",
610     "Mobility Management messages",
611     "Radio Resources Management messages",
612     "Unknown",
613     "GPRS Mobility Management messages",
614     "SMS messages",
615     "GPRS Session Management messages",
616     "Non call related SS messages",
617     "Location Services",
618     "Unknown",
619     "Reserved for extension of the PD to one octet length",
620     "Reserved for tests procedures"
621 };
622
623 static const value_string bssap_cc_values[] = {
624     { 0x00,             "not further specified" },
625     { 0x80,             "FACCH or SDCCH" },
626     { 0xc0,             "SACCH" },
627     { 0,                NULL } };
628
629 static const value_string bssap_sapi_values[] = {
630     { 0x00,             "RR/MM/CC" },
631     { 0x03,             "SMS" },
632     { 0,                NULL } };
633
634 static const gchar *cell_disc_str[] = {
635     "The whole Cell Global Identification, CGI, is used to identify the cells",
636     "Location Area Code, LAC, and Cell Identify, CI, is used to identify the cells",
637     "Cell Identity, CI, is used to identify the cells",
638     "No cell is associated with the transaction",
639     "Location Area Identification, LAI, is used to identify all cells within a Location Area",
640     "Location Area Code, LAC, is used to identify all cells within a location area",
641     "All cells on the BSS are identified"
642 };
643 #define NUM_CELL_DISC_STR       (sizeof(cell_disc_str)/sizeof(gchar *))
644
645 #define DTAP_PD_MASK            0x0f
646 #define DTAP_SKIP_MASK          0xf0
647 #define DTAP_TI_MASK            DTAP_SKIP_MASK
648 #define DTAP_TIE_PRES_MASK      0x07                    /* after TI shifted to right */
649 #define DTAP_TIE_MASK           0x7f
650
651 #define DTAP_MM_IEI_MASK        0x3f
652 #define DTAP_RR_IEI_MASK        0xff
653 #define DTAP_CC_IEI_MASK        0x3f
654 #define DTAP_GMM_IEI_MASK       0xff
655 #define DTAP_SMS_IEI_MASK       0xff
656 #define DTAP_SM_IEI_MASK        0xff
657 #define DTAP_SS_IEI_MASK        0x3f
658
659 /* Initialize the protocol and registered fields */
660 static int proto_a_bssmap = -1;
661 static int proto_a_dtap = -1;
662 static int proto_a_rp = -1;
663
664 static int gsm_a_tap = -1;
665
666 static int hf_gsm_a_none = -1;
667 static int hf_gsm_a_bssmap_msg_type = -1;
668 static int hf_gsm_a_dtap_msg_mm_type = -1;
669 static int hf_gsm_a_dtap_msg_rr_type = -1;
670 static int hf_gsm_a_dtap_msg_cc_type = -1;
671 static int hf_gsm_a_dtap_msg_gmm_type = -1;
672 static int hf_gsm_a_dtap_msg_sms_type = -1;
673 static int hf_gsm_a_dtap_msg_sm_type = -1;
674 static int hf_gsm_a_dtap_msg_ss_type = -1;
675 static int hf_gsm_a_rp_msg_type = -1;
676 static int hf_gsm_a_length = -1;
677 static int hf_gsm_a_bssmap_elem_id = -1;
678 static int hf_gsm_a_dtap_elem_id = -1;
679 static int hf_gsm_a_imsi = -1;
680 static int hf_gsm_a_tmsi = -1;
681 static int hf_gsm_a_imei = -1;
682 static int hf_gsm_a_imeisv = -1;
683 static int hf_gsm_a_cld_party_bcd_num = -1;
684 static int hf_gsm_a_clg_party_bcd_num = -1;
685 static int hf_gsm_a_cell_ci = -1;
686 static int hf_gsm_a_cell_lac = -1;
687 static int hf_gsm_a_dlci_cc = -1;
688 static int hf_gsm_a_dlci_spare = -1;
689 static int hf_gsm_a_dlci_sapi = -1;
690 static int hf_gsm_a_bssmap_cause = -1;
691 static int hf_gsm_a_dtap_cause = -1;
692
693 /* Initialize the subtree pointers */
694 static gint ett_bssmap_msg = -1;
695 static gint ett_dtap_msg = -1;
696 static gint ett_rp_msg = -1;
697 static gint ett_elems = -1;
698 static gint ett_elem = -1;
699 static gint ett_dtap_oct_1 = -1;
700 static gint ett_cm_srvc_type = -1;
701 static gint ett_gsm_enc_info = -1;
702 static gint ett_cell_list = -1;
703 static gint ett_dlci = -1;
704 static gint ett_bc_oct_3a = -1;
705 static gint ett_bc_oct_4 = -1;
706 static gint ett_bc_oct_5 = -1;
707 static gint ett_bc_oct_5a = -1;
708 static gint ett_bc_oct_5b = -1;
709 static gint ett_bc_oct_6 = -1;
710 static gint ett_bc_oct_6a = -1;
711 static gint ett_bc_oct_6b = -1;
712 static gint ett_bc_oct_6c = -1;
713 static gint ett_bc_oct_6d = -1;
714 static gint ett_bc_oct_6e = -1;
715 static gint ett_bc_oct_6f = -1;
716 static gint ett_bc_oct_6g = -1;
717 static gint ett_bc_oct_7 = -1;
718
719 static gint ett_tc_component = -1;
720 static gint ett_tc_invoke_id = -1;
721 static gint ett_tc_linked_id = -1;
722 static gint ett_tc_opr_code = -1;
723 static gint ett_tc_err_code = -1;
724 static gint ett_tc_prob_code = -1;
725 static gint ett_tc_sequence = -1;
726
727 static char a_bigbuf[1024];
728 static gchar a_add_string[1024];
729
730 static dissector_handle_t data_handle;
731 static dissector_handle_t bssmap_handle;
732 static dissector_handle_t dtap_handle;
733 static dissector_handle_t rp_handle;
734 static dissector_table_t sms_dissector_table;   /* SMS TPDU */
735
736 static packet_info *g_pinfo;
737 static proto_tree *g_tree;
738
739 /*
740  * this should be set on a per message basis, if possible
741  */
742 #define IS_UPLINK_FALSE         0
743 #define IS_UPLINK_TRUE          1
744 #define IS_UPLINK_UNKNOWN       2
745 static gint is_uplink;
746
747
748 typedef struct dgt_set_t
749 {
750     unsigned char out[15];
751 }
752 dgt_set_t;
753
754 static dgt_set_t Dgt_mbcd = {
755     {
756   /*  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e */
757      '0','1','2','3','4','5','6','7','8','9','*','#','a','b','c'
758     }
759 };
760
761 static dgt_set_t Dgt_tbcd = {
762     {
763   /*  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e */
764      '0','1','2','3','4','5','6','7','8','9','?','B','C','*','#'
765     }
766 };
767
768 static dgt_set_t Dgt_msid = {
769     {
770   /*  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e */
771      '0','1','2','3','4','5','6','7','8','9','?','?','?','?','?'
772     }
773 };
774
775 /* FUNCTIONS */
776
777 /*
778  * Unpack BCD input pattern into output ASCII pattern
779  *
780  * Input Pattern is supplied using the same format as the digits
781  *
782  * Returns: length of unpacked pattern
783  */
784 static int
785 my_dgt_tbcd_unpack(
786     char        *out,           /* ASCII pattern out */
787     guchar      *in,            /* packed pattern in */
788     int         num_octs,       /* Number of octets to unpack */
789     dgt_set_t   *dgt            /* Digit definitions */
790     )
791 {
792     int cnt = 0;
793     unsigned char i;
794
795     while (num_octs)
796     {
797         /*
798          * unpack first value in byte
799          */
800         i = *in++;
801         *out++ = dgt->out[i & 0x0f];
802         cnt++;
803
804         /*
805          * unpack second value in byte
806          */
807         i >>= 4;
808
809         if (i == 0x0f)  /* odd number bytes - hit filler */
810             break;
811
812         *out++ = dgt->out[i];
813         cnt++;
814         num_octs--;
815     }
816
817     *out = '\0';
818
819     return(cnt);
820 }
821
822 static gchar *
823 my_match_strval(guint32 val, const value_string *vs, gint *idx)
824 {
825     gint i = 0;
826
827     while (vs[i].strptr)
828     {
829         if (vs[i].value == val)
830         {
831             *idx = i;
832             return(vs[i].strptr);
833         }
834
835         i++;
836     }
837
838     *idx = -1;
839     return(NULL);
840 }
841
842 /* ELEMENT FUNCTIONS */
843
844 #define EXTRANEOUS_DATA_CHECK(edc_len, edc_max_len) \
845     if ((edc_len) > (edc_max_len)) \
846     { \
847         proto_tree_add_text(tree, tvb, \
848             curr_offset, (edc_len) - (edc_max_len), "Extraneous Data"); \
849         curr_offset += ((edc_len) - (edc_max_len)); \
850     }
851
852 #define SHORT_DATA_CHECK(sdc_len, sdc_min_len) \
853     if ((sdc_len) < (sdc_min_len)) \
854     { \
855         proto_tree_add_text(tree, tvb, \
856             curr_offset, (sdc_len), "Short Data (?)"); \
857         curr_offset += (sdc_len); \
858         return(curr_offset - offset); \
859     }
860
861 #define EXACT_DATA_CHECK(edc_len, edc_eq_len) \
862     if ((edc_len) != (edc_eq_len)) \
863     { \
864         proto_tree_add_text(tree, tvb, \
865             curr_offset, (edc_len), "Unexpected Data Length"); \
866         curr_offset += (edc_len); \
867         return(curr_offset - offset); \
868     }
869
870 #define NO_MORE_DATA_CHECK(nmdc_len) \
871     if ((nmdc_len) == (curr_offset - offset)) return(nmdc_len);
872
873 /*
874  * Decode the MCC/MNC from 3 octets in 'octs'
875  */
876 static void
877 mcc_mnc_aux(guint8 *octs, gchar *mcc, gchar *mnc)
878 {
879     if ((octs[0] & 0x0f) <= 9)
880     {
881         mcc[0] = Dgt_tbcd.out[octs[0] & 0x0f];
882     }
883     else
884     {
885         mcc[0] = (octs[0] & 0x0f) + 55;
886     }
887
888     if (((octs[0] & 0xf0) >> 4) <= 9)
889     {
890         mcc[1] = Dgt_tbcd.out[(octs[0] & 0xf0) >> 4];
891     }
892     else
893     {
894         mcc[1] = ((octs[0] & 0xf0) >> 4) + 55;
895     }
896
897     if ((octs[1] & 0x0f) <= 9)
898     {
899         mcc[2] = Dgt_tbcd.out[octs[1] & 0x0f];
900     }
901     else
902     {
903         mcc[2] = (octs[1] & 0x0f) + 55;
904     }
905
906     mcc[3] = '\0';
907
908     if (((octs[1] & 0xf0) >> 4) <= 9)
909     {
910         mnc[2] = Dgt_tbcd.out[(octs[1] & 0xf0) >> 4];
911     }
912     else
913     {
914         mnc[2] = ((octs[1] & 0xf0) >> 4) + 55;
915     }
916
917     if ((octs[2] & 0x0f) <= 9)
918     {
919         mnc[0] = Dgt_tbcd.out[octs[2] & 0x0f];
920     }
921     else
922     {
923         mnc[0] = (octs[2] & 0x0f) + 55;
924     }
925
926     if (((octs[2] & 0xf0) >> 4) <= 9)
927     {
928         mnc[1] = Dgt_tbcd.out[(octs[2] & 0xf0) >> 4];
929     }
930     else
931     {
932         mnc[1] = ((octs[2] & 0xf0) >> 4) + 55;
933     }
934
935     if (mnc[1] == 'F')
936     {
937         /*
938          * only a 1 digit MNC (very old)
939          */
940         mnc[1] = '\0';
941     }
942     else if (mnc[2] == 'F')
943     {
944         /*
945          * only a 2 digit MNC
946          */
947         mnc[2] = '\0';
948     }
949     else
950     {
951         mnc[3] = '\0';
952     }
953 }
954
955 typedef enum
956 {
957     BE_CIC,      /* Circuit Identity Code */
958     BE_RSVD_1,   /* Reserved */
959     BE_RES_AVAIL,        /* Resource Available */
960     BE_CAUSE,    /* Cause */
961     BE_CELL_ID,  /* Cell Identifier */
962     BE_PRIO,     /* Priority */
963     BE_L3_HEADER_INFO,   /* Layer 3 Header Information */
964     BE_IMSI,     /* IMSI */
965     BE_TMSI,     /* TMSI */
966     BE_ENC_INFO,         /* Encryption Information */
967     BE_CHAN_TYPE,        /* Channel Type */
968     BE_PERIODICITY,      /* Periodicity */
969     BE_EXT_RES_IND,      /* Extended Resource Indicator */
970     BE_NUM_MS,   /* Number Of MSs */
971     BE_RSVD_2,   /* Reserved */
972     BE_RSVD_3,   /* Reserved */
973     BE_RSVD_4,   /* Reserved */
974     BE_CM_INFO_2,        /* Classmark Information Type 2 */
975     BE_CM_INFO_3,        /* Classmark Information Type 3 */
976     BE_INT_BAND,         /* Interference Band To Be Used */
977     BE_RR_CAUSE,         /* RR Cause */
978     BE_RSVD_5,   /* Reserved */
979     BE_L3_INFO,  /* Layer 3 Information */
980     BE_DLCI,     /* DLCI */
981     BE_DOWN_DTX_FLAG,    /* Downlink DTX Flag */
982     BE_CELL_ID_LIST,     /* Cell Identifier List */
983     BE_RESP_REQ,         /* Response Request */
984     BE_RES_IND_METHOD,   /* Resource Indication Method */
985     BE_CM_INFO_1,        /* Classmark Information Type 1 */
986     BE_CIC_LIST,         /* Circuit Identity Code List */
987     BE_DIAG,     /* Diagnostic */
988     BE_L3_MSG,   /* Layer 3 Message Contents */
989     BE_CHOSEN_CHAN,      /* Chosen Channel */
990     BE_TOT_RES_ACC,      /* Total Resource Accessible */
991     BE_CIPH_RESP_MODE,   /* Cipher Response Mode */
992     BE_CHAN_NEEDED,      /* Channel Needed */
993     BE_TRACE_TYPE,       /* Trace Type */
994     BE_TRIGGERID,        /* TriggerID */
995     BE_TRACE_REF,        /* Trace Reference */
996     BE_TRANSID,  /* TransactionID */
997     BE_MID,      /* Mobile Identity */
998     BE_OMCID,    /* OMCID */
999     BE_FOR_IND,  /* Forward Indicator */
1000     BE_CHOSEN_ENC_ALG,   /* Chosen Encryption Algorithm */
1001     BE_CCT_POOL,         /* Circuit Pool */
1002     BE_CCT_POOL_LIST,    /* Circuit Pool List */
1003     BE_TIME_IND,         /* Time Indication */
1004     BE_RES_SIT,  /* Resource Situation */
1005     BE_CURR_CHAN_1,      /* Current Channel Type 1 */
1006     BE_QUE_IND,  /* Queueing Indicator */
1007     BE_SPEECH_VER,       /* Speech Version */
1008     BE_ASS_REQ,  /* Assignment Requirement */
1009     BE_TALKER_FLAG,      /* Talker Flag */
1010     BE_CONN_REL_REQ,     /* Connection Release Requested */
1011     BE_GROUP_CALL_REF,   /* Group Call Reference */
1012     BE_EMLPP_PRIO,       /* eMLPP Priority */
1013     BE_CONF_EVO_IND,     /* Configuration Evolution Indication */
1014     BE_OLD2NEW_INFO,     /* Old BSS to New BSS Information */
1015     BE_LSA_ID,   /* LSA Identifier */
1016     BE_LSA_ID_LIST,      /* LSA Identifier List */
1017     BE_LSA_INFO,         /* LSA Information */
1018     BE_LCS_QOS,  /* LCS QoS */
1019     BE_LSA_ACC_CTRL,     /* LSA access control suppression */
1020     BE_LCS_PRIO,         /* LCS Priority */
1021     BE_LOC_TYPE,         /* Location Type */
1022     BE_LOC_EST,  /* Location Estimate */
1023     BE_POS_DATA,         /* Positioning Data */
1024     BE_LCS_CAUSE,        /* LCS Cause */
1025     BE_LCS_CLIENT,       /* LCS Client Type */
1026     BE_APDU,     /* APDU */
1027     BE_NE_ID,    /* Network Element Identity */
1028     BE_GSP_ASSIST_DATA,  /* GPS Assistance Data */
1029     BE_DECIPH_KEYS,      /* Deciphering Keys */
1030     BE_RET_ERR_REQ,      /* Return Error Request */
1031     BE_RET_ERR_CAUSE,    /* Return Error Cause */
1032     BE_SEG,      /* Segmentation */
1033     BE_NONE     /* NONE */
1034 }
1035 bssmap_elem_idx_t;
1036
1037 #define NUM_GSM_BSSMAP_ELEM (sizeof(gsm_bssmap_elem_strings)/sizeof(value_string))
1038 static gint ett_gsm_bssmap_elem[NUM_GSM_BSSMAP_ELEM];
1039
1040 /*
1041  * [2] 3.2.2.2
1042  */
1043 static guint8
1044 be_cic(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
1045 {
1046     guint32     curr_offset;
1047     guint32     value;
1048
1049     len = len;
1050     curr_offset = offset;
1051
1052     value = tvb_get_ntohs(tvb, curr_offset);
1053
1054     other_decode_bitfield_value(a_bigbuf, value, 0xffe0, 16);
1055     proto_tree_add_text(tree,
1056         tvb, curr_offset, 2,
1057         "%s :  PCM Multiplexer: %u",
1058         a_bigbuf,
1059         (value & 0xffe0) >> 5);
1060
1061     other_decode_bitfield_value(a_bigbuf, value, 0x001f, 16);
1062     proto_tree_add_text(tree,
1063         tvb, curr_offset, 2,
1064         "%s :  Timeslot: %u",
1065         a_bigbuf,
1066         value & 0x001f);
1067
1068     curr_offset += 2;
1069
1070     sprintf(add_string, " - (%u) (0x%04x)", value, value);
1071
1072     /* no length check possible */
1073
1074     return(curr_offset - offset);
1075 }
1076
1077 /*
1078  * [2] 3.2.2.5
1079  */
1080 static guint8
1081 be_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
1082 {
1083     guint8      oct;
1084     guint32     value;
1085     guint32     curr_offset;
1086     gchar       *str = NULL;
1087
1088     curr_offset = offset;
1089
1090     oct = tvb_get_guint8(tvb, curr_offset);
1091
1092     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1093     proto_tree_add_text(tree,
1094         tvb, curr_offset, 1,
1095         "%s :  Extension: %s",
1096         a_bigbuf,
1097         (oct & 0x80) ? "extended" : "not extended");
1098
1099     if (oct & 0x80)
1100     {
1101         /* 2 octet cause */
1102
1103         if ((oct & 0x0f) == 0x00)
1104         {
1105             /* national cause */
1106             switch ((oct & 0x70) >> 4)
1107             {
1108             case 0: str = "Normal Event"; break;
1109             case 1: str = "Normal Event"; break;
1110             case 2: str = "Resource Unavailable"; break;
1111             case 3: str = "Service or option not available"; break;
1112             case 4: str = "Service or option not implemented"; break;
1113             case 5: str = "Invalid message (e.g., parameter out of range)"; break;
1114             case 6: str = "Protocol error"; break;
1115             default:
1116                 str = "Interworking";
1117                 break;
1118             }
1119
1120             other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
1121             proto_tree_add_text(tree,
1122                 tvb, curr_offset, 1,
1123                 "%s :  Cause Class: %s",
1124                 a_bigbuf,
1125                 str);
1126
1127             other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
1128             proto_tree_add_text(tree,
1129                 tvb, curr_offset, 1,
1130                 "%s :  National Cause",
1131                 a_bigbuf);
1132
1133             curr_offset++;
1134
1135             proto_tree_add_text(tree, tvb, curr_offset, 1,
1136                 "Cause Value");
1137
1138             curr_offset++;
1139
1140             strcpy(add_string, " - (National Cause)");
1141         }
1142         else
1143         {
1144             value = tvb_get_guint8(tvb, curr_offset + 1);
1145
1146             other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
1147             proto_tree_add_text(tree,
1148                 tvb, curr_offset, 1,
1149                 "%s :  Cause (MSB): %u",
1150                 a_bigbuf,
1151                 ((oct & 0x7f) << 8) | value);
1152
1153             curr_offset++;
1154
1155             other_decode_bitfield_value(a_bigbuf, value, 0xff, 8);
1156             proto_tree_add_text(tree, tvb, curr_offset, 1,
1157                 "%s :  Cause (LSB)",
1158                 a_bigbuf);
1159
1160             curr_offset++;
1161         }
1162     }
1163     else
1164     {
1165         switch (oct)
1166         {
1167         case 0x00: str = "Radio interface message failure"; break;
1168         case 0x01: str = "Radio interface failure"; break;
1169         case 0x02: str = "Uplink quality"; break;
1170         case 0x03: str = "Uplink strength"; break;
1171         case 0x04: str = "Downlink quality"; break;
1172         case 0x05: str = "Downlink strength"; break;
1173         case 0x06: str = "Distance"; break;
1174         case 0x07: str = "O and M intervention"; break;
1175         case 0x08: str = "Response to MSC invocation"; break;
1176         case 0x09: str = "Call control"; break;
1177         case 0x0a: str = "Radio interface failure, reversion to old channel"; break;
1178         case 0x0b: str = "Handover successful"; break;
1179         case 0x0c: str = "Better Cell"; break;
1180         case 0x0d: str = "Directed Retry"; break;
1181         case 0x0e: str = "Joined group call channel"; break;
1182         case 0x0f: str = "Traffic"; break;
1183
1184         case 0x20: str = "Equipment failure"; break;
1185         case 0x21: str = "No radio resource available"; break;
1186         case 0x22: str = "Requested terrestrial resource unavailable"; break;
1187         case 0x23: str = "CCCH overload"; break;
1188         case 0x24: str = "Processor overload"; break;
1189         case 0x25: str = "BSS not equipped"; break;
1190         case 0x26: str = "MS not equipped"; break;
1191         case 0x27: str = "Invalid cell"; break;
1192         case 0x28: str = "Traffic Load"; break;
1193         case 0x29: str = "Preemption"; break;
1194
1195         case 0x30: str = "Requested transcoding/rate adaption unavailable"; break;
1196         case 0x31: str = "Circuit pool mismatch"; break;
1197         case 0x32: str = "Switch circuit pool"; break;
1198         case 0x33: str = "Requested speech version unavailable"; break;
1199         case 0x34: str = "LSA not allowed"; break;
1200
1201         case 0x40: str = "Ciphering algorithm not supported"; break;
1202
1203         case 0x50: str = "Terrestrial circuit already allocated"; break;
1204         case 0x51: str = "Invalid message contents"; break;
1205         case 0x52: str = "Information element or field missing"; break;
1206         case 0x53: str = "Incorrect value"; break;
1207         case 0x54: str = "Unknown Message type"; break;
1208         case 0x55: str = "Unknown Information Element"; break;
1209
1210         case 0x60: str = "Protocol Error between BSS and MSC"; break;
1211         case 0x61: str = "VGCS/VBS call non existent"; break;
1212
1213         default:
1214             if ((oct >= 0x10) && (oct <= 0x17)) { str = "Reserved for international use"; }
1215             else if ((oct >= 0x18) && (oct <= 0x1f)) { str = "Reserved for national use"; }
1216             else if ((oct >= 0x2a) && (oct <= 0x2f)) { str = "Reserved for national use"; }
1217             else if ((oct >= 0x35) && (oct <= 0x3f)) { str = "Reserved for international use"; }
1218             else if ((oct >= 0x41) && (oct <= 0x47)) { str = "Reserved for international use"; }
1219             else if ((oct >= 0x48) && (oct <= 0x4f)) { str = "Reserved for national use"; }
1220             else if ((oct >= 0x56) && (oct <= 0x57)) { str = "Reserved for international use"; }
1221             else if ((oct >= 0x58) && (oct <= 0x5f)) { str = "Reserved for national use"; }
1222             else if ((oct >= 0x62) && (oct <= 0x67)) { str = "Reserved for international use"; }
1223             else if ((oct >= 0x68) && (oct <= 0x6f)) { str = "Reserved for national use"; }
1224             else if ((oct >= 0x70) && (oct <= 0x77)) { str = "Reserved for international use"; }
1225             else if ((oct >= 0x78) && (oct <= 0x7f)) { str = "Reserved for national use"; }
1226             break;
1227         }
1228
1229         other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
1230         proto_tree_add_uint_format(tree, hf_gsm_a_bssmap_cause,
1231             tvb, curr_offset, 1, oct & 0x7f,
1232             "%s :  Cause: (%u) %s",
1233             a_bigbuf,
1234             oct & 0x7f,
1235             str);
1236
1237         curr_offset++;
1238
1239         sprintf(add_string, " - (%u) %s", oct & 0x7f, str);
1240     }
1241
1242     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
1243
1244     return(curr_offset - offset);
1245 }
1246
1247 /*
1248  * [2] 3.2.2.7
1249  */
1250 static guint8
1251 be_tmsi(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
1252 {
1253     guint32     curr_offset;
1254     guint32     value;
1255
1256     curr_offset = offset;
1257
1258     value = tvb_get_ntohl(tvb, curr_offset);
1259
1260     proto_tree_add_uint(tree, hf_gsm_a_tmsi,
1261         tvb, curr_offset, 4,
1262         value);
1263
1264     sprintf(add_string, " - (0x%04x)", value);
1265
1266     curr_offset += 4;
1267
1268     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
1269
1270     return(curr_offset - offset);
1271 }
1272
1273 /*
1274  * [2] 3.2.2.9
1275  */
1276 static guint8
1277 be_l3_header_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
1278 {
1279     guint8      oct;
1280     guint32     curr_offset;
1281
1282     add_string = add_string;
1283     curr_offset = offset;
1284
1285     oct = tvb_get_guint8(tvb, curr_offset);
1286
1287     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
1288     proto_tree_add_text(tree,
1289         tvb, curr_offset, 1,
1290         "%s :  Spare",
1291         a_bigbuf);
1292
1293     other_decode_bitfield_value(a_bigbuf, oct, DTAP_PD_MASK, 8);
1294     proto_tree_add_text(tree,
1295         tvb, curr_offset, 1,
1296         "%s :  Protocol Discriminator: %s",
1297         a_bigbuf,
1298         gsm_a_pd_str[oct & DTAP_PD_MASK]);
1299
1300     curr_offset++;
1301
1302     NO_MORE_DATA_CHECK(len);
1303
1304     oct = tvb_get_guint8(tvb, curr_offset);
1305
1306     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
1307     proto_tree_add_text(tree,
1308         tvb, curr_offset, 1,
1309         "%s :  Spare",
1310         a_bigbuf);
1311
1312     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
1313     proto_tree_add_text(tree,
1314         tvb, curr_offset, 1,
1315         "%s :  TI flag: %s",
1316         a_bigbuf,
1317         ((oct & 0x08) ?  "allocated by receiver" : "allocated by sender"));
1318
1319     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
1320     proto_tree_add_text(tree,
1321         tvb, curr_offset, 1,
1322         "%s :  TIO: %u",
1323         a_bigbuf,
1324         oct & 0x07);
1325
1326     curr_offset++;
1327
1328     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
1329
1330     return(curr_offset - offset);
1331 }
1332
1333 /*
1334  * [2] 3.2.2.10
1335  */
1336 static guint8
1337 be_enc_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
1338 {
1339     guint8      oct;
1340     guint8      mask;
1341     guint8      alg_id;
1342     guint32     curr_offset;
1343
1344     add_string = add_string;
1345     curr_offset = offset;
1346
1347     oct = tvb_get_guint8(tvb, curr_offset);
1348
1349     mask = 0x80;
1350     alg_id = 7;
1351
1352     do
1353     {
1354         other_decode_bitfield_value(a_bigbuf, oct, mask, 8);
1355         proto_tree_add_text(tree,
1356             tvb, curr_offset, 1,
1357             "%s :  GSM A5/%u: %spermitted",
1358             a_bigbuf,
1359             alg_id,
1360             (mask & oct) ? "" : "not ");
1361
1362         mask >>= 1;
1363         alg_id--;
1364     }
1365     while (mask != 0x01);
1366
1367     other_decode_bitfield_value(a_bigbuf, oct, mask, 8);
1368     proto_tree_add_text(tree,
1369         tvb, curr_offset, 1,
1370         "%s :  No encryption: %spermitted",
1371         a_bigbuf,
1372         (mask & oct) ? "" : "not ");
1373
1374     curr_offset++;
1375
1376     NO_MORE_DATA_CHECK(len);
1377
1378     proto_tree_add_text(tree,
1379         tvb, curr_offset, len - (curr_offset - offset),
1380         "Key");
1381
1382     curr_offset += len - (curr_offset - offset);
1383
1384     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
1385
1386     return(curr_offset - offset);
1387 }
1388
1389 /*
1390  * [2] 3.2.2.11
1391  */
1392 static guint8
1393 be_chan_type(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
1394 {
1395     guint8      oct;
1396     guint8      sdi;
1397     guint8      num_chan;
1398     guint32     curr_offset;
1399     gchar       *str;
1400
1401     curr_offset = offset;
1402
1403     oct = tvb_get_guint8(tvb, curr_offset);
1404
1405     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
1406     proto_tree_add_text(tree,
1407         tvb, curr_offset, 1,
1408         "%s :  Spare",
1409         a_bigbuf);
1410
1411     sdi = oct & 0x0f;
1412     switch (sdi)
1413     {
1414     case 1: str = "Speech"; break;
1415     case 2: str = "Data"; break;
1416     case 3: str = "Signalling"; break;
1417     default:
1418         str = "Reserved";
1419         break;
1420     }
1421
1422     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
1423     proto_tree_add_text(tree,
1424         tvb, curr_offset, 1,
1425         "%s :  Speech/Data Indicator: %s",
1426         a_bigbuf,
1427         str);
1428
1429     sprintf(add_string, " - (%s)", str);
1430
1431     curr_offset++;
1432
1433     NO_MORE_DATA_CHECK(len);
1434
1435     oct = tvb_get_guint8(tvb, curr_offset);
1436
1437     if (sdi == 0x01)
1438     {
1439         /* speech */
1440
1441         switch (oct)
1442         {
1443         case 0x08: str = "Full rate TCH channel Bm.  Prefer full rate TCH"; break;
1444         case 0x09: str = "Half rate TCH channel Lm.  Prefer half rate TCH"; break;
1445         case 0x0a: str = "Full or Half rate channel, Full rate preferred changes allowed after first allocation"; break;
1446         case 0x0b: str = "Full or Half rate channel, Half rate preferred changes allowed after first allocation"; break;
1447         case 0x1a: str = "Full or Half rate channel, Full rate preferred changes between full and half rate not allowed after first allocation"; break;
1448         case 0x1b: str = "Full or Half rate channel, Half rate preferred changes between full and half rate not allowed after first allocation"; break;
1449         case 0x0f: str = "Full or Half rate channel, changes allowed after first allocation"; break;
1450         case 0x1f: str = "Full or Half rate channel, changes between full and half rate not allowed after first allocation"; break;
1451         default:
1452             str = "Reserved";
1453             break;
1454         }
1455
1456         proto_tree_add_text(tree,
1457             tvb, curr_offset, 1,
1458             "Channel Rate and Type: %s",
1459             str);
1460
1461         curr_offset++;
1462
1463         NO_MORE_DATA_CHECK(len);
1464
1465         do
1466         {
1467             oct = tvb_get_guint8(tvb, curr_offset);
1468
1469             other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1470             proto_tree_add_text(tree,
1471                 tvb, curr_offset, 1,
1472                 "%s :  Extension: %s",
1473                 a_bigbuf,
1474                 (oct & 0x80) ? "extended" : "not extended");
1475
1476             switch (oct & 0x7f)
1477             {
1478             case 0x01: str = "GSM speech full rate version 1"; break;
1479             case 0x11: str = "GSM speech full rate version 2"; break;
1480             case 0x21: str = "GSM speech full rate version 3 (AMR)"; break;
1481
1482             case 0x05: str = "GSM speech half rate version 1"; break;
1483             case 0x15: str = "GSM speech half rate version 2"; break;
1484             case 0x25: str = "GSM speech half rate version 3 (AMR)"; break;
1485
1486             default:
1487                 str = "Reserved";
1488                 break;
1489             }
1490
1491             other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
1492             proto_tree_add_text(tree,
1493                 tvb, curr_offset, 1,
1494                 "%s :  Speech version identifier: %s",
1495                 a_bigbuf,
1496                 str);
1497
1498             curr_offset++;
1499         }
1500         while ((len - (curr_offset - offset)) > 0);
1501     }
1502     else if (sdi == 0x02)
1503     {
1504         /* data */
1505
1506         num_chan = 0;
1507
1508         switch (oct)
1509         {
1510         case 0x08: str = "Full rate TCH channel Bm"; break;
1511         case 0x09: str = "Half rate TCH channel Lm"; break;
1512         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;
1513         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;
1514         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;
1515         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;
1516         default:
1517             if ((oct >= 0x20) && (oct <= 0x27))
1518             {
1519                 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";
1520
1521                 num_chan = (oct - 0x20) + 1;
1522             }
1523             else if ((oct >= 0x30) && (oct <= 0x37))
1524             {
1525                 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";
1526
1527                 num_chan = (oct - 0x30) + 1;
1528             }
1529             else
1530             {
1531                 str = "Reserved";
1532             }
1533             break;
1534         }
1535
1536         if (num_chan > 0)
1537         {
1538             proto_tree_add_text(tree,
1539                 tvb, curr_offset, 1,
1540                 "Channel Rate and Type: Max channels %u, %s",
1541                 num_chan,
1542                 str);
1543         }
1544         else
1545         {
1546             proto_tree_add_text(tree,
1547                 tvb, curr_offset, 1,
1548                 "Channel Rate and Type: %s",
1549                 str);
1550         }
1551
1552         curr_offset++;
1553
1554         NO_MORE_DATA_CHECK(len);
1555
1556         oct = tvb_get_guint8(tvb, curr_offset);
1557
1558         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1559         proto_tree_add_text(tree,
1560             tvb, curr_offset, 1,
1561             "%s :  Extension: %s",
1562             a_bigbuf,
1563             (oct & 0x80) ? "extended" : "not extended");
1564
1565         other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
1566         proto_tree_add_text(tree,
1567             tvb, curr_offset, 1,
1568             "%s :  %sTransparent service",
1569             a_bigbuf,
1570             (oct & 0x40) ? "Non-" : "");
1571
1572         if (num_chan == 0)
1573         {
1574             if (oct & 0x40)
1575             {
1576                 /* non-transparent */
1577
1578                 switch (oct & 0x3f)
1579                 {
1580                 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;
1581                 case 0x18: str = "14.5 kbit/s"; break;
1582                 case 0x10: str = "12 kbits/s"; break;
1583                 case 0x11: str = "6 kbits/s"; break;
1584                 default:
1585                     str = "Reserved";
1586                     break;
1587                 }
1588             }
1589             else
1590             {
1591                 switch (oct & 0x3f)
1592                 {
1593                 case 0x18: str = "14.4 kbit/s"; break;
1594                 case 0x10: str = "9.6kbit/s"; break;
1595                 case 0x11: str = "4.8kbit/s"; break;
1596                 case 0x12: str = "2.4kbit/s"; break;
1597                 case 0x13: str = "1.2Kbit/s"; break;
1598                 case 0x14: str = "600 bit/s"; break;
1599                 case 0x15: str = "1200/75 bit/s (1200 network-to-MS / 75 MS-to-network)"; break;
1600                 default:
1601                     str = "Reserved";
1602                     break;
1603                 }
1604             }
1605         }
1606         else
1607         {
1608             if (oct & 0x40)
1609             {
1610                 /* non-transparent */
1611
1612                 switch (oct & 0x3f)
1613                 {
1614                 case 0x16: str = "58 kbit/s (4x14.5 kbit/s)"; break;
1615                 case 0x14: str = "48.0 / 43.5 kbit/s (4x12 kbit/s or 3x14.5 kbit/s)"; break;
1616                 case 0x13: str = "36.0 / 29.0 kbit/s (3x12 kbit/s or 2x14.5 kbit/s)"; break;
1617                 case 0x12: str = "24.0 / 24.0 (4x6 kbit/s or 2x12 kbit/s)"; break;
1618                 case 0x11: str = "18.0 / 14.5 kbit/s (3x6 kbit/s or 1x14.5 kbit/s)"; break;
1619                 case 0x10: str = "12.0 / 12.0 kbit/s (2x6 kbit/s or 1x12 kbit/s)"; break;
1620                 default:
1621                     str = "Reserved";
1622                     break;
1623                 }
1624             }
1625             else
1626             {
1627                 switch (oct & 0x3f)
1628                 {
1629                 case 0x1f: str = "64 kbit/s, bit transparent"; break;
1630                 case 0x1e: str = "56 kbit/s, bit transparent"; break;
1631                 case 0x1d: str = "56 kbit/s"; break;
1632                 case 0x1c: str = "48 kbit/s"; break;
1633                 case 0x1b: str = "38.4 kbit/s"; break;
1634                 case 0x1a: str = "28.8 kbit/s"; break;
1635                 case 0x19: str = "19.2 kbit/s"; break;
1636                 case 0x18: str = "14.4 kbit/s"; break;
1637                 case 0x10: str = "9.6 kbit/s"; break;
1638                 default:
1639                     str = "Reserved";
1640                     break;
1641                 }
1642             }
1643         }
1644
1645         other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
1646         proto_tree_add_text(tree,
1647             tvb, curr_offset, 1,
1648             "%s :  Rate: %s",
1649             a_bigbuf,
1650             str);
1651
1652         curr_offset++;
1653
1654         NO_MORE_DATA_CHECK(len);
1655
1656         oct = tvb_get_guint8(tvb, curr_offset);
1657
1658         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1659         proto_tree_add_text(tree,
1660             tvb, curr_offset, 1,
1661             "%s :  Extension: %s",
1662             a_bigbuf,
1663             (oct & 0x80) ? "extended" : "not extended");
1664
1665         other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
1666         proto_tree_add_text(tree,
1667             tvb, curr_offset, 1,
1668             "%s :  Spare",
1669             a_bigbuf);
1670
1671         if (num_chan == 0)
1672         {
1673             other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
1674             proto_tree_add_text(tree,
1675                 tvb, curr_offset, 1,
1676                 "%s :  14.5 kbit/s (TCH/F14.4) %sallowed",
1677                 a_bigbuf,
1678                 (oct & 0x08) ? "" : "not ");
1679
1680             other_decode_bitfield_value(a_bigbuf, oct, 0x04, 8);
1681             proto_tree_add_text(tree,
1682                 tvb, curr_offset, 1,
1683                 "%s :  Spare",
1684                 a_bigbuf);
1685
1686             other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
1687             proto_tree_add_text(tree,
1688                 tvb, curr_offset, 1,
1689                 "%s :  12.0 kbit/s (TCH F/9.6) %sallowed",
1690                 a_bigbuf,
1691                 (oct & 0x02) ? "" : "not ");
1692
1693             other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
1694             proto_tree_add_text(tree,
1695                 tvb, curr_offset, 1,
1696                 "%s :  6.0 kbit/s (TCH F/4.8) %sallowed",
1697                 a_bigbuf,
1698                 (oct & 0x01) ? "" : "not ");
1699         }
1700         else
1701         {
1702             other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
1703             proto_tree_add_text(tree,
1704                 tvb, curr_offset, 1,
1705                 "%s :  14.5/14.4 kbit/s (TCH/F14.4) %sallowed",
1706                 a_bigbuf,
1707                 (oct & 0x08) ? "" : "not ");
1708
1709             other_decode_bitfield_value(a_bigbuf, oct, 0x04, 8);
1710             proto_tree_add_text(tree,
1711                 tvb, curr_offset, 1,
1712                 "%s :  Spare",
1713                 a_bigbuf);
1714
1715             other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
1716             proto_tree_add_text(tree,
1717                 tvb, curr_offset, 1,
1718                 "%s :  12.0/9.6 kbit/s (TCH F/9.6) %sallowed",
1719                 a_bigbuf,
1720                 (oct & 0x02) ? "" : "not ");
1721
1722             other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
1723             proto_tree_add_text(tree,
1724                 tvb, curr_offset, 1,
1725                 "%s :  6.0/4.8 kbit/s (TCH F/4.8) %sallowed",
1726                 a_bigbuf,
1727                 (oct & 0x01) ? "" : "not ");
1728         }
1729
1730         curr_offset++;
1731     }
1732     else if (sdi == 0x03)
1733     {
1734         /* signalling */
1735
1736         switch (oct)
1737         {
1738         case 0x00: str = "SDCCH or Full rate TCH channel Bm or Half rate TCH channel Lm"; break;
1739         case 0x01: str = "SDCCH"; break;
1740         case 0x02: str = "SDCCH or Full rate TCH channel Bm"; break;
1741         case 0x03: str = "SDCCH or Half rate TCH channel Lm"; break;
1742         case 0x08: str = "Full rate TCH channel Bm"; break;
1743         case 0x09: str = "Half rate TCH channel Lm"; break;
1744         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;
1745         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;
1746         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;
1747         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;
1748         default:
1749             str = "Reserved";
1750             break;
1751         }
1752
1753         proto_tree_add_text(tree,
1754             tvb, curr_offset, 1,
1755             "Channel Rate and Type: %s",
1756             str);
1757
1758         curr_offset++;
1759
1760         NO_MORE_DATA_CHECK(len);
1761
1762         proto_tree_add_text(tree,
1763             tvb, curr_offset, len - (curr_offset - offset),
1764             "Spare");
1765
1766         curr_offset += len - (curr_offset - offset);
1767     }
1768     else
1769     {
1770         /* unknown format */
1771
1772         proto_tree_add_text(tree,
1773             tvb, curr_offset, len - (curr_offset - offset),
1774             "Unknown format");
1775
1776         curr_offset += len - (curr_offset - offset);
1777     }
1778
1779     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
1780
1781     return(curr_offset - offset);
1782 }
1783
1784 /*
1785  * [2] 3.2.2.17
1786  * Formats everything after the discriminator, shared function
1787  */
1788 static guint8
1789 be_cell_id_aux(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, guint8 disc)
1790 {
1791     guint8      octs[3];
1792     guint32     value;
1793     guint32     curr_offset;
1794     gchar       mcc[4];
1795     gchar       mnc[4];
1796
1797     add_string[0] = '\0';
1798     curr_offset = offset;
1799
1800     switch (disc)
1801     {
1802     case 0x00:
1803         /* FALLTHRU */
1804
1805     case 0x04:
1806         octs[0] = tvb_get_guint8(tvb, curr_offset);
1807         octs[1] = tvb_get_guint8(tvb, curr_offset + 1);
1808         octs[2] = tvb_get_guint8(tvb, curr_offset + 2);
1809
1810         mcc_mnc_aux(octs, mcc, mnc);
1811
1812         proto_tree_add_text(tree,
1813             tvb, curr_offset, 3,
1814             "Mobile Country Code (MCC): %s, Mobile Network Code (MNC): %s",
1815             mcc,
1816             mnc);
1817
1818         curr_offset += 3;
1819
1820         /* FALLTHRU */
1821
1822     case 0x01:
1823     case 0x05:
1824
1825         /* LAC */
1826
1827         value = tvb_get_ntohs(tvb, curr_offset);
1828
1829         proto_tree_add_uint(tree, hf_gsm_a_cell_lac, tvb,
1830             curr_offset, 2, value);
1831
1832         curr_offset += 2;
1833
1834         sprintf(add_string, " - LAC (0x%04x)", value);
1835
1836         if ((disc == 0x04) || (disc == 0x05)) break;
1837
1838         /* FALLTHRU */
1839
1840     case 0x02:
1841
1842         /* CI */
1843
1844         value = tvb_get_ntohs(tvb, curr_offset);
1845
1846         proto_tree_add_uint(tree, hf_gsm_a_cell_ci, tvb,
1847             curr_offset, 2, value);
1848
1849         curr_offset += 2;
1850
1851         if (add_string[0] == '\0')
1852         {
1853             sprintf(add_string, " - CI (%u)", value);
1854         }
1855         else
1856         {
1857             sprintf(add_string, "%s/CI (%u)", add_string, value);
1858         }
1859         break;
1860
1861     default:
1862         proto_tree_add_text(tree, tvb, curr_offset, len - 1,
1863             "Cell ID - Unknown format");
1864
1865         curr_offset += (len - 1);
1866         break;
1867     }
1868
1869     return(curr_offset - offset);
1870 }
1871
1872 static guint8
1873 be_cell_id(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
1874 {
1875     guint8      oct;
1876     guint8      disc;
1877     guint32     curr_offset;
1878     const gchar *str = NULL;
1879
1880     len = len;
1881     add_string = add_string;
1882     curr_offset = offset;
1883
1884     oct = tvb_get_guint8(tvb, curr_offset);
1885
1886     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
1887     proto_tree_add_text(tree,
1888         tvb, curr_offset, 1,
1889         "%s :  Spare",
1890         a_bigbuf);
1891
1892     disc = oct & 0x0f;
1893
1894     if (disc >= (gint) NUM_CELL_DISC_STR)
1895     {
1896         str = "Unknown";
1897     }
1898     else
1899     {
1900         str = cell_disc_str[disc];
1901     }
1902
1903     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
1904     proto_tree_add_text(tree,
1905         tvb, curr_offset, 1,
1906         "%s :  Cell Identification Discriminator: (%u) %s",
1907         a_bigbuf,
1908         disc,
1909         str);
1910
1911     curr_offset++;
1912
1913     NO_MORE_DATA_CHECK(len);
1914
1915     curr_offset +=
1916         be_cell_id_aux(tvb, tree, curr_offset, len - (curr_offset - offset), add_string, disc);
1917
1918     /* no length check possible */
1919
1920     return(curr_offset - offset);
1921 }
1922
1923 /*
1924  * [2] 3.2.2.18
1925  */
1926 static guint8
1927 be_prio(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
1928 {
1929     guint8      oct;
1930     guint32     curr_offset;
1931     gchar       *str;
1932
1933     len = len;
1934     curr_offset = offset;
1935
1936     oct = tvb_get_guint8(tvb, curr_offset);
1937
1938     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1939     proto_tree_add_text(tree,
1940         tvb, curr_offset, 1,
1941         "%s :  Spare",
1942         a_bigbuf);
1943
1944     other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
1945     proto_tree_add_text(tree,
1946         tvb, curr_offset, 1,
1947         "%s :  Preemption Capability Indicator (PCI): this allocation request %s preempt an existing connection",
1948         a_bigbuf,
1949         (oct & 0x40) ? "may" : "shall not");
1950
1951     switch ((oct & 0x3c) >> 2)
1952     {
1953     case 0x00: str = "Spare"; break;
1954     case 0x0f: str = "priority not used"; break;
1955     default:
1956         str = "1 is highest";
1957         break;
1958     }
1959
1960     other_decode_bitfield_value(a_bigbuf, oct, 0x3c, 8);
1961     proto_tree_add_text(tree,
1962         tvb, curr_offset, 1,
1963         "%s :  Priority Level: (%u) %s",
1964         a_bigbuf,
1965         (oct & 0x3c) >> 2,
1966         str);
1967
1968     sprintf(add_string, " - (%u)", (oct & 0x3c) >> 2);
1969
1970     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
1971     proto_tree_add_text(tree,
1972         tvb, curr_offset, 1,
1973         "%s :  Queuing Allowed Indicator (QA): queuing %sallowed",
1974         a_bigbuf,
1975         (oct & 0x02) ? "" : "not ");
1976
1977     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
1978     proto_tree_add_text(tree,
1979         tvb, curr_offset, 1,
1980         "%s :  Preemption Vulnerability Indicator (PVI): this connection %s be preempted by another allocation request",
1981         a_bigbuf,
1982         (oct & 0x01) ? "might" : "shall not");
1983
1984     curr_offset++;
1985
1986     /* no length check possible */
1987
1988     return(curr_offset - offset);
1989 }
1990
1991 /*
1992  * [2] 3.2.2.24
1993  */
1994 static guint8
1995 be_l3_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
1996 {
1997     guint32     curr_offset;
1998     tvbuff_t    *l3_tvb;
1999
2000     add_string = add_string;
2001     curr_offset = offset;
2002
2003     proto_tree_add_text(tree, tvb, curr_offset, len,
2004         "Layer 3 Information value");
2005
2006     /*
2007      * dissect the embedded DTAP message
2008      */
2009     l3_tvb = tvb_new_subset(tvb, curr_offset, len, len);
2010
2011     call_dissector(dtap_handle, l3_tvb, g_pinfo, g_tree);
2012
2013     curr_offset += len;
2014
2015     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2016
2017     return(curr_offset - offset);
2018 }
2019
2020 /*
2021  * [2] 3.2.2.25
2022  */
2023 static guint8
2024 be_dlci(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2025 {
2026     guint8      oct;
2027     guint32     curr_offset;
2028     proto_item  *item = NULL;
2029     proto_tree  *subtree = NULL;
2030
2031     len = len;
2032     add_string = add_string;
2033     curr_offset = offset;
2034
2035     item =
2036         proto_tree_add_text(tree, tvb, curr_offset, 1,
2037             "Data Link Connection Identifier");
2038
2039     subtree = proto_item_add_subtree(item, ett_dlci);
2040
2041     oct = tvb_get_guint8(tvb, curr_offset);
2042
2043     proto_tree_add_uint(subtree, hf_gsm_a_dlci_cc, tvb, curr_offset, 1, oct);
2044     proto_tree_add_uint(subtree, hf_gsm_a_dlci_spare, tvb, curr_offset, 1, oct);
2045     proto_tree_add_uint(subtree, hf_gsm_a_dlci_sapi, tvb, curr_offset, 1, oct);
2046
2047     curr_offset++;
2048
2049     /* no length check possible */
2050
2051     return(curr_offset - offset);
2052 }
2053
2054 /*
2055  * [2] 3.2.2.26
2056  */
2057 static guint8
2058 be_down_dtx_flag(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2059 {
2060     guint       oct;
2061     guint32     curr_offset;
2062
2063     len = len;
2064     add_string = add_string;
2065     curr_offset = offset;
2066
2067     oct = tvb_get_guint8(tvb, curr_offset);
2068
2069     other_decode_bitfield_value(a_bigbuf, oct, 0xfe, 8);
2070     proto_tree_add_text(tree,
2071         tvb, curr_offset, 1,
2072         "%s :  Spare",
2073         a_bigbuf);
2074
2075     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
2076     proto_tree_add_text(tree,
2077         tvb, curr_offset, 1,
2078         "%s :  BSS is %s to activate DTX in the downlink direction",
2079         a_bigbuf,
2080         (oct & 0x01) ? "forbidden" : "allowed");
2081
2082     curr_offset++;
2083
2084     /* no length check possible */
2085
2086     return(curr_offset - offset);
2087 }
2088
2089 /*
2090  * [2] 3.2.2.27
2091  */
2092 static guint8
2093 be_cell_id_list(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2094 {
2095     guint8      oct;
2096     guint8      consumed;
2097     guint8      disc;
2098     guint8      num_cells;
2099     guint32     curr_offset;
2100     proto_item  *item = NULL;
2101     proto_tree  *subtree = NULL;
2102     const gchar *str = NULL;
2103
2104     curr_offset = offset;
2105
2106     oct = tvb_get_guint8(tvb, curr_offset);
2107
2108     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2109     proto_tree_add_text(tree,
2110         tvb, curr_offset, 1,
2111         "%s :  Spare",
2112         a_bigbuf);
2113
2114     disc = oct & 0x0f;
2115
2116     if (disc >= (gint) NUM_CELL_DISC_STR)
2117     {
2118         str = "Unknown";
2119     }
2120     else
2121     {
2122         str = cell_disc_str[disc];
2123     }
2124
2125     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
2126     proto_tree_add_text(tree,
2127         tvb, curr_offset, 1,
2128         "%s :  Cell Identification Discriminator: (%u) %s",
2129         a_bigbuf,
2130         disc,
2131         str);
2132
2133     curr_offset++;
2134
2135     NO_MORE_DATA_CHECK(len);
2136
2137     num_cells = 0;
2138     do
2139     {
2140         item =
2141             proto_tree_add_text(tree,
2142                 tvb, curr_offset, -1,
2143                 "Cell %u",
2144                 num_cells + 1);
2145
2146         subtree = proto_item_add_subtree(item, ett_cell_list);
2147
2148         add_string[0] = '\0';
2149         consumed =
2150             be_cell_id_aux(tvb, subtree, curr_offset, len - (curr_offset - offset), add_string, disc);
2151
2152         if (add_string[0] != '\0')
2153         {
2154             proto_item_append_text(item, add_string);
2155         }
2156
2157         proto_item_set_len(item, consumed);
2158
2159         curr_offset += consumed;
2160
2161         num_cells++;
2162     }
2163     while ((len - (curr_offset - offset)) > 0);
2164
2165     sprintf(add_string, " - %u cell%s",
2166         num_cells, plurality(num_cells, "", "s"));
2167
2168     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2169
2170     return(curr_offset - offset);
2171 }
2172
2173 /*
2174  * [2] 3.2.2.33
2175  */
2176 static guint8
2177 be_chosen_chan(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2178 {
2179     guint8      oct;
2180     guint32     curr_offset;
2181     gchar       *str = NULL;
2182
2183     len = len;
2184     add_string = add_string;
2185     curr_offset = offset;
2186
2187     oct = tvb_get_guint8(tvb, curr_offset);
2188
2189     switch ((oct & 0xf0) >> 4)
2190     {
2191     case 0: str = "No channel mode indication"; break;
2192     case 9: str = "Speech (full rate or half rate)"; break;
2193     case 14: str = "Data, 14.5 kbit/s radio interface rate"; break;
2194     case 11: str = "Data, 12.0 kbit/s radio interface rate"; break;
2195     case 12: str = "Data, 6.0 kbit/s radio interface rate"; break;
2196     case 13: str = "Data, 3.6 kbit/s radio interface rate"; break;
2197     case 8: str = "Signalling only"; break;
2198     default:
2199         str = "Reserved";
2200         break;
2201     }
2202
2203     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2204     proto_tree_add_text(tree,
2205         tvb, curr_offset, 1,
2206         "%s :  Channel mode: %s",
2207         a_bigbuf,
2208         str);
2209
2210     switch (oct & 0x0f)
2211     {
2212     case 0: str = "None"; break;
2213     case 1: str = "SDCCH"; break;
2214     case 8: str = "1 Full rate TCH"; break;
2215     case 9: str = "1 Half rate TCH"; break;
2216     case 10: str = "2 Full Rate TCHs"; break;
2217     case 11: str = "3 Full Rate TCHs"; break;
2218     case 12: str = "4 Full Rate TCHs"; break;
2219     case 13: str = "5 Full Rate TCHs"; break;
2220     case 14: str = "6 Full Rate TCHs"; break;
2221     case 15: str = "7 Full Rate TCHs"; break;
2222     case 4: str = "8 Full Rate TCHs"; break;
2223     default:
2224         str = "Reserved";
2225         break;
2226     }
2227
2228     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
2229     proto_tree_add_text(tree,
2230         tvb, curr_offset, 1,
2231         "%s :  Channel: %s",
2232         a_bigbuf,
2233         str);
2234
2235     curr_offset++;
2236
2237     /* no length check possible */
2238
2239     return(curr_offset - offset);
2240 }
2241
2242 /*
2243  * [2] 3.2.2.34
2244  */
2245 static guint8
2246 be_ciph_resp_mode(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2247 {
2248     guint8      oct;
2249     guint32     curr_offset;
2250
2251     len = len;
2252     add_string = add_string;
2253     curr_offset = offset;
2254
2255     oct = tvb_get_guint8(tvb, curr_offset);
2256
2257     other_decode_bitfield_value(a_bigbuf, oct, 0xfe, 8);
2258     proto_tree_add_text(tree,
2259         tvb, curr_offset, 1,
2260         "%s :  Spare",
2261         a_bigbuf);
2262
2263     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
2264     proto_tree_add_text(tree,
2265         tvb, curr_offset, 1,
2266         "%s :  IMEISV must %sbe included by the mobile station",
2267         a_bigbuf,
2268         (oct & 0x01) ? "" : "not ");
2269
2270     curr_offset++;
2271
2272     /* no length check possible */
2273
2274     return(curr_offset - offset);
2275 }
2276
2277 /*
2278  * [2] 3.2.2.35
2279  */
2280 static guint8
2281 be_l3_msg(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2282 {
2283     guint32     curr_offset;
2284     tvbuff_t    *l3_tvb;
2285
2286     add_string = add_string;
2287     curr_offset = offset;
2288
2289     proto_tree_add_text(tree, tvb, curr_offset, len,
2290         "Layer 3 Message Contents");
2291
2292     /*
2293      * dissect the embedded DTAP message
2294      */
2295     l3_tvb = tvb_new_subset(tvb, curr_offset, len, len);
2296
2297     call_dissector(dtap_handle, l3_tvb, g_pinfo, g_tree);
2298
2299     curr_offset += len;
2300
2301     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2302
2303     return(curr_offset - offset);
2304 }
2305
2306 /*
2307  * [2] 3.2.2.43
2308  */
2309 static guint8
2310 be_for_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2311 {
2312     guint8      oct;
2313     guint32     curr_offset;
2314     gchar       *str = NULL;
2315
2316     len = len;
2317     add_string = add_string;
2318     curr_offset = offset;
2319
2320     oct = tvb_get_guint8(tvb, curr_offset);
2321
2322     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2323     proto_tree_add_text(tree,
2324         tvb, curr_offset, 1,
2325         "%s :  Spare",
2326         a_bigbuf);
2327
2328     switch (oct & 0x0f)
2329     {
2330     case 1: str = "forward to subsequent BSS, no trace at MSC"; break;
2331     case 2: str = "forward to subsequent BSS, and trace at MSC"; break;
2332     default:
2333         str = "Reserved";
2334         break;
2335     }
2336
2337     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
2338     proto_tree_add_text(tree,
2339         tvb, curr_offset, 1,
2340         "%s :  %s",
2341         a_bigbuf,
2342         str);
2343
2344     curr_offset++;
2345
2346     /* no length check possible */
2347
2348     return(curr_offset - offset);
2349 }
2350
2351 /*
2352  * [2] 3.2.2.44
2353  */
2354 static guint8
2355 be_chosen_enc_alg(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2356 {
2357     guint8      oct;
2358     guint32     curr_offset;
2359     gchar       *str = NULL;
2360
2361     len = len;
2362     curr_offset = offset;
2363
2364     oct = tvb_get_guint8(tvb, curr_offset);
2365
2366     switch (oct)
2367     {
2368     case 0x01: str = "No encryption used"; break;
2369     case 0x02: str = "GSM A5/1"; break;
2370     case 0x03: str = "GSM A5/2"; break;
2371     case 0x04: str = "GSM A5/3"; break;
2372     case 0x05: str = "GSM A5/4"; break;
2373     case 0x06: str = "GSM A5/5"; break;
2374     case 0x07: str = "GSM A5/6"; break;
2375     case 0x08: str = "GSM A5/7"; break;
2376     default:
2377         str = "Reserved";
2378         break;
2379     }
2380
2381     proto_tree_add_text(tree,
2382         tvb, curr_offset, 1,
2383         "Algorithm Identifier: %s",
2384         str);
2385
2386     curr_offset++;
2387
2388     sprintf(add_string, " - %s", str);
2389
2390     /* no length check possible */
2391
2392     return(curr_offset - offset);
2393 }
2394
2395 /*
2396  * [2] 3.2.2.45
2397  */
2398 static guint8
2399 be_cct_pool(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2400 {
2401     guint8      oct;
2402     guint32     curr_offset;
2403     gchar       *str = NULL;
2404
2405     len = len;
2406     curr_offset = offset;
2407
2408     oct = tvb_get_guint8(tvb, curr_offset);
2409
2410     if (oct <= 32)
2411     {
2412         str = "";
2413     }
2414     else if ((oct >= 0x80) && (oct <= 0x8f))
2415     {
2416         str = ", for national/local use";
2417     }
2418     else
2419     {
2420         str = ", reserved for future international use";
2421     }
2422
2423     proto_tree_add_text(tree,
2424         tvb, curr_offset, 1,
2425         "Circuit pool number: %u%s",
2426         oct,
2427         str);
2428
2429     curr_offset++;
2430
2431     sprintf(add_string, " - (%u)", oct);
2432
2433     /* no length check possible */
2434
2435     return(curr_offset - offset);
2436 }
2437
2438 /*
2439  * [2] 3.2.2.49
2440  */
2441 static guint8
2442 be_curr_chan_1(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2443 {
2444     guint8      oct;
2445     guint32     curr_offset;
2446     gchar       *str;
2447
2448     len = len;
2449     add_string = add_string;
2450     curr_offset = offset;
2451
2452     oct = tvb_get_guint8(tvb, curr_offset);
2453
2454     switch ((oct & 0xf0) >> 4)
2455     {
2456     case 0x00: str = "Signalling only"; break;
2457     case 0x01: str = "Speech (full rate or half rate)"; break;
2458     case 0x06: str = "Data, 14.5 kbit/s radio interface rate"; break;
2459     case 0x03: str = "Data, 12.0 kbit/s radio interface rate"; break;
2460     case 0x04: str = "Data, 6.0 kbit/s radio interface rate"; break;
2461     case 0x05: str = "Data, 3.6 kbit/s radio interface rate"; break;
2462     default:
2463         str = "Reserved";
2464         break;
2465     }
2466
2467     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2468     proto_tree_add_text(tree,
2469         tvb, curr_offset, 1,
2470         "%s :  Channel Mode: %s",
2471         a_bigbuf,
2472         str);
2473
2474     switch (oct & 0x0f)
2475     {
2476     case 0x01: str = "SDCCH"; break;
2477     case 0x08: str = "1 Full rate TCH"; break;
2478     case 0x09: str = "1 Half rate TCH"; break;
2479     case 0x0a: str = "2 Full Rate TCHs"; break;
2480     case 0x0b: str = "3 Full Rate TCHs"; break;
2481     case 0x0c: str = "4 Full Rate TCHs"; break;
2482     case 0x0d: str = "5 Full Rate TCHs"; break;
2483     case 0x0e: str = "6 Full Rate TCHs"; break;
2484     case 0x0f: str = "7 Full Rate TCHs"; break;
2485     case 0x04: str = "8 Full Rate TCHs"; break;
2486     default:
2487         str = "Reserved";
2488         break;
2489     }
2490
2491     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
2492     proto_tree_add_text(tree,
2493         tvb, curr_offset, 1,
2494         "%s :  Channel: (%u) %s",
2495         a_bigbuf,
2496         oct & 0x0f,
2497         str);
2498
2499     curr_offset++;
2500
2501     /* no length check possible */
2502
2503     return(curr_offset - offset);
2504 }
2505
2506 /*
2507  * [2] 3.2.2.50
2508  */
2509 static guint8
2510 be_que_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2511 {
2512     guint8      oct;
2513     guint32     curr_offset;
2514
2515     len = len;
2516     add_string = add_string;
2517     curr_offset = offset;
2518
2519     oct = tvb_get_guint8(tvb, curr_offset);
2520
2521     other_decode_bitfield_value(a_bigbuf, oct, 0xfc, 8);
2522     proto_tree_add_text(tree,
2523         tvb, curr_offset, 1,
2524         "%s :  Spare",
2525         a_bigbuf);
2526
2527     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
2528     proto_tree_add_text(tree,
2529         tvb, curr_offset, 1,
2530         "%s :  qri: it is recommended %sto allow queuing",
2531         a_bigbuf,
2532         (oct & 0x02) ? "" : "not ");
2533
2534     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
2535     proto_tree_add_text(tree,
2536         tvb, curr_offset, 1,
2537         "%s :  Spare",
2538         a_bigbuf);
2539
2540     curr_offset++;
2541
2542     /* no length check possible */
2543
2544     return(curr_offset - offset);
2545 }
2546
2547 /*
2548  * [2] 3.2.2.51
2549  */
2550 static guint8
2551 be_speech_ver(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2552 {
2553     guint8      oct;
2554     guint32     curr_offset;
2555     gchar       *str = NULL;
2556     gchar       *short_str = NULL;
2557
2558     len = len;
2559     curr_offset = offset;
2560
2561     oct = tvb_get_guint8(tvb, curr_offset);
2562
2563     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
2564     proto_tree_add_text(tree,
2565         tvb, curr_offset, 1,
2566         "%s :  Spare",
2567         a_bigbuf);
2568
2569     switch (oct & 0x7f)
2570     {
2571     case 0x01: str = "GSM speech full rate version 1"; short_str = "FR1"; break;
2572     case 0x11: str = "GSM speech full rate version 2"; short_str = "FR2"; break;
2573     case 0x21: str = "GSM speech full rate version 3 (AMR)"; short_str = "FR3 (AMR)"; break;
2574
2575     case 0x05: str = "GSM speech half rate version 1"; short_str = "HR1"; break;
2576     case 0x15: str = "GSM speech half rate version 2"; short_str = "HR2"; break;
2577     case 0x25: str = "GSM speech half rate version 3 (AMR)"; short_str = "HR3 (AMR)"; break;
2578
2579     default:
2580         str = "Reserved";
2581         short_str = str;
2582         break;
2583     }
2584
2585     other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
2586     proto_tree_add_text(tree,
2587         tvb, curr_offset, 1,
2588         "%s :  Speech version identifier: %s",
2589         a_bigbuf,
2590         str);
2591
2592     curr_offset++;
2593
2594     sprintf(add_string, " - (%s)", short_str);
2595
2596     /* no length check possible */
2597
2598     return(curr_offset - offset);
2599 }
2600
2601 /*
2602  * [2] 3.2.2.68
2603  */
2604 static guint8
2605 be_apdu(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2606 {
2607     guint32     curr_offset;
2608
2609     add_string = add_string;
2610     curr_offset = offset;
2611
2612     proto_tree_add_text(tree, tvb, curr_offset, len,
2613         "APDU");
2614
2615     /*
2616      * dissect the embedded APDU message
2617      * if someone writes a TS 09.31 dissector
2618      */
2619
2620     curr_offset += len;
2621
2622     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2623
2624     return(curr_offset - offset);
2625 }
2626
2627 typedef enum
2628 {
2629     /* Common Information Elements 10.5.1 */
2630     DE_CELL_ID, /* Cell Identity */
2631     DE_CIPH_KEY_SEQ_NUM,        /* Ciphering Key Sequence Number */
2632     DE_LAI,     /* Location Area Identification */
2633     DE_MID,     /* Mobile Identity */
2634     DE_MS_CM_1, /* Mobile Station Classmark 1 */
2635     DE_MS_CM_2, /* Mobile Station Classmark 2 */
2636     DE_MS_CM_3, /* Mobile Station Classmark 3 */
2637     DE_D_GB_CALL_REF,   /* Descriptive group or broadcast call reference */
2638     DE_G_CIPH_KEY_NUM,  /* Group Cipher Key Number */
2639     DE_PD_SAPI, /* PD and SAPI $(CCBS)$ */
2640     DE_PRIO,    /* Priority Level */
2641     DE_PLMN_LIST,       /* PLMN List */
2642     /* Radio Resource Management Information Elements 10.5.2, most are from 10.5.1 */
2643     DE_RR_CAUSE,        /* RR Cause */
2644     /* Mobility Management Information Elements 10.5.3 */
2645     DE_AUTH_PARAM_RAND, /* Authentication Parameter RAND */
2646     DE_AUTH_PARAM_AUTN, /* Authentication Parameter AUTN (UMTS authentication challenge only) */
2647     DE_AUTH_RESP_PARAM, /* Authentication Response Parameter */
2648     DE_AUTH_RESP_PARAM_EXT,     /* Authentication Response Parameter (extension) (UMTS authentication challenge only) */
2649     DE_AUTH_FAIL_PARAM, /* Authentication Failure Parameter (UMTS authentication challenge only) */
2650     DE_CM_SRVC_TYPE,    /* CM Service Type */
2651     DE_ID_TYPE, /* Identity Type */
2652     DE_LOC_UPD_TYPE,    /* Location Updating Type */
2653     DE_NETWORK_NAME,    /* Network Name */
2654     DE_REJ_CAUSE,       /* Reject Cause */
2655     DE_FOP,     /* Follow-on Proceed */
2656     DE_TIME_ZONE,       /* Time Zone */
2657     DE_TIME_ZONE_TIME,  /* Time Zone and Time */
2658     DE_CTS_PERM,        /* CTS Permission */
2659     DE_LSA_ID,  /* LSA Identifier */
2660     DE_DAY_SAVING_TIME, /* Daylight Saving Time */
2661     /* Call Control Information Elements 10.5.4 */
2662     DE_AUX_STATES,      /* Auxiliary States */
2663     DE_BEARER_CAP,      /* Bearer Capability */
2664     DE_CC_CAP,  /* Call Control Capabilities */
2665     DE_CALL_STATE,      /* Call State */
2666     DE_CLD_PARTY_BCD_NUM,       /* Called Party BCD Number */
2667     DE_CLD_PARTY_SUB_ADDR,      /* Called Party Subaddress */
2668     DE_CLG_PARTY_BCD_NUM,       /* Calling Party BCD Number */
2669     DE_CLG_PARTY_SUB_ADDR,      /* Calling Party Subaddress */
2670     DE_CAUSE,   /* Cause */
2671     DE_CLIR_SUP,        /* CLIR Suppression */
2672     DE_CLIR_INV,        /* CLIR Invocation */
2673     DE_CONGESTION,      /* Congestion Level */
2674     DE_CONN_NUM,        /* Connected Number */
2675     DE_CONN_SUB_ADDR,   /* Connected Subaddress */
2676     DE_FACILITY,        /* Facility */
2677     DE_HLC,     /* High Layer Compatibility */
2678     DE_KEYPAD_FACILITY, /* Keypad Facility */
2679     DE_LLC,     /* Low Layer Compatibility */
2680     DE_MORE_DATA,       /* More Data */
2681     DE_NOT_IND, /* Notification Indicator */
2682     DE_PROG_IND,        /* Progress Indicator */
2683     DE_RECALL_TYPE,     /* Recall type $(CCBS)$ */
2684     DE_RED_PARTY_BCD_NUM,       /* Redirecting Party BCD Number */
2685     DE_RED_PARTY_SUB_ADDR,      /* Redirecting Party Subaddress */
2686     DE_REPEAT_IND,      /* Repeat Indicator */
2687     DE_REV_CALL_SETUP_DIR,      /* Reverse Call Setup Direction */
2688     DE_SETUP_CONTAINER, /* SETUP Container $(CCBS)$ */
2689     DE_SIGNAL,  /* Signal */
2690     DE_SS_VER_IND,      /* SS Version Indicator */
2691     DE_USER_USER,       /* User-user */
2692     DE_ALERT_PATTERN,   /* Alerting Pattern $(NIA)$ */
2693     DE_ALLOWED_ACTIONS, /* Allowed Actions $(CCBS)$ */
2694     DE_SI,      /* Stream Identifier */
2695     DE_NET_CC_CAP,      /* Network Call Control Capabilities */
2696     DE_CAUSE_NO_CLI,    /* Cause of No CLI */
2697     DE_IMM_MOD_IND,     /* Immediate Modification Indicator */
2698     DE_SUP_CODEC_LIST,  /* Supported Codec List */
2699     DE_SRVC_CAT,        /* Service Category */
2700     /* GPRS Mobility Management Information Elements 10.5.5 */
2701     DE_ATTACH_RES,      /* Attach Result */
2702     DE_ATTACH_TYPE,     /* Attach Type */
2703     DE_TMSI_STAT,       /* TMSI Status */
2704     DE_DETACH_TYPE,     /* Detach Type */
2705     DE_DRX_PARAM,       /* DRX Parameter */
2706     DE_FORCE_TO_STAND,  /* Force to Standby */
2707     DE_P_TMSI_SIG,      /* P-TMSI Signature */
2708     DE_P_TMSI_SIG_2,    /* P-TMSI Signature 2 */
2709     DE_ID_TYPE_2,       /* Identity Type 2 */
2710     DE_IMEISV_REQ,      /* IMEISV Request */
2711     DE_REC_N_PDU_NUM_LIST,      /* Receive N-PDU Numbers List */
2712     DE_MS_NET_CAP,      /* MS Network Capability */
2713     DE_MS_RAD_ACC_CAP,  /* MS Radio Access Capability */
2714     DE_GMM_CAUSE,       /* GMM Cause */
2715     DE_RAI,     /* Routing Area Identification */
2716     DE_UPD_RES, /* Update Result */
2717     DE_AC_REF_NUM,      /* A&C Reference Number */
2718     DE_SRVC_TYPE,       /* Service Type */
2719     DE_CELL_NOT,        /* Cell Notification */
2720     DE_NET_FEAT_SUP,    /* Network Feature Support */
2721     /* Short Message Service Information Elements [5] 8.1.4 */
2722     DE_CP_USER_DATA,    /* CP-User Data */
2723     DE_CP_CAUSE,        /* CP-Cause */
2724     /* Short Message Service Information Elements [5] 8.2 */
2725     DE_RP_MESSAGE_REF,  /* RP-Message Reference */
2726     DE_RP_ORIG_ADDR,    /* RP-Origination Address */
2727     DE_RP_DEST_ADDR,    /* RP-Destination Address */
2728     DE_RP_USER_DATA,    /* RP-User Data */
2729     DE_RP_CAUSE,        /* RP-Cause */
2730     /* Session Management Information Elements 10.5.6 */
2731     DE_ACC_POINT_NAME,  /* Access Point Name */
2732     DE_NET_SAPI,        /* Network Service Access Point Identifier */
2733     DE_PRO_CONF_OPT,    /* Protocol Configuration Options */
2734     DE_PD_PRO_ADDR,     /* Packet Data Protocol Address */
2735     DE_QOS,     /* Quality Of Service */
2736     DE_SM_CAUSE,        /* SM Cause */
2737     DE_LINKED_TI,       /* Linked TI */
2738     DE_LLC_SAPI,        /* LLC Service Access Point Identifier */
2739     DE_TEAR_DOWN_IND,   /* Tear Down Indicator */
2740     DE_PACKET_FLOW_ID,  /* Packet Flow Identifier */
2741     DE_TRAFFIC_FLOW_TEMPLATE,   /* Traffic Flow Template */
2742     /* GPRS Common Information Elements 10.5.7 */
2743     DE_PDP_CONTEXT_STAT,        /* PDP Context Status */
2744     DE_RAD_PRIO,        /* Radio Priority */
2745     DE_GPRS_TIMER,      /* GPRS Timer */
2746     DE_GPRS_TIMER_2,    /* GPRS Timer 2 */
2747     DE_NONE     /* NONE */
2748 }
2749 dtap_elem_idx_t;
2750
2751 #define NUM_GSM_DTAP_ELEM (sizeof(gsm_dtap_elem_strings)/sizeof(value_string))
2752 static gint ett_gsm_dtap_elem[NUM_GSM_DTAP_ELEM];
2753
2754 /*
2755  * [3] 10.5.1.1
2756  */
2757 static guint8
2758 de_cell_id(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2759 {
2760     guint32     curr_offset;
2761
2762     curr_offset = offset;
2763
2764     curr_offset +=
2765         be_cell_id_aux(tvb, tree, offset, len, add_string, 0x02);
2766
2767     /* no length check possible */
2768
2769     return(curr_offset - offset);
2770 }
2771
2772 /*
2773  * [3] 10.5.1.3
2774  */
2775 static guint8
2776 de_lai(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2777 {
2778     guint8      octs[3];
2779     guint16     value;
2780     guint32     curr_offset;
2781     proto_tree  *subtree;
2782     proto_item  *item;
2783     gchar       mcc[4];
2784     gchar       mnc[4];
2785
2786     len = len;
2787     add_string = add_string;
2788     curr_offset = offset;
2789
2790     octs[0] = tvb_get_guint8(tvb, curr_offset);
2791     octs[1] = tvb_get_guint8(tvb, curr_offset + 1);
2792     octs[2] = tvb_get_guint8(tvb, curr_offset + 2);
2793
2794     mcc_mnc_aux(octs, mcc, mnc);
2795
2796     item =
2797         proto_tree_add_text(tree,
2798             tvb, curr_offset, 5,
2799             gsm_dtap_elem_strings[DE_LAI].strptr);
2800
2801     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_LAI]);
2802
2803     proto_tree_add_text(subtree,
2804         tvb, curr_offset, 3,
2805         "Mobile Country Code (MCC): %s, Mobile Network Code (MNC): %s",
2806         mcc,
2807         mnc);
2808
2809     curr_offset += 3;
2810
2811     value = tvb_get_ntohs(tvb, curr_offset);
2812
2813     proto_tree_add_text(subtree,
2814         tvb, curr_offset, 2,
2815         "Location Area Code (LAC): 0x%04x (%u)",
2816         value,
2817         value);
2818
2819     proto_item_append_text(item, " - LAC (0x%04x)", value);
2820
2821     curr_offset += 2;
2822
2823     /* no length check possible */
2824
2825     return(curr_offset - offset);
2826 }
2827
2828 /*
2829  * [3] 10.5.1.4
2830  */
2831 static guint8
2832 de_mid(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2833 {
2834     guint8      oct;
2835     guint32     curr_offset;
2836     guint8      *poctets;
2837     guint32     value;
2838     gboolean    odd;
2839
2840     curr_offset = offset;
2841     odd = FALSE;
2842
2843     oct = tvb_get_guint8(tvb, curr_offset);
2844
2845     switch (oct & 0x07)
2846     {
2847     case 0:     /* No Identity */
2848         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2849         proto_tree_add_text(tree,
2850             tvb, curr_offset, 1,
2851             "%s :  Unused",
2852             a_bigbuf);
2853
2854         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
2855         proto_tree_add_text(tree,
2856             tvb, curr_offset, 1,
2857             "%s :  Odd/Even Indicator: %s",
2858             a_bigbuf,
2859             (oct & 0x08) ? "ODD" : "EVEN");
2860
2861         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
2862         proto_tree_add_text(tree,
2863             tvb, curr_offset, 1,
2864             "%s :  Type of Identity: No Identity Code",
2865             a_bigbuf);
2866
2867         strcpy(add_string, " - No Identity Code");
2868
2869         curr_offset++;
2870
2871         if (len > 1)
2872         {
2873             proto_tree_add_text(tree, tvb, curr_offset, len - 1,
2874                 "Format not supported");
2875         }
2876
2877         curr_offset += len - 1;
2878         break;
2879
2880     case 3:     /* IMEISV */
2881
2882         /* FALLTHRU */
2883
2884     case 1:     /* IMSI */
2885
2886         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2887         proto_tree_add_text(tree,
2888             tvb, curr_offset, 1,
2889             "%s :  Identity Digit 1: %c",
2890             a_bigbuf,
2891             Dgt_msid.out[(oct & 0xf0) >> 4]);
2892
2893         odd = oct & 0x08;
2894
2895         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
2896         proto_tree_add_text(tree,
2897             tvb, curr_offset, 1,
2898             "%s :  Odd/Even Indicator: %s",
2899             a_bigbuf,
2900             odd ? "ODD" : "EVEN");
2901
2902         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
2903         proto_tree_add_text(tree,
2904             tvb, curr_offset, 1,
2905             "%s :  Type of Identity: %s",
2906             a_bigbuf,
2907             ((oct & 0x07) == 3) ? "IMEISV" : "IMSI");
2908
2909         a_bigbuf[0] = Dgt_msid.out[(oct & 0xf0) >> 4];
2910         curr_offset++;
2911
2912         poctets = tvb_get_string(tvb, curr_offset, len - (curr_offset - offset));
2913
2914         my_dgt_tbcd_unpack(&a_bigbuf[1], poctets, len - (curr_offset - offset),
2915             &Dgt_msid);
2916         g_free(poctets);
2917
2918         proto_tree_add_string_format(tree,
2919             ((oct & 0x07) == 3) ? hf_gsm_a_imeisv : hf_gsm_a_imsi,
2920             tvb, curr_offset, len - (curr_offset - offset),
2921             a_bigbuf,
2922             "BCD Digits: %s",
2923             a_bigbuf);
2924
2925         sprintf(add_string, " - %s (%s)",
2926             ((oct & 0x07) == 3) ? "IMEISV" : "IMSI",
2927             a_bigbuf);
2928
2929         curr_offset += len - (curr_offset - offset);
2930
2931         if (!odd)
2932         {
2933             oct = tvb_get_guint8(tvb, curr_offset - 1);
2934
2935             other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2936             proto_tree_add_text(tree,
2937                 tvb, curr_offset - 1, 1,
2938                 "%s :  Filler",
2939                 a_bigbuf);
2940         }
2941         break;
2942
2943     case 2:     /* IMEI */
2944         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2945         proto_tree_add_text(tree,
2946             tvb, curr_offset, 1,
2947             "%s :  Identity Digit 1: %c",
2948             a_bigbuf,
2949             Dgt_msid.out[(oct & 0xf0) >> 4]);
2950
2951         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
2952         proto_tree_add_text(tree,
2953             tvb, curr_offset, 1,
2954             "%s :  Odd/Even Indicator: %s",
2955             a_bigbuf,
2956             (oct & 0x08) ? "ODD" : "EVEN");
2957
2958         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
2959         proto_tree_add_text(tree,
2960             tvb, curr_offset, 1,
2961             "%s :  Type of Identity: IMEI",
2962             a_bigbuf);
2963
2964         a_bigbuf[0] = Dgt_msid.out[(oct & 0xf0) >> 4];
2965         curr_offset++;
2966
2967         poctets = tvb_get_string(tvb, curr_offset, len - (curr_offset - offset));
2968
2969         my_dgt_tbcd_unpack(&a_bigbuf[1], poctets, len - (curr_offset - offset),
2970             &Dgt_msid);
2971         g_free(poctets);
2972
2973         proto_tree_add_string_format(tree,
2974             hf_gsm_a_imei,
2975             tvb, curr_offset, len - (curr_offset - offset),
2976             a_bigbuf,
2977             "BCD Digits: %s",
2978             a_bigbuf);
2979
2980         sprintf(add_string, " - IMEI (%s)", a_bigbuf);
2981
2982         curr_offset += len - (curr_offset - offset);
2983         break;
2984
2985     case 4:     /* TMSI/P-TMSI */
2986         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2987         proto_tree_add_text(tree,
2988             tvb, curr_offset, 1,
2989             "%s :  Unused",
2990             a_bigbuf);
2991
2992         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
2993         proto_tree_add_text(tree,
2994             tvb, curr_offset, 1,
2995             "%s :  Odd/Even Indicator: %s",
2996             a_bigbuf,
2997             (oct & 0x08) ? "ODD" : "EVEN");
2998
2999         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
3000         proto_tree_add_text(tree,
3001             tvb, curr_offset, 1,
3002             "%s :  Type of Identity: TMSI/P-TMSI",
3003             a_bigbuf);
3004
3005         curr_offset++;
3006
3007         value = tvb_get_ntohl(tvb, curr_offset);
3008
3009         proto_tree_add_uint(tree, hf_gsm_a_tmsi,
3010             tvb, curr_offset, 4,
3011             value);
3012
3013         sprintf(add_string, " - TMSI/P-TMSI (0x%04x)", value);
3014
3015         curr_offset += 4;
3016         break;
3017
3018     default:    /* Reserved */
3019         proto_tree_add_text(tree, tvb, curr_offset, len,
3020             "Format Unknown");
3021
3022         strcpy(add_string, " - Format Unknown");
3023
3024         curr_offset += len;
3025         break;
3026     }
3027
3028     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3029
3030     return(curr_offset - offset);
3031 }
3032
3033 /*
3034  * [3] 10.5.1.5
3035  */
3036 static guint8
3037 de_ms_cm_1(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3038 {
3039     guint8      oct;
3040     guint32     curr_offset;
3041     proto_tree  *subtree;
3042     proto_item  *item;
3043     gchar       *str;
3044
3045     len = len;
3046     add_string = add_string;
3047     curr_offset = offset;
3048
3049     oct = tvb_get_guint8(tvb, curr_offset);
3050
3051     item =
3052         proto_tree_add_text(tree,
3053             tvb, curr_offset, 1,
3054             gsm_dtap_elem_strings[DE_MS_CM_1].strptr);
3055
3056     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_MS_CM_1]);
3057
3058     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
3059     proto_tree_add_text(subtree,
3060         tvb, curr_offset, 1,
3061         "%s :  Spare",
3062         a_bigbuf);
3063
3064     switch ((oct & 0x60) >> 5)
3065     {
3066     case 0: str = "Reserved for GSM phase 1"; break;
3067     case 1: str = "Used by GSM phase 2 mobile stations"; break;
3068     case 2: str = "Used by mobile stations supporting R99 or later versions of the protocol"; break;
3069     default:
3070         str = "Reserved for future use";
3071         break;
3072     }
3073
3074     other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
3075     proto_tree_add_text(subtree,
3076         tvb, curr_offset, 1,
3077         "%s :  Revision Level: %s",
3078         a_bigbuf,
3079         str);
3080
3081     other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
3082     proto_tree_add_text(subtree,
3083         tvb, curr_offset, 1,
3084         "%s :  ES IND: Controlled Early Classmark Sending is %simplemented",
3085         a_bigbuf,
3086         (oct & 0x10) ? "" : "not ");
3087
3088     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
3089     proto_tree_add_text(subtree,
3090         tvb, curr_offset, 1,
3091         "%s :  A5/1: encryption algorithm A5/1 %savailable",
3092         a_bigbuf,
3093         (oct & 0x08) ? "not " : "");
3094
3095     switch (oct & 0x07)
3096     {
3097     case 0: str = "Class 1"; break;
3098     case 1: str = "Class 2"; break;
3099     case 2: str = "Class 3"; break;
3100     case 3: str = "Class 4"; break;
3101     case 4: str = "Class 5"; break;
3102     default:
3103         str = "Reserved";
3104         break;
3105     }
3106
3107     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
3108     proto_tree_add_text(subtree,
3109         tvb, curr_offset, 1,
3110         "%s :  RF power capability: %s",
3111         a_bigbuf,
3112         str);
3113
3114     curr_offset++;
3115
3116     /* no length check possible */
3117
3118     return(curr_offset - offset);
3119 }
3120
3121 /*
3122  * [3] 10.5.1.6
3123  */
3124 static guint8
3125 de_ms_cm_2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3126 {
3127     guint8      oct;
3128     guint32     curr_offset;
3129     gchar       *str;
3130
3131     add_string = add_string;
3132     curr_offset = offset;
3133
3134     oct = tvb_get_guint8(tvb, curr_offset);
3135
3136     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
3137     proto_tree_add_text(tree,
3138         tvb, curr_offset, 1,
3139         "%s :  Spare",
3140         a_bigbuf);
3141
3142     switch ((oct & 0x60) >> 5)
3143     {
3144     case 0: str = "Reserved for GSM phase 1"; break;
3145     case 1: str = "Used by GSM phase 2 mobile stations"; break;
3146     case 2: str = "Used by mobile stations supporting R99 or later versions of the protocol"; break;
3147     default:
3148         str = "Reserved for future use";
3149         break;
3150     }
3151
3152     other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
3153     proto_tree_add_text(tree,
3154         tvb, curr_offset, 1,
3155         "%s :  Revision Level: %s",
3156         a_bigbuf,
3157         str);
3158
3159     other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
3160     proto_tree_add_text(tree,
3161         tvb, curr_offset, 1,
3162         "%s :  ES IND: Controlled Early Classmark Sending is %simplemented",
3163         a_bigbuf,
3164         (oct & 0x10) ? "" : "not ");
3165
3166     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
3167     proto_tree_add_text(tree,
3168         tvb, curr_offset, 1,
3169         "%s :  A5/1: encryption algorithm A5/1 %savailable",
3170         a_bigbuf,
3171         (oct & 0x08) ? "not " : "");
3172
3173     switch (oct & 0x07)
3174     {
3175     case 0: str = "Class 1"; break;
3176     case 1: str = "Class 2"; break;
3177     case 2: str = "Class 3"; break;
3178     case 3: str = "Class 4"; break;
3179     case 4: str = "Class 5"; break;
3180     default:
3181         str = "Reserved";
3182         break;
3183     }
3184
3185     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
3186     proto_tree_add_text(tree,
3187         tvb, curr_offset, 1,
3188         "%s :  RF power capability: %s",
3189         a_bigbuf,
3190         str);
3191
3192     curr_offset++;
3193
3194     NO_MORE_DATA_CHECK(len);
3195
3196     oct = tvb_get_guint8(tvb, curr_offset);
3197
3198     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
3199     proto_tree_add_text(tree,
3200         tvb, curr_offset, 1,
3201         "%s :  Spare",
3202         a_bigbuf);
3203
3204     other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
3205     proto_tree_add_text(tree,
3206         tvb, curr_offset, 1,
3207         "%s :  PS capability (pseudo-synchronization capability): %spresent",
3208         a_bigbuf,
3209         (oct & 0x40) ? "" : "not ");
3210
3211     switch ((oct & 0x30) >> 4)
3212     {
3213     case 0: str = "Default value for phase 1"; break;
3214     case 1: str = "Capability of handling of ellipsis notation and phase 2 error handling"; break;
3215     default:
3216         str = "Reserved";
3217         break;
3218     }
3219
3220     other_decode_bitfield_value(a_bigbuf, oct, 0x30, 8);
3221     proto_tree_add_text(tree,
3222         tvb, curr_offset, 1,
3223         "%s :  SS Screening Indicator: %s",
3224         a_bigbuf,
3225         str);
3226
3227     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
3228     proto_tree_add_text(tree,
3229         tvb, curr_offset, 1,
3230         "%s :  SM capability (MT SMS pt to pt capability): MS %s MT SMS",
3231         a_bigbuf,
3232         (oct & 0x08) ? "supports" : "does not support");
3233
3234     other_decode_bitfield_value(a_bigbuf, oct, 0x04, 8);
3235     proto_tree_add_text(tree,
3236         tvb, curr_offset, 1,
3237         "%s :  VBS notification reception: %s",
3238         a_bigbuf,
3239         (oct & 0x04) ?  "VBS capability and notifications wanted" :
3240             "no VBS capability or no notifications wanted");
3241
3242     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
3243     proto_tree_add_text(tree,
3244         tvb, curr_offset, 1,
3245         "%s :  VGCS notification reception: %s",
3246         a_bigbuf,
3247         (oct & 0x02) ?  "VGCS capability and notifications wanted" :
3248             "no VGCS capability or no notifications wanted");
3249
3250     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
3251     proto_tree_add_text(tree,
3252         tvb, curr_offset, 1,
3253         "%s :  FC Frequency Capability",
3254         a_bigbuf);
3255
3256     curr_offset++;
3257
3258     NO_MORE_DATA_CHECK(len);
3259
3260     oct = tvb_get_guint8(tvb, curr_offset);
3261
3262     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
3263     proto_tree_add_text(tree,
3264         tvb, curr_offset, 1,
3265         "%s :  CM3: %s",
3266         a_bigbuf,
3267         (oct & 0x80) ?
3268             "The MS supports options that are indicated in classmark 3 IE" :
3269             "The MS does not support any options that are indicated in CM3");
3270
3271     other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
3272     proto_tree_add_text(tree,
3273         tvb, curr_offset, 1,
3274         "%s :  Spare",
3275         a_bigbuf);
3276
3277     other_decode_bitfield_value(a_bigbuf, oct, 0x20, 8);
3278     proto_tree_add_text(tree,
3279         tvb, curr_offset, 1,
3280         "%s :  LCS VA capability: LCS value added location request notification capability %ssupported",
3281         a_bigbuf,
3282         (oct & 0x20) ? "" : "not ");
3283
3284     other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
3285     proto_tree_add_text(tree,
3286         tvb, curr_offset, 1,
3287         "%s :  UCS2 treatment: %s",
3288         a_bigbuf,
3289         (oct & 0x10) ?
3290             "the ME has no preference between the use of the default alphabet and the use of UCS2" :
3291             "the ME has a preference for the default alphabet (defined in 3GPP TS 03.38) over UCS2");
3292
3293     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
3294     proto_tree_add_text(tree,
3295         tvb, curr_offset, 1,
3296         "%s :  SoLSA: the ME %s SoLSA",
3297         a_bigbuf,
3298         (oct & 0x08) ? "supports" : "does not support");
3299
3300     other_decode_bitfield_value(a_bigbuf, oct, 0x04, 8);
3301     proto_tree_add_text(tree,
3302         tvb, curr_offset, 1,
3303         "%s :  CMSP (CM Service Prompt): %s",
3304         a_bigbuf,
3305         (oct & 0x04) ?
3306             "'Network initiated MO CM connection request' supported for at least one CM protocol" :
3307             "'Network initiated MO CM connection request' not supported");
3308
3309     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
3310     proto_tree_add_text(tree,
3311         tvb, curr_offset, 1,
3312         "%s :  A5/3: encryption algorithm A5/3 %savailable",
3313         a_bigbuf,
3314         (oct & 0x02) ? "" : "not ");
3315
3316     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
3317     proto_tree_add_text(tree,
3318         tvb, curr_offset, 1,
3319         "%s :  A5/2: encryption algorithm A5/2 %savailable",
3320         a_bigbuf,
3321         (oct & 0x01) ? "" : "not ");
3322
3323     curr_offset++;
3324
3325     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3326
3327     return(curr_offset - offset);
3328 }
3329
3330 /*
3331  * [3] 10.5.1.9
3332  */
3333 static guint8
3334 de_d_gb_call_ref(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3335 {
3336     guint8      oct;
3337     guint32     value;
3338     guint32     curr_offset;
3339     gchar       *str;
3340
3341     len = len;
3342     add_string = add_string;
3343     curr_offset = offset;
3344
3345     value = tvb_get_ntohl(tvb, curr_offset);
3346
3347     other_decode_bitfield_value(a_bigbuf, value, 0xffffffe0, 32);
3348     proto_tree_add_text(tree, tvb, curr_offset, 4,
3349         "%s :  Group or Broadcast call reference: %u (0x%04x)",
3350         a_bigbuf,
3351         (value & 0xffffffe0) >> 5,
3352         (value & 0xffffffe0) >> 5);
3353
3354     other_decode_bitfield_value(a_bigbuf, value, 0x00000010, 32);
3355     proto_tree_add_text(tree, tvb, curr_offset, 4,
3356         "%s :  SF Service Flag: %s",
3357         a_bigbuf,
3358         (value & 0x00000010) ?
3359             "VGCS (Group call reference)" : "VBS (Broadcast call reference)");
3360
3361     other_decode_bitfield_value(a_bigbuf, value, 0x00000008, 32);
3362     proto_tree_add_text(tree, tvb, curr_offset, 4,
3363         "%s :  AF Acknowledgement Flag: acknowledgment is %srequired",
3364         a_bigbuf,
3365         (value & 0x00000008) ? "" : "not ");
3366
3367     switch (value & 0x00000007)
3368     {
3369     case 1: str = "call priority level 4"; break;
3370     case 2: str = "call priority level 3"; break;
3371     case 3: str = "call priority level 2"; break;
3372     case 4: str = "call priority level 1"; break;
3373     case 5: str = "call priority level 0"; break;
3374     case 6: str = "call priority level B"; break;
3375     case 7: str = "call priority level A"; break;
3376     default:
3377         str = "no priority applied";
3378         break;
3379     }
3380
3381     other_decode_bitfield_value(a_bigbuf, value, 0x00000007, 32);
3382     proto_tree_add_text(tree, tvb, curr_offset, 4,
3383         "%s :  Call Priority: %s",
3384         a_bigbuf,
3385         str);
3386
3387     curr_offset += 4;
3388
3389     oct = tvb_get_guint8(tvb, curr_offset);
3390
3391     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
3392     proto_tree_add_text(tree, tvb, curr_offset, 1,
3393         "%s :  Ciphering Information",
3394         a_bigbuf);
3395
3396     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
3397     proto_tree_add_text(tree, tvb, curr_offset, 1,
3398         "%s :  Spare",
3399         a_bigbuf);
3400
3401     curr_offset++;
3402
3403     /* no length check possible */
3404
3405     return(curr_offset - offset);
3406 }
3407
3408 /*
3409  * [3] 10.5.1.10a
3410  */
3411 static guint8
3412 de_pd_sapi(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3413 {
3414     guint8      oct;
3415     guint32     curr_offset;
3416     proto_tree  *subtree;
3417     proto_item  *item;
3418     gchar       *str;
3419
3420     len = len;
3421     add_string = add_string;
3422     curr_offset = offset;
3423
3424     oct = tvb_get_guint8(tvb, curr_offset);
3425
3426     item =
3427         proto_tree_add_text(tree,
3428             tvb, curr_offset, 1,
3429             gsm_dtap_elem_strings[DE_PD_SAPI].strptr);
3430
3431     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_PD_SAPI]);
3432
3433     other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
3434     proto_tree_add_text(subtree, tvb, curr_offset, 1,
3435         "%s :  Spare",
3436         a_bigbuf);
3437
3438     switch ((oct & 0x30) >> 4)
3439     {
3440     case 0: str = "SAPI 0"; break;
3441     case 3: str = "SAPI 3"; break;
3442     default:
3443         str = "Reserved";
3444         break;
3445     }
3446
3447     other_decode_bitfield_value(a_bigbuf, oct, 0x30, 8);
3448     proto_tree_add_text(subtree, tvb, curr_offset, 1,
3449         "%s :  SAPI (Sevice Access Point Identifier): %s",
3450         a_bigbuf,
3451         str);
3452
3453     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
3454     proto_tree_add_text(subtree, tvb, curr_offset, 1,
3455         "%s :  PD (Protocol Discriminator): %s",
3456         a_bigbuf,
3457         gsm_a_pd_str[oct & 0x0f]);
3458
3459     curr_offset++;
3460
3461     /* no length check possible */
3462
3463     return(curr_offset - offset);
3464 }
3465
3466 /*
3467  * [3] 10.5.1.11
3468  */
3469 static guint8
3470 de_prio(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3471 {
3472     guint8      oct;
3473     guint32     curr_offset;
3474     gchar       *str;
3475
3476     len = len;
3477     add_string = add_string;
3478     curr_offset = offset;
3479
3480     oct = tvb_get_guint8(tvb, curr_offset);
3481
3482     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
3483     proto_tree_add_text(tree,
3484         tvb, curr_offset, 1,
3485         "%s :  Spare",
3486         a_bigbuf);
3487
3488     switch (oct & 0x07)
3489     {
3490     case 1: str = "Call priority level 4"; break;
3491     case 2: str = "Call priority level 3"; break;
3492     case 3: str = "Call priority level 2"; break;
3493     case 4: str = "Call priority level 1"; break;
3494     case 5: str = "Call priority level 0"; break;
3495     case 6: str = "Call priority level B"; break;
3496     case 7: str = "Call priority level A"; break;
3497     default:
3498         str = "No priority applied";
3499         break;
3500     }
3501
3502     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
3503     proto_tree_add_text(tree,
3504         tvb, curr_offset, 1,
3505         "%s :  %s",
3506         a_bigbuf,
3507         str);
3508
3509     curr_offset++;
3510
3511     /* no length check possible */
3512
3513     return(curr_offset - offset);
3514 }
3515
3516 /*
3517  * [3] 10.5.1.13
3518  */
3519 static guint8
3520 de_plmn_list(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3521 {
3522     guint8      octs[3];
3523     guint32     curr_offset;
3524     gchar       mcc[4];
3525     gchar       mnc[4];
3526     guint8      num_plmn;
3527
3528     add_string = add_string;
3529     curr_offset = offset;
3530
3531     num_plmn = 0;
3532     while ((len - (curr_offset - offset)) >= 3)
3533     {
3534         octs[0] = tvb_get_guint8(tvb, curr_offset);
3535         octs[1] = tvb_get_guint8(tvb, curr_offset + 1);
3536         octs[2] = tvb_get_guint8(tvb, curr_offset + 2);
3537
3538         mcc_mnc_aux(octs, mcc, mnc);
3539
3540         proto_tree_add_text(tree,
3541             tvb, curr_offset, 3,
3542             "PLMN[%u]  Mobile Country Code (MCC): %s, Mobile Network Code (MNC): %s",
3543             num_plmn + 1,
3544             mcc,
3545             mnc);
3546
3547         curr_offset += 3;
3548
3549         num_plmn++;
3550     }
3551
3552     sprintf(add_string, " - %u PLMN%s",
3553         num_plmn, plurality(num_plmn, "", "s"));
3554
3555     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3556
3557     return(curr_offset - offset);
3558 }
3559
3560 /*
3561  * [3] 10.5.2.31
3562  */
3563 static guint8
3564 de_rr_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3565 {
3566     guint8      oct;
3567     guint32     curr_offset;
3568     gchar       *str;
3569
3570     len = len;
3571     add_string = add_string;
3572     curr_offset = offset;
3573
3574     oct = tvb_get_guint8(tvb, curr_offset);
3575
3576     switch (oct)
3577     {
3578     case 0x00: str = "Normal event"; break;
3579     case 0x01: str = "Abnormal release, unspecified"; break;
3580     case 0x02: str = "Abnormal release, channel unacceptable"; break;
3581     case 0x03: str = "Abnormal release, timer expired"; break;
3582     case 0x04: str = "Abnormal release, no activity on the radio path"; break;
3583     case 0x05: str = "Preemptive release"; break;
3584     case 0x08: str = "Handover impossible, timing advance out of range"; break;
3585     case 0x09: str = "Channel mode unacceptable"; break;
3586     case 0x0a: str = "Frequency not implemented"; break;
3587     case 0x41: str = "Call already cleared"; break;
3588     case 0x5f: str = "Semantically incorrect message"; break;
3589     case 0x60: str = "Invalid mandatory information"; break;
3590     case 0x61: str = "Message type non-existent or not implemented"; break;
3591     case 0x62: str = "Message type not compatible with protocol state"; break;
3592     case 0x64: str = "Conditional IE error"; break;
3593     case 0x65: str = "No cell allocation available"; break;
3594     case 0x6f: str = "Protocol error unspecified"; break;
3595     default:
3596         str = "Reserved, treat as Normal event";
3597         break;
3598     }
3599
3600     proto_tree_add_text(tree,
3601         tvb, curr_offset, 1,
3602         "RR Cause value: 0x%02x (%u) %s",
3603         oct,
3604         oct,
3605         str);
3606
3607     curr_offset++;
3608
3609     /* no length check possible */
3610
3611     return(curr_offset - offset);
3612 }
3613
3614 /*
3615  * [3] 10.5.3.1
3616  */
3617 static guint8
3618 de_auth_param_rand(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3619 {
3620     guint32     curr_offset;
3621
3622     len = len;
3623     add_string = add_string;
3624     curr_offset = offset;
3625
3626 /*
3627  * 12 octets == 128 bits
3628  */
3629 #define AUTH_PARAM_RAND_LEN     12
3630
3631     proto_tree_add_text(tree,
3632         tvb, curr_offset, AUTH_PARAM_RAND_LEN,
3633         "RAND value");
3634
3635     curr_offset += AUTH_PARAM_RAND_LEN;
3636
3637     /* no length check possible */
3638
3639     return(curr_offset - offset);
3640 }
3641
3642 /*
3643  * [3] 10.5.3.1.1
3644  */
3645 static guint8
3646 de_auth_param_autn(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3647 {
3648     guint32     curr_offset;
3649
3650     add_string = add_string;
3651     curr_offset = offset;
3652
3653     proto_tree_add_text(tree,
3654         tvb, curr_offset, len,
3655         "AUTN value");
3656
3657     curr_offset += len;
3658
3659     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3660
3661     return(curr_offset - offset);
3662 }
3663
3664 /*
3665  * [3] 10.5.3.2
3666  */
3667 static guint8
3668 de_auth_resp_param(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3669 {
3670     guint32     curr_offset;
3671
3672     len = len;
3673     add_string = add_string;
3674     curr_offset = offset;
3675
3676 /*
3677  * 4 octets == 32 bits
3678  */
3679 #define AUTH_PARAM_RESP_LEN     4
3680
3681     proto_tree_add_text(tree,
3682         tvb, curr_offset, AUTH_PARAM_RESP_LEN,
3683         "SRES value");
3684
3685     curr_offset += AUTH_PARAM_RESP_LEN;
3686
3687     /* no length check possible */
3688
3689     return(curr_offset - offset);
3690 }
3691
3692 /*
3693  * [3] 10.5.3.2.1
3694  */
3695 static guint8
3696 de_auth_resp_param_ext(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3697 {
3698     guint32     curr_offset;
3699
3700     add_string = add_string;
3701     curr_offset = offset;
3702
3703     proto_tree_add_text(tree,
3704         tvb, curr_offset, len,
3705         "RES (extension) value");
3706
3707     curr_offset += len;
3708
3709     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3710
3711     return(curr_offset - offset);
3712 }
3713
3714 /*
3715  * [3] 10.5.3.2.2
3716  */
3717 static guint8
3718 de_auth_fail_param(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3719 {
3720     guint32     curr_offset;
3721
3722     add_string = add_string;
3723     curr_offset = offset;
3724
3725     proto_tree_add_text(tree,
3726         tvb, curr_offset, len,
3727         "AUTS value");
3728
3729     curr_offset += len;
3730
3731     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3732
3733     return(curr_offset - offset);
3734 }
3735
3736 /*
3737  * [3] 10.5.3.5a
3738  */
3739 static guint8
3740 de_network_name(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3741 {
3742     guint8      oct;
3743     guint32     curr_offset;
3744     gchar       *str;
3745
3746     add_string = add_string;
3747     curr_offset = offset;
3748
3749     oct = tvb_get_guint8(tvb, curr_offset);
3750
3751     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
3752     proto_tree_add_text(tree,
3753         tvb, curr_offset, 1,
3754         "%s :  Extension",
3755         a_bigbuf);
3756
3757     switch ((oct & 0x70) >> 4)
3758     {
3759     case 0x00: str = "Cell Broadcast data coding scheme, GSM default alphabet, language unspecified, defined in 3GPP TS 03.38"; break;
3760     case 0x01: str = "UCS2 (16 bit)"; break;
3761     default:
3762         str = "Reserved";
3763         break;
3764     }
3765
3766     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
3767     proto_tree_add_text(tree,
3768         tvb, curr_offset, 1,
3769         "%s :  Coding Scheme: %s",
3770         a_bigbuf,
3771         str);
3772
3773     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
3774     proto_tree_add_text(tree,
3775         tvb, curr_offset, 1,
3776         "%s :  Add CI: The MS should %s",
3777         a_bigbuf,
3778         (oct & 0x08) ?
3779             "add the letters for the Country's Initials and a separator (e.g. a space) to the text string" :
3780             "The MS should not add the letters for the Country's Initials to the text string");
3781
3782     switch (oct & 0x07)
3783     {
3784     case 1: str = "bit 8 is spare and set to '0' in octet n"; break;
3785     case 2: str = "bits 7 and 8 are spare and set to '0' in octet n"; break;
3786     case 3: str = "bits 6 to 8(inclusive) are spare and set to '0' in octet n"; break;
3787     case 4: str = "bits 5 to 8(inclusive) are spare and set to '0' in octet n"; break;
3788     case 5: str = "bits 4 to 8(inclusive) are spare and set to '0' in octet n"; break;
3789     case 6: str = "bits 3 to 8(inclusive) are spare and set to '0' in octet n"; break;
3790     case 7: str = "bits 2 to 8(inclusive) are spare and set to '0' in octet n"; break;
3791     default:
3792         str = "this field carries no information about the number of spare bits in octet n";
3793         break;
3794     }
3795
3796     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
3797     proto_tree_add_text(tree,
3798         tvb, curr_offset, 1,
3799         "%s :  Number of spare bits in last octet: %s",
3800         a_bigbuf,
3801         str);
3802
3803     curr_offset++;
3804
3805     NO_MORE_DATA_CHECK(len);
3806
3807     proto_tree_add_text(tree,
3808         tvb, curr_offset, len - 1,
3809         "Text string encoded according to Coding Scheme");
3810
3811     curr_offset += len - 1;
3812
3813     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3814
3815     return(curr_offset - offset);
3816 }
3817
3818 /*
3819  * [3] 10.5.3.6
3820  */
3821 static guint8
3822 de_rej_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3823 {
3824     guint8      oct;
3825     guint32     curr_offset;
3826     gchar       *str;
3827
3828     len = len;
3829     add_string = add_string;
3830     curr_offset = offset;
3831
3832     oct = tvb_get_guint8(tvb, curr_offset);
3833
3834     switch (oct)
3835     {
3836     case 0x02: str = "IMSI unknown in HLR"; break;
3837     case 0x03: str = "Illegal MS"; break;
3838     case 0x04: str = "IMSI unknown in VLR"; break;
3839     case 0x05: str = "IMEI not accepted"; break;
3840     case 0x06: str = "Illegal ME"; break;
3841     case 0x0b: str = "PLMN not allowed"; break;
3842     case 0x0c: str = "Location Area not allowed"; break;
3843     case 0x0d: str = "Roaming not allowed in this location area"; break;
3844     case 0x0f: str = "No Suitable Cells In Location Area"; break;
3845     case 0x11: str = "Network failure"; break;
3846     case 0x14: str = "MAC failure"; break;
3847     case 0x15: str = "Synch failure"; break;
3848     case 0x16: str = "Congestion"; break;
3849     case 0x17: str = "GSM authentication unacceptable"; break;
3850     case 0x20: str = "Service option not supported"; break;
3851     case 0x21: str = "Requested service option not subscribed"; break;
3852     case 0x22: str = "Service option temporarily out of order"; break;
3853     case 0x26: str = "Call cannot be identified"; break;
3854     case 0x5f: str = "Semantically incorrect message"; break;
3855     case 0x60: str = "Invalid mandatory information"; break;
3856     case 0x61: str = "Message type non-existent or not implemented"; break;
3857     case 0x62: str = "Message type not compatible with the protocol state"; break;
3858     case 0x63: str = "Information element non-existent or not implemented"; break;
3859     case 0x64: str = "Conditional IE error"; break;
3860     case 0x65: str = "Message not compatible with the protocol state"; break;
3861     case 0x6f: str = "Protocol error, unspecified"; break;
3862     default:
3863         switch (is_uplink)
3864         {
3865         case IS_UPLINK_FALSE:
3866             str = "Service option temporarily out of order";
3867             break;
3868         default:
3869             str = "Protocol error, unspecified";
3870             break;
3871         }
3872         break;
3873     }
3874
3875     proto_tree_add_text(tree,
3876         tvb, curr_offset, 1,
3877         "Reject Cause value: 0x%02x (%u) %s",
3878         oct,
3879         oct,
3880         str);
3881
3882     curr_offset++;
3883
3884     /* no length check possible */
3885
3886     return(curr_offset - offset);
3887 }
3888
3889 /*
3890  * [3] 10.5.3.8
3891  */
3892 static guint8
3893 de_time_zone(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3894 {
3895     guint8      oct;
3896     guint32     curr_offset;
3897
3898     len = len;
3899     add_string = add_string;
3900     curr_offset = offset;
3901
3902     oct = tvb_get_guint8(tvb, curr_offset);
3903
3904     proto_tree_add_text(tree,
3905         tvb, curr_offset, 1,
3906         "Time Zone: 0x%02x (%u)",
3907         oct,
3908         oct);
3909
3910     curr_offset++;
3911
3912     /* no length check possible */
3913
3914     return(curr_offset - offset);
3915 }
3916
3917 /*
3918  * [3] 10.5.3.9
3919  */
3920 static guint8
3921 de_time_zone_time(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3922 {
3923     guint8      oct, oct2, oct3;
3924     guint32     curr_offset;
3925
3926     len = len;
3927     add_string = add_string;
3928     curr_offset = offset;
3929
3930     oct = tvb_get_guint8(tvb, curr_offset);
3931     oct2 = tvb_get_guint8(tvb, curr_offset+1);
3932     oct3 = tvb_get_guint8(tvb, curr_offset+2);
3933
3934     proto_tree_add_text(tree,
3935         tvb, curr_offset, 3,
3936         "Year %u%u, Month %u%u, Day %u%u",
3937         oct & 0x0f,
3938         (oct & 0xf0) >> 4,
3939         oct2 & 0x0f,
3940         (oct2 & 0xf0) >> 4,
3941         oct3 & 0x0f,
3942         (oct3 & 0xf0) >> 4);
3943
3944     curr_offset += 3;
3945
3946     oct = tvb_get_guint8(tvb, curr_offset);
3947     oct2 = tvb_get_guint8(tvb, curr_offset+1);
3948     oct3 = tvb_get_guint8(tvb, curr_offset+2);
3949
3950     proto_tree_add_text(tree,
3951         tvb, curr_offset, 3,
3952         "Hour %u%u, Minutes %u%u, Seconds %u%u",
3953         oct & 0x0f,
3954         (oct & 0xf0) >> 4,
3955         oct2 & 0x0f,
3956         (oct2 & 0xf0) >> 4,
3957         oct3 & 0x0f,
3958         (oct3 & 0xf0) >> 4);
3959
3960     curr_offset += 3;
3961
3962     oct = tvb_get_guint8(tvb, curr_offset);
3963
3964     proto_tree_add_text(tree,
3965         tvb, curr_offset, 1,
3966         "Time Zone: 0x%02x (%u)",
3967         oct,
3968         oct);
3969
3970     curr_offset++;
3971
3972     /* no length check possible */
3973
3974     return(curr_offset - offset);
3975 }
3976
3977 /*
3978  * [3] 10.5.3.11
3979  */
3980 static guint8
3981 de_lsa_id(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3982 {
3983     guint32     curr_offset;
3984
3985     add_string = add_string;
3986     curr_offset = offset;
3987
3988     proto_tree_add_text(tree,
3989         tvb, curr_offset, len,
3990         "LSA ID");
3991
3992     curr_offset += len;
3993
3994     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3995
3996     return(curr_offset - offset);
3997 }
3998
3999 /*
4000  * [3] 10.5.3.12
4001  */
4002 static guint8
4003 de_day_saving_time(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
4004 {
4005     guint8      oct;
4006     guint32     curr_offset;
4007     gchar       *str;
4008
4009     add_string = add_string;
4010     curr_offset = offset;
4011
4012     oct = tvb_get_guint8(tvb, curr_offset);
4013
4014     other_decode_bitfield_value(a_bigbuf, oct, 0xfc, 8);
4015     proto_tree_add_text(tree,
4016         tvb, curr_offset, 1,
4017         "%s :  Spare",
4018         a_bigbuf);
4019
4020     switch (oct & 0x03)
4021     {
4022     case 0: str = "No adjustment for Daylight Saving Time"; break;
4023     case 1: str = "+1 hour adjustment for Daylight Saving Time"; break;
4024     case 2: str = "+2 hours adjustment for Daylight Saving Time"; break;
4025     default:
4026         str = "Reserved";
4027         break;
4028     }
4029
4030     other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
4031     proto_tree_add_text(tree,
4032         tvb, curr_offset, 1,
4033         "%s :  %s",
4034         a_bigbuf,
4035         str);
4036
4037     curr_offset++;
4038
4039     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
4040
4041     return(curr_offset - offset);
4042 }
4043
4044 /*
4045  * [3] 10.5.4.4
4046  */
4047 static guint8
4048 de_aux_states(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
4049 {
4050     guint8      oct;
4051     guint32     curr_offset;
4052     gchar       *str;
4053
4054     add_string = add_string;
4055     curr_offset = offset;
4056
4057     oct = tvb_get_guint8(tvb, curr_offset);
4058
4059     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
4060     proto_tree_add_text(tree,
4061         tvb, curr_offset, 1,
4062         "%s :  Extension",
4063         a_bigbuf);
4064
4065     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
4066     proto_tree_add_text(tree,
4067         tvb, curr_offset, 1,
4068         "%s :  Spare",
4069         a_bigbuf);
4070
4071     switch ((oct & 0x0c) >> 2)
4072     {
4073     case 0: str = "Idle"; break;
4074     case 1: str = "Hold request"; break;
4075     case 2: str = "Call held"; break;
4076     default:
4077         str = "Retrieve request";
4078         break;
4079     }
4080
4081     other_decode_bitfield_value(a_bigbuf, oct, 0x0c, 8);
4082     proto_tree_add_text(tree,
4083         tvb, curr_offset, 1,
4084         "%s :  Hold auxiliary state: %s",
4085         a_bigbuf,
4086         str);
4087
4088     switch (oct & 0x03)
4089     {
4090     case 0: str = "Idle"; break;
4091     case 1: str = "MPTY request"; break;
4092     case 2: str = "Call in MPTY"; break;
4093     default:
4094         str = "Split request";
4095         break;
4096     }
4097
4098     other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
4099     proto_tree_add_text(tree,
4100         tvb, curr_offset, 1,
4101         "%s :  Multi party auxiliary state: %s",
4102         a_bigbuf,
4103         str);
4104
4105     curr_offset++;
4106
4107     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
4108
4109     return(curr_offset - offset);
4110 }
4111
4112 /*
4113  * [3] 10.5.4.5
4114  */
4115 static guint8
4116 de_bearer_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
4117 {
4118     guint8      oct;
4119     guint8      itc;
4120     gboolean    extended;
4121     guint32     curr_offset;
4122     guint32     saved_offset;
4123     proto_tree  *subtree;
4124     proto_item  *item;
4125     gchar       *str;
4126
4127 #define DE_BC_ITC_SPEECH        0x00
4128 #define DE_BC_ITC_UDI           0x01
4129 #define DE_BC_ITC_EX_PLMN       0x02
4130 #define DE_BC_ITC_FASC_G3       0x03
4131 #define DE_BC_ITC_OTHER_ITC     0x05
4132 #define DE_BC_ITC_RSVD_NET      0x07
4133
4134     curr_offset = offset;
4135
4136     oct = tvb_get_guint8(tvb, curr_offset);
4137
4138     /* octet 3 */
4139
4140     /*
4141      * warning, bearer cap uses extended values that
4142      * are reversed from other parameters!
4143      */
4144     extended = (oct & 0x80) ? FALSE : TRUE;
4145     itc = oct & 0x07;
4146
4147     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
4148     proto_tree_add_text(tree,
4149         tvb, curr_offset, 1,
4150         "%s :  Extension: %s",
4151         a_bigbuf,
4152         extended ? "extended" : "not extended");
4153
4154     switch (is_uplink)
4155     {
4156     case IS_UPLINK_FALSE:
4157         str = "Spare";
4158         break;
4159
4160     case IS_UPLINK_TRUE:
4161         /*
4162          * depends on Information transfer capability
4163          */
4164         switch (itc)
4165         {
4166         case DE_BC_ITC_SPEECH:
4167             if (extended)
4168             {
4169                 switch ((oct & 0x60) >> 5)
4170                 {
4171                 case 1: str = "MS supports at least full rate speech version 1 but does not support half rate speech version 1"; break;
4172                 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;
4173                 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;
4174                 default:
4175                     str = "Reserved";
4176                     break;
4177                 }
4178                 break;
4179             }
4180             else
4181             {
4182                 switch ((oct & 0x60) >> 5)
4183                 {
4184                 case 1: str = "Full rate support only MS/fullrate speech version 1 supported"; break;
4185                 case 2: str = "Dual rate support MS/half rate speech version 1 preferred, full rate speech version 1 also supported"; break;
4186                 case 3: str = "Dual rate support MS/full rate speech version 1 preferred, half rate speech version 1 also supported"; break;
4187                 default:
4188                     str = "Reserved";
4189                     break;
4190                 }
4191                 break;
4192             }
4193             break;
4194
4195         default:
4196             switch ((oct & 0x60) >> 5)
4197             {
4198             case 1: str = "Full rate support only MS"; break;
4199             case 2: str = "Dual rate support MS/half rate preferred"; break;
4200             case 3: str = "Dual rate support MS/full rate preferred"; break;
4201             default:
4202                 str = "Reserved";
4203                 break;
4204             }
4205             break;
4206         }
4207         break;
4208
4209     default:
4210         str = "(dissect problem)";
4211         break;
4212     }
4213
4214     other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
4215     proto_tree_add_text(tree,
4216         tvb, curr_offset, 1,
4217         "%s :  Radio channel requirement: %s",
4218         a_bigbuf,
4219         str);
4220
4221     other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
4222     proto_tree_add_text(tree,
4223         tvb, curr_offset, 1,
4224         "%s :  Coding standard: %s",
4225         a_bigbuf,
4226         (oct & 0x10) ? "reserved" : "GSM standardized coding");
4227
4228     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
4229     proto_tree_add_text(tree,
4230         tvb, curr_offset, 1,
4231         "%s :  Transfer mode: %s",
4232         a_bigbuf,
4233         (oct & 0x08) ? "packet" : "circuit");
4234
4235     switch (itc)
4236     {
4237     case DE_BC_ITC_SPEECH: str = "Speech"; break;
4238     case DE_BC_ITC_UDI: str = "Unrestricted digital information"; break;
4239     case DE_BC_ITC_EX_PLMN: str = "3.1 kHz audio, ex PLMN"; break;
4240     case DE_BC_ITC_FASC_G3: str = "Facsimile group 3"; break;
4241     case DE_BC_ITC_OTHER_ITC: str = "Other ITC (See Octet 5a)"; break;
4242     case DE_BC_ITC_RSVD_NET: str = "Reserved, to be used in the network"; break;
4243     default:
4244         str = "Reserved";
4245         break;
4246     }
4247
4248     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
4249     proto_tree_add_text(tree,
4250         tvb, curr_offset, 1,
4251         "%s :  Information transfer capability: %s",
4252         a_bigbuf,
4253         str);
4254
4255     sprintf(add_string, " - (%s)", str);
4256
4257     curr_offset++;
4258
4259     NO_MORE_DATA_CHECK(len);
4260
4261     switch (itc)
4262     {
4263     case DE_BC_ITC_SPEECH:
4264         /* octets 3a */
4265
4266         item =
4267             proto_tree_add_text(tree,
4268                 tvb, curr_offset, -1,
4269                 "Octets 3a - Speech Versions");
4270
4271         subtree = proto_item_add_subtree(item, ett_bc_oct_3a);
4272
4273         saved_offset = curr_offset;
4274
4275         do
4276         {
4277             oct = tvb_get_guint8(tvb, curr_offset);
4278
4279             extended = (oct & 0x80) ? FALSE : TRUE;
4280
4281             other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
4282             proto_tree_add_text(subtree,
4283                 tvb, curr_offset, 1,
4284                 "%s :  Extension: %s",
4285                 a_bigbuf,
4286                 extended ? "extended" : "not extended");
4287
4288             other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
4289             proto_tree_add_text(subtree,
4290                 tvb, curr_offset, 1,
4291                 "%s :  Coding: octet used for %s",
4292                 a_bigbuf,
4293                 (oct & 0x40) ? "other extension of octet 3" :
4294                     "extension of information transfer capability");
4295
4296             other_decode_bitfield_value(a_bigbuf, oct, 0x30, 8);
4297             proto_tree_add_text(subtree,
4298                 tvb, curr_offset, 1,
4299                 "%s :  Spare",
4300                 a_bigbuf);
4301
4302             switch (oct & 0x0f)
4303             {
4304             case 0: str = "GSM full rate speech version 1"; break;
4305             case 2: str = "GSM full rate speech version 2"; break;
4306             case 4: str = "GSM full rate speech version 3"; break;
4307             case 1: str = "GSM half rate speech version 1"; break;
4308             case 5: str = "GSM half rate speech version 3"; break;
4309             default:
4310                 str = "Speech version TBD";
4311                 break;
4312             }
4313
4314             other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
4315             proto_tree_add_text(subtree,
4316                 tvb, curr_offset, 1,
4317                 "%s :  Speech version indication: %s",
4318                 a_bigbuf,
4319                 str);
4320
4321             curr_offset++;
4322         }
4323         while (extended &&
4324             ((len - (curr_offset - offset)) > 0));
4325
4326         proto_item_set_len(item, curr_offset - saved_offset);
4327         break;
4328
4329     default:
4330         /* octet 4 */
4331
4332         item =
4333             proto_tree_add_text(tree,
4334                 tvb, curr_offset, 1,
4335                 "Octet 4");
4336
4337         subtree = proto_item_add_subtree(item, ett_bc_oct_4);
4338
4339         oct = tvb_get_guint8(tvb, curr_offset);
4340
4341         extended = (oct & 0x80) ? FALSE : TRUE;
4342
4343         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
4344         proto_tree_add_text(subtree,
4345             tvb, curr_offset, 1,
4346             "%s :  Extension: %s",
4347             a_bigbuf,
4348             extended ? "extended" : "not extended");
4349
4350         other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
4351         proto_tree_add_text(subtree,
4352             tvb, curr_offset, 1,
4353             "%s :  Compression: data compression %s%s",
4354             a_bigbuf,
4355             (oct & 0x40) ? "" : "not ",
4356             is_uplink ? "allowed" : "possible");
4357
4358         switch ((oct & 0x30) >> 4)
4359         {
4360         case 0x00: str = "Service data unit integrity"; break;
4361         case 0x03: str = "Unstructured"; break;
4362         default:
4363             str = "Reserved";
4364             break;
4365         }
4366
4367         other_decode_bitfield_value(a_bigbuf, oct, 0x30, 8);
4368         proto_tree_add_text(subtree,
4369             tvb, curr_offset, 1,
4370             "%s :  Structure: %s",
4371             a_bigbuf,
4372             str);
4373
4374         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
4375         proto_tree_add_text(subtree,
4376             tvb, curr_offset, 1,
4377             "%s :  Duplex mode: %s",
4378             a_bigbuf,
4379             (oct & 0x08) ? "Full" : "Half");
4380
4381         other_decode_bitfield_value(a_bigbuf, oct, 0x04, 8);
4382         proto_tree_add_text(subtree,
4383             tvb, curr_offset, 1,
4384             "%s :  Configuration: %s",
4385             a_bigbuf,
4386             (oct & 0x04) ? "Reserved" : "Point-to-point");
4387
4388         other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
4389         proto_tree_add_text(subtree,
4390             tvb, curr_offset, 1,
4391             "%s :  NIRR: %s",
4392             a_bigbuf,
4393             (oct & 0x02) ?
4394                 "Data up to and including 4.8 kb/s, full rate, non-transparent, 6 kb/s radio interface rate is requested" :
4395                 "No meaning is associated with this value");
4396
4397         other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
4398         proto_tree_add_text(subtree,
4399             tvb, curr_offset, 1,
4400             "%s :  Establishment: %s",
4401             a_bigbuf,
4402             (oct & 0x01) ? "Reserved" : "Demand");
4403
4404         curr_offset++;
4405
4406         NO_MORE_DATA_CHECK(len);
4407
4408         /* octet 5 */
4409
4410         item =
4411             proto_tree_add_text(tree,
4412                 tvb, curr_offset, 1,
4413                 "Octet 5");
4414
4415         subtree = proto_item_add_subtree(item, ett_bc_oct_5);
4416
4417         oct = tvb_get_guint8(tvb, curr_offset);
4418
4419         extended = (oct & 0x80) ? FALSE : TRUE;
4420
4421         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
4422         proto_tree_add_text(subtree,
4423             tvb, curr_offset, 1,
4424             "%s :  Extension: %s",
4425             a_bigbuf,
4426             extended ? "extended" : "not extended");
4427
4428         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
4429         proto_tree_add_text(subtree,
4430             tvb, curr_offset, 1,
4431             "%s :  Access Identity: %s",
4432             a_bigbuf,
4433             (oct & 0x60) ? "Reserved" : "Octet identifier");
4434
4435         switch ((oct & 0x18) >> 3)
4436         {
4437         case 0x00: str = "No rate adaption"; break;
4438         case 0x01: str = "V.110, I.460/X.30 rate adaptation"; break;
4439         case 0x02: str = "ITU-T X.31 flag stuffing"; break;
4440         default:
4441             str = "Other rate adaption (see octet 5a)"; break;
4442             break;
4443         }
4444
4445         other_decode_bitfield_value(a_bigbuf, oct, 0x18, 8);
4446         proto_tree_add_text(subtree,
4447             tvb, curr_offset, 1,
4448             "%s :  Rate Adaption: %s",
4449             a_bigbuf,
4450             str);
4451
4452         switch (oct & 0x07)
4453         {
4454         case 0x01: str = "I.440/450"; break;
4455         case 0x02: str = "Reserved: was allocated in earlier phases of the protocol"; break;
4456         case 0x03: str = "Reserved: was allocated in earlier phases of the protocol"; break;
4457         case 0x04: str = "Reserved: was allocated in earlier phases of the protocol"; break;
4458         case 0x05: str = "Reserved: was allocated in earlier phases of the protocol"; break;
4459         case 0x06: str = "Reserved: was allocated in earlier phases of the protocol"; break;
4460         default:
4461             str = "Reserved"; break;
4462             break;
4463         }
4464
4465         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
4466         proto_tree_add_text(subtree,
4467             tvb, curr_offset, 1,
4468             "%s :  Signalling Access Protocol: %s",
4469             a_bigbuf,
4470             str);
4471
4472         curr_offset++;
4473
4474         NO_MORE_DATA_CHECK(len);
4475
4476         if (!extended) goto bc_octet_6;
4477
4478         /* octet 5a */
4479
4480         item =
4481             proto_tree_add_text(tree,
4482                 tvb, curr_offset, 1,
4483                 "Octet 5a");
4484
4485         subtree = proto_item_add_subtree(item, ett_bc_oct_5a);
4486
4487         oct = tvb_get_guint8(tvb, curr_offset);
4488
4489         extended = (oct & 0x80) ? FALSE : TRUE;
4490
4491         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
4492         proto_tree_add_text(subtree,
4493             tvb, curr_offset, 1,
4494             "%s :  Extension: %s",
4495             a_bigbuf,
4496             extended ? "extended" : "not extended");
4497
4498         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
4499         proto_tree_add_text(subtree,
4500             tvb, curr_offset, 1,
4501             "%s :  Other ITC: %s",
4502             a_bigbuf,
4503             (oct & 0x60) ? "Reserved" : "Restricted digital information");
4504
4505         switch ((oct & 0x18) >> 3)
4506         {
4507         case 0x00: str = "V.120"; break;
4508         case 0x01: str = "H.223 & H.245"; break;
4509         case 0x02: str = "PIAFS"; break;
4510         default:
4511             str = "Reserved";
4512             break;
4513         }
4514
4515         other_decode_bitfield_value(a_bigbuf, oct, 0x18, 8);
4516         proto_tree_add_text(subtree,
4517             tvb, curr_offset, 1,
4518             "%s :  Other Rate Adaption: %s",
4519             a_bigbuf,
4520             str);
4521
4522         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
4523         proto_tree_add_text(subtree,
4524             tvb, curr_offset, 1,
4525             "%s :  Spare",
4526             a_bigbuf);
4527
4528         curr_offset++;
4529
4530         NO_MORE_DATA_CHECK(len);
4531
4532         if (!extended) goto bc_octet_6;
4533
4534         /* octet 5b */
4535
4536         item =
4537             proto_tree_add_text(tree,
4538                 tvb, curr_offset, 1,
4539                 "Octet 5b");
4540
4541         subtree = proto_item_add_subtree(item, ett_bc_oct_5b);
4542
4543         extended = (oct & 0x80) ? FALSE : TRUE;
4544
4545         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
4546         proto_tree_add_text(subtree,
4547             tvb, curr_offset, 1,
4548             "%s :  Extension: %s",
4549             a_bigbuf,
4550             extended ? "extended" : "not extended");
4551
4552         other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
4553         proto_tree_add_text(subtree,
4554             tvb, curr_offset, 1,
4555             "%s :  Rate Adaption Header: %sincluded",
4556             a_bigbuf,
4557             (oct & 0x40) ? "" : "not ");
4558
4559         other_decode_bitfield_value(a_bigbuf, oct, 0x20, 8);
4560         proto_tree_add_text(subtree,
4561             tvb, curr_offset, 1,
4562             "%s :  Multiple frame establishment support in data link: %s",
4563             a_bigbuf,
4564             (oct & 0x20) ? "Supported" : "Not supported, only UI frames allowed");
4565
4566         other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
4567         proto_tree_add_text(subtree,
4568             tvb, curr_offset, 1,
4569             "%s :  Mode of operation: %s",
4570             a_bigbuf,
4571             (oct & 0x10) ? "Protocol sensitive" : "Bit transparent");
4572
4573         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
4574         proto_tree_add_text(subtree,
4575             tvb, curr_offset, 1,
4576             "%s :  Logical link identifier negotiation: %s",
4577             a_bigbuf,
4578             (oct & 0x08) ? "Full protocol negotiation" : "Default, LLI=256 only");
4579
4580         other_decode_bitfield_value(a_bigbuf, oct, 0x04, 8);
4581         proto_tree_add_text(subtree,
4582             tvb, curr_offset, 1,
4583             "%s :  Assignor/Assignee: Message originator is '%s'",
4584             a_bigbuf,
4585             (oct & 0x04) ? "assignor only" : "default assignee");
4586
4587         other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
4588         proto_tree_add_text(subtree,
4589             tvb, curr_offset, 1,
4590             "%s :  In band/Out of band negotiation: Negotiation is done %s",
4591             a_bigbuf,
4592             (oct & 0x02) ?
4593                 "with USER INFORMATION messages on a temporary signalling connection" :
4594                 "in-band using logical link zero");
4595
4596         other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
4597         proto_tree_add_text(subtree,
4598             tvb, curr_offset, 1,
4599             "%s :  Spare",
4600             a_bigbuf);
4601
4602         curr_offset++;
4603
4604         NO_MORE_DATA_CHECK(len);
4605
4606 bc_octet_6:
4607
4608         /* octet 6 */
4609
4610         item =
4611             proto_tree_add_text(tree,
4612                 tvb, curr_offset, 1,
4613                 "Octet 6");
4614
4615         subtree = proto_item_add_subtree(item, ett_bc_oct_6);
4616
4617         extended = (oct & 0x80) ? FALSE : TRUE;
4618
4619         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
4620         proto_tree_add_text(subtree,
4621             tvb, curr_offset, 1,
4622             "%s :  Extension: %s",
4623             a_bigbuf,
4624             extended ? "extended" : "not extended");
4625
4626         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
4627         proto_tree_add_text(subtree,
4628             tvb, curr_offset, 1,
4629             "%s :  Layer 1 Identity: %s",
4630             a_bigbuf,
4631             ((oct & 0x60) == 0x20) ? "Octet identifier" : "Reserved");
4632
4633         other_decode_bitfield_value(a_bigbuf, oct, 0x1e, 8);
4634         proto_tree_add_text(subtree,
4635             tvb, curr_offset, 1,
4636             "%s :  User information layer 1 protocol: %s",
4637             a_bigbuf,
4638             (oct & 0x1e) ? "Reserved" : "Default layer 1 protocol");
4639
4640         other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
4641         proto_tree_add_text(subtree,
4642             tvb, curr_offset, 1,
4643             "%s :  Synchronous/asynchronous: %s",
4644             a_bigbuf,
4645             (oct & 0x01) ? "Asynchronous" : "Synchronous");
4646
4647         curr_offset++;
4648
4649         NO_MORE_DATA_CHECK(len);
4650
4651         if (!extended) goto bc_octet_7;
4652
4653         /* octet 6a */
4654
4655         item =
4656             proto_tree_add_text(tree,
4657                 tvb, curr_offset, 1,
4658                 "Octet 6a");
4659
4660         subtree = proto_item_add_subtree(item, ett_bc_oct_6a);
4661
4662         extended = (oct & 0x80) ? FALSE : TRUE;
4663
4664         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
4665         proto_tree_add_text(subtree,
4666             tvb, curr_offset, 1,
4667             "%s :  Extension: %s",
4668             a_bigbuf,
4669             extended ? "extended" : "not extended");
4670
4671         other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
4672         proto_tree_add_text(subtree,
4673             tvb, curr_offset, 1,
4674             "%s :  Number of Stop Bits: %s",
4675             a_bigbuf,
4676             (oct & 0x40) ? "2" : "1");
4677
4678         other_decode_bitfield_value(a_bigbuf, oct, 0x20, 8);
4679         proto_tree_add_text(subtree,
4680             tvb, curr_offset, 1,
4681             "%s :  Negotiation: %s",
4682             a_bigbuf,
4683             (oct & 0x20) ? "Reserved" : "In-band negotiation not possible");
4684
4685         other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
4686         proto_tree_add_text(subtree,
4687             tvb, curr_offset, 1,
4688             "%s :  Number of data bits excluding parity bit if present: %s",
4689             a_bigbuf,
4690             (oct & 0x10) ? "8" : "7");
4691
4692         switch (oct & 0x0f)
4693         {
4694         case 0x01: str = "0.3 kbit/s Recommendation X.1 and V.110"; break;
4695         case 0x02: str = "1.2 kbit/s Recommendation X.1 and V.110"; break;
4696         case 0x03: str = "2.4 kbit/s Recommendation X.1 and V.110"; break;
4697         case 0x04: str = "4.8 kbit/s Recommendation X.1 and V.110"; break;
4698         case 0x05: str = "9.6 kbit/s Recommendation X.1 and V.110"; break;
4699         case 0x06: str = "12.0 kbit/s transparent (non compliance with X.1 and V.110)"; break;
4700         case 0x07: str = "Reserved: was allocated in earlier phases of the protocol"; break;
4701         default:
4702             str = "Reserved";
4703             break;
4704         }
4705
4706         other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
4707         proto_tree_add_text(subtree,
4708             tvb, curr_offset, 1,
4709             "%s :  User rate: %s",
4710             a_bigbuf,
4711             str);
4712
4713         curr_offset++;
4714
4715         NO_MORE_DATA_CHECK(len);
4716
4717         if (!extended) goto bc_octet_7;
4718
4719         /* octet 6b */
4720
4721         item =
4722             proto_tree_add_text(tree,
4723                 tvb, curr_offset, 1,
4724                 "Octet 6b");
4725
4726         subtree = proto_item_add_subtree(item, ett_bc_oct_6b);
4727
4728         extended = (oct & 0x80) ? FALSE : TRUE;
4729
4730         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
4731         proto_tree_add_text(subtree,
4732             tvb, curr_offset, 1,
4733             "%s :  Extension: %s",
4734             a_bigbuf,
4735             extended ? "extended" : "not extended");
4736
4737         switch ((oct & 0x60) >> 5)
4738         {
4739         case 0x02: str = "8 kbit/s"; break;
4740         case 0x03: str = "16 kbit/s"; break;
4741         default:
4742             str = "Reserved";
4743             break;
4744         }
4745
4746         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
4747         proto_tree_add_text(subtree,
4748             tvb, curr_offset, 1,
4749             "%s :  V.110/X.30 rate adaptation Intermediate rate: %s",
4750             a_bigbuf,
4751             str);
4752
4753         other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
4754         proto_tree_add_text(subtree,
4755             tvb, curr_offset, 1,
4756             "%s :  Network independent clock (NIC) on transmission (Tx): %s to send data with network independent clock",
4757             a_bigbuf,
4758             (oct & 0x10) ? "requires" : "does not require");
4759
4760         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
4761         proto_tree_add_text(subtree,
4762             tvb, curr_offset, 1,
4763             "%s :  Network independent clock (NIC) on reception (Rx): %s accept data with network independent clock",
4764             a_bigbuf,
4765             (oct & 0x08) ? "can" : "cannot");
4766
4767         switch (oct & 0x07)
4768         {
4769         case 0x00: str = "Odd"; break;
4770         case 0x02: str = "Even"; break;
4771         case 0x03: str = "None"; break;
4772         case 0x04: str = "Forced to 0"; break;
4773         case 0x05: str = "Forced to 1"; break;
4774         default:
4775             str = "Reserved";
4776             break;
4777         }
4778
4779         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
4780         proto_tree_add_text(subtree,
4781             tvb, curr_offset, 1,
4782             "%s :  Parity information: %s",
4783             a_bigbuf,
4784             str);
4785
4786         curr_offset++;
4787
4788         NO_MORE_DATA_CHECK(len);
4789
4790         if (!extended) goto bc_octet_7;
4791
4792         /* octet 6c */
4793
4794         item =
4795             proto_tree_add_text(tree,
4796                 tvb, curr_offset, 1,
4797                 "Octet 6c");
4798
4799         subtree = proto_item_add_subtree(item, ett_bc_oct_6c);
4800
4801         extended = (oct & 0x80) ? FALSE : TRUE;
4802
4803         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
4804         proto_tree_add_text(subtree,
4805             tvb, curr_offset, 1,
4806             "%s :  Extension: %s",
4807             a_bigbuf,
4808             extended ? "extended" : "not extended");
4809
4810         switch ((oct & 0x60) >> 5)
4811         {
4812         case 0x01: str = "Non transparent (RLP)"; break;
4813         case 0x02: str = "Both, transparent preferred"; break;
4814         case 0x03: str = "Both, non transparent preferred"; break;
4815         default:
4816             str = "Transparent";
4817             break;
4818         }
4819
4820         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
4821         proto_tree_add_text(subtree,
4822             tvb, curr_offset, 1,
4823             "%s :  Connection element: %s",
4824             a_bigbuf,
4825             str);
4826
4827         switch (oct & 0x1f)
4828         {
4829         case 0x00: str = "None"; break;
4830         case 0x01: str = "V.21"; break;
4831         case 0x02: str = "V.22"; break;
4832         case 0x03: str = "V.22 bis"; break;
4833         case 0x04: str = "Reserved: was allocated in earlier phases of the protocol"; break;
4834         case 0x05: str = "V.26 ter"; break;
4835         case 0x06: str = "V.32"; break;
4836         case 0x07: str = "Modem for undefined interface"; break;
4837         case 0x08: str = "Autobauding type 1"; break;
4838         default:
4839             str = "Reserved";
4840             break;
4841         }
4842
4843         other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
4844         proto_tree_add_text(subtree,
4845             tvb, curr_offset, 1,
4846             "%s :  Modem type: %s",
4847             a_bigbuf,
4848             str);
4849
4850         curr_offset++;
4851
4852         NO_MORE_DATA_CHECK(len);
4853
4854         if (!extended) goto bc_octet_7;
4855
4856         /* octet 6d */
4857
4858         item =
4859             proto_tree_add_text(tree,
4860                 tvb, curr_offset, 1,
4861                 "Octet 6d");
4862
4863         subtree = proto_item_add_subtree(item, ett_bc_oct_6d);
4864
4865         extended = (oct & 0x80) ? FALSE : TRUE;
4866
4867         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
4868         proto_tree_add_text(subtree,
4869             tvb, curr_offset, 1,
4870             "%s :  Extension: %s",
4871             a_bigbuf,
4872             extended ? "extended" : "not extended");
4873
4874         switch ((oct & 0x60) >> 5)
4875         {
4876         case 0x00: str = "No other modem type specified in this field"; break;
4877         case 0x02: str = "V.34"; break;
4878         default:
4879             str = "Reserved";
4880             break;
4881         }
4882
4883         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
4884         proto_tree_add_text(subtree,
4885             tvb, curr_offset, 1,
4886             "%s :  Other modem type: %s",
4887             a_bigbuf,
4888             str);
4889
4890         switch (oct & 0x1f)
4891         {
4892         case 0x00: str = "Fixed network user rate not applicable/No meaning is associated with this value"; break;
4893         case 0x01: str = "9.6 kbit/s Recommendation X.1 and V.110"; break;
4894         case 0x02: str = "14.4 kbit/s Recommendation X.1 and V.110"; break;
4895         case 0x03: str = "19.2 kbit/s Recommendation X.1 and V.110"; break;
4896         case 0x04: str = "28.8 kbit/s Recommendation X.1 and V.110"; break;
4897         case 0x05: str = "38.4 kbit/s Recommendation X.1 and V.110"; break;
4898         case 0x06: str = "48.0 kbit/s Recommendation X.1 and V.110(synch)"; break;
4899         case 0x07: str = "56.0 kbit/s Recommendation X.1 and V.110(synch) /bit transparent"; break;
4900         case 0x08: str = "64.0 kbit/s bit transparent"; break;
4901         case 0x09: str = "33.6 kbit/s bit transparent"; break;
4902         case 0x0a: str = "32.0 kbit/s Recommendation I.460"; break;
4903         case 0x0b: str = "31.2 kbit/s Recommendation V.34"; break;
4904         default:
4905             str = "Reserved";
4906             break;
4907         }
4908
4909         other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
4910         proto_tree_add_text(subtree,
4911             tvb, curr_offset, 1,
4912             "%s :  Fixed network user rate: %s",
4913             a_bigbuf,
4914             str);
4915
4916         curr_offset++;
4917
4918         NO_MORE_DATA_CHECK(len);
4919
4920         if (!extended) goto bc_octet_7;
4921
4922         /* octet 6e */
4923
4924         item =
4925             proto_tree_add_text(tree,
4926                 tvb, curr_offset, 1,
4927                 "Octet 6e");
4928
4929         subtree = proto_item_add_subtree(item, ett_bc_oct_6e);
4930
4931         extended = (oct & 0x80) ? FALSE : TRUE;
4932
4933         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
4934         proto_tree_add_text(subtree,
4935             tvb, curr_offset, 1,
4936             "%s :  Extension: %s",
4937             a_bigbuf,
4938             extended ? "extended" : "not extended");
4939
4940         if (is_uplink == IS_UPLINK_TRUE)
4941         {
4942             other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
4943             proto_tree_add_text(subtree,
4944                 tvb, curr_offset, 1,
4945                 "%s :  Acceptable channel codings: TCH/F14.4 %sacceptable",
4946                 a_bigbuf,
4947                 (oct & 0x40) ? "" : "not ");
4948
4949             other_decode_bitfield_value(a_bigbuf, oct, 0x20, 8);
4950             proto_tree_add_text(subtree,
4951                 tvb, curr_offset, 1,
4952                 "%s :  Acceptable channel codings: Spare",
4953                 a_bigbuf);
4954
4955             other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
4956             proto_tree_add_text(subtree,
4957                 tvb, curr_offset, 1,
4958                 "%s :  Acceptable channel codings: TCH/F9.6 %sacceptable",
4959                 a_bigbuf,
4960                 (oct & 0x10) ? "" : "not ");
4961
4962             other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
4963             proto_tree_add_text(subtree,
4964                 tvb, curr_offset, 1,
4965                 "%s :  Acceptable channel codings: TCH/F4.8 %sacceptable",
4966                 a_bigbuf,
4967                 (oct & 0x08) ? "" : "not ");
4968
4969             other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
4970             proto_tree_add_text(subtree,
4971                 tvb, curr_offset, 1,
4972                 "%s :  Maximum number of traffic channels: %u TCH",
4973                 a_bigbuf,
4974                 (oct & 0x07) + 1);
4975         }
4976         else
4977         {
4978             other_decode_bitfield_value(a_bigbuf, oct, 0x78, 8);
4979             proto_tree_add_text(subtree,
4980                 tvb, curr_offset, 1,
4981                 "%s :  Acceptable channel codings: Spare",
4982                 a_bigbuf);
4983
4984             other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
4985             proto_tree_add_text(subtree,
4986                 tvb, curr_offset, 1,
4987                 "%s :  Maximum number of traffic channels: Spare",
4988                 a_bigbuf);
4989         }
4990
4991         curr_offset++;
4992
4993         NO_MORE_DATA_CHECK(len);
4994
4995         if (!extended) goto bc_octet_7;
4996
4997         /* octet 6f */
4998
4999         item =
5000             proto_tree_add_text(tree,
5001                 tvb, curr_offset, 1,
5002                 "Octet 6f");
5003
5004         subtree = proto_item_add_subtree(item, ett_bc_oct_6f);
5005
5006         extended = (oct & 0x80) ? FALSE : TRUE;
5007
5008         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
5009         proto_tree_add_text(subtree,
5010             tvb, curr_offset, 1,
5011             "%s :  Extension: %s",
5012             a_bigbuf,
5013             extended ? "extended" : "not extended");
5014
5015         switch ((oct & 0x70) >> 4)
5016         {
5017         case 0x00: str = "not allowed/required/applicable"; break;
5018         case 0x01: str = "up to 1 TCH/F allowed/may be requested"; break;
5019         case 0x02: str = "up to 2 TCH/F allowed/may be requested"; break;
5020         case 0x03: str = "up to 3 TCH/F allowed/may be requested"; break;
5021         case 0x04: str = "up to 4 TCH/F allowed/may be requested"; break;
5022         default:
5023             str = "up to 4 TCH/F may be requested";
5024             break;
5025         }
5026
5027         other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
5028         proto_tree_add_text(subtree,
5029             tvb, curr_offset, 1,
5030             "%s :  UIMI, User initiated modification indication: %s",
5031             a_bigbuf,
5032             str);
5033
5034         if (is_uplink == IS_UPLINK_TRUE)
5035         {
5036             switch (oct & 0x0f)
5037             {
5038             case 0x00: str = "Air interface user rate not applicable/No meaning associated with this value"; break;
5039             case 0x01: str = "9.6 kbit/s"; break;
5040             case 0x02: str = "14.4 kbit/s"; break;
5041             case 0x03: str = "19.2 kbit/s"; break;
5042             case 0x05: str = "28.8 kbit/s"; break;
5043             case 0x06: str = "38.4 kbit/s"; break;
5044             case 0x07: str = "43.2 kbit/s"; break;
5045             case 0x08: str = "57.6 kbit/s"; break;
5046             case 0x09: str = "interpreted by the network as 38.4 kbit/s in this version of the protocol"; break;
5047             case 0x0a: str = "interpreted by the network as 38.4 kbit/s in this version of the protocol"; break;
5048             case 0x0b: str = "interpreted by the network as 38.4 kbit/s in this version of the protocol"; break;
5049             case 0x0c: str = "interpreted by the network as 38.4 kbit/s in this version of the protocol"; break;
5050             default:
5051                 str = "Reserved";
5052                 break;
5053             }
5054
5055             other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
5056             proto_tree_add_text(subtree,
5057                 tvb, curr_offset, 1,
5058                 "%s :  Wanted air interface user rate: %s",
5059                 a_bigbuf,
5060                 str);
5061         }
5062         else
5063         {
5064             other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
5065             proto_tree_add_text(subtree,
5066                 tvb, curr_offset, 1,
5067                 "%s :  Wanted air interface user rate: Spare",
5068                 a_bigbuf);
5069         }
5070
5071         curr_offset++;
5072
5073         NO_MORE_DATA_CHECK(len);
5074
5075         if (!extended) goto bc_octet_7;
5076
5077         /* octet 6g */
5078
5079         item =
5080             proto_tree_add_text(tree,
5081                 tvb, curr_offset, 1,
5082                 "Octet 6g");
5083
5084         subtree = proto_item_add_subtree(item, ett_bc_oct_6g);
5085
5086         extended = (oct & 0x80) ? FALSE : TRUE;
5087
5088         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
5089         proto_tree_add_text(subtree,
5090             tvb, curr_offset, 1,
5091             "%s :  Extension: %s",
5092             a_bigbuf,
5093             extended ? "extended" : "not extended");
5094
5095         if (is_uplink == IS_UPLINK_TRUE)
5096         {
5097             other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
5098             proto_tree_add_text(subtree,
5099                 tvb, curr_offset, 1,
5100                 "%s :  Acceptable channel codings extended: TCH/F28.8 %sacceptable",
5101                 a_bigbuf,
5102                 (oct & 0x40) ? "" : "not ");
5103
5104             other_decode_bitfield_value(a_bigbuf, oct, 0x20, 8);
5105             proto_tree_add_text(subtree,
5106                 tvb, curr_offset, 1,
5107                 "%s :  Acceptable channel codings extended: TCH/F32.0 %sacceptable",
5108                 a_bigbuf,
5109                 (oct & 0x20) ? "" : "not ");
5110
5111             other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
5112             proto_tree_add_text(subtree,
5113                 tvb, curr_offset, 1,
5114                 "%s :  Acceptable channel codings extended: TCH/F43.2 %sacceptable",
5115                 a_bigbuf,
5116                 (oct & 0x10) ? "" : "not ");
5117
5118             other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
5119             proto_tree_add_text(subtree,
5120                 tvb, curr_offset, 1,
5121                 "%s :  Acceptable channel codings extended: TCH/F43.2 %sacceptable",
5122                 a_bigbuf,
5123                 (oct & 0x10) ? "" : "not ");
5124
5125             switch ((oct & 0x0c) >> 2)
5126             {
5127             case 0: str = "Channel coding symmetry preferred"; break;
5128             case 2: str = "Downlink biased channel coding asymmetry is preferred"; break;
5129             case 1: str = "Uplink biased channel coding asymmetry is preferred"; break;
5130             default:
5131                 str = "Unused, treat as Channel coding symmetry preferred";
5132                 break;
5133             }
5134
5135             other_decode_bitfield_value(a_bigbuf, oct, 0x0c, 8);
5136             proto_tree_add_text(subtree,
5137                 tvb, curr_offset, 1,
5138                 "%s :  Channel Coding Asymmetry Indication: %s",
5139                 a_bigbuf,
5140                 str);
5141         }
5142         else
5143         {
5144             other_decode_bitfield_value(a_bigbuf, oct, 0x7c, 8);
5145             proto_tree_add_text(subtree,
5146                 tvb, curr_offset, 1,
5147                 "%s :  EDGE Channel Codings: Spare",
5148                 a_bigbuf);
5149         }
5150
5151         other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
5152         proto_tree_add_text(subtree,
5153             tvb, curr_offset, 1,
5154             "%s :  Spare",
5155             a_bigbuf);
5156
5157         curr_offset++;
5158
5159         NO_MORE_DATA_CHECK(len);
5160
5161 bc_octet_7:
5162
5163         /* octet 7 */
5164
5165         item =
5166             proto_tree_add_text(tree,
5167                 tvb, curr_offset, 1,
5168                 "Octet 7");
5169
5170         subtree = proto_item_add_subtree(item, ett_bc_oct_7);
5171
5172         extended = (oct & 0x80) ? FALSE : TRUE;
5173
5174         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
5175         proto_tree_add_text(subtree,
5176             tvb, curr_offset, 1,
5177             "%s :  Extension: %s",
5178             a_bigbuf,
5179             extended ? "extended" : "not extended");
5180
5181         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
5182         proto_tree_add_text(subtree,
5183             tvb, curr_offset, 1,
5184             "%s :  Layer 2 Identity: %s",
5185             a_bigbuf,
5186             ((oct & 0x60) == 0x40) ? "Octet identifier" : "Reserved");
5187
5188         switch (oct & 0x1f)
5189         {
5190         case 0x06: str = "Reserved: was allocated in earlier phases of the protocol"; break;
5191         case 0x08: str = "ISO 6429, codeset 0 (DC1/DC3)"; break;
5192         case 0x09: str = "Reserved: was allocated but never used in earlier phases of the protocol"; break;
5193         case 0x0a: str = "Videotex profile 1"; break;
5194         case 0x0c: str = "COPnoFlCt (Character oriented Protocol with no Flow Control mechanism)"; break;
5195         case 0x0d: str = "Reserved: was allocated in earlier phases of the protocol"; break;
5196         default:
5197             str = "Reserved";
5198             break;
5199         }
5200
5201         other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
5202         proto_tree_add_text(subtree,
5203             tvb, curr_offset, 1,
5204             "%s :  User information layer 2 protocol: %s",
5205             a_bigbuf,
5206             str);
5207         break;
5208     }
5209
5210     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5211
5212     return(curr_offset - offset);
5213 }
5214
5215 /*
5216  * [3] 10.5.4.5a
5217  */
5218 static guint8
5219 de_cc_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
5220 {
5221     guint8      oct;
5222     guint32     curr_offset;
5223
5224     add_string = add_string;
5225     curr_offset = offset;
5226
5227     oct = tvb_get_guint8(tvb, curr_offset);
5228
5229     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
5230
5231     switch ((oct & 0xf0) >> 4)
5232     {
5233     case 0:
5234         proto_tree_add_text(tree,
5235             tvb, curr_offset, 1,
5236             "%s :  Maximum number of supported bearers: 1",
5237             a_bigbuf);
5238         break;
5239
5240     default:
5241         proto_tree_add_text(tree,
5242             tvb, curr_offset, 1,
5243             "%s :  Maximum number of supported bearers: %u",
5244             a_bigbuf,
5245             (oct & 0xf0) >> 4);
5246         break;
5247     }
5248
5249     other_decode_bitfield_value(a_bigbuf, oct, 0x0c, 8);
5250     proto_tree_add_text(tree,
5251         tvb, curr_offset, 1,
5252         "%s :  Spare",
5253         a_bigbuf);
5254
5255     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
5256     proto_tree_add_text(tree,
5257         tvb, curr_offset, 1,
5258         "%s :  PCP: the mobile station %s the Prolonged Clearing Procedure",
5259         a_bigbuf,
5260         (oct & 0x02) ? "supports" : "does not support");
5261
5262     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
5263     proto_tree_add_text(tree,
5264         tvb, curr_offset, 1,
5265         "%s :  DTMF: %s",
5266         a_bigbuf,
5267         (oct & 0x01) ?
5268             "the mobile station supports DTMF as specified in subclause 5.5.7 of TS 24.008" :
5269             "reserved for earlier versions of the protocol");
5270
5271     curr_offset++;
5272
5273     NO_MORE_DATA_CHECK(len);
5274
5275     oct = tvb_get_guint8(tvb, curr_offset);
5276
5277     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
5278     proto_tree_add_text(tree,
5279         tvb, curr_offset, 1,
5280         "%s :  Spare",
5281         a_bigbuf);
5282
5283     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
5284     proto_tree_add_text(tree,
5285         tvb, curr_offset, 1,
5286         "%s :  Maximum number of speech bearers: %u",
5287         a_bigbuf,
5288         oct & 0x0f);
5289
5290     curr_offset++;
5291
5292     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5293
5294     return(curr_offset - offset);
5295 }
5296
5297 /*
5298  * [3] 10.5.4.6
5299  */
5300 static guint8
5301 de_call_state(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
5302 {
5303     guint8      oct;
5304     guint32     curr_offset;
5305     proto_tree  *subtree;
5306     proto_item  *item;
5307     gchar       *str;
5308
5309     len = len;
5310     add_string = add_string;
5311     curr_offset = offset;
5312
5313     oct = tvb_get_guint8(tvb, curr_offset);
5314
5315     item =
5316         proto_tree_add_text(tree,
5317             tvb, curr_offset, 1,
5318             gsm_dtap_elem_strings[DE_CALL_STATE].strptr);
5319
5320     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CALL_STATE]);
5321
5322     switch ((oct & 0xc0) >> 6)
5323     {
5324     case 0: str = "Coding as specified in ITU-T Rec. Q.931"; break;
5325     case 1: str = "Reserved for other international standards"; break;
5326     case 2: str = "National standard"; break;
5327     default:
5328         str = "Standard defined for the GSM PLMNS";
5329         break;
5330     }
5331
5332     other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
5333     proto_tree_add_text(subtree,
5334         tvb, curr_offset, 1,
5335         "%s :  Coding standard: %s",
5336         a_bigbuf,
5337         str);
5338
5339     switch (oct & 0x3f)
5340     {
5341     case 0x00: str = "UO - null                                 NO - null"; break;
5342     case 0x02: str = "U0.1- MM connection pending               N0.1- MM connection pending"; break;
5343     case 0x22: str = "U0.2- CC prompt present                   N0.2- CC connection pending"; break;
5344     case 0x23: str = "U0.3- Wait for network information        N0.3- Network answer pending"; break;
5345     case 0x24: str = "U0.4- CC-Establishment present            N0.4- CC-Establishment present"; break;
5346     case 0x25: str = "U0.5- CC-Establishment confirmed          N0.5- CC-Establishment confirmed"; break;
5347     case 0x26: str = "U0.6- Recall present                      N0.6- Recall present"; break;
5348     case 0x01: str = "U1 - call initiated                       N1 - call initiated"; break;
5349     case 0x03: str = "U3 - mobile originating call proceeding   N3 - mobile originating call proceeding"; break;
5350     case 0x04: str = "U4 - call delivered                       N4 - call delivered"; break;
5351     case 0x06: str = "U6 - call present                         N6 - call present"; break;
5352     case 0x07: str = "U7 - call received                        N7 - call received"; break;
5353     case 0x08: str = "U8 - connect request                      N8 - connect request"; break;
5354     case 0x09: str = "U9 - mobile terminating call confirmed    N9 - mobile terminating call confirmed"; break;
5355     case 0x0a: str = "U10- active                               N10- active"; break;
5356     case 0x0b: str = "U11- disconnect request"; break;
5357     case 0x0c: str = "U12- disconnect indication                N12-disconnect indication"; break;
5358     case 0x13: str = "U19- release request                      N19- release request"; break;
5359     case 0x1a: str = "U26- mobile originating modify            N26- mobile originating modify"; break;
5360     case 0x1b: str = "U27- mobile terminating modify            N27- mobile terminating modify"; break;
5361     case 0x1c: str = "                                          N28- connect indication"; break;
5362     default:
5363         str = "Unknown";
5364         break;
5365     }
5366
5367     other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
5368     proto_tree_add_text(subtree,
5369         tvb, curr_offset, 1,
5370         "%s :  Call state value: %s",
5371         a_bigbuf,
5372         str);
5373
5374     curr_offset++;
5375
5376     /* no length check possible */
5377
5378     return(curr_offset - offset);
5379 }
5380
5381 /*
5382  * [3] 10.5.4.7
5383  */
5384 static guint8
5385 de_cld_party_bcd_num(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
5386 {
5387     guint8      oct;
5388     guint8      ton;
5389     guint8      *poctets;
5390     guint32     curr_offset;
5391     gchar       *str;
5392
5393     curr_offset = offset;
5394
5395     oct = tvb_get_guint8(tvb, curr_offset);
5396
5397     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
5398     proto_tree_add_text(tree,
5399         tvb, curr_offset, 1,
5400         "%s :  Extension",
5401         a_bigbuf);
5402
5403     ton = (oct & 0x70) >> 4;
5404     switch (ton)
5405     {
5406     case 0: str = "Unknown"; break;
5407     case 1: str = "International number"; break;
5408     case 2: str = "National number"; break;
5409     case 3: str = "Network specific number"; break;
5410     case 4: str = "Dedicated access, short code"; break;
5411     case 7: str = "Reserved for extension"; break;
5412     default:
5413         str = "Reserved";
5414         break;
5415     }
5416
5417     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
5418     proto_tree_add_text(tree,
5419         tvb, curr_offset, 1,
5420         "%s :  Type of number: %s",
5421         a_bigbuf,
5422         str);
5423
5424     if ((ton == 0) ||
5425         (ton == 1) ||
5426         (ton == 2) ||
5427         (ton == 4))
5428     {
5429         switch (oct & 0x0f)
5430         {
5431         case 0: str = "Unknown"; break;
5432         case 1: str = "ISDN/telephony numbering plan (Rec. E.164/E.163)"; break;
5433         case 3: str = "Data numbering plan (Recommendation X.121)"; break;
5434         case 4: str = "Telex numbering plan (Recommendation F.69)"; break;
5435         case 8: str = "National numbering plan"; break;
5436         case 9: str = "Private numbering plan"; break;
5437         case 11: str = "Reserved for CTS (see 3GPP TS 44.056)"; break;
5438         case 15: str = "Reserved for extension"; break;
5439         default:
5440             str = "Reserved";
5441             break;
5442         }
5443     }
5444     else
5445     {
5446         str = "not applicable";
5447     }
5448
5449     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
5450     proto_tree_add_text(tree,
5451         tvb, curr_offset, 1,
5452         "%s :  Numbering plan identification: %s",
5453         a_bigbuf,
5454         str);
5455
5456     curr_offset++;
5457
5458     NO_MORE_DATA_CHECK(len);
5459
5460     poctets = tvb_get_string(tvb, curr_offset, len - (curr_offset - offset));
5461
5462     my_dgt_tbcd_unpack(a_bigbuf, poctets, len - (curr_offset - offset),
5463         &Dgt_mbcd);
5464     g_free(poctets);
5465
5466     proto_tree_add_string_format(tree, hf_gsm_a_cld_party_bcd_num,
5467         tvb, curr_offset, len - (curr_offset - offset),
5468         a_bigbuf,
5469         "BCD Digits: %s",
5470         a_bigbuf);
5471
5472     curr_offset += len - (curr_offset - offset);
5473
5474     sprintf(add_string, " - (%s)", a_bigbuf);
5475
5476     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5477
5478     return(curr_offset - offset);
5479 }
5480
5481 /*
5482  * [3] 10.5.4.8
5483  */
5484 static guint8
5485 de_cld_party_sub_addr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
5486 {
5487     guint8      oct;
5488     guint32     curr_offset;
5489     gchar       *str;
5490
5491     add_string = add_string;
5492     curr_offset = offset;
5493
5494     oct = tvb_get_guint8(tvb, curr_offset);
5495
5496     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
5497     proto_tree_add_text(tree,
5498         tvb, curr_offset, 1,
5499         "%s :  Extension",
5500         a_bigbuf);
5501
5502     switch ((oct & 0x70) >> 4)
5503     {
5504     case 0: str = "NSAP (X.213/ISO 8348 AD2)"; break;
5505     case 2: str = "User specified"; break;
5506     default:
5507         str = "Reserved";
5508         break;
5509     }
5510
5511     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
5512     proto_tree_add_text(tree,
5513         tvb, curr_offset, 1,
5514         "%s :  Type of subaddress: %s",
5515         a_bigbuf,
5516         str);
5517
5518     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
5519     proto_tree_add_text(tree,
5520         tvb, curr_offset, 1,
5521         "%s :  Odd/Even indicator: %s",
5522         a_bigbuf,
5523         (oct & 0x08) ?
5524             "odd number of address signals" : "even number of address signals");
5525
5526     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
5527     proto_tree_add_text(tree,
5528         tvb, curr_offset, 1,
5529         "%s :  Spare",
5530         a_bigbuf);
5531
5532     curr_offset++;
5533
5534     NO_MORE_DATA_CHECK(len);
5535
5536     proto_tree_add_text(tree,
5537         tvb, curr_offset, len - (curr_offset - offset),
5538         "Subaddress information");
5539
5540     curr_offset += len - (curr_offset - offset);
5541
5542     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5543
5544     return(curr_offset - offset);
5545 }
5546
5547 /*
5548  * [3] 10.5.4.9
5549  */
5550 static guint8
5551 de_clg_party_bcd_num(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
5552 {
5553     guint8      oct;
5554     guint8      ton;
5555     guint8      *poctets;
5556     guint32     curr_offset;
5557     gchar       *str;
5558
5559     curr_offset = offset;
5560
5561     oct = tvb_get_guint8(tvb, curr_offset);
5562
5563     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
5564     proto_tree_add_text(tree,
5565         tvb, curr_offset, 1,
5566         "%s :  Extension",
5567         a_bigbuf);
5568
5569     ton = (oct & 0x70) >> 4;
5570     switch (ton)
5571     {
5572     case 0: str = "Unknown"; break;
5573     case 1: str = "International number"; break;
5574     case 2: str = "National number"; break;
5575     case 3: str = "Network specific number"; break;
5576     case 4: str = "Dedicated access, short code"; break;
5577     case 7: str = "Reserved for extension"; break;
5578     default:
5579         str = "Reserved";
5580         break;
5581     }
5582
5583     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
5584     proto_tree_add_text(tree,
5585         tvb, curr_offset, 1,
5586         "%s :  Type of number: %s",
5587         a_bigbuf,
5588         str);
5589
5590     if ((ton == 0) ||
5591         (ton == 1) ||
5592         (ton == 2) ||
5593         (ton == 4))
5594     {
5595         switch (oct & 0x0f)
5596         {
5597         case 0: str = "Unknown"; break;
5598         case 1: str = "ISDN/telephony numbering plan (Rec. E.164/E.163)"; break;
5599         case 3: str = "Data numbering plan (Recommendation X.121)"; break;
5600         case 4: str = "Telex numbering plan (Recommendation F.69)"; break;
5601         case 8: str = "National numbering plan"; break;
5602         case 9: str = "Private numbering plan"; break;
5603         case 11: str = "Reserved for CTS (see 3GPP TS 44.056)"; break;
5604         case 15: str = "Reserved for extension"; break;
5605         default:
5606             str = "Reserved";
5607             break;
5608         }
5609     }
5610     else
5611     {
5612         str = "not applicable";
5613     }
5614
5615     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
5616     proto_tree_add_text(tree,
5617         tvb, curr_offset, 1,
5618         "%s :  Numbering plan identification: %s",
5619         a_bigbuf,
5620         str);
5621
5622     curr_offset++;
5623
5624     oct = tvb_get_guint8(tvb, curr_offset);
5625
5626     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
5627     proto_tree_add_text(tree,
5628         tvb, curr_offset, 1,
5629         "%s :  Extension",
5630         a_bigbuf);
5631
5632     switch ((oct & 0x60) >> 5)
5633     {
5634     case 0: str = "Presentation allowed"; break;
5635     case 1: str = "Presentation restricted"; break;
5636     case 2: str = "Number not available due to interworking"; break;
5637     default:
5638         str = "Reserved";
5639         break;
5640     }
5641
5642     other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
5643     proto_tree_add_text(tree,
5644         tvb, curr_offset, 1,
5645         "%s :  Presentation indicator: %s",
5646         a_bigbuf,
5647         str);
5648
5649     other_decode_bitfield_value(a_bigbuf, oct, 0x1c, 8);
5650     proto_tree_add_text(tree,
5651         tvb, curr_offset, 1,
5652         "%s :  Spare",
5653         a_bigbuf);
5654
5655     switch (oct & 0x03)
5656     {
5657     case 0: str = "User-provided, not screened"; break;
5658     case 1: str = "User-provided, verified and passed"; break;
5659     case 2: str = "User-provided, verified and failed"; break;
5660     default:
5661         str = "Network provided";
5662         break;
5663     }
5664
5665     other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
5666     proto_tree_add_text(tree,
5667         tvb, curr_offset, 1,
5668         "%s :  Screening indicator: %s",
5669         a_bigbuf,
5670         str);
5671
5672     curr_offset++;
5673
5674     NO_MORE_DATA_CHECK(len);
5675
5676     poctets = tvb_get_string(tvb, curr_offset, len - (curr_offset - offset));
5677
5678     my_dgt_tbcd_unpack(a_bigbuf, poctets, len - (curr_offset - offset),
5679         &Dgt_mbcd);
5680     g_free(poctets);
5681
5682     proto_tree_add_string_format(tree, hf_gsm_a_clg_party_bcd_num,
5683         tvb, curr_offset, len - (curr_offset - offset),
5684         a_bigbuf,
5685         "BCD Digits: %s",
5686         a_bigbuf);
5687
5688     curr_offset += len - (curr_offset - offset);
5689
5690     sprintf(add_string, " - (%s)", a_bigbuf);
5691
5692     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5693
5694     return(curr_offset - offset);
5695 }
5696
5697 /*
5698  * [3] 10.5.4.10
5699  */
5700 static guint8
5701 de_clg_party_sub_addr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
5702 {
5703     guint8      oct;
5704     guint32     curr_offset;
5705     gchar       *str;
5706
5707     add_string = add_string;
5708     curr_offset = offset;
5709
5710     oct = tvb_get_guint8(tvb, curr_offset);
5711
5712     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
5713     proto_tree_add_text(tree,
5714         tvb, curr_offset, 1,
5715         "%s :  Extension",
5716         a_bigbuf);
5717
5718     switch ((oct & 0x70) >> 4)
5719     {
5720     case 0: str = "NSAP (X.213/ISO 8348 AD2)"; break;
5721     case 2: str = "User specified"; break;
5722     default:
5723         str = "Reserved";
5724         break;
5725     }
5726
5727     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
5728     proto_tree_add_text(tree,
5729         tvb, curr_offset, 1,
5730         "%s :  Type of subaddress: %s",
5731         a_bigbuf,
5732         str);
5733
5734     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
5735     proto_tree_add_text(tree,
5736         tvb, curr_offset, 1,
5737         "%s :  Odd/Even indicator: %s",
5738         a_bigbuf,
5739         (oct & 0x08) ?
5740             "odd number of address signals" : "even number of address signals");
5741
5742     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
5743     proto_tree_add_text(tree,
5744         tvb, curr_offset, 1,
5745         "%s :  Spare",
5746         a_bigbuf);
5747
5748     curr_offset++;
5749
5750     NO_MORE_DATA_CHECK(len);
5751
5752     proto_tree_add_text(tree,
5753         tvb, curr_offset, len - (curr_offset - offset),
5754         "Subaddress information");
5755
5756     curr_offset += len - (curr_offset - offset);
5757
5758     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5759
5760     return(curr_offset - offset);
5761 }
5762
5763 /*
5764  * [3] 10.5.4.11
5765  */
5766 static guint8
5767 de_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
5768 {
5769     guint8      oct;
5770     guint8      cause;
5771     guint32     curr_offset;
5772     gchar       *str;
5773
5774     curr_offset = offset;
5775
5776     oct = tvb_get_guint8(tvb, curr_offset);
5777
5778     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
5779     proto_tree_add_text(tree,
5780         tvb, curr_offset, 1,
5781         "%s :  Extension: %s",
5782         a_bigbuf,
5783         (oct & 0x80) ? "not extended" : "extended");
5784
5785     switch ((oct & 0x60) >> 5)
5786     {
5787     case 0: str = "Coding as specified in ITU-T Rec. Q.931"; break;
5788     case 1: str = "Reserved for other international standards"; break;
5789     case 2: str = "National standard"; break;
5790     default:
5791         str = "Standard defined for the GSM PLMNS";
5792         break;
5793     }
5794
5795     other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
5796     proto_tree_add_text(tree,
5797         tvb, curr_offset, 1,
5798         "%s :  Coding standard: %s",
5799         a_bigbuf,
5800         str);
5801
5802     other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
5803     proto_tree_add_text(tree,
5804         tvb, curr_offset, 1,
5805         "%s :  Spare",
5806         a_bigbuf);
5807
5808     switch (oct & 0x0f)
5809     {
5810     case 0: str = "User"; break;
5811     case 1: str = "Private network serving the local user"; break;
5812     case 2: str = "Public network serving the local user"; break;
5813     case 3: str = "Transit network"; break;
5814     case 4: str = "Public network serving the remote user"; break;
5815     case 5: str = "Private network serving the remote user"; break;
5816     case 7: str = "International network"; break;
5817     case 10: str = "Network beyond interworking point"; break;
5818     default:
5819         str = "Reserved";
5820         break;
5821     }
5822
5823     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
5824     proto_tree_add_text(tree,
5825         tvb, curr_offset, 1,
5826         "%s :  Location: %s",
5827         a_bigbuf,
5828         str);
5829
5830     curr_offset++;
5831
5832     oct = tvb_get_guint8(tvb, curr_offset);
5833
5834     if (!(oct & 0x80))
5835     {
5836         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
5837         proto_tree_add_text(tree,
5838             tvb, curr_offset, 1,
5839             "%s :  Extension",
5840             a_bigbuf);
5841
5842         other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
5843         proto_tree_add_text(tree,
5844             tvb, curr_offset, 1,
5845             "%s :  Recommendation",
5846             a_bigbuf);
5847
5848         curr_offset++;
5849
5850         oct = tvb_get_guint8(tvb, curr_offset);
5851     }
5852
5853     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
5854     proto_tree_add_text(tree,
5855         tvb, curr_offset, 1,
5856         "%s :  Extension",
5857         a_bigbuf);
5858
5859     cause = oct & 0x7f;
5860     switch (cause)
5861     {
5862     case 1: str = "Unassigned (unallocated) number"; break;
5863     case 3: str = "No route to destination"; break;
5864     case 6: str = "Channel unacceptable"; break;
5865     case 8: str = "Operator determined barring"; break;
5866     case 16: str = "Normal call clearing"; break;
5867     case 17: str = "User busy"; break;
5868     case 18: str = "No user responding"; break;
5869     case 19: str = "User alerting, no answer"; break;
5870     case 21: str = "Call rejected"; break;
5871     case 22: str = "Number changed"; break;
5872     case 25: str = "Pre-emption"; break;
5873     case 26: str = "Non selected user clearing"; break;
5874     case 27: str = "Destination out of order"; break;
5875     case 28: str = "Invalid number format (incomplete number)"; break;
5876     case 29: str = "Facility rejected"; break;
5877     case 30: str = "Response to STATUS ENQUIRY"; break;
5878     case 31: str = "Normal, unspecified"; break;
5879     case 34: str = "No circuit/channel available"; break;
5880     case 38: str = "Network out of order"; break;
5881     case 41: str = "Temporary failure"; break;
5882     case 42: str = "Switching equipment congestion"; break;
5883     case 43: str = "Access information discarded"; break;
5884     case 44: str = "requested circuit/channel not available"; break;
5885     case 47: str = "Resources unavailable, unspecified"; break;
5886     case 49: str = "Quality of service unavailable"; break;
5887     case 50: str = "Requested facility not subscribed"; break;
5888     case 55: str = "Incoming calls barred within the CUG"; break;
5889     case 57: str = "Bearer capability not authorized"; break;
5890     case 58: str = "Bearer capability not presently available"; break;
5891     case 63: str = "Service or option not available, unspecified"; break;
5892     case 65: str = "Bearer service not implemented"; break;
5893     case 68: str = "ACM equal to or greater than ACMmax"; break;
5894     case 69: str = "Requested facility not implemented"; break;
5895     case 70: str = "Only restricted digital information bearer capability is available"; break;
5896     case 79: str = "Service or option not implemented, unspecified"; break;
5897     case 81: str = "Invalid transaction identifier value"; break;
5898     case 87: str = "User not member of CUG"; break;
5899     case 88: str = "Incompatible destination"; break;
5900     case 91: str = "Invalid transit network selection"; break;
5901     case 95: str = "Semantically incorrect message"; break;
5902     case 96: str = "Invalid mandatory information"; break;
5903     case 97: str = "Message type non-existent or not implemented"; break;
5904     case 98: str = "Message type not compatible with protocol state"; break;
5905     case 99: str = "Information element non-existent or not implemented"; break;
5906     case 100: str = "Conditional IE error"; break;
5907     case 101: str = "Message not compatible with protocol state"; break;
5908     case 102: str = "Recovery on timer expiry"; break;
5909     case 111: str = "Protocol error, unspecified"; break;
5910     case 127: str = "Interworking, unspecified"; break;
5911     default:
5912         if (cause <= 31) { str = "Treat as Normal, unspecified"; }
5913         else if ((cause >= 32) && (cause <= 47)) { str = "Treat as Resources unavailable, unspecified"; }
5914         else if ((cause >= 48) && (cause <= 63)) { str = "Treat as Service or option not available, unspecified"; }
5915         else if ((cause >= 64) && (cause <= 79)) { str = "Treat as Service or option not implemented, unspecified"; }
5916         else if ((cause >= 80) && (cause <= 95)) { str = "Treat as Semantically incorrect message"; }
5917         else if ((cause >= 96) && (cause <= 111)) { str = "Treat as Protocol error, unspecified"; }
5918         else if ((cause >= 112) && (cause <= 127)) { str = "Treat as Interworking, unspecified"; }
5919         break;
5920     }
5921
5922     other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
5923     proto_tree_add_uint_format(tree, hf_gsm_a_dtap_cause,
5924         tvb, curr_offset, 1, cause,
5925         "%s :  Cause: (%u) %s",
5926         a_bigbuf,
5927         cause,
5928         str);
5929
5930     curr_offset++;
5931
5932     sprintf(add_string, " - (%u) %s", cause, str);
5933
5934     NO_MORE_DATA_CHECK(len);
5935
5936     proto_tree_add_text(tree,
5937         tvb, curr_offset, len - (curr_offset - offset),
5938         "Diagnostics");
5939
5940     curr_offset += len - (curr_offset - offset);
5941
5942     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5943
5944     return(curr_offset - offset);
5945 }
5946
5947
5948 #define GSM_A_TC_START_SUBTREE(_Gtree, _Gsaved_offset, _Gtag, _Gstr1, _Gett, _Gdef_len_p, _Glen_p, _Gsubtree_p) \
5949     { \
5950         guint           _len_offset; \
5951         proto_item      *_item; \
5952  \
5953         _len_offset = asn1->offset; \
5954         asn1_length_decode(asn1, _Gdef_len_p, _Glen_p); \
5955  \
5956         _item = \
5957             proto_tree_add_text(_Gtree, asn1->tvb, _Gsaved_offset, -1, _Gstr1); \
5958  \
5959         _Gsubtree_p = proto_item_add_subtree(_item, _Gett); \
5960  \
5961         proto_tree_add_text(_Gsubtree_p, asn1->tvb, \
5962             _Gsaved_offset, _len_offset - _Gsaved_offset, "Tag: 0x%02x", _Gtag); \
5963  \
5964         if (*_Gdef_len_p) \
5965         { \
5966             proto_tree_add_text(_Gsubtree_p, asn1->tvb, \
5967                 _len_offset, asn1->offset - _len_offset, "Length: %d", *_Glen_p); \
5968         } \
5969         else \
5970         { \
5971             proto_tree_add_text(_Gsubtree_p, asn1->tvb, \
5972                 _len_offset, asn1->offset - _len_offset, "Length: Indefinite"); \
5973  \
5974             *_Glen_p = tcap_find_eoc(asn1); \
5975         } \
5976  \
5977         proto_item_set_len(_item, (asn1->offset - _Gsaved_offset) + *_Glen_p + \
5978             (*_Gdef_len_p ? 0 : TCAP_EOC_LEN)); \
5979     }
5980
5981 /*
5982  * [6] 3.6
5983  */
5984 static guint8
5985 de_facility(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
5986 {
5987     ASN1_SCK    asn1_real, *asn1;
5988     proto_item  *item;
5989     proto_tree  *subtree, *temp_subtree, *seq_subtree;
5990     guint       saved_offset, comp_saved_offset, comp_len_offset, comp_data_offset;
5991     guint       comp_len, temp_len;
5992     gboolean    def_len[3];
5993     guint       comp_tag, tag;
5994     gchar       *str;
5995     gint32      int_val;
5996
5997     add_string = add_string;
5998
5999     asn1 = &asn1_real;
6000     asn1_open(asn1, tvb, offset);
6001
6002     /* call next dissector for EACH component */
6003
6004     while ((len - (asn1->offset - offset)) > 0)
6005     {
6006         comp_saved_offset = asn1->offset;
6007         saved_offset = asn1->offset;
6008         asn1_id_decode1(asn1, &comp_tag);
6009
6010         comp_len_offset = asn1->offset;
6011         comp_len = 0;
6012         def_len[0] = FALSE;
6013         asn1_length_decode(asn1, &def_len[0], &comp_len);
6014         comp_data_offset = asn1->offset;
6015
6016         if (def_len[0])
6017         {
6018             temp_len = comp_len + (asn1->offset - saved_offset);
6019         }
6020         else
6021         {
6022             comp_len = tcap_find_eoc(asn1);
6023             temp_len = comp_len + (asn1->offset - saved_offset) + TCAP_EOC_LEN;
6024         }
6025
6026         item =
6027             proto_tree_add_text(tree, asn1->tvb, comp_saved_offset, temp_len, "Component");
6028
6029         subtree = proto_item_add_subtree(item, ett_tc_component);
6030
6031         str = match_strval((guint32) comp_tag, tcap_component_type_str);
6032
6033         if (str == NULL)
6034         {
6035             proto_tree_add_text(subtree, asn1->tvb, comp_saved_offset, temp_len,
6036                 "Unknown component type tag, ignoring component");
6037
6038             asn1->offset = comp_saved_offset + temp_len;
6039             continue;
6040         }
6041
6042         proto_tree_add_text(subtree, asn1->tvb, comp_saved_offset,
6043             comp_len_offset - comp_saved_offset,
6044             "%s Type Tag: 0x%02x", str, comp_tag);
6045
6046         if (def_len[0])
6047         {
6048             proto_tree_add_text(subtree, asn1->tvb,
6049                 comp_len_offset, asn1->offset - comp_len_offset, "Length: %d", comp_len);
6050         }
6051         else
6052         {
6053             proto_tree_add_text(subtree, asn1->tvb,
6054                 comp_len_offset, asn1->offset - comp_len_offset, "Length: Indefinite");
6055         }
6056
6057         saved_offset = asn1->offset;
6058         asn1_id_decode1(asn1, &tag);
6059
6060         GSM_A_TC_START_SUBTREE(subtree, saved_offset, tag, "Invoke ID",
6061             ett_tc_invoke_id, &def_len[1], &temp_len, temp_subtree);
6062
6063         if (temp_len > 0)
6064         {
6065             saved_offset = asn1->offset;
6066             asn1_int32_value_decode(asn1, temp_len, &int_val);
6067
6068             proto_tree_add_text(temp_subtree, asn1->tvb,
6069                 saved_offset, temp_len, "Invoke ID: %d", int_val);
6070         }
6071
6072         if (!def_len[1])
6073         {
6074             saved_offset = asn1->offset;
6075             asn1_eoc_decode(asn1, -1);
6076
6077             proto_tree_add_text(subtree, asn1->tvb,
6078                 saved_offset, asn1->offset - saved_offset, "End of Contents");
6079         }
6080
6081         switch (comp_tag)
6082         {
6083         case TCAP_COMP_INVOKE:
6084             saved_offset = asn1->offset;
6085             asn1_id_decode1(asn1, &tag);
6086
6087             if (tag == TCAP_LINKED_ID_TAG)
6088             {
6089                 GSM_A_TC_START_SUBTREE(subtree, saved_offset, tag, "Linked ID",
6090                     ett_tc_linked_id, &def_len[1], &temp_len, temp_subtree);
6091
6092                 if (temp_len > 0)
6093                 {
6094                     saved_offset = asn1->offset;
6095                     asn1_int32_value_decode(asn1, temp_len, &int_val);
6096
6097                     proto_tree_add_text(temp_subtree, asn1->tvb,
6098                         saved_offset, temp_len, "Linked ID: %d", int_val);
6099                 }
6100
6101                 if (!def_len[1])
6102                 {
6103                     saved_offset = asn1->offset;
6104                     asn1_eoc_decode(asn1, -1);
6105
6106                     proto_tree_add_text(subtree, asn1->tvb,
6107                         saved_offset, asn1->offset - saved_offset, "End of Contents");
6108                 }
6109
6110                 saved_offset = asn1->offset;
6111                 asn1_id_decode1(asn1, &tag);
6112             }
6113
6114             GSM_A_TC_START_SUBTREE(subtree, saved_offset, tag, "Operation Code",
6115                 ett_tc_opr_code, &def_len[1], &temp_len, temp_subtree);
6116
6117             if (temp_len > 0)
6118             {
6119                 saved_offset = asn1->offset;
6120                 asn1_int32_value_decode(asn1, temp_len, &int_val);
6121
6122                 str = match_strval(int_val, gsm_ss_opr_code_strings);
6123
6124                 proto_tree_add_text(temp_subtree, asn1->tvb,
6125                     saved_offset, temp_len, "Operation Code: %s (%d)",
6126                     (str == NULL) ? "Unknown Operation Code" : str,
6127                     int_val);
6128             }
6129
6130             if (!def_len[1])
6131             {
6132                 saved_offset = asn1->offset;
6133                 asn1_eoc_decode(asn1, -1);
6134
6135                 proto_tree_add_text(subtree, asn1->tvb,
6136                     saved_offset, asn1->offset - saved_offset, "End of Contents");
6137             }
6138
6139             if ((comp_len - (asn1->offset - comp_data_offset)) > 0)
6140             {
6141                 gsm_ss_dissect(asn1, subtree,
6142                     comp_len - (asn1->offset - comp_data_offset), int_val, comp_tag);
6143             }
6144             break;
6145
6146         case TCAP_COMP_RRL:
6147             if ((len - (asn1->offset - offset)) > 0)
6148             {
6149                 saved_offset = asn1->offset;
6150                 asn1_id_decode1(asn1, &tag);
6151
6152                 GSM_A_TC_START_SUBTREE(subtree, saved_offset, tag, "Sequence",
6153                     ett_tc_sequence, &def_len[1], &temp_len, seq_subtree);
6154
6155                 saved_offset = asn1->offset;
6156                 asn1_id_decode1(asn1, &tag);
6157
6158                 GSM_A_TC_START_SUBTREE(seq_subtree, saved_offset, tag, "Operation Code",
6159                     ett_tc_opr_code, &def_len[2], &temp_len, temp_subtree);
6160
6161                 if (temp_len > 0)
6162                 {
6163                     saved_offset = asn1->offset;
6164                     asn1_int32_value_decode(asn1, temp_len, &int_val);
6165
6166                     str = match_strval(int_val, gsm_ss_opr_code_strings);
6167
6168                     proto_tree_add_text(temp_subtree, asn1->tvb,
6169                         saved_offset, temp_len, "Operation Code: %s (%d)",
6170                         (str == NULL) ? "Unknown Operation Code" : str,
6171                         int_val);
6172                 }
6173
6174                 if (!def_len[2])
6175                 {
6176                     saved_offset = asn1->offset;
6177                     asn1_eoc_decode(asn1, -1);
6178
6179                     proto_tree_add_text(subtree, asn1->tvb,
6180                         saved_offset, asn1->offset - saved_offset, "End of Contents");
6181                 }
6182
6183                 if ((comp_len - (asn1->offset - comp_data_offset)) > 0)
6184                 {
6185                     gsm_ss_dissect(asn1, seq_subtree,
6186                         comp_len - (asn1->offset - comp_data_offset), int_val, comp_tag);
6187                 }
6188
6189                 if (!def_len[1])
6190                 {
6191                     saved_offset = asn1->offset;
6192                     asn1_eoc_decode(asn1, -1);
6193
6194                     proto_tree_add_text(subtree, asn1->tvb,
6195                         saved_offset, asn1->offset - saved_offset, "End of Contents");
6196                 }
6197             }
6198             break;
6199
6200         case TCAP_COMP_RE:
6201             saved_offset = asn1->offset;
6202             asn1_id_decode1(asn1, &tag);
6203
6204             switch (tag)
6205             {
6206             case 0x02:
6207                 GSM_A_TC_START_SUBTREE(subtree, saved_offset, tag, "Local Error Code",
6208                     ett_tc_err_code, &def_len[1], &temp_len, temp_subtree);
6209
6210                 if (temp_len > 0)
6211                 {
6212                     saved_offset = asn1->offset;
6213                     asn1_int32_value_decode(asn1, temp_len, &int_val);
6214
6215                     str = match_strval(int_val, gsm_ss_err_code_strings);
6216
6217                     proto_tree_add_text(temp_subtree, asn1->tvb,
6218                         saved_offset, temp_len, "Error Code: %s (%d)",
6219                         (str == NULL) ? "Unknown Error Code" : str,
6220                         int_val);
6221                 }
6222                 break;
6223
6224             case 0x06:
6225                 GSM_A_TC_START_SUBTREE(subtree, saved_offset, tag, "Global Error Code",
6226                     ett_tc_err_code, &def_len[1], &temp_len, temp_subtree);
6227
6228                 if (temp_len > 0)
6229                 {
6230                     saved_offset = asn1->offset;
6231                     asn1_int32_value_decode(asn1, temp_len, &int_val);
6232
6233                     proto_tree_add_text(temp_subtree, asn1->tvb,
6234                         saved_offset, temp_len, "Error Code: %d",
6235                         int_val);
6236                 }
6237                 break;
6238
6239             default:
6240                 GSM_A_TC_START_SUBTREE(subtree, saved_offset, tag, "Unknown Error Code",
6241                     ett_tc_err_code, &def_len[1], &temp_len, temp_subtree);
6242
6243                 if (temp_len > 0)
6244                 {
6245                     saved_offset = asn1->offset;
6246                     asn1_int32_value_decode(asn1, temp_len, &int_val);
6247
6248                     proto_tree_add_text(temp_subtree, asn1->tvb,
6249                         saved_offset, temp_len, "Error Code: %d",
6250                         int_val);
6251                 }
6252                 break;
6253             }
6254
6255             if (!def_len[1])
6256             {
6257                 saved_offset = asn1->offset;
6258                 asn1_eoc_decode(asn1, -1);
6259
6260                 proto_tree_add_text(subtree, asn1->tvb,
6261                     saved_offset, asn1->offset - saved_offset, "End of Contents");
6262             }
6263
6264             if ((comp_len - (asn1->offset - comp_data_offset)) > 0)
6265             {
6266                 /*
6267                  * XXX need conversations to determine 'opr_code'
6268                  */
6269                 gsm_ss_dissect(asn1, subtree,
6270                     comp_len - (asn1->offset - comp_data_offset), 0, comp_tag);
6271             }
6272             break;
6273
6274         case TCAP_COMP_REJECT:
6275             saved_offset = asn1->offset;
6276             asn1_id_decode1(asn1, &tag);
6277
6278             GSM_A_TC_START_SUBTREE(subtree, saved_offset, tag, "Problem Code",
6279                 ett_tc_prob_code, &def_len[1], &temp_len, temp_subtree);
6280
6281             if (temp_len > 0)
6282             {
6283                 proto_tree_add_text(temp_subtree, asn1->tvb,
6284                     asn1->offset, temp_len, "Problem Code");
6285
6286                 asn1->offset += temp_len;
6287             }
6288
6289             if (!def_len[1])
6290             {
6291                 saved_offset = asn1->offset;
6292                 asn1_eoc_decode(asn1, -1);
6293
6294                 proto_tree_add_text(subtree, asn1->tvb,
6295                     saved_offset, asn1->offset - saved_offset, "End of Contents");
6296             }
6297             break;
6298         }
6299
6300         if (!def_len[0])
6301         {
6302             saved_offset = asn1->offset;
6303             asn1_eoc_decode(asn1, -1);
6304
6305             proto_tree_add_text(subtree, asn1->tvb,
6306                 saved_offset, asn1->offset - saved_offset, "End of Contents");
6307         }
6308     }
6309
6310     return(len);
6311 }
6312
6313 /*
6314  * [3] 10.5.4.17
6315  */
6316 static guint8
6317 de_keypad_facility(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
6318 {
6319     guint8      oct;
6320     guint32     curr_offset;
6321
6322     len = len;
6323     curr_offset = offset;
6324
6325     oct = tvb_get_guint8(tvb, curr_offset);
6326
6327     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6328     proto_tree_add_text(tree,
6329         tvb, curr_offset, 1,
6330         "%s :  Spare",
6331         a_bigbuf);
6332
6333     other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
6334     proto_tree_add_text(tree,
6335         tvb, curr_offset, 1,
6336         "%s :  Keypad information: %c",
6337         a_bigbuf,
6338         oct & 0x7f);
6339
6340     curr_offset++;
6341
6342     sprintf(add_string, " - %c", oct & 0x7f);
6343
6344     /* no length check possible */
6345
6346     return(curr_offset - offset);
6347 }
6348
6349 /*
6350  * [3] 10.5.4.21
6351  */
6352 static guint8
6353 de_prog_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
6354 {
6355     guint8      oct;
6356     guint32     curr_offset;
6357     gchar       *str;
6358
6359     len = len;
6360     curr_offset = offset;
6361
6362     oct = tvb_get_guint8(tvb, curr_offset);
6363
6364     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6365     proto_tree_add_text(tree,
6366         tvb, curr_offset, 1,
6367         "%s :  Extension: %s",
6368         a_bigbuf,
6369         (oct & 0x80) ? "extended" : "not extended");
6370
6371     switch ((oct & 0x60) >> 5)
6372     {
6373     case 0: str = "Coding as specified in ITU-T Rec. Q.931"; break;
6374     case 1: str = "Reserved for other international standards"; break;
6375     case 2: str = "National standard"; break;
6376     default:
6377         str = "Standard defined for the GSM PLMNS";
6378         break;
6379     }
6380
6381     other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
6382     proto_tree_add_text(tree,
6383         tvb, curr_offset, 1,
6384         "%s :  Coding standard: %s",
6385         a_bigbuf,
6386         str);
6387
6388     other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
6389     proto_tree_add_text(tree,
6390         tvb, curr_offset, 1,
6391         "%s :  Spare",
6392         a_bigbuf);
6393
6394     switch (oct & 0x0f)
6395     {
6396     case 0: str = "User"; break;
6397     case 1: str = "Private network serving the local user"; break;
6398     case 2: str = "Public network serving the local user"; break;
6399     case 4: str = "Public network serving the remote user"; break;
6400     case 5: str = "Private network serving the remote user"; break;
6401     case 10: str = "Network beyond interworking point"; break;
6402     default:
6403         str = "Reserved";
6404         break;
6405     }
6406
6407     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
6408     proto_tree_add_text(tree,
6409         tvb, curr_offset, 1,
6410         "%s :  Location: %s",
6411         a_bigbuf,
6412         str);
6413
6414     curr_offset++;
6415
6416     oct = tvb_get_guint8(tvb, curr_offset);
6417
6418     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6419     proto_tree_add_text(tree,
6420         tvb, curr_offset, 1,
6421         "%s :  Extension: %s",
6422         a_bigbuf,
6423         (oct & 0x80) ? "extended" : "not extended");
6424
6425     switch (oct & 0x7f)
6426     {
6427     case 1: str = "Call is not end-to-end PLMN/ISDN, further call progress information may be available in-band"; break;
6428     case 2: str = "Destination address in non-PLMN/ISDN"; break;
6429     case 3: str = "Origination address in non-PLMN/ISDN"; break;
6430     case 4: str = "Call has returned to the PLMN/ISDN"; break;
6431     case 8: str = "In-band information or appropriate pattern now available"; break;
6432     case 32: str = "Call is end-to-end PLMN/ISDN"; break;
6433     case 64: str = "Queueing"; break;
6434     default:
6435         str = "Unspecific";
6436         break;
6437     }
6438
6439     other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
6440     proto_tree_add_text(tree,
6441         tvb, curr_offset, 1,
6442         "%s :  Progress Description: %s (%d)",
6443         a_bigbuf,
6444         str,
6445         oct & 0x7f);
6446
6447     sprintf(add_string, " - %d", oct & 0x7f);
6448
6449     curr_offset++;
6450
6451     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
6452
6453     return(curr_offset - offset);
6454 }
6455
6456 /*
6457  * [3] 10.5.4.22
6458  */
6459 static guint8
6460 de_repeat_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
6461 {
6462     guint8      oct;
6463     guint32     curr_offset;
6464     gchar       *str;
6465
6466     len = len;
6467     add_string = add_string;
6468     curr_offset = offset;
6469
6470     oct = tvb_get_guint8(tvb, curr_offset);
6471
6472     switch (oct & 0x0f)
6473     {
6474     case 1: str = "Circular for successive selection 'mode 1 alternate mode 2'"; break;
6475     case 2: str = "Support of fallback  mode 1 preferred, mode 2 selected if setup of mode 1 fails"; break;
6476     case 3: str = "Reserved: was allocated in earlier phases of the protocol"; break;
6477     default:
6478         str = "Reserved";
6479         break;
6480     }
6481
6482     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
6483     proto_tree_add_text(tree,
6484         tvb, curr_offset, 1,
6485         "%s :  %s",
6486         a_bigbuf,
6487         str);
6488
6489     curr_offset++;
6490
6491     /* no length check possible */
6492
6493     return(curr_offset - offset);
6494 }
6495
6496 /*
6497  * [6] 3.7.2
6498  */
6499 static guint8
6500 de_ss_ver_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
6501 {
6502     guint8      oct;
6503     guint32     curr_offset;
6504     gchar       *str;
6505
6506     add_string = add_string;
6507     curr_offset = offset;
6508
6509     oct = tvb_get_guint8(tvb, curr_offset);
6510
6511     switch (oct)
6512     {
6513     case 0: str = "Phase 2 service, ellipsis notation, and phase 2 error handling is supported"; break;
6514     case 1: str = "SS-Protocol version 3 is supported, and phase 2 error handling is supported"; break;
6515     default:
6516         str = "Reserved";
6517         break;
6518     }
6519
6520     proto_tree_add_text(tree,
6521         tvb, curr_offset, 1,
6522         "%s",
6523         str);
6524
6525     curr_offset++;
6526
6527     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
6528
6529     return(curr_offset - offset);
6530 }
6531
6532 /*
6533  * [5] 8.1.4.1
6534  */
6535 static guint8
6536 de_cp_user_data(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
6537 {
6538     guint32     curr_offset;
6539     tvbuff_t    *rp_tvb;
6540
6541     add_string = add_string;
6542     curr_offset = offset;
6543
6544     proto_tree_add_text(tree, tvb, curr_offset, len,
6545         "RPDU");
6546
6547     /*
6548      * dissect the embedded RP message
6549      */
6550     rp_tvb = tvb_new_subset(tvb, curr_offset, len, len);
6551
6552     call_dissector(rp_handle, rp_tvb, g_pinfo, g_tree);
6553
6554     curr_offset += len;
6555
6556     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
6557
6558     return(curr_offset - offset);
6559 }
6560
6561 /*
6562  * [5] 8.1.4.2
6563  */
6564 static guint8
6565 de_cp_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
6566 {
6567     guint8      oct;
6568     guint32     curr_offset;
6569     gchar       *str;
6570
6571     len = len;
6572     curr_offset = offset;
6573
6574     oct = tvb_get_guint8(tvb, curr_offset);
6575
6576     switch (oct)
6577     {
6578     case 17: str = "Network failure"; break;
6579     case 22: str = "Congestion"; break;
6580     case 81: str = "Invalid Transaction Identifier value"; break;
6581     case 95: str = "Semantically incorrect message"; break;
6582     case 96: str = "Invalid mandatory information"; break;
6583     case 97: str = "Message type non-existent or not implemented"; break;
6584     case 98: str = "Message not compatible with the short message protocol state"; break;
6585     case 99: str = "Information element non-existent or not implemented"; break;
6586     case 111: str = "Protocol error, unspecified"; break;
6587     default:
6588         str = "Reserved, treat as Protocol error, unspecified";
6589         break;
6590     }
6591
6592     proto_tree_add_text(tree,
6593         tvb, curr_offset, 1,
6594         "Cause: (%u) %s",
6595         oct,
6596         str);
6597
6598     curr_offset++;
6599
6600     sprintf(add_string, " - (%u) %s", oct, str);
6601
6602     /* no length check possible */
6603
6604     return(curr_offset - offset);
6605 }
6606
6607 /*
6608  * [5] 8.2.3
6609  */
6610 static guint8
6611 de_rp_message_ref(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
6612 {
6613     guint8      oct;
6614     guint32     curr_offset;
6615
6616     len = len;
6617     add_string = add_string;
6618     curr_offset = offset;
6619
6620     oct = tvb_get_guint8(tvb, curr_offset);
6621
6622     proto_tree_add_text(tree,
6623         tvb, curr_offset, 1,
6624         "RP-Message Reference: 0x%02x (%u)",
6625         oct,
6626         oct);
6627
6628     curr_offset++;
6629
6630     /* no length check possible */
6631
6632     return(curr_offset - offset);
6633 }
6634
6635 /*
6636  * [5] 8.2.5.1
6637  */
6638 static guint8
6639 de_rp_orig_addr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
6640 {
6641     return(de_cld_party_bcd_num(tvb, tree, offset, len, add_string));
6642 }
6643
6644 /*
6645  * [5] 8.2.5.2
6646  */
6647 static guint8
6648 de_rp_dest_addr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
6649 {
6650     return(de_cld_party_bcd_num(tvb, tree, offset, len, add_string));
6651 }
6652
6653 /*
6654  * [5] 8.2.5.3
6655  */
6656 static guint8
6657 de_rp_user_data(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
6658 {
6659     guint32     curr_offset;
6660     tvbuff_t    *tpdu_tvb;
6661
6662     add_string = add_string;
6663     curr_offset = offset;
6664
6665     proto_tree_add_text(tree, tvb, curr_offset, len,
6666         "TPDU");
6667
6668     /*
6669      * dissect the embedded TPDU message
6670      */
6671     tpdu_tvb = tvb_new_subset(tvb, curr_offset, len, len);
6672
6673     dissector_try_port(sms_dissector_table, 0, tpdu_tvb, g_pinfo, g_tree);
6674
6675     curr_offset += len;
6676
6677     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
6678
6679     return(curr_offset - offset);
6680 }
6681
6682 /*
6683  * [5] 8.2.5.4
6684  */
6685 static guint8
6686 de_rp_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
6687 {
6688     guint8      oct;
6689     guint32     curr_offset;
6690     gchar       *str;
6691
6692     curr_offset = offset;
6693
6694     oct = tvb_get_guint8(tvb, curr_offset);
6695
6696     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6697     proto_tree_add_text(tree,
6698         tvb, curr_offset, 1,
6699         "%s :  Extension: %s",
6700         a_bigbuf,
6701         (oct & 0x80) ? "extended" : "not extended");
6702
6703     switch (oct & 0x7f)
6704     {
6705     case 1: str = "Unassigned (unallocated) number"; break;
6706     case 8: str = "Operator determined barring"; break;
6707     case 10: str = "Call barred"; break;
6708     case 11: str = "Reserved"; break;
6709     case 21: str = "Short message transfer rejected"; break;
6710     case 22: str = "Memory capacity exceeded"; break;
6711     case 27: str = "Destination out of order"; break;
6712     case 28: str = "Unidentified subscriber"; break;
6713     case 29: str = "Facility rejected"; break;
6714     case 30: str = "Unknown subscriber"; break;
6715     case 38: str = "Network out of order"; break;
6716     case 41: str = "Temporary failure"; break;
6717     case 42: str = "Congestion"; break;
6718     case 47: str = "Resources unavailable, unspecified"; break;
6719     case 50: str = "Requested facility not subscribed"; break;
6720     case 69: str = "Requested facility not implemented"; break;
6721     case 81: str = "Invalid short message transfer reference value"; break;
6722     case 95: str = "Semantically incorrect message"; break;
6723     case 96: str = "Invalid mandatory information"; break;
6724     case 97: str = "Message type non-existent or not implemented"; break;
6725     case 98: str = "Message not compatible with short message protocol state"; break;
6726     case 99: str = "Information element non-existent or not implemented"; break;
6727     case 111: str = "Protocol error, unspecified"; break;
6728     case 127: str = "Interworking, unspecified"; break;
6729     default:
6730         str = "Reserved";
6731         break;
6732     }
6733
6734     other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
6735     proto_tree_add_text(tree,
6736         tvb, curr_offset, 1,
6737         "%s :  Cause: (%u) %s",
6738         a_bigbuf,
6739         oct & 0x7f,
6740         str);
6741
6742     curr_offset++;
6743
6744     sprintf(add_string, " - (%u) %s", oct & 0x7f, str);
6745
6746     NO_MORE_DATA_CHECK(len);
6747
6748     proto_tree_add_text(tree,
6749         tvb, curr_offset, len - (curr_offset - offset),
6750         "Diagnostic field");
6751
6752     curr_offset += len - (curr_offset - offset);
6753
6754     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
6755
6756     return(curr_offset - offset);
6757 }
6758
6759 static guint8 (*bssmap_elem_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string) = {
6760     be_cic,     /* Circuit Identity Code */
6761     NULL,       /* Reserved */
6762     NULL,       /* Resource Available */
6763     be_cause,   /* Cause */
6764     be_cell_id, /* Cell Identifier */
6765     be_prio,    /* Priority */
6766     be_l3_header_info,  /* Layer 3 Header Information */
6767     de_mid,     /* IMSI */
6768     be_tmsi,    /* TMSI */
6769     be_enc_info,        /* Encryption Information */
6770     be_chan_type,       /* Channel Type */
6771     NULL,       /* Periodicity */
6772     NULL,       /* Extended Resource Indicator */
6773     NULL,       /* Number Of MSs */
6774     NULL,       /* Reserved */
6775     NULL,       /* Reserved */
6776     NULL,       /* Reserved */
6777     de_ms_cm_2, /* Classmark Information Type 2 */
6778     NULL,       /* Classmark Information Type 3 */
6779     NULL,       /* Interference Band To Be Used */
6780     de_rr_cause,        /* RR Cause */
6781     NULL,       /* Reserved */
6782     be_l3_info, /* Layer 3 Information */
6783     be_dlci,    /* DLCI */
6784     be_down_dtx_flag,   /* Downlink DTX Flag */
6785     be_cell_id_list,    /* Cell Identifier List */
6786     NULL /* no associated data */,      /* Response Request */
6787     NULL,       /* Resource Indication Method */
6788     de_ms_cm_1, /* Classmark Information Type 1 */
6789     NULL,       /* Circuit Identity Code List */
6790     NULL,       /* Diagnostic */
6791     be_l3_msg,  /* Layer 3 Message Contents */
6792     be_chosen_chan,     /* Chosen Channel */
6793     NULL,       /* Total Resource Accessible */
6794     be_ciph_resp_mode,  /* Cipher Response Mode */
6795     NULL,       /* Channel Needed */
6796     NULL,       /* Trace Type */
6797     NULL,       /* TriggerID */
6798     NULL,       /* Trace Reference */
6799     NULL,       /* TransactionID */
6800     de_mid,     /* Mobile Identity */
6801     NULL,       /* OMCID */
6802     be_for_ind, /* Forward Indicator */
6803     be_chosen_enc_alg,  /* Chosen Encryption Algorithm */
6804     be_cct_pool,        /* Circuit Pool */
6805     NULL,       /* Circuit Pool List */
6806     NULL,       /* Time Indication */
6807     NULL,       /* Resource Situation */
6808     be_curr_chan_1,     /* Current Channel Type 1 */
6809     be_que_ind, /* Queueing Indicator */
6810     be_speech_ver,      /* Speech Version */
6811     NULL,       /* Assignment Requirement */
6812     NULL /* no associated data */,      /* Talker Flag */
6813     NULL /* no associated data */,      /* Connection Release Requested */
6814     NULL,       /* Group Call Reference */
6815     NULL,       /* eMLPP Priority */
6816     NULL,       /* Configuration Evolution Indication */
6817     NULL /* no decode required */,      /* Old BSS to New BSS Information */
6818     NULL,       /* LSA Identifier */
6819     NULL,       /* LSA Identifier List */
6820     NULL,       /* LSA Information */
6821     NULL,       /* LCS QoS */
6822     NULL,       /* LSA access control suppression */
6823     NULL,       /* LCS Priority */
6824     NULL,       /* Location Type */
6825     NULL,       /* Location Estimate */
6826     NULL,       /* Positioning Data */
6827     NULL,       /* LCS Cause */
6828     NULL,       /* LCS Client Type */
6829     be_apdu,    /* APDU */
6830     NULL,       /* Network Element Identity */
6831     NULL,       /* GPS Assistance Data */
6832     NULL,       /* Deciphering Keys */
6833     NULL,       /* Return Error Request */
6834     NULL,       /* Return Error Cause */
6835     NULL,       /* Segmentation */
6836     NULL,       /* NONE */
6837 };
6838
6839 static guint8 (*dtap_elem_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string) = {
6840     /* Common Information Elements 10.5.1 */
6841     de_cell_id, /* Cell Identity */
6842     NULL /* handled inline */,  /* Ciphering Key Sequence Number */
6843     de_lai,     /* Location Area Identification */
6844     de_mid,     /* Mobile Identity */
6845     de_ms_cm_1, /* Mobile Station Classmark 1 */
6846     de_ms_cm_2, /* Mobile Station Classmark 2 */
6847     NULL,       /* Mobile Station Classmark 3 */
6848     de_d_gb_call_ref,   /* Descriptive group or broadcast call reference */
6849     NULL /* handled inline */,  /* Group Cipher Key Number */
6850     de_pd_sapi, /* PD and SAPI $(CCBS)$ */
6851     de_prio /* handled inline */,       /* Priority Level */
6852     de_plmn_list,       /* PLMN List */
6853     /* Radio Resource Management Information Elements 10.5.2, most are from 10.5.1 */
6854     de_rr_cause,        /* RR Cause */
6855     /* Mobility Management Information Elements 10.5.3 */
6856     de_auth_param_rand, /* Authentication Parameter RAND */
6857     de_auth_param_autn, /* Authentication Parameter AUTN (UMTS authentication challenge only) */
6858     de_auth_resp_param, /* Authentication Response Parameter */
6859     de_auth_resp_param_ext,     /* Authentication Response Parameter (extension) (UMTS authentication challenge only) */
6860     de_auth_fail_param, /* Authentication Failure Parameter (UMTS authentication challenge only) */
6861     NULL /* handled inline */,  /* CM Service Type */
6862     NULL /* handled inline */,  /* Identity Type */
6863     NULL /* handled inline */,  /* Location Updating Type */
6864     de_network_name,    /* Network Name */
6865     de_rej_cause,       /* Reject Cause */
6866     NULL /* no associated data */,      /* Follow-on Proceed */
6867     de_time_zone,       /* Time Zone */
6868     de_time_zone_time,  /* Time Zone and Time */
6869     NULL /* no associated data */,      /* CTS Permission */
6870     de_lsa_id,  /* LSA Identifier */
6871     de_day_saving_time, /* Daylight Saving Time */
6872     /* Call Control Information Elements 10.5.4 */
6873     de_aux_states,      /* Auxiliary States */
6874     de_bearer_cap,      /* Bearer Capability */
6875     de_cc_cap,  /* Call Control Capabilities */
6876     de_call_state,      /* Call State */
6877     de_cld_party_bcd_num,       /* Called Party BCD Number */
6878     de_cld_party_sub_addr,      /* Called Party Subaddress */
6879     de_clg_party_bcd_num,       /* Calling Party BCD Number */
6880     de_clg_party_sub_addr,      /* Calling Party Subaddress */
6881     de_cause,   /* Cause */
6882     NULL /* no associated data */,      /* CLIR Suppression */
6883     NULL /* no associated data */,      /* CLIR Invocation */
6884     NULL /* handled inline */,  /* Congestion Level */
6885     NULL,       /* Connected Number */
6886     NULL,       /* Connected Subaddress */
6887     de_facility,        /* Facility */
6888     NULL,       /* High Layer Compatibility */
6889     de_keypad_facility, /* Keypad Facility */
6890     NULL,       /* Low Layer Compatibility */
6891     NULL,       /* More Data */
6892     NULL,       /* Notification Indicator */
6893     de_prog_ind,        /* Progress Indicator */
6894     NULL,       /* Recall type $(CCBS)$ */
6895     NULL,       /* Redirecting Party BCD Number */
6896     NULL,       /* Redirecting Party Subaddress */
6897     de_repeat_ind,      /* Repeat Indicator */
6898     NULL /* no associated data */,      /* Reverse Call Setup Direction */
6899     NULL,       /* SETUP Container $(CCBS)$ */
6900     NULL,       /* Signal */
6901     de_ss_ver_ind,      /* SS Version Indicator */
6902     NULL,       /* User-user */
6903     NULL,       /* Alerting Pattern $(NIA)$ */
6904     NULL,       /* Allowed Actions $(CCBS)$ */
6905     NULL,       /* Stream Identifier */
6906     NULL,       /* Network Call Control Capabilities */
6907     NULL,       /* Cause of No CLI */
6908     NULL,       /* Immediate Modification Indicator */
6909     NULL,       /* Supported Codec List */
6910     NULL,       /* Service Category */
6911     /* GPRS Mobility Management Information Elements 10.5.5 */
6912     NULL,       /* Attach Result */
6913     NULL,       /* Attach Type */
6914     NULL,       /* TMSI Status */
6915     NULL,       /* Detach Type */
6916     NULL,       /* DRX Parameter */
6917     NULL,       /* Force to Standby */
6918     NULL,       /* P-TMSI Signature */
6919     NULL,       /* P-TMSI Signature 2 */
6920     NULL,       /* Identity Type 2 */
6921     NULL,       /* IMEISV Request */
6922     NULL,       /* Receive N-PDU Numbers List */
6923     NULL,       /* MS Network Capability */
6924     NULL,       /* MS Radio Access Capability */
6925     NULL,       /* GMM Cause */
6926     NULL,       /* Routing Area Identification */
6927     NULL,       /* Update Result */
6928     NULL,       /* A&C Reference Number */
6929     NULL,       /* Service Type */
6930     NULL,       /* Cell Notification */
6931     NULL,       /* Network Feature Support */
6932     /* Short Message Service Information Elements [5] 8.1.4 */
6933     de_cp_user_data,    /* CP-User Data */
6934     de_cp_cause,        /* CP-Cause */
6935     /* Short Message Service Information Elements [5] 8.2 */
6936     de_rp_message_ref,  /* RP-Message Reference */
6937     de_rp_orig_addr,    /* RP-Origination Address */
6938     de_rp_dest_addr,    /* RP-Destination Address */
6939     de_rp_user_data,    /* RP-User Data */
6940     de_rp_cause,        /* RP-Cause */
6941     /* Session Management Information Elements 10.5.6 */
6942     NULL,       /* Access Point Name */
6943     NULL,       /* Network Service Access Point Identifier */
6944     NULL,       /* Protocol Configuration Options */
6945     NULL,       /* Packet Data Protocol Address */
6946     NULL,       /* Quality Of Service */
6947     NULL,       /* SM Cause */
6948     NULL,       /* Linked TI */
6949     NULL,       /* LLC Service Access Point Identifier */
6950     NULL,       /* Tear Down Indicator */
6951     NULL,       /* Packet Flow Identifier */
6952     NULL,       /* Traffic Flow Template */
6953     /* GPRS Common Information Elements 10.5.7 */
6954     NULL,       /* PDP Context Status */
6955     NULL,       /* Radio Priority */
6956     NULL,       /* GPRS Timer */
6957     NULL,       /* GPRS Timer 2 */
6958     NULL,       /* NONE */
6959 };
6960
6961 #define SET_ELEM_VARS(SEV_pdu_type, SEV_elem_names, SEV_elem_ett, SEV_elem_funcs) \
6962     switch (SEV_pdu_type) \
6963     { \
6964     case BSSAP_PDU_TYPE_BSSMAP: \
6965         SEV_elem_names = gsm_bssmap_elem_strings; \
6966         SEV_elem_ett = ett_gsm_bssmap_elem; \
6967         SEV_elem_funcs = bssmap_elem_fcn; \
6968         break; \
6969     case BSSAP_PDU_TYPE_DTAP: \
6970         SEV_elem_names = gsm_dtap_elem_strings; \
6971         SEV_elem_ett = ett_gsm_dtap_elem; \
6972         SEV_elem_funcs = dtap_elem_fcn; \
6973         break; \
6974     default: \
6975         proto_tree_add_text(tree, \
6976             tvb, curr_offset, -1, \
6977             "Unknown PDU type (%u)", SEV_pdu_type); \
6978         return(consumed); \
6979     }
6980
6981 /*
6982  * Type Length Value (TLV) element dissector
6983  */
6984 static guint8
6985 elem_tlv(tvbuff_t *tvb, proto_tree *tree, guint8 iei, gint pdu_type, int idx, guint32 offset, guint len, gchar *name_add)
6986 {
6987     guint8              oct, parm_len;
6988     guint8              consumed;
6989     guint32             curr_offset;
6990     proto_tree          *subtree;
6991     proto_item          *item;
6992     const value_string  *elem_names;
6993     gint                *elem_ett;
6994     guint8 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string);
6995
6996     len = len;
6997     curr_offset = offset;
6998     consumed = 0;
6999
7000     SET_ELEM_VARS(pdu_type, elem_names, elem_ett, elem_funcs);
7001
7002     oct = tvb_get_guint8(tvb, curr_offset);
7003
7004     if (oct == iei)
7005     {
7006         parm_len = tvb_get_guint8(tvb, curr_offset + 1);
7007
7008         item =
7009             proto_tree_add_text(tree,
7010                 tvb, curr_offset, parm_len + 2,
7011                 "%s%s",
7012                 elem_names[idx].strptr,
7013                 (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
7014
7015         subtree = proto_item_add_subtree(item, elem_ett[idx]);
7016
7017         proto_tree_add_uint(subtree,
7018             (BSSAP_PDU_TYPE_BSSMAP == pdu_type) ? hf_gsm_a_bssmap_elem_id : hf_gsm_a_dtap_elem_id, tvb,
7019             curr_offset, 1, oct);
7020
7021         proto_tree_add_uint(subtree, hf_gsm_a_length, tvb,
7022             curr_offset + 1, 1, parm_len);
7023
7024         if (parm_len > 0)
7025         {
7026             if (elem_funcs[idx] == NULL)
7027             {
7028                 proto_tree_add_text(subtree,
7029                     tvb, curr_offset + 2, parm_len,
7030                     "Element Value");
7031
7032                 consumed = parm_len;
7033             }
7034             else
7035             {
7036                 a_add_string[0] = '\0';
7037                 consumed =
7038                     (*elem_funcs[idx])(tvb, subtree, curr_offset + 2,
7039                         parm_len, a_add_string);
7040
7041                 if (a_add_string[0] != '\0')
7042                 {
7043                     proto_item_append_text(item, a_add_string);
7044                     a_add_string[0] = '\0';
7045                 }
7046             }
7047         }
7048
7049         consumed += 2;
7050     }
7051
7052     return(consumed);
7053 }
7054
7055 /*
7056  * Type Value (TV) element dissector
7057  *
7058  * Length cannot be used in these functions, big problem if a element dissector
7059  * is not defined for these.
7060  */
7061 static guint8
7062 elem_tv(tvbuff_t *tvb, proto_tree *tree, guint8 iei, gint pdu_type, int idx, guint32 offset, gchar *name_add)
7063 {
7064     guint8              oct;
7065     guint8              consumed;
7066     guint32             curr_offset;
7067     proto_tree          *subtree;
7068     proto_item          *item;
7069     const value_string  *elem_names;
7070     gint                *elem_ett;
7071     guint8 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string);
7072
7073     curr_offset = offset;
7074     consumed = 0;
7075
7076     SET_ELEM_VARS(pdu_type, elem_names, elem_ett, elem_funcs);
7077
7078     oct = tvb_get_guint8(tvb, curr_offset);
7079
7080     if (oct == iei)
7081     {
7082         item =
7083             proto_tree_add_text(tree,
7084                 tvb, curr_offset, -1,
7085                 "%s%s",
7086                 elem_names[idx].strptr,
7087                 (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
7088
7089         subtree = proto_item_add_subtree(item, elem_ett[idx]);
7090
7091         proto_tree_add_uint(subtree,
7092             (BSSAP_PDU_TYPE_BSSMAP == pdu_type) ? hf_gsm_a_bssmap_elem_id : hf_gsm_a_dtap_elem_id, tvb,
7093             curr_offset, 1, oct);
7094
7095         if (elem_funcs[idx] == NULL)
7096         {
7097             /* BAD THING, CANNOT DETERMINE LENGTH */
7098
7099             proto_tree_add_text(subtree,
7100                 tvb, curr_offset + 1, 1,
7101                 "No element dissector, rest of dissection may be incorrect");
7102
7103             consumed = 1;
7104         }
7105         else
7106         {
7107             a_add_string[0] = '\0';
7108             consumed = (*elem_funcs[idx])(tvb, subtree, curr_offset + 1, -1, a_add_string);
7109
7110             if (a_add_string[0] != '\0')
7111             {
7112                 proto_item_append_text(item, a_add_string);
7113                 a_add_string[0] = '\0';
7114             }
7115         }
7116
7117         consumed++;
7118
7119         proto_item_set_len(item, consumed);
7120     }
7121
7122     return(consumed);
7123 }
7124
7125 /*
7126  * Type Value (TV) element dissector
7127  * Where top half nibble is IEI and bottom half nibble is value.
7128  *
7129  * Length cannot be used in these functions, big problem if a element dissector
7130  * is not defined for these.
7131  */
7132 static guint8
7133 elem_tv_short(tvbuff_t *tvb, proto_tree *tree, guint8 iei, gint pdu_type, int idx, guint32 offset, gchar *name_add)
7134 {
7135     guint8              oct;
7136     guint8              consumed;
7137     guint32             curr_offset;
7138     proto_tree          *subtree;
7139     proto_item          *item;
7140     const value_string  *elem_names;
7141     gint                *elem_ett;
7142     guint8 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string);
7143
7144     curr_offset = offset;
7145     consumed = 0;
7146
7147     SET_ELEM_VARS(pdu_type, elem_names, elem_ett, elem_funcs);
7148
7149     oct = tvb_get_guint8(tvb, curr_offset);
7150
7151     if ((oct & 0xf0) == (iei & 0xf0))
7152     {
7153         item =
7154             proto_tree_add_text(tree,
7155                 tvb, curr_offset, -1,
7156                 "%s%s",
7157                 elem_names[idx].strptr,
7158                 (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
7159
7160         subtree = proto_item_add_subtree(item, elem_ett[idx]);
7161
7162         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
7163         proto_tree_add_text(subtree,
7164             tvb, curr_offset, 1,
7165             "%s :  Element ID",
7166             a_bigbuf);
7167
7168         if (elem_funcs[idx] == NULL)
7169         {
7170             /* BAD THING, CANNOT DETERMINE LENGTH */
7171
7172             proto_tree_add_text(subtree,
7173                 tvb, curr_offset, 1,
7174                 "No element dissector, rest of dissection may be incorrect");
7175
7176             consumed++;
7177         }
7178         else
7179         {
7180             a_add_string[0] = '\0';
7181             consumed = (*elem_funcs[idx])(tvb, subtree, curr_offset, -1, a_add_string);
7182
7183             if (a_add_string[0] != '\0')
7184             {
7185                 proto_item_append_text(item, a_add_string);
7186                 a_add_string[0] = '\0';
7187             }
7188         }
7189
7190         proto_item_set_len(item, consumed);
7191     }
7192
7193     return(consumed);
7194 }
7195
7196 /*
7197  * Type (T) element dissector
7198  */
7199 static guint8
7200 elem_t(tvbuff_t *tvb, proto_tree *tree, guint8 iei, gint pdu_type, int idx, guint32 offset, gchar *name_add)
7201 {
7202     guint8              oct;
7203     guint32             curr_offset;
7204     guint8              consumed;
7205     const value_string  *elem_names;
7206     gint                *elem_ett;
7207     guint8 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string);
7208
7209     curr_offset = offset;
7210     consumed = 0;
7211
7212     SET_ELEM_VARS(pdu_type, elem_names, elem_ett, elem_funcs);
7213
7214     oct = tvb_get_guint8(tvb, curr_offset);
7215
7216     if (oct == iei)
7217     {
7218         proto_tree_add_uint_format(tree,
7219             (BSSAP_PDU_TYPE_BSSMAP == pdu_type) ? hf_gsm_a_bssmap_elem_id : hf_gsm_a_dtap_elem_id, tvb,
7220             curr_offset, 1, oct,
7221             "%s%s",
7222             elem_names[idx].strptr,
7223             (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
7224
7225         consumed = 1;
7226     }
7227
7228     return(consumed);
7229 }
7230
7231 /*
7232  * Length Value (LV) element dissector
7233  */
7234 static guint8
7235 elem_lv(tvbuff_t *tvb, proto_tree *tree, gint pdu_type, int idx, guint32 offset, guint len, gchar *name_add)
7236 {
7237     guint8              parm_len;
7238     guint8              consumed;
7239     guint32             curr_offset;
7240     proto_tree          *subtree;
7241     proto_item          *item;
7242     const value_string  *elem_names;
7243     gint                *elem_ett;
7244     guint8 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string);
7245
7246     len = len;
7247     curr_offset = offset;
7248     consumed = 0;
7249
7250     SET_ELEM_VARS(pdu_type, elem_names, elem_ett, elem_funcs);
7251
7252     parm_len = tvb_get_guint8(tvb, curr_offset);
7253
7254     item =
7255         proto_tree_add_text(tree,
7256             tvb, curr_offset, parm_len + 1,
7257             "%s%s",
7258             elem_names[idx].strptr,
7259             (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
7260
7261     subtree = proto_item_add_subtree(item, elem_ett[idx]);
7262
7263     proto_tree_add_uint(subtree, hf_gsm_a_length, tvb,
7264         curr_offset, 1, parm_len);
7265
7266     if (parm_len > 0)
7267     {
7268         if (elem_funcs[idx] == NULL)
7269         {
7270             proto_tree_add_text(subtree,
7271                 tvb, curr_offset + 1, parm_len,
7272                 "Element Value");
7273
7274             consumed = parm_len;
7275         }
7276         else
7277         {
7278             a_add_string[0] = '\0';
7279             consumed =
7280                 (*elem_funcs[idx])(tvb, subtree, curr_offset + 1,
7281                     parm_len, a_add_string);
7282
7283             if (a_add_string[0] != '\0')
7284             {
7285                 proto_item_append_text(item, a_add_string);
7286                 a_add_string[0] = '\0';
7287             }
7288         }
7289     }
7290
7291     return(consumed + 1);
7292 }
7293
7294 /*
7295  * Value (V) element dissector
7296  *
7297  * Length cannot be used in these functions, big problem if a element dissector
7298  * is not defined for these.
7299  */
7300 static guint8
7301 elem_v(tvbuff_t *tvb, proto_tree *tree, gint pdu_type, int idx, guint32 offset)
7302 {
7303     guint8              consumed;
7304     guint32             curr_offset;
7305     const value_string  *elem_names;
7306     gint                *elem_ett;
7307     guint8 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string);
7308
7309     curr_offset = offset;
7310     consumed = 0;
7311
7312     SET_ELEM_VARS(pdu_type, elem_names, elem_ett, elem_funcs);
7313
7314     if (elem_funcs[idx] == NULL)
7315     {
7316         /* BAD THING, CANNOT DETERMINE LENGTH */
7317
7318         proto_tree_add_text(tree,
7319             tvb, curr_offset, 1,
7320             "No element dissector, rest of dissection may be incorrect");
7321
7322         consumed = 1;
7323     }
7324     else
7325     {
7326         a_add_string[0] = '\0';
7327         consumed = (*elem_funcs[idx])(tvb, tree, curr_offset, -1, a_add_string);
7328         a_add_string[0] = '\0';
7329     }
7330
7331     return(consumed);
7332 }
7333
7334 #define ELEM_MAND_TLV(EMT_iei, EMT_pdu_type, EMT_elem_idx, EMT_elem_name_addition) \
7335 {\
7336     if ((consumed = elem_tlv(tvb, tree, (guint8) EMT_iei, EMT_pdu_type, EMT_elem_idx, curr_offset, curr_len, EMT_elem_name_addition)) > 0) \
7337     { \
7338         curr_offset += consumed; \
7339         curr_len -= consumed; \
7340     } \
7341     else \
7342     { \
7343         proto_tree_add_text(tree, \
7344             tvb, curr_offset, 0, \
7345             "Missing Mandatory element (0x%02x) %s%s, rest of dissection is suspect", \
7346                 EMT_iei, \
7347                 (EMT_pdu_type == BSSAP_PDU_TYPE_BSSMAP) ? \
7348                     gsm_bssmap_elem_strings[EMT_elem_idx].strptr : gsm_dtap_elem_strings[EMT_elem_idx].strptr, \
7349                 (EMT_elem_name_addition == NULL) || (EMT_elem_name_addition[0] == '\0') ? "" : EMT_elem_name_addition \
7350             ); \
7351     } \
7352     if (curr_len <= 0) return; \
7353 }
7354
7355 #define ELEM_OPT_TLV(EOT_iei, EOT_pdu_type, EOT_elem_idx, EOT_elem_name_addition) \
7356 {\
7357     if ((consumed = elem_tlv(tvb, tree, (guint8) EOT_iei, EOT_pdu_type, EOT_elem_idx, curr_offset, curr_len, EOT_elem_name_addition)) > 0) \
7358     { \
7359         curr_offset += consumed; \
7360         curr_len -= consumed; \
7361     } \
7362     if (curr_len <= 0) return; \
7363 }
7364
7365 #define ELEM_MAND_TV(EMT_iei, EMT_pdu_type, EMT_elem_idx, EMT_elem_name_addition) \
7366 {\
7367     if ((consumed = elem_tv(tvb, tree, (guint8) EMT_iei, EMT_pdu_type, EMT_elem_idx, curr_offset, EMT_elem_name_addition)) > 0) \
7368     { \
7369         curr_offset += consumed; \
7370         curr_len -= consumed; \
7371     } \
7372     else \
7373     { \
7374         proto_tree_add_text(tree, \
7375             tvb, curr_offset, 0, \
7376             "Missing Mandatory element (0x%02x) %s%s, rest of dissection is suspect", \
7377                 EMT_iei, \
7378                 (EMT_pdu_type == BSSAP_PDU_TYPE_BSSMAP) ? \
7379                     gsm_bssmap_elem_strings[EMT_elem_idx].strptr : gsm_dtap_elem_strings[EMT_elem_idx].strptr, \
7380                 (EMT_elem_name_addition == NULL) || (EMT_elem_name_addition[0] == '\0') ? "" : EMT_elem_name_addition \
7381             ); \
7382     } \
7383     if (curr_len <= 0) return; \
7384 }
7385
7386 #define ELEM_OPT_TV(EOT_iei, EOT_pdu_type, EOT_elem_idx, EOT_elem_name_addition) \
7387 {\
7388     if ((consumed = elem_tv(tvb, tree, (guint8) EOT_iei, EOT_pdu_type, EOT_elem_idx, curr_offset, EOT_elem_name_addition)) > 0) \
7389     { \
7390         curr_offset += consumed; \
7391         curr_len -= consumed; \
7392     } \
7393     if (curr_len <= 0) return; \
7394 }
7395
7396 #define ELEM_OPT_TV_SHORT(EOT_iei, EOT_pdu_type, EOT_elem_idx, EOT_elem_name_addition) \
7397 {\
7398     if ((consumed = elem_tv_short(tvb, tree, EOT_iei, EOT_pdu_type, EOT_elem_idx, curr_offset, EOT_elem_name_addition)) > 0) \
7399     { \
7400         curr_offset += consumed; \
7401         curr_len -= consumed; \
7402     } \
7403     if (curr_len <= 0) return; \
7404 }
7405
7406 #define ELEM_OPT_T(EOT_iei, EOT_pdu_type, EOT_elem_idx, EOT_elem_name_addition) \
7407 {\
7408     if ((consumed = elem_t(tvb, tree, (guint8) EOT_iei, EOT_pdu_type, EOT_elem_idx, curr_offset, EOT_elem_name_addition)) > 0) \
7409     { \
7410         curr_offset += consumed; \
7411         curr_len -= consumed; \
7412     } \
7413     if (curr_len <= 0) return; \
7414 }
7415
7416 #define ELEM_MAND_LV(EML_pdu_type, EML_elem_idx, EML_elem_name_addition) \
7417 {\
7418     if ((consumed = elem_lv(tvb, tree, EML_pdu_type, EML_elem_idx, curr_offset, curr_len, EML_elem_name_addition)) > 0) \
7419     { \
7420         curr_offset += consumed; \
7421         curr_len -= consumed; \
7422     } \
7423     else \
7424     { \
7425         /* Mandatory, but nothing we can do */ \
7426     } \
7427     if (curr_len <= 0) return; \
7428 }
7429
7430 #define ELEM_MAND_V(EMV_pdu_type, EMV_elem_idx) \
7431 {\
7432     if ((consumed = elem_v(tvb, tree, EMV_pdu_type, EMV_elem_idx, curr_offset)) > 0) \
7433     { \
7434         curr_offset += consumed; \
7435         curr_len -= consumed; \
7436     } \
7437     else \
7438     { \
7439         /* Mandatory, but nothing we can do */ \
7440     } \
7441     if (curr_len <= 0) return; \
7442 }
7443
7444
7445 /* MESSAGE FUNCTIONS */
7446
7447 /*
7448  *  [2] 3.2.1.1
7449  */
7450 static void
7451 bssmap_ass_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7452 {
7453     guint32     curr_offset;
7454     guint32     consumed;
7455     guint       curr_len;
7456
7457     curr_offset = offset;
7458     curr_len = len;
7459
7460     is_uplink = IS_UPLINK_FALSE;
7461
7462     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CHAN_TYPE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHAN_TYPE, "");
7463
7464     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_L3_HEADER_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_L3_HEADER_INFO, "");
7465
7466     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_PRIO].value, BSSAP_PDU_TYPE_BSSMAP, BE_PRIO, "");
7467
7468     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
7469
7470     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_DOWN_DTX_FLAG].value, BSSAP_PDU_TYPE_BSSMAP, BE_DOWN_DTX_FLAG, "");
7471
7472     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_INT_BAND].value, BSSAP_PDU_TYPE_BSSMAP, BE_INT_BAND, "");
7473
7474     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CM_INFO_2].value, BSSAP_PDU_TYPE_BSSMAP, BE_CM_INFO_2, "");
7475
7476     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_GROUP_CALL_REF].value, BSSAP_PDU_TYPE_BSSMAP, BE_GROUP_CALL_REF, "");
7477
7478     ELEM_OPT_T(gsm_bssmap_elem_strings[BE_TALKER_FLAG].value, BSSAP_PDU_TYPE_BSSMAP, BE_TALKER_FLAG, "");
7479
7480     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_LSA_ACC_CTRL].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_ACC_CTRL, "");
7481
7482     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7483 }
7484
7485 /*
7486  *  [2] 3.2.1.2
7487  */
7488 static void
7489 bssmap_ass_complete(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7490 {
7491     guint32     curr_offset;
7492     guint32     consumed;
7493     guint       curr_len;
7494
7495     curr_offset = offset;
7496     curr_len = len;
7497
7498     is_uplink = IS_UPLINK_TRUE;
7499
7500     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_RR_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_RR_CAUSE, "");
7501
7502     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
7503
7504     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
7505
7506     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_CHAN].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_CHAN, "");
7507
7508     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_ENC_ALG].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_ENC_ALG, "");
7509
7510     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CCT_POOL].value, BSSAP_PDU_TYPE_BSSMAP, BE_CCT_POOL, "");
7511
7512     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_SPEECH_VER].value, BSSAP_PDU_TYPE_BSSMAP, BE_SPEECH_VER, " (Chosen)");
7513
7514     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_LSA_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_ID, "");
7515
7516     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7517 }
7518
7519 /*
7520  *  [2] 3.2.1.3
7521  */
7522 static void
7523 bssmap_ass_failure(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7524 {
7525     guint32     curr_offset;
7526     guint32     consumed;
7527     guint       curr_len;
7528
7529     curr_offset = offset;
7530     curr_len = len;
7531
7532     is_uplink = IS_UPLINK_TRUE;
7533
7534     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
7535
7536     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_RR_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_RR_CAUSE, "");
7537
7538     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CCT_POOL].value, BSSAP_PDU_TYPE_BSSMAP, BE_CCT_POOL, "");
7539
7540     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CCT_POOL_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CCT_POOL_LIST, "");
7541
7542     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7543 }
7544
7545 /*
7546  *  [2] 3.2.1.4
7547  */
7548 static void
7549 bssmap_block(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7550 {
7551     guint32     curr_offset;
7552     guint32     consumed;
7553     guint       curr_len;
7554
7555     curr_offset = offset;
7556     curr_len = len;
7557
7558     is_uplink = IS_UPLINK_TRUE;
7559
7560     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
7561
7562     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
7563
7564     ELEM_OPT_T(gsm_bssmap_elem_strings[BE_CONN_REL_REQ].value, BSSAP_PDU_TYPE_BSSMAP, BE_CONN_REL_REQ, "");
7565
7566     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7567 }
7568
7569 /*
7570  *  [2] 3.2.1.5
7571  */
7572 static void
7573 bssmap_block_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7574 {
7575     guint32     curr_offset;
7576     guint32     consumed;
7577     guint       curr_len;
7578
7579     curr_offset = offset;
7580     curr_len = len;
7581
7582     is_uplink = IS_UPLINK_TRUE;
7583
7584     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
7585
7586     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7587 }
7588
7589 /*
7590  *  [2] 3.2.1.6
7591  */
7592 static void
7593 bssmap_unblock(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7594 {
7595     guint32     curr_offset;
7596     guint32     consumed;
7597     guint       curr_len;
7598
7599     curr_offset = offset;
7600     curr_len = len;
7601
7602     is_uplink = IS_UPLINK_TRUE;
7603
7604     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
7605
7606     ELEM_OPT_T(gsm_bssmap_elem_strings[BE_CONN_REL_REQ].value, BSSAP_PDU_TYPE_BSSMAP, BE_CONN_REL_REQ, "");
7607
7608     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7609 }
7610
7611 /*
7612  *  [2] 3.2.1.7
7613  */
7614 static void
7615 bssmap_unblock_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7616 {
7617     guint32     curr_offset;
7618     guint32     consumed;
7619     guint       curr_len;
7620
7621     curr_offset = offset;
7622     curr_len = len;
7623
7624     is_uplink = IS_UPLINK_TRUE;
7625
7626     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
7627
7628     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7629 }
7630
7631 /*
7632  *  [2] 3.2.1.8
7633  */
7634 static void
7635 bssmap_ho_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7636 {
7637     guint32     curr_offset;
7638     guint32     consumed;
7639     guint       curr_len;
7640
7641     curr_offset = offset;
7642     curr_len = len;
7643
7644     is_uplink = IS_UPLINK_FALSE;
7645
7646     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CHAN_TYPE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHAN_TYPE, "");
7647
7648     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_ENC_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_ENC_INFO, "");
7649
7650     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CM_INFO_1].value, BSSAP_PDU_TYPE_BSSMAP, BE_CM_INFO_1, "");
7651
7652     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CM_INFO_2].value, BSSAP_PDU_TYPE_BSSMAP, BE_CM_INFO_2, "");
7653
7654     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, " (Serving)");
7655
7656     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_PRIO].value, BSSAP_PDU_TYPE_BSSMAP, BE_PRIO, "");
7657
7658     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
7659
7660     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_DOWN_DTX_FLAG].value, BSSAP_PDU_TYPE_BSSMAP, BE_DOWN_DTX_FLAG, "");
7661
7662     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, " (Target)");
7663
7664     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_INT_BAND].value, BSSAP_PDU_TYPE_BSSMAP, BE_INT_BAND, "");
7665
7666     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
7667
7668     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CM_INFO_3].value, BSSAP_PDU_TYPE_BSSMAP, BE_CM_INFO_3, "");
7669
7670     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CURR_CHAN_1].value, BSSAP_PDU_TYPE_BSSMAP, BE_CURR_CHAN_1, "");
7671
7672     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_SPEECH_VER].value, BSSAP_PDU_TYPE_BSSMAP, BE_SPEECH_VER, " (Used)");
7673
7674     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_GROUP_CALL_REF].value, BSSAP_PDU_TYPE_BSSMAP, BE_GROUP_CALL_REF, "");
7675
7676     ELEM_OPT_T(gsm_bssmap_elem_strings[BE_TALKER_FLAG].value, BSSAP_PDU_TYPE_BSSMAP, BE_TALKER_FLAG, "");
7677
7678     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CONF_EVO_IND].value, BSSAP_PDU_TYPE_BSSMAP, BE_CONF_EVO_IND, "");
7679
7680     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_ENC_ALG].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_ENC_ALG, " (Serving)");
7681
7682     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_OLD2NEW_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_OLD2NEW_INFO, "");
7683
7684     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_LSA_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_INFO, "");
7685
7686     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_LSA_ACC_CTRL].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_ACC_CTRL, "");
7687
7688     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7689 }
7690
7691 /*
7692  *  [2] 3.2.1.9
7693  */
7694 static void
7695 bssmap_ho_reqd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7696 {
7697     guint32     curr_offset;
7698     guint32     consumed;
7699     guint       curr_len;
7700
7701     curr_offset = offset;
7702     curr_len = len;
7703
7704     is_uplink = IS_UPLINK_TRUE;
7705
7706     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
7707
7708     ELEM_OPT_T(gsm_bssmap_elem_strings[BE_RESP_REQ].value, BSSAP_PDU_TYPE_BSSMAP, BE_RESP_REQ, "");
7709
7710     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID_LIST, " (Preferred)");
7711
7712     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CCT_POOL_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CCT_POOL_LIST, "");
7713
7714     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CURR_CHAN_1].value, BSSAP_PDU_TYPE_BSSMAP, BE_CURR_CHAN_1, "");
7715
7716     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_SPEECH_VER].value, BSSAP_PDU_TYPE_BSSMAP, BE_SPEECH_VER, " (Used)");
7717
7718     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_QUE_IND].value, BSSAP_PDU_TYPE_BSSMAP, BE_QUE_IND, "");
7719
7720     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_OLD2NEW_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_OLD2NEW_INFO, "");
7721
7722     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7723 }
7724
7725 /*
7726  *  [2] 3.2.1.10
7727  */
7728 static void
7729 bssmap_ho_req_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7730 {
7731     guint32     curr_offset;
7732     guint32     consumed;
7733     guint       curr_len;
7734
7735     curr_offset = offset;
7736     curr_len = len;
7737
7738     is_uplink = IS_UPLINK_TRUE;
7739
7740     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_L3_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_L3_INFO, "");
7741
7742     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_CHAN].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_CHAN, "");
7743
7744     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_ENC_ALG].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_ENC_ALG, "");
7745
7746     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CCT_POOL].value, BSSAP_PDU_TYPE_BSSMAP, BE_CCT_POOL, "");
7747
7748     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_SPEECH_VER].value, BSSAP_PDU_TYPE_BSSMAP, BE_SPEECH_VER, " (Chosen)");
7749
7750     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
7751
7752     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_LSA_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_ID, "");
7753
7754     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7755 }
7756
7757 /*
7758  *  [2] 3.2.1.11
7759  */
7760 static void
7761 bssmap_ho_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7762 {
7763     guint32     curr_offset;
7764     guint32     consumed;
7765     guint       curr_len;
7766
7767     curr_offset = offset;
7768     curr_len = len;
7769
7770     is_uplink = IS_UPLINK_FALSE;
7771
7772     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_L3_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_L3_INFO, "");
7773
7774     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
7775
7776     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7777 }
7778
7779 /*
7780  *  [2] 3.2.1.12
7781  */
7782 static void
7783 bssmap_ho_complete(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7784 {
7785     guint32     curr_offset;
7786     guint32     consumed;
7787     guint       curr_len;
7788
7789     curr_offset = offset;
7790     curr_len = len;
7791
7792     is_uplink = IS_UPLINK_TRUE;
7793
7794     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_RR_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_RR_CAUSE, "");
7795
7796     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7797 }
7798
7799 /*
7800  *  [2] 3.2.1.14
7801  */
7802 static void
7803 bssmap_ho_cand_enq(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7804 {
7805     guint32     curr_offset;
7806     guint32     consumed;
7807     guint       curr_len;
7808
7809     curr_offset = offset;
7810     curr_len = len;
7811
7812     is_uplink = IS_UPLINK_FALSE;
7813
7814     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_NUM_MS].value, BSSAP_PDU_TYPE_BSSMAP, BE_NUM_MS, "");
7815
7816     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID_LIST, "");
7817
7818     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
7819
7820     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7821 }
7822
7823 /*
7824  *  [2] 3.2.1.15
7825  */
7826 static void
7827 bssmap_ho_cand_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7828 {
7829     guint32     curr_offset;
7830     guint32     consumed;
7831     guint       curr_len;
7832
7833     curr_offset = offset;
7834     curr_len = len;
7835
7836     is_uplink = IS_UPLINK_TRUE;
7837
7838     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_NUM_MS].value, BSSAP_PDU_TYPE_BSSMAP, BE_NUM_MS, "");
7839
7840     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
7841
7842     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7843 }
7844
7845 /*
7846  *  [2] 3.2.1.16
7847  */
7848 static void
7849 bssmap_ho_failure(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7850 {
7851     guint32     curr_offset;
7852     guint32     consumed;
7853     guint       curr_len;
7854
7855     curr_offset = offset;
7856     curr_len = len;
7857
7858     is_uplink = IS_UPLINK_TRUE;
7859
7860     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
7861
7862     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_RR_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_RR_CAUSE, "");
7863
7864     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CCT_POOL].value, BSSAP_PDU_TYPE_BSSMAP, BE_CCT_POOL, "");
7865
7866     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CCT_POOL_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CCT_POOL_LIST, "");
7867
7868     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7869 }
7870
7871 /*
7872  *  [2] 3.2.1.19
7873  */
7874 static void
7875 bssmap_paging(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7876 {
7877     guint32     curr_offset;
7878     guint32     consumed;
7879     guint       curr_len;
7880
7881     curr_offset = offset;
7882     curr_len = len;
7883
7884     is_uplink = IS_UPLINK_FALSE;
7885
7886     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_IMSI].value, BSSAP_PDU_TYPE_BSSMAP, BE_IMSI, "");
7887
7888     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_TMSI].value, BSSAP_PDU_TYPE_BSSMAP, BE_TMSI, "");
7889
7890     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID_LIST, "");
7891
7892     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CHAN_NEEDED].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHAN_NEEDED, "");
7893
7894     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_EMLPP_PRIO].value, BSSAP_PDU_TYPE_BSSMAP, BE_EMLPP_PRIO, "");
7895
7896     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7897 }
7898
7899 /*
7900  *  [2] 3.2.1.20
7901  */
7902 static void
7903 bssmap_clear_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7904 {
7905     guint32     curr_offset;
7906     guint32     consumed;
7907     guint       curr_len;
7908
7909     curr_offset = offset;
7910     curr_len = len;
7911
7912     is_uplink = IS_UPLINK_TRUE;
7913
7914     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
7915
7916     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7917 }
7918
7919 /*
7920  *  [2] 3.2.1.21
7921  */
7922 static void
7923 bssmap_clear_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7924 {
7925     guint32     curr_offset;
7926     guint32     consumed;
7927     guint       curr_len;
7928
7929     curr_offset = offset;
7930     curr_len = len;
7931
7932     is_uplink = IS_UPLINK_FALSE;
7933
7934     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_L3_HEADER_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_L3_HEADER_INFO, "");
7935
7936     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
7937
7938     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7939 }
7940
7941 /*
7942  *  [2] 3.2.1.23
7943  */
7944 static void
7945 bssmap_reset(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7946 {
7947     guint32     curr_offset;
7948     guint32     consumed;
7949     guint       curr_len;
7950
7951     curr_offset = offset;
7952     curr_len = len;
7953
7954     is_uplink = IS_UPLINK_UNKNOWN;
7955
7956     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
7957
7958     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7959 }
7960
7961 /*
7962  *  [2] 3.2.1.25
7963  */
7964 static void
7965 bssmap_ho_performed(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7966 {
7967     guint32     curr_offset;
7968     guint32     consumed;
7969     guint       curr_len;
7970
7971     curr_offset = offset;
7972     curr_len = len;
7973
7974     is_uplink = IS_UPLINK_TRUE;
7975
7976     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
7977
7978     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
7979
7980     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_CHAN].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_CHAN, "");
7981
7982     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_ENC_ALG].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_ENC_ALG, "");
7983
7984     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_SPEECH_VER].value, BSSAP_PDU_TYPE_BSSMAP, BE_SPEECH_VER, " (Chosen)");
7985
7986     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_LSA_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_ID, "");
7987
7988     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7989 }
7990
7991 /*
7992  *  [2] 3.2.1.26
7993  */
7994 static void
7995 bssmap_overload(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7996 {
7997     guint32     curr_offset;
7998     guint32     consumed;
7999     guint       curr_len;
8000
8001     curr_offset = offset;
8002     curr_len = len;
8003
8004     is_uplink = IS_UPLINK_TRUE;
8005
8006     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
8007
8008     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
8009
8010     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8011 }
8012
8013 /*
8014  *  [2] 3.2.1.29
8015  */
8016 static void
8017 bssmap_cm_upd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8018 {
8019     guint32     curr_offset;
8020     guint32     consumed;
8021     guint       curr_len;
8022
8023     curr_offset = offset;
8024     curr_len = len;
8025
8026     is_uplink = IS_UPLINK_FALSE;
8027
8028     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CM_INFO_2].value, BSSAP_PDU_TYPE_BSSMAP, BE_CM_INFO_2, "");
8029
8030     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CM_INFO_3].value, BSSAP_PDU_TYPE_BSSMAP, BE_CM_INFO_3, "");
8031
8032     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8033 }
8034
8035 /*
8036  *  [2] 3.2.1.30
8037  */
8038 static void
8039 bssmap_ciph_mode_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8040 {
8041     guint32     curr_offset;
8042     guint32     consumed;
8043     guint       curr_len;
8044
8045     curr_offset = offset;
8046     curr_len = len;
8047
8048     is_uplink = IS_UPLINK_FALSE;
8049
8050     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_L3_HEADER_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_L3_HEADER_INFO, "");
8051
8052     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_ENC_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_ENC_INFO, "");
8053
8054     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CIPH_RESP_MODE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIPH_RESP_MODE, "");
8055
8056     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8057 }
8058
8059 /*
8060  *  [2] 3.2.1.31
8061  */
8062 static void
8063 bssmap_ciph_mode_complete(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8064 {
8065     guint32     curr_offset;
8066     guint32     consumed;
8067     guint       curr_len;
8068
8069     curr_offset = offset;
8070     curr_len = len;
8071
8072     is_uplink = IS_UPLINK_TRUE;
8073
8074     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_L3_MSG].value, BSSAP_PDU_TYPE_BSSMAP, BE_L3_MSG, "");
8075
8076     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_ENC_ALG].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_ENC_ALG, "");
8077
8078     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8079 }
8080
8081 /*
8082  * [2] 3.2.1.32
8083  */
8084 static void
8085 bssmap_cl3_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8086 {
8087     guint8      consumed;
8088     guint32     curr_offset;
8089     guint       curr_len;
8090
8091     curr_offset = offset;
8092     curr_len = len;
8093
8094     is_uplink = IS_UPLINK_TRUE;
8095
8096     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
8097
8098     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_L3_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_L3_INFO, "");
8099
8100     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_CHAN].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_CHAN, "");
8101
8102     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_LSA_ID_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_ID_LIST, "");
8103
8104     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_APDU].value, BSSAP_PDU_TYPE_BSSMAP, BE_APDU, "");
8105
8106     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8107 }
8108
8109 /*
8110  * [2] 3.2.1.34
8111  */
8112 static void
8113 bssmap_sapi_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8114 {
8115     guint8      consumed;
8116     guint32     curr_offset;
8117     guint       curr_len;
8118
8119     curr_offset = offset;
8120     curr_len = len;
8121
8122     is_uplink = IS_UPLINK_TRUE;
8123
8124     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_DLCI].value, BSSAP_PDU_TYPE_BSSMAP, BE_DLCI, "");
8125
8126     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
8127
8128     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8129 }
8130
8131 /*
8132  *  [2] 3.2.1.37
8133  */
8134 static void
8135 bssmap_ho_reqd_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8136 {
8137     guint32     curr_offset;
8138     guint32     consumed;
8139     guint       curr_len;
8140
8141     curr_offset = offset;
8142     curr_len = len;
8143
8144     is_uplink = IS_UPLINK_FALSE;
8145
8146     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
8147
8148     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8149 }
8150
8151 /*
8152  *  [2] 3.2.1.38
8153  */
8154 static void
8155 bssmap_reset_cct(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8156 {
8157     guint32     curr_offset;
8158     guint32     consumed;
8159     guint       curr_len;
8160
8161     curr_offset = offset;
8162     curr_len = len;
8163
8164     is_uplink = IS_UPLINK_TRUE;
8165
8166     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
8167
8168     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
8169
8170     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8171 }
8172
8173 /*
8174  *  [2] 3.2.1.39
8175  */
8176 static void
8177 bssmap_reset_cct_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8178 {
8179     guint32     curr_offset;
8180     guint32     consumed;
8181     guint       curr_len;
8182
8183     curr_offset = offset;
8184     curr_len = len;
8185
8186     is_uplink = IS_UPLINK_TRUE;
8187
8188     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
8189
8190     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8191 }
8192
8193 /*
8194  *  [2] 3.2.1.41
8195  */
8196 static void
8197 bssmap_cct_group_block(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8198 {
8199     guint32     curr_offset;
8200     guint32     consumed;
8201     guint       curr_len;
8202
8203     curr_offset = offset;
8204     curr_len = len;
8205
8206     is_uplink = IS_UPLINK_TRUE;
8207
8208     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
8209
8210     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
8211
8212     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC_LIST, "");
8213
8214     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8215 }
8216
8217 /*
8218  *  [2] 3.2.1.42
8219  */
8220 static void
8221 bssmap_cct_group_block_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8222 {
8223     guint32     curr_offset;
8224     guint32     consumed;
8225     guint       curr_len;
8226
8227     curr_offset = offset;
8228     curr_len = len;
8229
8230     is_uplink = IS_UPLINK_TRUE;
8231
8232     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
8233
8234     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC_LIST, "");
8235
8236     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8237 }
8238
8239 /*
8240  *  [2] 3.2.1.43
8241  */
8242 static void
8243 bssmap_cct_group_unblock(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8244 {
8245     guint32     curr_offset;
8246     guint32     consumed;
8247     guint       curr_len;
8248
8249     curr_offset = offset;
8250     curr_len = len;
8251
8252     is_uplink = IS_UPLINK_TRUE;
8253
8254     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
8255
8256     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC_LIST, "");
8257
8258     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8259 }
8260
8261 /*
8262  *  [2] 3.2.1.44
8263  */
8264 static void
8265 bssmap_cct_group_unblock_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8266 {
8267     guint32     curr_offset;
8268     guint32     consumed;
8269     guint       curr_len;
8270
8271     curr_offset = offset;
8272     curr_len = len;
8273
8274     is_uplink = IS_UPLINK_TRUE;
8275
8276     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
8277
8278     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC_LIST, "");
8279
8280     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8281 }
8282
8283 /*
8284  *  [2] 3.2.1.45
8285  */
8286 static void
8287 bssmap_confusion(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8288 {
8289     guint32     curr_offset;
8290     guint32     consumed;
8291     guint       curr_len;
8292
8293     curr_offset = offset;
8294     curr_len = len;
8295
8296     is_uplink = IS_UPLINK_TRUE;
8297
8298     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
8299
8300     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_DIAG].value, BSSAP_PDU_TYPE_BSSMAP, BE_DIAG, "");
8301
8302     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8303 }
8304
8305 /*
8306  *  [2] 3.2.1.47
8307  */
8308 static void
8309 bssmap_unequipped_cct(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8310 {
8311     guint32     curr_offset;
8312     guint32     consumed;
8313     guint       curr_len;
8314
8315     curr_offset = offset;
8316     curr_len = len;
8317
8318     is_uplink = IS_UPLINK_TRUE;
8319
8320     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
8321
8322     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CIC_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC_LIST, "");
8323
8324     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8325 }
8326
8327 /*
8328  *  [2] 3.2.1.48
8329  */
8330 static void
8331 bssmap_ciph_mode_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8332 {
8333     guint32     curr_offset;
8334     guint32     consumed;
8335     guint       curr_len;
8336
8337     curr_offset = offset;
8338     curr_len = len;
8339
8340     is_uplink = IS_UPLINK_TRUE;
8341
8342     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
8343
8344     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8345 }
8346
8347 /*
8348  *  [2] 3.2.1.49
8349  */
8350 static void
8351 bssmap_load_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8352 {
8353     guint32     curr_offset;
8354     guint32     consumed;
8355     guint       curr_len;
8356
8357     curr_offset = offset;
8358     curr_len = len;
8359
8360     is_uplink = IS_UPLINK_TRUE;
8361
8362     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_TIME_IND].value, BSSAP_PDU_TYPE_BSSMAP, BE_TIME_IND, "");
8363
8364     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
8365
8366     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID_LIST, " (Target)");
8367
8368     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_RES_SIT].value, BSSAP_PDU_TYPE_BSSMAP, BE_RES_SIT, "");
8369
8370     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
8371
8372     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8373 }
8374
8375 /*
8376  *  [2] 3.2.1.66
8377  */
8378 static void
8379 bssmap_change_cct(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8380 {
8381     guint32     curr_offset;
8382     guint32     consumed;
8383     guint       curr_len;
8384
8385     curr_offset = offset;
8386     curr_len = len;
8387
8388     is_uplink = IS_UPLINK_FALSE;
8389
8390     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
8391
8392     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8393 }
8394
8395 /*
8396  *  [2] 3.2.1.67
8397  */
8398 static void
8399 bssmap_change_cct_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8400 {
8401     guint32     curr_offset;
8402     guint32     consumed;
8403     guint       curr_len;
8404
8405     curr_offset = offset;
8406     curr_len = len;
8407
8408     is_uplink = IS_UPLINK_TRUE;
8409
8410     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
8411
8412     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8413 }
8414
8415 /*
8416  *  [2] 3.2.1.69
8417  */
8418 static void
8419 bssmap_lsa_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8420 {
8421     guint32     curr_offset;
8422     guint32     consumed;
8423     guint       curr_len;
8424
8425     curr_offset = offset;
8426     curr_len = len;
8427
8428     is_uplink = IS_UPLINK_FALSE;
8429
8430     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_LSA_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_INFO, "");
8431
8432     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8433 }
8434
8435 /*
8436  *  [2] 3.2.1.70
8437  */
8438 static void
8439 bssmap_conn_oriented(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8440 {
8441     guint32     curr_offset;
8442     guint32     consumed;
8443     guint       curr_len;
8444
8445     curr_offset = offset;
8446     curr_len = len;
8447
8448     is_uplink = IS_UPLINK_FALSE;
8449
8450     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_APDU].value, BSSAP_PDU_TYPE_BSSMAP, BE_APDU, "");
8451
8452     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_SEG].value, BSSAP_PDU_TYPE_BSSMAP, BE_SEG, "");
8453
8454     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8455 }
8456
8457 #define NUM_GSM_BSSMAP_MSG (sizeof(gsm_a_bssmap_msg_strings)/sizeof(value_string))
8458 static gint ett_gsm_bssmap_msg[NUM_GSM_BSSMAP_MSG];
8459 static void (*bssmap_msg_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
8460     bssmap_ass_req,     /* Assignment Request */
8461     bssmap_ass_complete,        /* Assignment Complete */
8462     bssmap_ass_failure, /* Assignment Failure */
8463     bssmap_ho_req,      /* Handover Request */
8464     bssmap_ho_reqd,     /* Handover Required */
8465     bssmap_ho_req_ack,  /* Handover Request Acknowledge */
8466     bssmap_ho_cmd,      /* Handover Command */
8467     bssmap_ho_complete, /* Handover Complete */
8468     NULL /* no associated data */,      /* Handover Succeeded */
8469     bssmap_ho_failure,  /* Handover Failure */
8470     bssmap_ho_performed,        /* Handover Performed */
8471     bssmap_ho_cand_enq, /* Handover Candidate Enquire */
8472     bssmap_ho_cand_resp,        /* Handover Candidate Response */
8473     bssmap_ho_reqd_rej, /* Handover Required Reject */
8474     NULL /* no associated data */,      /* Handover Detect */
8475     bssmap_clear_cmd,   /* Clear Command */
8476     NULL /* no associated data */,      /* Clear Complete */
8477     bssmap_clear_req,   /* Clear Request */
8478     NULL,       /* Reserved */
8479     NULL,       /* Reserved */
8480     bssmap_sapi_rej,    /* SAPI 'n' Reject */
8481     bssmap_confusion,   /* Confusion */
8482     NULL,       /* Suspend */
8483     NULL,       /* Resume */
8484     bssmap_conn_oriented,       /* Connection Oriented Information */
8485     NULL,       /* Perform Location Request */
8486     bssmap_lsa_info,    /* LSA Information */
8487     NULL,       /* Perform Location Response */
8488     NULL,       /* Perform Location Abort */
8489     bssmap_reset,       /* Reset */
8490     NULL /* no associated data */,      /* Reset Acknowledge */
8491     bssmap_overload,    /* Overload */
8492     NULL,       /* Reserved */
8493     bssmap_reset_cct,   /* Reset Circuit */
8494     bssmap_reset_cct_ack,       /* Reset Circuit Acknowledge */
8495     NULL,       /* MSC Invoke Trace */
8496     NULL,       /* BSS Invoke Trace */
8497     NULL,       /* Connectionless Information */
8498     bssmap_block,       /* Block */
8499     bssmap_block_ack,   /* Blocking Acknowledge */
8500     bssmap_unblock,     /* Unblock */
8501     bssmap_unblock_ack, /* Unblocking Acknowledge */
8502     bssmap_cct_group_block,     /* Circuit Group Block */
8503     bssmap_cct_group_block_ack, /* Circuit Group Blocking Acknowledge */
8504     bssmap_cct_group_unblock,   /* Circuit Group Unblock */
8505     bssmap_cct_group_unblock_ack,       /* Circuit Group Unblocking Acknowledge */
8506     bssmap_unequipped_cct,      /* Unequipped Circuit */
8507     bssmap_change_cct,  /* Change Circuit */
8508     bssmap_change_cct_ack,      /* Change Circuit Acknowledge */
8509     NULL,       /* Resource Request */
8510     NULL,       /* Resource Indication */
8511     bssmap_paging,      /* Paging */
8512     bssmap_ciph_mode_cmd,       /* Cipher Mode Command */
8513     bssmap_cm_upd,      /* Classmark Update */
8514     bssmap_ciph_mode_complete,  /* Cipher Mode Complete */
8515     NULL /* no associated data */,      /* Queuing Indication */
8516     bssmap_cl3_info,    /* Complete Layer 3 Information */
8517     NULL /* no associated data */,      /* Classmark Request */
8518     bssmap_ciph_mode_rej,       /* Cipher Mode Reject */
8519     bssmap_load_ind,    /* Load Indication */
8520     NULL,       /* VGCS/VBS Setup */
8521     NULL,       /* VGCS/VBS Setup Ack */
8522     NULL,       /* VGCS/VBS Setup Refuse */
8523     NULL,       /* VGCS/VBS Assignment Request */
8524     NULL,       /* VGCS/VBS Assignment Result */
8525     NULL,       /* VGCS/VBS Assignment Failure */
8526     NULL,       /* VGCS/VBS Queuing Indication */
8527     NULL,       /* Uplink Request */
8528     NULL,       /* Uplink Request Acknowledge */
8529     NULL,       /* Uplink Request Confirmation */
8530     NULL,       /* Uplink Release Indication */
8531     NULL,       /* Uplink Reject Command */
8532     NULL,       /* Uplink Release Command */
8533     NULL,       /* Uplink Seized Command */
8534     NULL,       /* NONE */
8535 };
8536
8537 /*
8538  * [4] 9.2.2
8539  */
8540 static void
8541 dtap_mm_auth_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8542 {
8543     guint32     curr_offset;
8544     guint32     consumed;
8545     guint       curr_len;
8546     guint8      oct;
8547     proto_tree  *subtree;
8548     proto_item  *item;
8549
8550     curr_offset = offset;
8551     curr_len = len;
8552
8553     is_uplink = IS_UPLINK_FALSE;
8554
8555     /*
8556      * special dissection for Cipher Key Sequence Number
8557      */
8558     oct = tvb_get_guint8(tvb, curr_offset);
8559
8560     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
8561     proto_tree_add_text(tree,
8562         tvb, curr_offset, 1,
8563         "%s :  Spare",
8564         a_bigbuf);
8565
8566     item =
8567         proto_tree_add_text(tree,
8568             tvb, curr_offset, 1,
8569             gsm_dtap_elem_strings[DE_CIPH_KEY_SEQ_NUM].strptr);
8570
8571     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CIPH_KEY_SEQ_NUM]);
8572
8573     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
8574     proto_tree_add_text(subtree,
8575         tvb, curr_offset, 1,
8576         "%s :  Spare",
8577         a_bigbuf);
8578
8579     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
8580
8581     switch (oct & 0x07)
8582     {
8583     case 0x07:
8584         proto_tree_add_text(subtree,
8585             tvb, curr_offset, 1,
8586             "%s :  Ciphering Key Sequence Number: No key is available",
8587             a_bigbuf);
8588         break;
8589
8590     default:
8591         proto_tree_add_text(subtree,
8592             tvb, curr_offset, 1,
8593             "%s :  Ciphering Key Sequence Number: %u",
8594             a_bigbuf,
8595             oct & 0x07);
8596         break;
8597     }
8598
8599     curr_offset++;
8600     curr_len--;
8601
8602     if (curr_len <= 0) return;
8603
8604     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_AUTH_PARAM_RAND);
8605
8606     ELEM_OPT_TLV(0x20, BSSAP_PDU_TYPE_DTAP, DE_AUTH_PARAM_AUTN, "");
8607
8608     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8609 }
8610
8611 /*
8612  * [4] 9.2.3
8613  */
8614 static void
8615 dtap_mm_auth_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8616 {
8617     guint32     curr_offset;
8618     guint32     consumed;
8619     guint       curr_len;
8620
8621     curr_offset = offset;
8622     curr_len = len;
8623
8624     is_uplink = IS_UPLINK_TRUE;
8625
8626     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_AUTH_RESP_PARAM);
8627
8628     ELEM_OPT_TLV(0x21, BSSAP_PDU_TYPE_DTAP, DE_AUTH_RESP_PARAM_EXT, "");
8629
8630     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8631 }
8632
8633 /*
8634  * [4] 9.2.3a
8635  */
8636 static void
8637 dtap_mm_auth_fail(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8638 {
8639     guint32     curr_offset;
8640     guint32     consumed;
8641     guint       curr_len;
8642
8643     curr_offset = offset;
8644     curr_len = len;
8645
8646     is_uplink = IS_UPLINK_TRUE;
8647
8648     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_REJ_CAUSE);
8649
8650     ELEM_OPT_TLV(0x22, BSSAP_PDU_TYPE_DTAP, DE_AUTH_FAIL_PARAM, "");
8651
8652     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8653 }
8654
8655 /*
8656  * [3] 9.2.4
8657  */
8658 static void
8659 dtap_mm_cm_reestab_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8660 {
8661     guint32     curr_offset;
8662     guint32     consumed;
8663     guint       curr_len;
8664     guint8      oct;
8665     proto_tree  *subtree;
8666     proto_item  *item;
8667
8668     curr_offset = offset;
8669     curr_len = len;
8670
8671     is_uplink = IS_UPLINK_TRUE;
8672
8673     /*
8674      * special dissection for Cipher Key Sequence Number
8675      */
8676     oct = tvb_get_guint8(tvb, curr_offset);
8677
8678     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
8679     proto_tree_add_text(tree,
8680         tvb, curr_offset, 1,
8681         "%s :  Spare",
8682         a_bigbuf);
8683
8684     item =
8685         proto_tree_add_text(tree,
8686             tvb, curr_offset, 1,
8687             gsm_dtap_elem_strings[DE_CIPH_KEY_SEQ_NUM].strptr);
8688
8689     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CIPH_KEY_SEQ_NUM]);
8690
8691     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
8692     proto_tree_add_text(subtree,
8693         tvb, curr_offset, 1,
8694         "%s :  Spare",
8695         a_bigbuf);
8696
8697     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
8698
8699     switch (oct & 0x07)
8700     {
8701     case 0x07:
8702         proto_tree_add_text(subtree,
8703             tvb, curr_offset, 1,
8704             "%s :  Ciphering Key Sequence Number: No key is available",
8705             a_bigbuf);
8706         break;
8707
8708     default:
8709         proto_tree_add_text(subtree,
8710             tvb, curr_offset, 1,
8711             "%s :  Ciphering Key Sequence Number: %u",
8712             a_bigbuf,
8713             oct & 0x07);
8714         break;
8715     }
8716
8717     curr_offset++;
8718     curr_len--;
8719
8720     if (curr_len <= 0) return;
8721
8722     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MS_CM_2, "");
8723
8724     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID, "");
8725
8726     ELEM_OPT_TV(0x13, BSSAP_PDU_TYPE_DTAP, DE_LAI, "");
8727
8728     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8729 }
8730
8731 /*
8732  * [3] 9.2.5a
8733  */
8734 static void
8735 dtap_mm_cm_srvc_prompt(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8736 {
8737     guint32     curr_offset;
8738     guint32     consumed;
8739     guint       curr_len;
8740
8741     curr_offset = offset;
8742     curr_len = len;
8743
8744     is_uplink = IS_UPLINK_FALSE;
8745
8746     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_PD_SAPI);
8747
8748     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8749 }
8750
8751 /*
8752  * [4] 9.2.6
8753  */
8754 static void
8755 dtap_mm_cm_srvc_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8756 {
8757     guint32     curr_offset;
8758     guint32     consumed;
8759     guint       curr_len;
8760
8761     curr_offset = offset;
8762     curr_len = len;
8763
8764     is_uplink = IS_UPLINK_FALSE;
8765
8766     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_REJ_CAUSE);
8767
8768     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8769 }
8770
8771 /*
8772  * [4] 9.2.8
8773  */
8774 static void
8775 dtap_mm_abort(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8776 {
8777     guint32     curr_offset;
8778     guint32     consumed;
8779     guint       curr_len;
8780
8781     curr_offset = offset;
8782     curr_len = len;
8783
8784     is_uplink = IS_UPLINK_FALSE;
8785
8786     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_REJ_CAUSE);
8787
8788     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8789 }
8790
8791 /*
8792  * [3] 9.2.9
8793  */
8794 static void
8795 dtap_mm_cm_srvc_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8796 {
8797     guint32     curr_offset;
8798     guint32     consumed;
8799     guint       curr_len;
8800     guint8      oct;
8801     proto_tree  *subtree;
8802     proto_item  *item;
8803     gchar       *str;
8804
8805     curr_offset = offset;
8806     curr_len = len;
8807
8808     is_uplink = IS_UPLINK_TRUE;
8809
8810     /*
8811      * special dissection for CM Service Type
8812      */
8813     oct = tvb_get_guint8(tvb, curr_offset);
8814
8815     item =
8816         proto_tree_add_text(tree,
8817             tvb, curr_offset, 1,
8818             gsm_dtap_elem_strings[DE_CIPH_KEY_SEQ_NUM].strptr);
8819
8820     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CIPH_KEY_SEQ_NUM]);
8821
8822     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
8823     proto_tree_add_text(subtree,
8824         tvb, curr_offset, 1,
8825         "%s :  Spare",
8826         a_bigbuf);
8827
8828     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
8829
8830     switch ((oct & 0x70) >> 4)
8831     {
8832     case 0x07:
8833         proto_tree_add_text(subtree,
8834             tvb, curr_offset, 1,
8835             "%s :  Ciphering Key Sequence Number: No key is available",
8836             a_bigbuf);
8837         break;
8838
8839     default:
8840         proto_tree_add_text(subtree,
8841             tvb, curr_offset, 1,
8842             "%s :  Ciphering Key Sequence Number: %u",
8843             a_bigbuf,
8844             (oct & 0x70) >> 4);
8845         break;
8846     }
8847
8848     item =
8849         proto_tree_add_text(tree,
8850             tvb, curr_offset, 1,
8851             gsm_dtap_elem_strings[DE_CM_SRVC_TYPE].strptr);
8852
8853     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CM_SRVC_TYPE]);
8854
8855     switch (oct & 0x0f)
8856     {
8857     case 0x01: str = "Mobile originating call establishment or packet mode connection establishment"; break;
8858     case 0x02: str = "Emergency call establishment"; break;
8859     case 0x04: str = "Short message service"; break;
8860     case 0x08: str = "Supplementary service activation"; break;
8861     case 0x09: str = "Voice group call establishment"; break;
8862     case 0x0a: str = "Voice broadcast call establishment"; break;
8863     case 0x0b: str = "Location Services"; break;
8864     default:
8865         str = "Reserved";
8866         break;
8867     }
8868
8869     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
8870     proto_tree_add_text(subtree,
8871         tvb, curr_offset, 1,
8872         "%s :  Service Type: (%u) %s",
8873         a_bigbuf,
8874         oct & 0x0f,
8875         str);
8876
8877     curr_offset++;
8878     curr_len--;
8879
8880     if (curr_len <= 0) return;
8881
8882     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MS_CM_2, "");
8883
8884     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID, "");
8885
8886     ELEM_OPT_TV_SHORT(0x80, BSSAP_PDU_TYPE_DTAP, DE_PRIO, "");
8887
8888     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8889 }
8890
8891 /*
8892  * [3] 9.2.10
8893  */
8894 static void
8895 dtap_mm_id_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8896 {
8897     guint8      oct;
8898     guint32     curr_offset;
8899     guint       curr_len;
8900     proto_tree  *subtree;
8901     proto_item  *item;
8902     gchar       *str;
8903
8904     curr_offset = offset;
8905     curr_len = len;
8906
8907     is_uplink = IS_UPLINK_FALSE;
8908
8909     /*
8910      * special dissection for Identity Type
8911      */
8912     oct = tvb_get_guint8(tvb, curr_offset);
8913
8914     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
8915     proto_tree_add_text(tree,
8916         tvb, curr_offset, 1,
8917         "%s :  Spare",
8918         a_bigbuf);
8919
8920     item =
8921         proto_tree_add_text(tree,
8922             tvb, curr_offset, 1,
8923             gsm_dtap_elem_strings[DE_ID_TYPE].strptr);
8924
8925     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_ID_TYPE]);
8926
8927     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
8928     proto_tree_add_text(subtree,
8929         tvb, curr_offset, 1,
8930         "%s :  Spare",
8931         a_bigbuf);
8932
8933     switch (oct & 0x07)
8934     {
8935     case 1: str = "IMSI"; break;
8936     case 2: str = "IMEI"; break;
8937     case 3: str = "IMEISV"; break;
8938     case 4: str = "TMSI"; break;
8939     default:
8940         str = "Reserved";
8941         break;
8942     }
8943
8944     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
8945     proto_tree_add_text(subtree,
8946         tvb, curr_offset, 1,
8947         "%s :  Type of identity: %s",
8948         a_bigbuf,
8949         str);
8950
8951     curr_offset++;
8952     curr_len--;
8953
8954     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8955 }
8956
8957 /*
8958  * [3] 9.2.11
8959  */
8960 static void
8961 dtap_mm_id_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8962 {
8963     guint32     curr_offset;
8964     guint32     consumed;
8965     guint       curr_len;
8966
8967     curr_offset = offset;
8968     curr_len = len;
8969
8970     is_uplink = IS_UPLINK_TRUE;
8971
8972     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID, "");
8973
8974     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8975 }
8976
8977 /*
8978  * [3] 9.2.12
8979  */
8980 static void
8981 dtap_mm_imsi_det_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8982 {
8983     guint32     curr_offset;
8984     guint32     consumed;
8985     guint       curr_len;
8986
8987     curr_offset = offset;
8988     curr_len = len;
8989
8990     is_uplink = IS_UPLINK_TRUE;
8991
8992     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_MS_CM_1);
8993
8994     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID, "");
8995
8996     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8997 }
8998
8999 /*
9000  * [3] 9.2.13
9001  */
9002 static void
9003 dtap_mm_loc_upd_acc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9004 {
9005     guint32     curr_offset;
9006     guint32     consumed;
9007     guint       curr_len;
9008
9009     curr_offset = offset;
9010     curr_len = len;
9011
9012     is_uplink = IS_UPLINK_FALSE;
9013
9014     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_LAI);
9015
9016     ELEM_OPT_TLV(0x17, BSSAP_PDU_TYPE_DTAP, DE_MID, "");
9017
9018     ELEM_OPT_T(0xa1, BSSAP_PDU_TYPE_DTAP, DE_FOP, "");
9019
9020     ELEM_OPT_T(0xa2, BSSAP_PDU_TYPE_DTAP, DE_CTS_PERM, "");
9021
9022     ELEM_OPT_TLV(0x4a, BSSAP_PDU_TYPE_DTAP, DE_PLMN_LIST, " Equivalent");
9023
9024     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9025 }
9026
9027 /*
9028  * [3] 9.2.14
9029  */
9030 static void
9031 dtap_mm_loc_upd_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9032 {
9033     guint32     curr_offset;
9034     guint32     consumed;
9035     guint       curr_len;
9036
9037     curr_offset = offset;
9038     curr_len = len;
9039
9040     is_uplink = IS_UPLINK_FALSE;
9041
9042     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_REJ_CAUSE);
9043
9044     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9045 }
9046
9047 /*
9048  * [3] 9.2.15
9049  */
9050 static void
9051 dtap_mm_loc_upd_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9052 {
9053     guint32     curr_offset;
9054     guint32     consumed;
9055     guint       curr_len;
9056     guint8      oct;
9057     proto_tree  *subtree;
9058     proto_item  *item;
9059     gchar       *str;
9060
9061     curr_offset = offset;
9062     curr_len = len;
9063
9064     is_uplink = IS_UPLINK_TRUE;
9065
9066     /*
9067      * special dissection for Location Updating Type
9068      */
9069     oct = tvb_get_guint8(tvb, curr_offset);
9070
9071     item =
9072         proto_tree_add_text(tree,
9073             tvb, curr_offset, 1,
9074             gsm_dtap_elem_strings[DE_CIPH_KEY_SEQ_NUM].strptr);
9075
9076     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CIPH_KEY_SEQ_NUM]);
9077
9078     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
9079     proto_tree_add_text(subtree,
9080         tvb, curr_offset, 1,
9081         "%s :  Spare",
9082         a_bigbuf);
9083
9084     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
9085
9086     switch ((oct & 0x70) >> 4)
9087     {
9088     case 0x07:
9089         proto_tree_add_text(subtree,
9090             tvb, curr_offset, 1,
9091             "%s :  Ciphering Key Sequence Number: No key is available",
9092             a_bigbuf);
9093         break;
9094
9095     default:
9096         proto_tree_add_text(subtree,
9097             tvb, curr_offset, 1,
9098             "%s :  Ciphering Key Sequence Number: %u",
9099             a_bigbuf,
9100             (oct & 0x70) >> 4);
9101         break;
9102     }
9103
9104     item =
9105         proto_tree_add_text(tree,
9106             tvb, curr_offset, 1,
9107             gsm_dtap_elem_strings[DE_LOC_UPD_TYPE].strptr);
9108
9109     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_LOC_UPD_TYPE]);
9110
9111     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
9112     proto_tree_add_text(subtree,
9113         tvb, curr_offset, 1,
9114         "%s :  Follow-On Request (FOR): %s",
9115         a_bigbuf,
9116         (oct & 0x08) ? "Follow-on request pending" : "No follow-on request pending");
9117
9118     other_decode_bitfield_value(a_bigbuf, oct, 0x04, 8);
9119     proto_tree_add_text(subtree,
9120         tvb, curr_offset, 1,
9121         "%s :  Spare",
9122         a_bigbuf);
9123
9124     switch (oct & 0x03)
9125     {
9126     case 0: str = "Normal"; break;
9127     case 1: str = "Periodic"; break;
9128     case 2: str = "IMSI attach"; break;
9129     default:
9130         str = "Reserved";
9131         break;
9132     }
9133
9134     other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
9135     proto_tree_add_text(subtree,
9136         tvb, curr_offset, 1,
9137         "%s :  Updating Type: %s",
9138         a_bigbuf,
9139         str);
9140
9141     proto_item_append_text(item, " - %s", str);
9142
9143     curr_offset++;
9144     curr_len--;
9145
9146     if (curr_len <= 0) return;
9147
9148     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_LAI);
9149
9150     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_MS_CM_1);
9151
9152     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID, "");
9153
9154     ELEM_OPT_TLV(0x33, BSSAP_PDU_TYPE_DTAP, DE_MS_CM_2, "");
9155
9156     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9157 }
9158
9159 /*
9160  * [4] 9.1.15a
9161  */
9162 static void
9163 dtap_mm_mm_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9164 {
9165     guint32     curr_offset;
9166     guint32     consumed;
9167     guint       curr_len;
9168
9169     curr_offset = offset;
9170     curr_len = len;
9171
9172     is_uplink = IS_UPLINK_TRUE;
9173
9174     ELEM_OPT_TLV(0x43, BSSAP_PDU_TYPE_DTAP, DE_NETWORK_NAME, " - Full Name");
9175
9176     ELEM_OPT_TLV(0x45, BSSAP_PDU_TYPE_DTAP, DE_NETWORK_NAME, " - Short Name");
9177
9178     ELEM_OPT_TV(0x46, BSSAP_PDU_TYPE_DTAP, DE_TIME_ZONE, " - Local");
9179
9180     ELEM_OPT_TV(0x47, BSSAP_PDU_TYPE_DTAP, DE_TIME_ZONE_TIME, " - Universal Time and Local Time Zone");
9181
9182     ELEM_OPT_TLV(0x48, BSSAP_PDU_TYPE_DTAP, DE_LSA_ID, "");
9183
9184     ELEM_OPT_TLV(0x49, BSSAP_PDU_TYPE_DTAP, DE_DAY_SAVING_TIME, "");
9185
9186     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9187 }
9188
9189 /*
9190  * [4] 9.1.16
9191  */
9192 static void
9193 dtap_mm_mm_status(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9194 {
9195     guint32     curr_offset;
9196     guint32     consumed;
9197     guint       curr_len;
9198
9199     curr_offset = offset;
9200     curr_len = len;
9201
9202     is_uplink = IS_UPLINK_TRUE;
9203
9204     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_REJ_CAUSE);
9205
9206     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9207 }
9208
9209 /*
9210  * [3] 9.2.17
9211  */
9212 static void
9213 dtap_mm_tmsi_realloc_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9214 {
9215     guint32     curr_offset;
9216     guint32     consumed;
9217     guint       curr_len;
9218
9219     curr_offset = offset;
9220     curr_len = len;
9221
9222     is_uplink = IS_UPLINK_FALSE;
9223
9224     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_LAI);
9225
9226     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID, "");
9227
9228     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9229 }
9230
9231 /*
9232  * [4] 9.1.25
9233  */
9234 static void
9235 dtap_rr_paging_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9236 {
9237     guint32     curr_offset;
9238     guint32     consumed;
9239     guint       curr_len;
9240     guint8      oct;
9241     proto_tree  *subtree;
9242     proto_item  *item;
9243
9244     curr_offset = offset;
9245     curr_len = len;
9246
9247     is_uplink = IS_UPLINK_TRUE;
9248
9249     /*
9250      * special dissection for Cipher Key Sequence Number
9251      */
9252     oct = tvb_get_guint8(tvb, curr_offset);
9253
9254     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
9255     proto_tree_add_text(tree,
9256         tvb, curr_offset, 1,
9257         "%s :  Spare",
9258         a_bigbuf);
9259
9260     item =
9261         proto_tree_add_text(tree,
9262             tvb, curr_offset, 1,
9263             gsm_dtap_elem_strings[DE_CIPH_KEY_SEQ_NUM].strptr);
9264
9265     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CIPH_KEY_SEQ_NUM]);
9266
9267     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
9268     proto_tree_add_text(subtree,
9269         tvb, curr_offset, 1,
9270         "%s :  Spare",
9271         a_bigbuf);
9272
9273     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
9274
9275     switch (oct & 0x07)
9276     {
9277     case 0x07:
9278         proto_tree_add_text(subtree,
9279             tvb, curr_offset, 1,
9280             "%s :  Ciphering Key Sequence Number: No key is available",
9281             a_bigbuf);
9282         break;
9283
9284     default:
9285         proto_tree_add_text(subtree,
9286             tvb, curr_offset, 1,
9287             "%s :  Ciphering Key Sequence Number: %u",
9288             a_bigbuf,
9289             oct & 0x07);
9290         break;
9291     }
9292
9293     curr_offset++;
9294     curr_len--;
9295
9296     if (curr_len <= 0) return;
9297
9298     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MS_CM_2, "");
9299
9300     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID, "");
9301
9302     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9303 }
9304
9305 /*
9306  * [4] 9.1.29
9307  */
9308 static void
9309 dtap_rr_rr_status(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9310 {
9311     guint32     curr_offset;
9312     guint32     consumed;
9313     guint       curr_len;
9314
9315     curr_offset = offset;
9316     curr_len = len;
9317
9318     is_uplink = IS_UPLINK_TRUE;
9319
9320     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RR_CAUSE);
9321
9322     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9323 }
9324
9325 /*
9326  * [4] 9.3.1
9327  */
9328 static void
9329 dtap_cc_alerting(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9330 {
9331     guint32     curr_offset;
9332     guint32     consumed;
9333     guint       curr_len;
9334
9335     curr_offset = offset;
9336     curr_len = len;
9337
9338     is_uplink = IS_UPLINK_TRUE;
9339
9340     ELEM_OPT_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
9341
9342     ELEM_OPT_TLV(0x1e, BSSAP_PDU_TYPE_DTAP, DE_PROG_IND, "");
9343
9344     ELEM_OPT_TLV(0x7e, BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
9345
9346     /* uplink only */
9347
9348     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
9349
9350     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9351 }
9352
9353 /*
9354  * [4] 9.3.2
9355  */
9356 static void
9357 dtap_cc_call_conf(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9358 {
9359     guint32     curr_offset;
9360     guint32     consumed;
9361     guint       curr_len;
9362
9363     curr_offset = offset;
9364     curr_len = len;
9365
9366     is_uplink = IS_UPLINK_TRUE;
9367
9368     ELEM_OPT_TV_SHORT(0xd0, BSSAP_PDU_TYPE_DTAP, DE_REPEAT_IND, " BC repeat indicator");
9369
9370     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 1");
9371
9372     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 2");
9373
9374     ELEM_OPT_TLV(0x08, BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
9375
9376     ELEM_OPT_TLV(0x15, BSSAP_PDU_TYPE_DTAP, DE_CC_CAP, "");
9377
9378     ELEM_OPT_TLV(0x2d, BSSAP_PDU_TYPE_DTAP, DE_SI, "");
9379
9380     ELEM_OPT_TLV(0x40, BSSAP_PDU_TYPE_DTAP, DE_SUP_CODEC_LIST, "");
9381
9382     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9383 }
9384
9385 /*
9386  * [4] 9.3.3
9387  */
9388 static void
9389 dtap_cc_call_proceed(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9390 {
9391     guint32     curr_offset;
9392     guint32     consumed;
9393     guint       curr_len;
9394
9395     curr_offset = offset;
9396     curr_len = len;
9397
9398     is_uplink = IS_UPLINK_FALSE;
9399
9400     ELEM_OPT_TV_SHORT(0xd0, BSSAP_PDU_TYPE_DTAP, DE_REPEAT_IND, " BC repeat indicator");
9401
9402     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 1");
9403
9404     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 2");
9405
9406     ELEM_OPT_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
9407
9408     ELEM_OPT_TLV(0x1e, BSSAP_PDU_TYPE_DTAP, DE_PROG_IND, "");
9409
9410     ELEM_OPT_TV_SHORT(0x80, BSSAP_PDU_TYPE_DTAP, DE_PRIO, "");
9411
9412     ELEM_OPT_TLV(0x2f, BSSAP_PDU_TYPE_DTAP, DE_NET_CC_CAP, "");
9413
9414     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9415 }
9416
9417 /*
9418  * [4] 9.3.4
9419  */
9420 static void
9421 dtap_cc_congestion_control(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9422 {
9423     guint32     curr_offset;
9424     guint32     consumed;
9425     guint       curr_len;
9426     guint8      oct;
9427     proto_tree  *subtree;
9428     proto_item  *item;
9429     gchar       *str;
9430
9431     curr_offset = offset;
9432     curr_len = len;
9433
9434     is_uplink = IS_UPLINK_FALSE;
9435
9436     /*
9437      * special dissection for Congestion Level
9438      */
9439     oct = tvb_get_guint8(tvb, curr_offset);
9440
9441     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
9442     proto_tree_add_text(tree,
9443         tvb, curr_offset, 1,
9444         "%s :  Spare",
9445         a_bigbuf);
9446
9447     item =
9448         proto_tree_add_text(tree,
9449             tvb, curr_offset, 1,
9450             gsm_dtap_elem_strings[DE_CONGESTION].strptr);
9451
9452     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CONGESTION]);
9453
9454     switch (oct & 0x0f)
9455     {
9456     case 0: str = "Receiver ready"; break;
9457     case 15: str = "Receiver not ready"; break;
9458     default:
9459         str = "Reserved";
9460         break;
9461     }
9462
9463     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
9464     proto_tree_add_text(subtree,
9465         tvb, curr_offset, 1,
9466         "%s :  Congestion level: %s",
9467         a_bigbuf,
9468         str);
9469
9470     curr_offset++;
9471     curr_len--;
9472
9473     if (curr_len <= 0) return;
9474
9475     ELEM_OPT_TLV(0x08, BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
9476
9477     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9478 }
9479
9480 /*
9481  * [4] 9.3.5
9482  */
9483 static void
9484 dtap_cc_connect(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9485 {
9486     guint32     curr_offset;
9487     guint32     consumed;
9488     guint       curr_len;
9489
9490     curr_offset = offset;
9491     curr_len = len;
9492
9493     is_uplink = IS_UPLINK_TRUE;
9494
9495     ELEM_OPT_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
9496
9497     ELEM_OPT_TLV(0x1e, BSSAP_PDU_TYPE_DTAP, DE_PROG_IND, "");
9498
9499     ELEM_OPT_TLV(0x4c, BSSAP_PDU_TYPE_DTAP, DE_CONN_NUM, "");
9500
9501     ELEM_OPT_TLV(0x4d, BSSAP_PDU_TYPE_DTAP, DE_CONN_SUB_ADDR, "");
9502
9503     ELEM_OPT_TLV(0x7e, BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
9504
9505     /* uplink only */
9506
9507     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
9508
9509     ELEM_OPT_TLV(0x2d, BSSAP_PDU_TYPE_DTAP, DE_SI, "");
9510
9511     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9512 }
9513
9514 /*
9515  * [4] 9.3.7
9516  */
9517 static void
9518 dtap_cc_disconnect(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9519 {
9520     guint32     curr_offset;
9521     guint32     consumed;
9522     guint       curr_len;
9523
9524     curr_offset = offset;
9525     curr_len = len;
9526
9527     is_uplink = IS_UPLINK_TRUE;
9528
9529     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
9530
9531     ELEM_OPT_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
9532
9533     ELEM_OPT_TLV(0x1e, BSSAP_PDU_TYPE_DTAP, DE_PROG_IND, "");
9534
9535     ELEM_OPT_TLV(0x7e, BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
9536
9537     ELEM_OPT_TLV(0x7b, BSSAP_PDU_TYPE_DTAP, DE_ALLOWED_ACTIONS, "");
9538
9539     /* uplink only */
9540
9541     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
9542
9543     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9544 }
9545
9546 /*
9547  * [4] 9.3.8
9548  */
9549 static void
9550 dtap_cc_emerg_setup(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9551 {
9552     guint32     curr_offset;
9553     guint32     consumed;
9554     guint       curr_len;
9555
9556     curr_offset = offset;
9557     curr_len = len;
9558
9559     is_uplink = IS_UPLINK_TRUE;
9560
9561     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, "");
9562
9563     ELEM_OPT_TLV(0x2d, BSSAP_PDU_TYPE_DTAP, DE_SI, "");
9564
9565     ELEM_OPT_TLV(0x40, BSSAP_PDU_TYPE_DTAP, DE_SUP_CODEC_LIST, "");
9566
9567     ELEM_OPT_TLV(0x2e, BSSAP_PDU_TYPE_DTAP, DE_SRVC_CAT, " Emergency");
9568
9569     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9570 }
9571
9572 /*
9573  * [4] 9.3.9
9574  */
9575 static void
9576 dtap_cc_facility(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9577 {
9578     guint32     curr_offset;
9579     guint32     consumed;
9580     guint       curr_len;
9581
9582     curr_offset = offset;
9583     curr_len = len;
9584
9585     is_uplink = IS_UPLINK_TRUE;
9586
9587     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
9588
9589     /* uplink only */
9590
9591     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
9592
9593     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9594 }
9595
9596 /*
9597  * [4] 9.3.12
9598  */
9599 static void
9600 dtap_cc_hold_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9601 {
9602     guint32     curr_offset;
9603     guint32     consumed;
9604     guint       curr_len;
9605
9606     curr_offset = offset;
9607     curr_len = len;
9608
9609     is_uplink = IS_UPLINK_FALSE;
9610
9611     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
9612
9613     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9614 }
9615
9616 /*
9617  * [4] 9.3.13
9618  */
9619 static void
9620 dtap_cc_modify(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9621 {
9622     guint32     curr_offset;
9623     guint32     consumed;
9624     guint       curr_len;
9625
9626     curr_offset = offset;
9627     curr_len = len;
9628
9629     is_uplink = IS_UPLINK_TRUE;
9630
9631     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, "");
9632
9633     ELEM_OPT_TLV(0x7c, BSSAP_PDU_TYPE_DTAP, DE_LLC, "");
9634
9635     ELEM_OPT_TLV(0x7d, BSSAP_PDU_TYPE_DTAP, DE_HLC, "");
9636
9637     ELEM_OPT_T(0xa3, BSSAP_PDU_TYPE_DTAP, DE_REV_CALL_SETUP_DIR, "");
9638
9639     ELEM_OPT_T(0xa4, BSSAP_PDU_TYPE_DTAP, DE_IMM_MOD_IND, "");
9640
9641     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9642 }
9643
9644 /*
9645  * [4] 9.3.14
9646  */
9647 static void
9648 dtap_cc_modify_complete(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9649 {
9650     guint32     curr_offset;
9651     guint32     consumed;
9652     guint       curr_len;
9653
9654     curr_offset = offset;
9655     curr_len = len;
9656
9657     is_uplink = IS_UPLINK_TRUE;
9658
9659     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, "");
9660
9661     ELEM_OPT_TLV(0x7c, BSSAP_PDU_TYPE_DTAP, DE_LLC, "");
9662
9663     ELEM_OPT_TLV(0x7d, BSSAP_PDU_TYPE_DTAP, DE_HLC, "");
9664
9665     ELEM_OPT_T(0xa3, BSSAP_PDU_TYPE_DTAP, DE_REV_CALL_SETUP_DIR, "");
9666
9667     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9668 }
9669
9670 /*
9671  * [4] 9.3.15
9672  */
9673 static void
9674 dtap_cc_modify_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9675 {
9676     guint32     curr_offset;
9677     guint32     consumed;
9678     guint       curr_len;
9679
9680     curr_offset = offset;
9681     curr_len = len;
9682
9683     is_uplink = IS_UPLINK_FALSE;
9684
9685     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, "");
9686
9687     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
9688
9689     ELEM_OPT_TLV(0x7c, BSSAP_PDU_TYPE_DTAP, DE_LLC, "");
9690
9691     ELEM_OPT_TLV(0x7d, BSSAP_PDU_TYPE_DTAP, DE_HLC, "");
9692
9693     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9694 }
9695
9696 /*
9697  * [4] 9.3.16
9698  */
9699 static void
9700 dtap_cc_notify(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9701 {
9702     guint32     curr_offset;
9703     guint32     consumed;
9704     guint       curr_len;
9705
9706     curr_offset = offset;
9707     curr_len = len;
9708
9709     is_uplink = IS_UPLINK_FALSE;
9710
9711     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_NOT_IND);
9712
9713     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9714 }
9715
9716 /*
9717  * [4] 9.3.17
9718  */
9719 static void
9720 dtap_cc_progress(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9721 {
9722     guint32     curr_offset;
9723     guint32     consumed;
9724     guint       curr_len;
9725
9726     curr_offset = offset;
9727     curr_len = len;
9728
9729     is_uplink = IS_UPLINK_FALSE;
9730
9731     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_PROG_IND, "");
9732
9733     ELEM_OPT_TLV(0x7e, BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
9734
9735     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9736 }
9737
9738 /*
9739  * [4] 9.3.17a
9740  */
9741 static void
9742 dtap_cc_cc_est(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9743 {
9744     guint32     curr_offset;
9745     guint32     consumed;
9746     guint       curr_len;
9747
9748     curr_offset = offset;
9749     curr_len = len;
9750
9751     is_uplink = IS_UPLINK_FALSE;
9752
9753     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_SETUP_CONTAINER, "");
9754
9755     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9756 }
9757
9758 /*
9759  * [4] 9.3.17b
9760  */
9761 static void
9762 dtap_cc_cc_est_conf(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9763 {
9764     guint32     curr_offset;
9765     guint32     consumed;
9766     guint       curr_len;
9767
9768     curr_offset = offset;
9769     curr_len = len;
9770
9771     is_uplink = IS_UPLINK_TRUE;
9772
9773     ELEM_OPT_TV_SHORT(0xd0, BSSAP_PDU_TYPE_DTAP, DE_REPEAT_IND, " Repeat indicator");
9774
9775     ELEM_MAND_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 1");
9776
9777     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 2");
9778
9779     ELEM_OPT_TLV(0x08, BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
9780
9781     ELEM_OPT_TLV(0x40, BSSAP_PDU_TYPE_DTAP, DE_SUP_CODEC_LIST, "");
9782
9783     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9784 }
9785
9786 /*
9787  * [4] 9.3.18
9788  */
9789 static void
9790 dtap_cc_release(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9791 {
9792     guint32     curr_offset;
9793     guint32     consumed;
9794     guint       curr_len;
9795
9796     curr_offset = offset;
9797     curr_len = len;
9798
9799     is_uplink = IS_UPLINK_TRUE;
9800
9801     ELEM_OPT_TLV(0x08, BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
9802
9803     ELEM_OPT_TLV(0x08, BSSAP_PDU_TYPE_DTAP, DE_CAUSE, " 2");
9804
9805     ELEM_OPT_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
9806
9807     ELEM_OPT_TLV(0x7e, BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
9808
9809     /* uplink only */
9810
9811     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
9812
9813     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9814 }
9815
9816 /*
9817  * [4] 9.3.18a
9818  */
9819 static void
9820 dtap_cc_recall(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9821 {
9822     guint32     curr_offset;
9823     guint32     consumed;
9824     guint       curr_len;
9825
9826     curr_offset = offset;
9827     curr_len = len;
9828
9829     is_uplink = IS_UPLINK_FALSE;
9830
9831     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RECALL_TYPE);
9832
9833     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
9834
9835     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9836 }
9837
9838 /*
9839  * [4] 9.3.19
9840  */
9841 static void
9842 dtap_cc_release_complete(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9843 {
9844     guint32     curr_offset;
9845     guint32     consumed;
9846     guint       curr_len;
9847
9848     curr_offset = offset;
9849     curr_len = len;
9850
9851     is_uplink = IS_UPLINK_FALSE;
9852
9853     ELEM_OPT_TLV(0x08, BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
9854
9855     ELEM_OPT_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
9856
9857     ELEM_OPT_TLV(0x7e, BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
9858
9859     /* uplink only */
9860
9861     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
9862
9863     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9864 }
9865
9866 /*
9867  * [4] 9.3.22
9868  */
9869 static void
9870 dtap_cc_retrieve_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9871 {
9872     guint32     curr_offset;
9873     guint32     consumed;
9874     guint       curr_len;
9875
9876     curr_offset = offset;
9877     curr_len = len;
9878
9879     is_uplink = IS_UPLINK_FALSE;
9880
9881     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
9882
9883     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9884 }
9885
9886 /*
9887  * [4] 9.3.23
9888  */
9889 static void
9890 dtap_cc_setup(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9891 {
9892     guint32     curr_offset;
9893     guint32     consumed;
9894     guint       curr_len;
9895
9896     curr_offset = offset;
9897     curr_len = len;
9898
9899     is_uplink = IS_UPLINK_TRUE;
9900
9901     ELEM_OPT_TV_SHORT(0xd0, BSSAP_PDU_TYPE_DTAP, DE_REPEAT_IND, " BC repeat indicator");
9902
9903     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 1");
9904
9905     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 2");
9906
9907     ELEM_OPT_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
9908
9909     ELEM_OPT_TLV(0x1e, BSSAP_PDU_TYPE_DTAP, DE_PROG_IND, "");
9910
9911     ELEM_OPT_TV(0x34, BSSAP_PDU_TYPE_DTAP, DE_SIGNAL, "");
9912
9913     ELEM_OPT_TLV(0x5c, BSSAP_PDU_TYPE_DTAP, DE_CLG_PARTY_BCD_NUM, "");
9914
9915     ELEM_OPT_TLV(0x5d, BSSAP_PDU_TYPE_DTAP, DE_CLG_PARTY_SUB_ADDR, "");
9916
9917     ELEM_OPT_TLV(0x5e, BSSAP_PDU_TYPE_DTAP, DE_CLD_PARTY_BCD_NUM, "");
9918
9919     ELEM_OPT_TLV(0x6d, BSSAP_PDU_TYPE_DTAP, DE_CLD_PARTY_SUB_ADDR, "");
9920
9921     ELEM_OPT_TLV(0x74, BSSAP_PDU_TYPE_DTAP, DE_RED_PARTY_BCD_NUM, "");
9922
9923     ELEM_OPT_TLV(0x75, BSSAP_PDU_TYPE_DTAP, DE_RED_PARTY_SUB_ADDR, "");
9924
9925     ELEM_OPT_TV_SHORT(0xd0, BSSAP_PDU_TYPE_DTAP, DE_REPEAT_IND, " LLC repeat indicator");
9926
9927     ELEM_OPT_TLV(0x7c, BSSAP_PDU_TYPE_DTAP, DE_LLC, " 1");
9928
9929     ELEM_OPT_TLV(0x7c, BSSAP_PDU_TYPE_DTAP, DE_LLC, " 2");
9930
9931     ELEM_OPT_TV_SHORT(0xd0, BSSAP_PDU_TYPE_DTAP, DE_REPEAT_IND, " HLC repeat indicator");
9932
9933     ELEM_OPT_TLV(0x7d, BSSAP_PDU_TYPE_DTAP, DE_HLC, " 1");
9934
9935     ELEM_OPT_TLV(0x7d, BSSAP_PDU_TYPE_DTAP, DE_HLC, " 2");
9936
9937     ELEM_OPT_TLV(0x7e, BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
9938
9939     /* downlink only */
9940
9941     ELEM_OPT_TV_SHORT(0x80, BSSAP_PDU_TYPE_DTAP, DE_PRIO, "");
9942
9943     ELEM_OPT_TLV(0x19, BSSAP_PDU_TYPE_DTAP, DE_ALERT_PATTERN, "");
9944
9945     ELEM_OPT_TLV(0x2f, BSSAP_PDU_TYPE_DTAP, DE_NET_CC_CAP, "");
9946
9947     ELEM_OPT_TLV(0x3a, BSSAP_PDU_TYPE_DTAP, DE_CAUSE_NO_CLI, "");
9948
9949     /* uplink only */
9950
9951     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
9952
9953     ELEM_OPT_T(0xa1, BSSAP_PDU_TYPE_DTAP, DE_FOP, "");
9954
9955     ELEM_OPT_T(0xa2, BSSAP_PDU_TYPE_DTAP, DE_CTS_PERM, "");
9956
9957     ELEM_OPT_TLV(0x15, BSSAP_PDU_TYPE_DTAP, DE_CC_CAP, "");
9958
9959     ELEM_OPT_TLV(0x1d, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, " $(CCBS)$ (advanced recall alignment)");
9960
9961     ELEM_OPT_TLV(0x1b, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, " (recall alignment Not essential) $(CCBS)$");
9962
9963     ELEM_OPT_TLV(0x2d, BSSAP_PDU_TYPE_DTAP, DE_SI, "");
9964
9965     ELEM_OPT_TLV(0x40, BSSAP_PDU_TYPE_DTAP, DE_SUP_CODEC_LIST, "");
9966
9967     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9968 }
9969
9970 /*
9971  * [4] 9.3.23a
9972  */
9973 static void
9974 dtap_cc_start_cc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9975 {
9976     guint32     curr_offset;
9977     guint32     consumed;
9978     guint       curr_len;
9979
9980     curr_offset = offset;
9981     curr_len = len;
9982
9983     is_uplink = IS_UPLINK_FALSE;
9984
9985     ELEM_OPT_TLV(0x15, BSSAP_PDU_TYPE_DTAP, DE_CC_CAP, "");
9986
9987     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9988 }
9989
9990 /*
9991  * [4] 9.3.24
9992  */
9993 static void
9994 dtap_cc_start_dtmf(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9995 {
9996     guint32     curr_offset;
9997     guint32     consumed;
9998     guint       curr_len;
9999
10000     curr_offset = offset;
10001     curr_len = len;
10002
10003     is_uplink = IS_UPLINK_TRUE;
10004
10005     ELEM_MAND_TV(0x2c, BSSAP_PDU_TYPE_DTAP, DE_KEYPAD_FACILITY, "");
10006
10007     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10008 }
10009
10010 /*
10011  * [4] 9.3.25
10012  */
10013 static void
10014 dtap_cc_start_dtmf_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10015 {
10016     guint32     curr_offset;
10017     guint32     consumed;
10018     guint       curr_len;
10019
10020     curr_offset = offset;
10021     curr_len = len;
10022
10023     is_uplink = IS_UPLINK_FALSE;
10024
10025     ELEM_MAND_TV(0x2c, BSSAP_PDU_TYPE_DTAP, DE_KEYPAD_FACILITY, "");
10026
10027     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10028 }
10029
10030 /*
10031  * [4] 9.3.26
10032  */
10033 static void
10034 dtap_cc_start_dtmf_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10035 {
10036     guint32     curr_offset;
10037     guint32     consumed;
10038     guint       curr_len;
10039
10040     curr_offset = offset;
10041     curr_len = len;
10042
10043     is_uplink = IS_UPLINK_FALSE;
10044
10045     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
10046
10047     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10048 }
10049
10050 /*
10051  * [4] 9.3.27
10052  */
10053 static void
10054 dtap_cc_status(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10055 {
10056     guint32     curr_offset;
10057     guint32     consumed;
10058     guint       curr_len;
10059
10060     curr_offset = offset;
10061     curr_len = len;
10062
10063     is_uplink = IS_UPLINK_FALSE;
10064
10065     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
10066
10067     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_CALL_STATE);
10068
10069     ELEM_OPT_TLV(0x24, BSSAP_PDU_TYPE_DTAP, DE_AUX_STATES, "");
10070
10071     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10072 }
10073
10074 /*
10075  * [4] 9.3.31
10076  */
10077 static void
10078 dtap_cc_user_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10079 {
10080     guint32     curr_offset;
10081     guint32     consumed;
10082     guint       curr_len;
10083
10084     curr_offset = offset;
10085     curr_len = len;
10086
10087     is_uplink = IS_UPLINK_TRUE;
10088
10089     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
10090
10091     ELEM_OPT_T(0xa0, BSSAP_PDU_TYPE_DTAP, DE_MORE_DATA, "");
10092
10093     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10094 }
10095
10096 /*
10097  * [6] 2.4.2
10098  */
10099 static void
10100 dtap_ss_register(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10101 {
10102     guint32     curr_offset;
10103     guint32     consumed;
10104     guint       curr_len;
10105
10106     curr_offset = offset;
10107     curr_len = len;
10108
10109     is_uplink = IS_UPLINK_TRUE;
10110
10111     ELEM_MAND_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
10112
10113     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
10114
10115     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10116 }
10117
10118 /*
10119  * [5] 7.2.1
10120  */
10121 static void
10122 dtap_sms_cp_data(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10123 {
10124     guint32     curr_offset;
10125     guint32     consumed;
10126     guint       curr_len;
10127
10128     curr_offset = offset;
10129     curr_len = len;
10130
10131     is_uplink = IS_UPLINK_TRUE;
10132
10133     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_CP_USER_DATA, "");
10134
10135     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10136 }
10137
10138 /*
10139  * [5] 7.2.3
10140  */
10141 static void
10142 dtap_sms_cp_error(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10143 {
10144     guint32     curr_offset;
10145     guint32     consumed;
10146     guint       curr_len;
10147
10148     curr_offset = offset;
10149     curr_len = len;
10150
10151     is_uplink = IS_UPLINK_TRUE;
10152
10153     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_CP_CAUSE);
10154
10155     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10156 }
10157
10158 /*
10159  * [5] 7.3.1.1
10160  */
10161 static void
10162 rp_data_n_ms(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10163 {
10164     guint32     curr_offset;
10165     guint32     consumed;
10166     guint       curr_len;
10167
10168     curr_offset = offset;
10169     curr_len = len;
10170
10171     is_uplink = IS_UPLINK_FALSE;
10172     g_pinfo->p2p_dir = P2P_DIR_SENT;
10173
10174     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RP_MESSAGE_REF);
10175
10176     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_ORIG_ADDR, "");
10177
10178     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_DEST_ADDR, "");
10179
10180     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_USER_DATA, "");
10181
10182     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10183 }
10184
10185 /*
10186  * [5] 7.3.1.2
10187  */
10188 static void
10189 rp_data_ms_n(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10190 {
10191     guint32     curr_offset;
10192     guint32     consumed;
10193     guint       curr_len;
10194
10195     curr_offset = offset;
10196     curr_len = len;
10197
10198     is_uplink = IS_UPLINK_TRUE;
10199     g_pinfo->p2p_dir = P2P_DIR_RECV;
10200
10201     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RP_MESSAGE_REF);
10202
10203     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_ORIG_ADDR, "");
10204
10205     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_DEST_ADDR, "");
10206
10207     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_USER_DATA, "");
10208
10209     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10210 }
10211
10212 /*
10213  * [5] 7.3.2
10214  */
10215 static void
10216 rp_smma(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10217 {
10218     guint32     curr_offset;
10219     guint32     consumed;
10220     guint       curr_len;
10221
10222     curr_offset = offset;
10223     curr_len = len;
10224
10225     is_uplink = IS_UPLINK_TRUE;
10226
10227     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RP_MESSAGE_REF);
10228
10229     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10230 }
10231
10232 /*
10233  * [5] 7.3.3
10234  */
10235 static void
10236 rp_ack_n_ms(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10237 {
10238     guint32     curr_offset;
10239     guint32     consumed;
10240     guint       curr_len;
10241
10242     curr_offset = offset;
10243     curr_len = len;
10244
10245     is_uplink = IS_UPLINK_FALSE;
10246     g_pinfo->p2p_dir = P2P_DIR_SENT;
10247
10248     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RP_MESSAGE_REF);
10249
10250     ELEM_OPT_TLV(0x41, BSSAP_PDU_TYPE_DTAP, DE_RP_USER_DATA, "");
10251
10252     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10253 }
10254
10255 /*
10256  * [5] 7.3.3
10257  */
10258 static void
10259 rp_ack_ms_n(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10260 {
10261     guint32     curr_offset;
10262     guint32     consumed;
10263     guint       curr_len;
10264
10265     curr_offset = offset;
10266     curr_len = len;
10267
10268     is_uplink = IS_UPLINK_TRUE;
10269     g_pinfo->p2p_dir = P2P_DIR_RECV;
10270
10271     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RP_MESSAGE_REF);
10272
10273     ELEM_OPT_TLV(0x41, BSSAP_PDU_TYPE_DTAP, DE_RP_USER_DATA, "");
10274
10275     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10276 }
10277
10278 /*
10279  * [5] 7.3.4
10280  */
10281 static void
10282 rp_error_n_ms(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10283 {
10284     guint32     curr_offset;
10285     guint32     consumed;
10286     guint       curr_len;
10287
10288     curr_offset = offset;
10289     curr_len = len;
10290
10291     is_uplink = IS_UPLINK_FALSE;
10292     g_pinfo->p2p_dir = P2P_DIR_SENT;
10293
10294     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RP_MESSAGE_REF);
10295
10296     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_CAUSE, "");
10297
10298     ELEM_OPT_TLV(0x41, BSSAP_PDU_TYPE_DTAP, DE_RP_USER_DATA, "");
10299
10300     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10301 }
10302
10303 /*
10304  * [5] 7.3.4
10305  */
10306 static void
10307 rp_error_ms_n(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10308 {
10309     guint32     curr_offset;
10310     guint32     consumed;
10311     guint       curr_len;
10312
10313     curr_offset = offset;
10314     curr_len = len;
10315
10316     is_uplink = IS_UPLINK_TRUE;
10317     g_pinfo->p2p_dir = P2P_DIR_RECV;
10318
10319     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RP_MESSAGE_REF);
10320
10321     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_CAUSE, "");
10322
10323     ELEM_OPT_TLV(0x41, BSSAP_PDU_TYPE_DTAP, DE_RP_USER_DATA, "");
10324
10325     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10326 }
10327
10328 #define NUM_GSM_DTAP_MSG_MM (sizeof(gsm_a_dtap_msg_mm_strings)/sizeof(value_string))
10329 static gint ett_gsm_dtap_msg_mm[NUM_GSM_DTAP_MSG_MM];
10330 static void (*dtap_msg_mm_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
10331     dtap_mm_imsi_det_ind,       /* IMSI Detach Indication */
10332     dtap_mm_loc_upd_acc,        /* Location Updating Accept */
10333     dtap_mm_loc_upd_rej,        /* Location Updating Reject */
10334     dtap_mm_loc_upd_req,        /* Location Updating Request */
10335     NULL /* no associated data */,      /* Authentication Reject */
10336     dtap_mm_auth_req,   /* Authentication Request */
10337     dtap_mm_auth_resp,  /* Authentication Response */
10338     dtap_mm_auth_fail,  /* Authentication Failure */
10339     dtap_mm_id_req,     /* Identity Request */
10340     dtap_mm_id_resp,    /* Identity Response */
10341     dtap_mm_tmsi_realloc_cmd,   /* TMSI Reallocation Command */
10342     NULL /* no associated data */,      /* TMSI Reallocation Complete */
10343     NULL /* no associated data */,      /* CM Service Accept */
10344     dtap_mm_cm_srvc_rej,        /* CM Service Reject */
10345     NULL /* no associated data */,      /* CM Service Abort */
10346     dtap_mm_cm_srvc_req,        /* CM Service Request */
10347     dtap_mm_cm_srvc_prompt,     /* CM Service Prompt */
10348     NULL,       /* Reserved: was allocated in earlier phases of the protocol */
10349     dtap_mm_cm_reestab_req,     /* CM Re-establishment Request */
10350     dtap_mm_abort,      /* Abort */
10351     NULL /* no associated data */,      /* MM Null */
10352     dtap_mm_mm_status,  /* MM Status */
10353     dtap_mm_mm_info,    /* MM Information */
10354     NULL,       /* NONE */
10355 };
10356
10357 #define NUM_GSM_DTAP_MSG_RR (sizeof(gsm_a_dtap_msg_rr_strings)/sizeof(value_string))
10358 static gint ett_gsm_dtap_msg_rr[NUM_GSM_DTAP_MSG_RR];
10359 static void (*dtap_msg_rr_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
10360     NULL,       /* RR Initialisation Request */
10361     NULL,       /* Additional Assignment */
10362     NULL,       /* Immediate Assignment */
10363     NULL,       /* Immediate Assignment Extended */
10364     NULL,       /* Immediate Assignment Reject */
10365
10366     NULL,       /* DTM Assignment Failure */
10367     NULL,       /* DTM Reject */
10368     NULL,       /* DTM Request */
10369     NULL,       /* Main DCCH Assignment Command */
10370     NULL,       /* Packet Assignment Command */
10371
10372     NULL,       /* Ciphering Mode Command */
10373     NULL,       /* Ciphering Mode Complete */
10374
10375     NULL,       /* Configuration Change Command */
10376     NULL,       /* Configuration Change Ack. */
10377     NULL,       /* Configuration Change Reject */
10378
10379     NULL,       /* Assignment Command */
10380     NULL,       /* Assignment Complete */
10381     NULL,       /* Assignment Failure */
10382     NULL,       /* Handover Command */
10383     NULL,       /* Handover Complete */
10384     NULL,       /* Handover Failure */
10385     NULL,       /* Physical Information */
10386     NULL,       /* DTM Assignment Command */
10387
10388     NULL,       /* RR-cell Change Order */
10389     NULL,       /* PDCH Assignment Command */
10390
10391     NULL,       /* Channel Release */
10392     NULL,       /* Partial Release */
10393     NULL,       /* Partial Release Complete */
10394
10395     NULL,       /* Paging Request Type 1 */
10396     NULL,       /* Paging Request Type 2 */
10397     NULL,       /* Paging Request Type 3 */
10398     dtap_rr_paging_resp,        /* Paging Response */
10399     NULL,       /* Notification/NCH */
10400     NULL,       /* Reserved */
10401     NULL,       /* Notification/Response */
10402
10403     NULL,       /* Reserved */
10404
10405 /*    NULL,     * Utran Classmark Change * CONFLICTS WITH Handover To UTRAN Command */
10406     NULL,       /* UE RAB Preconfiguration */
10407     NULL,       /* cdma2000 Classmark Change */
10408
10409     NULL,       /* System Information Type 8 */
10410     NULL,       /* System Information Type 1 */
10411     NULL,       /* System Information Type 2 */
10412     NULL,       /* System Information Type 3 */
10413     NULL,       /* System Information Type 4 */
10414     NULL,       /* System Information Type 5 */
10415     NULL,       /* System Information Type 6 */
10416     NULL,       /* System Information Type 7 */
10417
10418     NULL,       /* System Information Type 2bis */
10419     NULL,       /* System Information Type 2ter */
10420     NULL,       /* System Information Type 2quater */
10421     NULL,       /* System Information Type 5bis */
10422     NULL,       /* System Information Type 5ter */
10423     NULL,       /* System Information Type 9 */
10424     NULL,       /* System Information Type 13 */
10425
10426     NULL,       /* System Information Type 16 */
10427     NULL,       /* System Information Type 17 */
10428
10429     NULL,       /* System Information Type 18 */
10430     NULL,       /* System Information Type 19 */
10431     NULL,       /* System Information Type 20 */
10432
10433     NULL,       /* Channel Mode Modify */
10434     dtap_rr_rr_status,  /* RR Status */
10435     NULL,       /* Channel Mode Modify Acknowledge */
10436     NULL,       /* Frequency Redefinition */
10437     NULL,       /* Measurement Report */
10438     NULL,       /* Classmark Change */
10439     NULL,       /* Classmark Enquiry */
10440     NULL,       /* Extended Measurement Report */
10441     NULL,       /* Extended Measurement Order */
10442     NULL,       /* GPRS Suspension Request */
10443
10444     NULL,       /* VGCS Uplink Grant */
10445     NULL,       /* Uplink Release */
10446     NULL,       /* Reserved */
10447     NULL,       /* Uplink Busy */
10448     NULL,       /* Talker Indication */
10449
10450     NULL,       /* UTRAN Classmark Change/Handover To UTRAN Command */  /* spec conflict */
10451
10452     NULL,       /* Application Information */
10453
10454     NULL,       /* NONE */
10455 };
10456
10457 #define NUM_GSM_DTAP_MSG_CC (sizeof(gsm_a_dtap_msg_cc_strings)/sizeof(value_string))
10458 static gint ett_gsm_dtap_msg_cc[NUM_GSM_DTAP_MSG_CC];
10459 static void (*dtap_msg_cc_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
10460     dtap_cc_alerting,   /* Alerting */
10461     dtap_cc_call_conf,  /* Call Confirmed */
10462     dtap_cc_call_proceed,       /* Call Proceeding */
10463     dtap_cc_connect,    /* Connect */
10464     NULL /* no associated data */,      /* Connect Acknowledge */
10465     dtap_cc_emerg_setup,        /* Emergency Setup */
10466     dtap_cc_progress,   /* Progress */
10467     dtap_cc_cc_est,     /* CC-Establishment */
10468     dtap_cc_cc_est_conf,        /* CC-Establishment Confirmed */
10469     dtap_cc_recall,     /* Recall */
10470     dtap_cc_start_cc,   /* Start CC */
10471     dtap_cc_setup,      /* Setup */
10472     dtap_cc_modify,     /* Modify */
10473     dtap_cc_modify_complete,    /* Modify Complete */
10474     dtap_cc_modify_rej, /* Modify Reject */
10475     dtap_cc_user_info,  /* User Information */
10476     NULL /* no associated data */,      /* Hold */
10477     NULL /* no associated data */,      /* Hold Acknowledge */
10478     dtap_cc_hold_rej,   /* Hold Reject */
10479     NULL /* no associated data */,      /* Retrieve */
10480     NULL /* no associated data */,      /* Retrieve Acknowledge */
10481     dtap_cc_retrieve_rej,       /* Retrieve Reject */
10482     dtap_cc_disconnect, /* Disconnect */
10483     dtap_cc_release,    /* Release */
10484     dtap_cc_release_complete,   /* Release Complete */
10485     dtap_cc_congestion_control, /* Congestion Control */
10486     dtap_cc_notify,     /* Notify */
10487     dtap_cc_status,     /* Status */
10488     NULL /* no associated data */,      /* Status Enquiry */
10489     dtap_cc_start_dtmf, /* Start DTMF */
10490     NULL /* no associated data */,      /* Stop DTMF */
10491     NULL /* no associated data */,      /* Stop DTMF Acknowledge */
10492     dtap_cc_start_dtmf_ack,     /* Start DTMF Acknowledge */
10493     dtap_cc_start_dtmf_rej,     /* Start DTMF Reject */
10494     dtap_cc_facility,   /* Facility */
10495     NULL,       /* NONE */
10496 };
10497
10498 #define NUM_GSM_DTAP_MSG_GMM (sizeof(gsm_a_dtap_msg_gmm_strings)/sizeof(value_string))
10499 static gint ett_gsm_dtap_msg_gmm[NUM_GSM_DTAP_MSG_GMM];
10500 static void (*dtap_msg_gmm_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
10501     NULL,       /* Attach Request */
10502     NULL,       /* Attach Accept */
10503     NULL,       /* Attach Complete */
10504     NULL,       /* Attach Reject */
10505     NULL,       /* Detach Request */
10506     NULL,       /* Detach Accept */
10507     NULL,       /* Routing Area Update Request */
10508     NULL,       /* Routing Area Update Accept */
10509     NULL,       /* Routing Area Update Complete */
10510     NULL,       /* Routing Area Update Reject */
10511     NULL,       /* Service Request */
10512     NULL,       /* Service Accept */
10513     NULL,       /* Service Reject */
10514     NULL,       /* P-TMSI Reallocation Command */
10515     NULL,       /* P-TMSI Reallocation Complete */
10516     NULL,       /* Authentication and Ciphering Req */
10517     NULL,       /* Authentication and Ciphering Resp */
10518     NULL,       /* Authentication and Ciphering Rej */
10519     NULL,       /* Authentication and Ciphering Failure */
10520     NULL,       /* Identity Request */
10521     NULL,       /* Identity Response */
10522     NULL,       /* GMM Status */
10523     NULL,       /* GMM Information */
10524     NULL,       /* NONE */
10525 };
10526
10527 #define NUM_GSM_DTAP_MSG_SMS (sizeof(gsm_a_dtap_msg_sms_strings)/sizeof(value_string))
10528 static gint ett_gsm_dtap_msg_sms[NUM_GSM_DTAP_MSG_SMS];
10529 static void (*dtap_msg_sms_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
10530     dtap_sms_cp_data,   /* CP-DATA */
10531     NULL /* no associated data */,      /* CP-ACK */
10532     dtap_sms_cp_error,  /* CP-ERROR */
10533     NULL,       /* NONE */
10534 };
10535
10536 #define NUM_GSM_DTAP_MSG_SM (sizeof(gsm_a_dtap_msg_sm_strings)/sizeof(value_string))
10537 static gint ett_gsm_dtap_msg_sm[NUM_GSM_DTAP_MSG_SM];
10538 static void (*dtap_msg_sm_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
10539     NULL,       /* Activate PDP Context Request */
10540     NULL,       /* Activate PDP Context Accept */
10541     NULL,       /* Activate PDP Context Reject */
10542     NULL,       /* Request PDP Context Activation */
10543     NULL,       /* Request PDP Context Activation rej. */
10544     NULL,       /* Deactivate PDP Context Request */
10545     NULL,       /* Deactivate PDP Context Accept */
10546     NULL,       /* Modify PDP Context Request(Network to MS direction) */
10547     NULL,       /* Modify PDP Context Accept (MS to network direction) */
10548     NULL,       /* Modify PDP Context Request(MS to network direction) */
10549     NULL,       /* Modify PDP Context Accept (Network to MS direction) */
10550     NULL,       /* Modify PDP Context Reject */
10551     NULL,       /* Activate Secondary PDP Context Request */
10552     NULL,       /* Activate Secondary PDP Context Accept */
10553     NULL,       /* Activate Secondary PDP Context Reject */
10554     NULL,       /* Reserved: was allocated in earlier phases of the protocol */
10555     NULL,       /* Reserved: was allocated in earlier phases of the protocol */
10556     NULL,       /* Reserved: was allocated in earlier phases of the protocol */
10557     NULL,       /* Reserved: was allocated in earlier phases of the protocol */
10558     NULL,       /* Reserved: was allocated in earlier phases of the protocol */
10559     NULL,       /* SM Status */
10560     NULL,       /* NONE */
10561 };
10562
10563 #define NUM_GSM_DTAP_MSG_SS (sizeof(gsm_a_dtap_msg_ss_strings)/sizeof(value_string))
10564 static gint ett_gsm_dtap_msg_ss[NUM_GSM_DTAP_MSG_SS];
10565 static void (*dtap_msg_ss_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
10566     dtap_cc_release_complete,   /* Release Complete */
10567     dtap_cc_facility,   /* Facility */
10568     dtap_ss_register,   /* Register */
10569     NULL,       /* NONE */
10570 };
10571
10572 #define NUM_GSM_RP_MSG (sizeof(gsm_rp_msg_strings)/sizeof(value_string))
10573 static gint ett_gsm_rp_msg[NUM_GSM_RP_MSG];
10574 static void (*rp_msg_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
10575     rp_data_ms_n,       /* RP-DATA (MS to Network) */
10576     rp_data_n_ms,       /* RP-DATA (Network to MS */
10577     rp_ack_ms_n,        /* RP-ACK (MS to Network) */
10578     rp_ack_n_ms,        /* RP-ACK (Network to MS) */
10579     rp_error_ms_n,      /* RP-ERROR (MS to Network) */
10580     rp_error_n_ms,      /* RP-ERROR (Network to MS) */
10581     rp_smma,    /* RP-SMMA (MS to Network) */
10582     NULL,       /* NONE */
10583 };
10584
10585 /* GENERIC DISSECTOR FUNCTIONS */
10586
10587 static void
10588 dissect_rp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
10589 {
10590     guint8      oct;
10591     guint32     offset, saved_offset;
10592     guint32     len;
10593     gint        idx;
10594     proto_item  *rp_item = NULL;
10595     proto_tree  *rp_tree = NULL;
10596     gchar       *str;
10597
10598
10599     if (check_col(pinfo->cinfo, COL_INFO))
10600     {
10601         col_append_str(pinfo->cinfo, COL_INFO, "(RP) ");
10602     }
10603
10604     /*
10605      * In the interest of speed, if "tree" is NULL, don't do any work
10606      * not necessary to generate protocol tree items.
10607      */
10608     if (!tree)
10609     {
10610         return;
10611     }
10612
10613     offset = 0;
10614     saved_offset = offset;
10615
10616     g_pinfo = pinfo;
10617     g_tree = tree;
10618
10619     len = tvb_length(tvb);
10620
10621     /*
10622      * add RP message name
10623      */
10624     oct = tvb_get_guint8(tvb, offset++);
10625
10626     str = my_match_strval((guint32) oct, gsm_rp_msg_strings, &idx);
10627
10628     /*
10629      * create the protocol tree
10630      */
10631     if (str == NULL)
10632     {
10633         rp_item =
10634             proto_tree_add_protocol_format(tree, proto_a_rp, tvb, 0, len,
10635                 "GSM A-I/F RP - Unknown RP Message Type (0x%02x)",
10636                 oct);
10637
10638         rp_tree = proto_item_add_subtree(rp_item, ett_rp_msg);
10639     }
10640     else
10641     {
10642         rp_item =
10643             proto_tree_add_protocol_format(tree, proto_a_rp, tvb, 0, -1,
10644                 "GSM A-I/F RP - %s",
10645                 str);
10646
10647         rp_tree = proto_item_add_subtree(rp_item, ett_gsm_rp_msg[idx]);
10648
10649         if (check_col(pinfo->cinfo, COL_INFO))
10650         {
10651             col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", str);
10652         }
10653     }
10654
10655     /*
10656      * add RP message name
10657      */
10658     proto_tree_add_uint_format(rp_tree, hf_gsm_a_rp_msg_type,
10659         tvb, saved_offset, 1, oct, "Message Type");
10660
10661     if (str == NULL) return;
10662
10663     if ((len - offset) <= 0) return;
10664
10665     /*
10666      * decode elements
10667      */
10668     if (rp_msg_fcn[idx] == NULL)
10669     {
10670         proto_tree_add_text(rp_tree,
10671             tvb, offset, len - offset,
10672             "Message Elements");
10673     }
10674     else
10675     {
10676         (*rp_msg_fcn[idx])(tvb, rp_tree, offset, len - offset);
10677     }
10678 }
10679
10680
10681 static void
10682 dissect_bssmap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
10683 {
10684     static gsm_a_tap_rec_t      tap_rec[4];
10685     static gsm_a_tap_rec_t      *tap_p;
10686     static int                  tap_current=0;
10687     guint8      oct;
10688     guint32     offset, saved_offset;
10689     guint32     len;
10690     gint        idx;
10691     proto_item  *bssmap_item = NULL;
10692     proto_tree  *bssmap_tree = NULL;
10693     gchar       *str;
10694
10695
10696     if (check_col(pinfo->cinfo, COL_INFO))
10697     {
10698         col_append_str(pinfo->cinfo, COL_INFO, "(BSSMAP) ");
10699     }
10700
10701     /*
10702      * set tap record pointer
10703      */
10704     tap_current++;
10705     if (tap_current == 4)
10706     {
10707         tap_current = 0;
10708     }
10709     tap_p = &tap_rec[tap_current];
10710
10711
10712     offset = 0;
10713     saved_offset = offset;
10714
10715     g_pinfo = pinfo;
10716     g_tree = tree;
10717
10718     len = tvb_length(tvb);
10719
10720     /*
10721      * add BSSMAP message name
10722      */
10723     oct = tvb_get_guint8(tvb, offset++);
10724
10725     str = my_match_strval((guint32) oct, gsm_a_bssmap_msg_strings, &idx);
10726
10727     /*
10728      * create the protocol tree
10729      */
10730     if (str == NULL)
10731     {
10732         bssmap_item =
10733             proto_tree_add_protocol_format(tree, proto_a_bssmap, tvb, 0, len,
10734                 "GSM A-I/F BSSMAP - Unknown BSSMAP Message Type (0x%02x)",
10735                 oct);
10736
10737         bssmap_tree = proto_item_add_subtree(bssmap_item, ett_bssmap_msg);
10738     }
10739     else
10740     {
10741         bssmap_item =
10742             proto_tree_add_protocol_format(tree, proto_a_bssmap, tvb, 0, -1,
10743                 "GSM A-I/F BSSMAP - %s",
10744                 str);
10745
10746         bssmap_tree = proto_item_add_subtree(bssmap_item, ett_gsm_bssmap_msg[idx]);
10747
10748         if (check_col(pinfo->cinfo, COL_INFO))
10749         {
10750             col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", str);
10751         }
10752     }
10753
10754     /*
10755      * add BSSMAP message name
10756      */
10757     proto_tree_add_uint_format(bssmap_tree, hf_gsm_a_bssmap_msg_type,
10758         tvb, saved_offset, 1, oct, "Message Type");
10759
10760     tap_p->pdu_type = BSSAP_PDU_TYPE_BSSMAP;
10761     tap_p->message_type = oct;
10762
10763     tap_queue_packet(gsm_a_tap, pinfo, tap_p);
10764
10765     if (str == NULL) return;
10766
10767     if ((len - offset) <= 0) return;
10768
10769     /*
10770      * decode elements
10771      */
10772     if (bssmap_msg_fcn[idx] == NULL)
10773     {
10774         proto_tree_add_text(bssmap_tree,
10775             tvb, offset, len - offset,
10776             "Message Elements");
10777     }
10778     else
10779     {
10780         (*bssmap_msg_fcn[idx])(tvb, bssmap_tree, offset, len - offset);
10781     }
10782 }
10783
10784
10785 static void
10786 dissect_dtap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
10787 {
10788     static gsm_a_tap_rec_t      tap_rec[4];
10789     static gsm_a_tap_rec_t      *tap_p;
10790     static int                  tap_current=0;
10791     void                        (*msg_fcn)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len);
10792     guint8                      oct;
10793     guint8                      pd;
10794     guint32                     offset;
10795     guint32                     len;
10796     guint32                     oct_1, oct_2;
10797     gint                        idx;
10798     proto_item                  *dtap_item = NULL;
10799     proto_tree                  *dtap_tree = NULL;
10800     proto_item                  *oct_1_item = NULL;
10801     proto_tree                  *pd_tree = NULL;
10802     gchar                       *msg_str;
10803     const gchar                 *str;
10804     gint                        ett_tree;
10805     gint                        ti;
10806     int                         hf_idx;
10807     gboolean                    nsd;
10808
10809
10810     len = tvb_length(tvb);
10811
10812     if (len < 2)
10813     {
10814         /*
10815          * too short to be DTAP
10816          */
10817         call_dissector(data_handle, tvb, pinfo, tree);
10818         return;
10819     }
10820
10821     if (check_col(pinfo->cinfo, COL_INFO))
10822     {
10823         col_append_str(pinfo->cinfo, COL_INFO, "(DTAP) ");
10824     }
10825
10826     /*
10827      * set tap record pointer
10828      */
10829     tap_current++;
10830     if (tap_current == 4)
10831     {
10832         tap_current = 0;
10833     }
10834     tap_p = &tap_rec[tap_current];
10835
10836
10837     offset = 0;
10838     oct_2 = 0;
10839
10840     g_pinfo = pinfo;
10841     g_tree = tree;
10842
10843     /*
10844      * get protocol discriminator
10845      */
10846     oct_1 = tvb_get_guint8(tvb, offset++);
10847
10848     if ((((oct_1 & DTAP_TI_MASK) >> 4) & DTAP_TIE_PRES_MASK) == DTAP_TIE_PRES_MASK)
10849     {
10850         /*
10851          * eventhough we don't know if a TI should be in the message yet
10852          * we rely on the TI/SKIP indicator to be 0 to avoid taking this
10853          * octet
10854          */
10855         oct_2 = tvb_get_guint8(tvb, offset++);
10856     }
10857
10858     oct = tvb_get_guint8(tvb, offset);
10859
10860     pd = oct_1 & DTAP_PD_MASK;
10861     ti = -1;
10862     msg_str = NULL;
10863     ett_tree = -1;
10864     hf_idx = -1;
10865     msg_fcn = NULL;
10866     nsd = FALSE;
10867
10868     /*
10869      * octet 1
10870      */
10871     switch (pd)
10872     {
10873     case 3:
10874         str = gsm_a_pd_str[pd];
10875         msg_str = my_match_strval((guint32) (oct & DTAP_CC_IEI_MASK), gsm_a_dtap_msg_cc_strings, &idx);
10876         ett_tree = ett_gsm_dtap_msg_cc[idx];
10877         hf_idx = hf_gsm_a_dtap_msg_cc_type;
10878         msg_fcn = dtap_msg_cc_fcn[idx];
10879         ti = (oct_1 & DTAP_TI_MASK) >> 4;
10880         nsd = TRUE;
10881         break;
10882
10883     case 5:
10884         str = gsm_a_pd_str[pd];
10885         msg_str = my_match_strval((guint32) (oct & DTAP_MM_IEI_MASK), gsm_a_dtap_msg_mm_strings, &idx);
10886         ett_tree = ett_gsm_dtap_msg_mm[idx];
10887         hf_idx = hf_gsm_a_dtap_msg_mm_type;
10888         msg_fcn = dtap_msg_mm_fcn[idx];
10889         nsd = TRUE;
10890         break;
10891
10892     case 6:
10893         str = gsm_a_pd_str[pd];
10894         msg_str = my_match_strval((guint32) (oct & DTAP_RR_IEI_MASK), gsm_a_dtap_msg_rr_strings, &idx);
10895         ett_tree = ett_gsm_dtap_msg_rr[idx];
10896         hf_idx = hf_gsm_a_dtap_msg_rr_type;
10897         msg_fcn = dtap_msg_rr_fcn[idx];
10898         break;
10899
10900     case 8:
10901         str = gsm_a_pd_str[pd];
10902         msg_str = my_match_strval((guint32) (oct & DTAP_GMM_IEI_MASK), gsm_a_dtap_msg_gmm_strings, &idx);
10903         ett_tree = ett_gsm_dtap_msg_gmm[idx];
10904         hf_idx = hf_gsm_a_dtap_msg_gmm_type;
10905         msg_fcn = dtap_msg_gmm_fcn[idx];
10906         break;
10907
10908     case 9:
10909         str = gsm_a_pd_str[pd];
10910         msg_str = my_match_strval((guint32) (oct & DTAP_SMS_IEI_MASK), gsm_a_dtap_msg_sms_strings, &idx);
10911         ett_tree = ett_gsm_dtap_msg_sms[idx];
10912         hf_idx = hf_gsm_a_dtap_msg_sms_type;
10913         msg_fcn = dtap_msg_sms_fcn[idx];
10914         ti = (oct_1 & DTAP_TI_MASK) >> 4;
10915         break;
10916
10917     case 10:
10918         str = gsm_a_pd_str[pd];
10919         msg_str = my_match_strval((guint32) (oct & DTAP_SM_IEI_MASK), gsm_a_dtap_msg_sm_strings, &idx);
10920         ett_tree = ett_gsm_dtap_msg_sm[idx];
10921         hf_idx = hf_gsm_a_dtap_msg_sm_type;
10922         msg_fcn = dtap_msg_sm_fcn[idx];
10923         ti = (oct_1 & DTAP_TI_MASK) >> 4;
10924         break;
10925
10926     case 11:
10927         str = gsm_a_pd_str[pd];
10928         msg_str = my_match_strval((guint32) (oct & DTAP_SS_IEI_MASK), gsm_a_dtap_msg_ss_strings, &idx);
10929         ett_tree = ett_gsm_dtap_msg_ss[idx];
10930         hf_idx = hf_gsm_a_dtap_msg_ss_type;
10931         msg_fcn = dtap_msg_ss_fcn[idx];
10932         ti = (oct_1 & DTAP_TI_MASK) >> 4;
10933         nsd = TRUE;
10934         break;
10935
10936     default:
10937         str = gsm_a_pd_str[pd];
10938         break;
10939     }
10940
10941     /*
10942      * create the protocol tree
10943      */
10944     if (msg_str == NULL)
10945     {
10946         dtap_item =
10947             proto_tree_add_protocol_format(tree, proto_a_dtap, tvb, 0, len,
10948                 "GSM A-I/F DTAP - Unknown DTAP Message Type (0x%02x)",
10949                 oct);
10950
10951         dtap_tree = proto_item_add_subtree(dtap_item, ett_dtap_msg);
10952     }
10953     else
10954     {
10955         dtap_item =
10956             proto_tree_add_protocol_format(tree, proto_a_dtap, tvb, 0, -1,
10957                 "GSM A-I/F DTAP - %s",
10958                 msg_str);
10959
10960         dtap_tree = proto_item_add_subtree(dtap_item, ett_tree);
10961
10962         if (check_col(pinfo->cinfo, COL_INFO))
10963         {
10964             col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", msg_str);
10965         }
10966     }
10967
10968     oct_1_item =
10969         proto_tree_add_text(dtap_tree,
10970             tvb, 0, 1,
10971             "Protocol Discriminator: %s",
10972             str);
10973
10974     pd_tree = proto_item_add_subtree(oct_1_item, ett_dtap_oct_1);
10975
10976     if (ti == -1)
10977     {
10978         other_decode_bitfield_value(a_bigbuf, oct_1, 0xf0, 8);
10979         proto_tree_add_text(pd_tree,
10980             tvb, 0, 1,
10981             "%s :  Skip Indicator",
10982             a_bigbuf);
10983     }
10984     else
10985     {
10986         other_decode_bitfield_value(a_bigbuf, oct_1, 0x80, 8);
10987         proto_tree_add_text(pd_tree,
10988             tvb, 0, 1,
10989             "%s :  TI flag: %s",
10990             a_bigbuf,
10991             ((oct_1 & 0x80) ?  "allocated by receiver" : "allocated by sender"));
10992
10993         if ((ti & DTAP_TIE_PRES_MASK) == DTAP_TIE_PRES_MASK)
10994         {
10995             /* ti is extended to next octet */
10996
10997             other_decode_bitfield_value(a_bigbuf, oct_1, 0x70, 8);
10998             proto_tree_add_text(pd_tree,
10999                 tvb, 0, 1,
11000                 "%s :  TIO: The TI value is given by the TIE in octet 2",
11001                 a_bigbuf);
11002         }
11003         else
11004         {
11005             other_decode_bitfield_value(a_bigbuf, oct_1, 0x70, 8);
11006             proto_tree_add_text(pd_tree,
11007                 tvb, 0, 1,
11008                 "%s :  TIO: %u",
11009                 a_bigbuf,
11010                 ti & DTAP_TIE_PRES_MASK);
11011         }
11012     }
11013
11014     other_decode_bitfield_value(a_bigbuf, oct_1, DTAP_PD_MASK, 8);
11015     proto_tree_add_text(pd_tree,
11016         tvb, 0, 1,
11017         "%s :  Protocol Discriminator: %u",
11018         a_bigbuf,
11019         pd);
11020
11021     if ((ti != -1) &&
11022         (ti & DTAP_TIE_PRES_MASK) == DTAP_TIE_PRES_MASK)
11023     {
11024         other_decode_bitfield_value(a_bigbuf, oct_2, 0x80, 8);
11025         proto_tree_add_text(pd_tree,
11026             tvb, 1, 1,
11027             "%s :  Extension",
11028             a_bigbuf);
11029
11030         other_decode_bitfield_value(a_bigbuf, oct_2, DTAP_TIE_MASK, 8);
11031         proto_tree_add_text(pd_tree,
11032             tvb, 1, 1,
11033             "%s :  TIE: %u",
11034             a_bigbuf,
11035             oct_2 & DTAP_TIE_MASK);
11036     }
11037
11038     /*
11039      * N(SD)
11040      */
11041     if ((pinfo->p2p_dir == P2P_DIR_RECV) &&
11042         nsd)
11043     {
11044         /* XXX */
11045     }
11046
11047     /*
11048      * add DTAP message name
11049      */
11050     proto_tree_add_uint_format(dtap_tree, hf_idx,
11051         tvb, offset, 1, oct,
11052         "Message Type");
11053
11054     offset++;
11055
11056     tap_p->pdu_type = BSSAP_PDU_TYPE_DTAP;
11057     tap_p->message_type = (nsd ? (oct & 0x3f) : oct);
11058     tap_p->protocol_disc = pd;
11059
11060     tap_queue_packet(gsm_a_tap, pinfo, tap_p);
11061
11062     if (msg_str == NULL) return;
11063
11064     if ((len - offset) <= 0) return;
11065
11066     /*
11067      * decode elements
11068      */
11069     if (msg_fcn == NULL)
11070     {
11071         proto_tree_add_text(dtap_tree,
11072             tvb, offset, len - offset,
11073             "Message Elements");
11074     }
11075     else
11076     {
11077         (*msg_fcn)(tvb, dtap_tree, offset, len - offset);
11078     }
11079 }
11080
11081
11082 /* Register the protocol with Ethereal */
11083 void
11084 proto_register_gsm_a(void)
11085 {
11086     guint               i;
11087     guint               last_offset;
11088
11089     /* Setup list of header fields */
11090
11091     static hf_register_info hf[] =
11092     {
11093         { &hf_gsm_a_bssmap_msg_type,
11094             { "BSSMAP Message Type",    "gsm_a.bssmap_msgtype",
11095             FT_UINT8, BASE_HEX, VALS(gsm_a_bssmap_msg_strings), 0x0,
11096             "", HFILL }
11097         },
11098         { &hf_gsm_a_dtap_msg_mm_type,
11099             { "DTAP Mobility Management Message Type",  "gsm_a.dtap_msg_mm_type",
11100             FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_mm_strings), 0x0,
11101             "", HFILL }
11102         },
11103         { &hf_gsm_a_dtap_msg_rr_type,
11104             { "DTAP Radio Resources Management Message Type",   "gsm_a.dtap_msg_rr_type",
11105             FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_rr_strings), 0x0,
11106             "", HFILL }
11107         },
11108         { &hf_gsm_a_dtap_msg_cc_type,
11109             { "DTAP Call Control Message Type", "gsm_a.dtap_msg_cc_type",
11110             FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_cc_strings), 0x0,
11111             "", HFILL }
11112         },
11113         { &hf_gsm_a_dtap_msg_gmm_type,
11114             { "DTAP GPRS Mobility Management Message Type",     "gsm_a.dtap_msg_gmm_type",
11115             FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_gmm_strings), 0x0,
11116             "", HFILL }
11117         },
11118         { &hf_gsm_a_dtap_msg_sms_type,
11119             { "DTAP Short Message Service Message Type",        "gsm_a.dtap_msg_sms_type",
11120             FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_sms_strings), 0x0,
11121             "", HFILL }
11122         },
11123         { &hf_gsm_a_dtap_msg_sm_type,
11124             { "DTAP GPRS Session Management Message Type",      "gsm_a.dtap_msg_sm_type",
11125             FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_sm_strings), 0x0,
11126             "", HFILL }
11127         },
11128         { &hf_gsm_a_dtap_msg_ss_type,
11129             { "DTAP Non call Supplementary Service Message Type",       "gsm_a.dtap_msg_ss_type",
11130             FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_ss_strings), 0x0,
11131             "", HFILL }
11132         },
11133         { &hf_gsm_a_rp_msg_type,
11134             { "RP Message Type",        "gsm_a.rp_msg_type",
11135             FT_UINT8, BASE_HEX, VALS(gsm_rp_msg_strings), 0x0,
11136             "", HFILL }
11137         },
11138         { &hf_gsm_a_bssmap_elem_id,
11139             { "Element ID",     "gsm_a_bssmap.elem_id",
11140             FT_UINT8, BASE_DEC, NULL, 0,
11141             "", HFILL }
11142         },
11143         { &hf_gsm_a_dtap_elem_id,
11144             { "Element ID",     "gsm_a_dtap.elem_id",
11145             FT_UINT8, BASE_DEC, NULL, 0,
11146             "", HFILL }
11147         },
11148         { &hf_gsm_a_length,
11149             { "Length",         "gsm_a.len",
11150             FT_UINT8, BASE_DEC, NULL, 0,
11151             "", HFILL }
11152         },
11153         { &hf_gsm_a_none,
11154             { "Sub tree",       "gsm_a.none",
11155             FT_NONE, 0, 0, 0,
11156             "", HFILL }
11157         },
11158         { &hf_gsm_a_imsi,
11159             { "IMSI",   "gsm_a.imsi",
11160             FT_STRING, BASE_DEC, 0, 0,
11161             "", HFILL }
11162         },
11163         { &hf_gsm_a_tmsi,
11164             { "TMSI/P-TMSI",    "gsm_a.tmsi",
11165             FT_UINT32, BASE_HEX, 0, 0x0,
11166             "", HFILL }
11167         },
11168         { &hf_gsm_a_imei,
11169             { "IMEI",   "gsm_a.imei",
11170             FT_STRING, BASE_DEC, 0, 0,
11171             "", HFILL }
11172         },
11173         { &hf_gsm_a_imeisv,
11174             { "IMEISV", "gsm_a.imeisv",
11175             FT_STRING, BASE_DEC, 0, 0,
11176             "", HFILL }
11177         },
11178         { &hf_gsm_a_cld_party_bcd_num,
11179             { "Called Party BCD Number",        "gsm_a.cld_party_bcd_num",
11180             FT_STRING, BASE_DEC, 0, 0,
11181             "", HFILL }
11182         },
11183         { &hf_gsm_a_clg_party_bcd_num,
11184             { "Calling Party BCD Number",       "gsm_a.clg_party_bcd_num",
11185             FT_STRING, BASE_DEC, 0, 0,
11186             "", HFILL }
11187         },
11188         { &hf_gsm_a_cell_ci,
11189             { "Cell CI",        "gsm_a.cell_ci",
11190             FT_UINT16, BASE_HEX, 0, 0x0,
11191             "", HFILL }
11192         },
11193         { &hf_gsm_a_cell_lac,
11194             { "Cell LAC",       "gsm_a.cell_lac",
11195             FT_UINT16, BASE_HEX, 0, 0x0,
11196             "", HFILL }
11197         },
11198         { &hf_gsm_a_dlci_cc,
11199             { "Control Channel", "bssap.dlci.cc",
11200             FT_UINT8, BASE_HEX, VALS(bssap_cc_values), 0xc0,
11201             "", HFILL}
11202         },
11203         { &hf_gsm_a_dlci_spare,
11204             { "Spare", "bssap.dlci.spare",
11205             FT_UINT8, BASE_HEX, NULL, 0x38,
11206             "", HFILL}
11207         },
11208         { &hf_gsm_a_dlci_sapi,
11209             { "SAPI", "bssap.dlci.sapi",
11210             FT_UINT8, BASE_HEX, VALS(bssap_sapi_values), 0x07,
11211             "", HFILL}
11212         },
11213         { &hf_gsm_a_bssmap_cause,
11214             { "BSSMAP Cause",   "gsm_a_bssmap.cause",
11215             FT_UINT8, BASE_HEX, 0, 0x0,
11216             "", HFILL }
11217         },
11218         { &hf_gsm_a_dtap_cause,
11219             { "DTAP Cause",     "gsm_a_dtap.cause",
11220             FT_UINT8, BASE_HEX, 0, 0x0,
11221             "", HFILL }
11222         },
11223     };
11224
11225     /* Setup protocol subtree array */
11226 #define NUM_INDIVIDUAL_ELEMS    31
11227     static gint *ett[NUM_INDIVIDUAL_ELEMS + NUM_GSM_BSSMAP_MSG +
11228                         NUM_GSM_DTAP_MSG_MM + NUM_GSM_DTAP_MSG_RR + NUM_GSM_DTAP_MSG_CC +
11229                         NUM_GSM_DTAP_MSG_GMM + NUM_GSM_DTAP_MSG_SMS +
11230                         NUM_GSM_DTAP_MSG_SM + NUM_GSM_DTAP_MSG_SS + NUM_GSM_RP_MSG +
11231                         NUM_GSM_BSSMAP_ELEM + NUM_GSM_DTAP_ELEM +
11232                         NUM_GSM_SS_ETT];
11233
11234     ett[0] = &ett_bssmap_msg;
11235     ett[1] = &ett_dtap_msg;
11236     ett[2] = &ett_rp_msg;
11237     ett[3] = &ett_elems;
11238     ett[4] = &ett_elem;
11239     ett[5] = &ett_dtap_oct_1;
11240     ett[6] = &ett_cm_srvc_type;
11241     ett[7] = &ett_gsm_enc_info;
11242     ett[8] = &ett_cell_list;
11243     ett[9] = &ett_dlci;
11244     ett[10] = &ett_bc_oct_3a;
11245     ett[11] = &ett_bc_oct_4;
11246     ett[12] = &ett_bc_oct_5;
11247     ett[13] = &ett_bc_oct_5a;
11248     ett[14] = &ett_bc_oct_5b;
11249     ett[15] = &ett_bc_oct_6;
11250     ett[16] = &ett_bc_oct_6a;
11251     ett[17] = &ett_bc_oct_6b;
11252     ett[18] = &ett_bc_oct_6c;
11253     ett[19] = &ett_bc_oct_6d;
11254     ett[20] = &ett_bc_oct_6e;
11255     ett[21] = &ett_bc_oct_6f;
11256     ett[22] = &ett_bc_oct_6g;
11257     ett[23] = &ett_bc_oct_7;
11258
11259     ett[24] = &ett_tc_component;
11260     ett[25] = &ett_tc_invoke_id;
11261     ett[26] = &ett_tc_linked_id;
11262     ett[27] = &ett_tc_opr_code;
11263     ett[28] = &ett_tc_err_code;
11264     ett[29] = &ett_tc_prob_code;
11265     ett[30] = &ett_tc_sequence;
11266
11267     last_offset = NUM_INDIVIDUAL_ELEMS;
11268
11269     for (i=0; i < NUM_GSM_BSSMAP_MSG; i++, last_offset++)
11270     {
11271         ett_gsm_bssmap_msg[i] = -1;
11272         ett[last_offset] = &ett_gsm_bssmap_msg[i];
11273     }
11274
11275     for (i=0; i < NUM_GSM_DTAP_MSG_MM; i++, last_offset++)
11276     {
11277         ett_gsm_dtap_msg_mm[i] = -1;
11278         ett[last_offset] = &ett_gsm_dtap_msg_mm[i];
11279     }
11280
11281     for (i=0; i < NUM_GSM_DTAP_MSG_RR; i++, last_offset++)
11282     {
11283         ett_gsm_dtap_msg_rr[i] = -1;
11284         ett[last_offset] = &ett_gsm_dtap_msg_rr[i];
11285     }
11286
11287     for (i=0; i < NUM_GSM_DTAP_MSG_CC; i++, last_offset++)
11288     {
11289         ett_gsm_dtap_msg_cc[i] = -1;
11290         ett[last_offset] = &ett_gsm_dtap_msg_cc[i];
11291     }
11292
11293     for (i=0; i < NUM_GSM_DTAP_MSG_GMM; i++, last_offset++)
11294     {
11295         ett_gsm_dtap_msg_gmm[i] = -1;
11296         ett[last_offset] = &ett_gsm_dtap_msg_gmm[i];
11297     }
11298
11299     for (i=0; i < NUM_GSM_DTAP_MSG_SMS; i++, last_offset++)
11300     {
11301         ett_gsm_dtap_msg_sms[i] = -1;
11302         ett[last_offset] = &ett_gsm_dtap_msg_sms[i];
11303     }
11304
11305     for (i=0; i < NUM_GSM_DTAP_MSG_SM; i++, last_offset++)
11306     {
11307         ett_gsm_dtap_msg_sm[i] = -1;
11308         ett[last_offset] = &ett_gsm_dtap_msg_sm[i];
11309     }
11310
11311     for (i=0; i < NUM_GSM_DTAP_MSG_SS; i++, last_offset++)
11312     {
11313         ett_gsm_dtap_msg_ss[i] = -1;
11314         ett[last_offset] = &ett_gsm_dtap_msg_ss[i];
11315     }
11316
11317     for (i=0; i < NUM_GSM_RP_MSG; i++, last_offset++)
11318     {
11319         ett_gsm_rp_msg[i] = -1;
11320         ett[last_offset] = &ett_gsm_rp_msg[i];
11321     }
11322
11323     for (i=0; i < NUM_GSM_BSSMAP_ELEM; i++, last_offset++)
11324     {
11325         ett_gsm_bssmap_elem[i] = -1;
11326         ett[last_offset] = &ett_gsm_bssmap_elem[i];
11327     }
11328
11329     for (i=0; i < NUM_GSM_DTAP_ELEM; i++, last_offset++)
11330     {
11331         ett_gsm_dtap_elem[i] = -1;
11332         ett[last_offset] = &ett_gsm_dtap_elem[i];
11333     }
11334
11335     for (i=0; i < NUM_GSM_SS_ETT; i++, last_offset++)
11336     {
11337         gsm_ss_ett[i] = -1;
11338         ett[last_offset] = &gsm_ss_ett[i];
11339     }
11340
11341     /* Register the protocol name and description */
11342
11343     proto_a_bssmap =
11344         proto_register_protocol("GSM A-I/F BSSMAP", "GSM BSSMAP", "gsm_a_bssmap");
11345
11346     proto_register_field_array(proto_a_bssmap, hf, array_length(hf));
11347
11348     proto_a_dtap =
11349         proto_register_protocol("GSM A-I/F DTAP", "GSM DTAP", "gsm_a_dtap");
11350
11351     proto_a_rp =
11352         proto_register_protocol("GSM A-I/F RP", "GSM RP", "gsm_a_rp");
11353
11354     sms_dissector_table =
11355         register_dissector_table("gsm_a.sms_tpdu", "GSM SMS TPDU",
11356         FT_UINT8, BASE_DEC);
11357
11358     proto_register_subtree_array(ett, array_length(ett));
11359
11360     gsm_a_tap = register_tap("gsm_a");
11361 }
11362
11363
11364 void
11365 proto_reg_handoff_gsm_a(void)
11366 {
11367
11368     bssmap_handle = create_dissector_handle(dissect_bssmap, proto_a_bssmap);
11369     dtap_handle = create_dissector_handle(dissect_dtap, proto_a_dtap);
11370     rp_handle = create_dissector_handle(dissect_rp, proto_a_rp);
11371
11372     dissector_add("bssap.pdu_type",  BSSAP_PDU_TYPE_BSSMAP, bssmap_handle);
11373     dissector_add("bssap.pdu_type",  BSSAP_PDU_TYPE_DTAP, dtap_handle);
11374     dissector_add("ranap.nas_pdu",  BSSAP_PDU_TYPE_DTAP, dtap_handle);
11375
11376     data_handle = find_dissector("data");
11377 }