Some aclocal warning fixes during autogen.sh
[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.12 2004/03/19 07:54:57 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             GSM_A_TC_START_SUBTREE(subtree, saved_offset, tag, "Error Code",
6205                 ett_tc_err_code, &def_len[1], &temp_len, temp_subtree);
6206
6207             if (temp_len > 0)
6208             {
6209                 proto_tree_add_text(temp_subtree, asn1->tvb,
6210                     asn1->offset, temp_len, "Error Code");
6211
6212                 asn1->offset += temp_len;
6213             }
6214
6215             if (!def_len[1])
6216             {
6217                 saved_offset = asn1->offset;
6218                 asn1_eoc_decode(asn1, -1);
6219
6220                 proto_tree_add_text(subtree, asn1->tvb,
6221                     saved_offset, asn1->offset - saved_offset, "End of Contents");
6222             }
6223
6224             if ((comp_len - (asn1->offset - comp_data_offset)) > 0)
6225             {
6226                 /*
6227                  * XXX need conversations to determine 'opr_code'
6228                  */
6229                 gsm_ss_dissect(asn1, subtree,
6230                     comp_len - (asn1->offset - comp_data_offset), 0, comp_tag);
6231             }
6232             break;
6233
6234         case TCAP_COMP_REJECT:
6235             saved_offset = asn1->offset;
6236             asn1_id_decode1(asn1, &tag);
6237
6238             GSM_A_TC_START_SUBTREE(subtree, saved_offset, tag, "Problem Code",
6239                 ett_tc_prob_code, &def_len[1], &temp_len, temp_subtree);
6240
6241             if (temp_len > 0)
6242             {
6243                 proto_tree_add_text(temp_subtree, asn1->tvb,
6244                     asn1->offset, temp_len, "Problem Code");
6245
6246                 asn1->offset += temp_len;
6247             }
6248
6249             if (!def_len[1])
6250             {
6251                 saved_offset = asn1->offset;
6252                 asn1_eoc_decode(asn1, -1);
6253
6254                 proto_tree_add_text(subtree, asn1->tvb,
6255                     saved_offset, asn1->offset - saved_offset, "End of Contents");
6256             }
6257             break;
6258         }
6259
6260         if (!def_len[0])
6261         {
6262             saved_offset = asn1->offset;
6263             asn1_eoc_decode(asn1, -1);
6264
6265             proto_tree_add_text(subtree, asn1->tvb,
6266                 saved_offset, asn1->offset - saved_offset, "End of Contents");
6267         }
6268     }
6269
6270     return(len);
6271 }
6272
6273 /*
6274  * [3] 10.5.4.17
6275  */
6276 static guint8
6277 de_keypad_facility(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
6278 {
6279     guint8      oct;
6280     guint32     curr_offset;
6281
6282     len = len;
6283     curr_offset = offset;
6284
6285     oct = tvb_get_guint8(tvb, curr_offset);
6286
6287     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6288     proto_tree_add_text(tree,
6289         tvb, curr_offset, 1,
6290         "%s :  Spare",
6291         a_bigbuf);
6292
6293     other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
6294     proto_tree_add_text(tree,
6295         tvb, curr_offset, 1,
6296         "%s :  Keypad information: %c",
6297         a_bigbuf,
6298         oct & 0x7f);
6299
6300     curr_offset++;
6301
6302     sprintf(add_string, " - %c", oct & 0x7f);
6303
6304     /* no length check possible */
6305
6306     return(curr_offset - offset);
6307 }
6308
6309 /*
6310  * [3] 10.5.4.21
6311  */
6312 static guint8
6313 de_prog_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
6314 {
6315     guint8      oct;
6316     guint32     curr_offset;
6317     gchar       *str;
6318
6319     len = len;
6320     curr_offset = offset;
6321
6322     oct = tvb_get_guint8(tvb, curr_offset);
6323
6324     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6325     proto_tree_add_text(tree,
6326         tvb, curr_offset, 1,
6327         "%s :  Extension: %s",
6328         a_bigbuf,
6329         (oct & 0x80) ? "extended" : "not extended");
6330
6331     switch ((oct & 0x60) >> 5)
6332     {
6333     case 0: str = "Coding as specified in ITU-T Rec. Q.931"; break;
6334     case 1: str = "Reserved for other international standards"; break;
6335     case 2: str = "National standard"; break;
6336     default:
6337         str = "Standard defined for the GSM PLMNS";
6338         break;
6339     }
6340
6341     other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
6342     proto_tree_add_text(tree,
6343         tvb, curr_offset, 1,
6344         "%s :  Coding standard: %s",
6345         a_bigbuf,
6346         str);
6347
6348     other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
6349     proto_tree_add_text(tree,
6350         tvb, curr_offset, 1,
6351         "%s :  Spare",
6352         a_bigbuf);
6353
6354     switch (oct & 0x0f)
6355     {
6356     case 0: str = "User"; break;
6357     case 1: str = "Private network serving the local user"; break;
6358     case 2: str = "Public network serving the local user"; break;
6359     case 4: str = "Public network serving the remote user"; break;
6360     case 5: str = "Private network serving the remote user"; break;
6361     case 10: str = "Network beyond interworking point"; break;
6362     default:
6363         str = "Reserved";
6364         break;
6365     }
6366
6367     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
6368     proto_tree_add_text(tree,
6369         tvb, curr_offset, 1,
6370         "%s :  Location: %s",
6371         a_bigbuf,
6372         str);
6373
6374     curr_offset++;
6375
6376     oct = tvb_get_guint8(tvb, curr_offset);
6377
6378     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6379     proto_tree_add_text(tree,
6380         tvb, curr_offset, 1,
6381         "%s :  Extension: %s",
6382         a_bigbuf,
6383         (oct & 0x80) ? "extended" : "not extended");
6384
6385     switch (oct & 0x7f)
6386     {
6387     case 1: str = "Call is not end-to-end PLMN/ISDN, further call progress information may be available in-band"; break;
6388     case 2: str = "Destination address in non-PLMN/ISDN"; break;
6389     case 3: str = "Origination address in non-PLMN/ISDN"; break;
6390     case 4: str = "Call has returned to the PLMN/ISDN"; break;
6391     case 8: str = "In-band information or appropriate pattern now available"; break;
6392     case 32: str = "Call is end-to-end PLMN/ISDN"; break;
6393     case 64: str = "Queueing"; break;
6394     default:
6395         str = "Unspecific";
6396         break;
6397     }
6398
6399     other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
6400     proto_tree_add_text(tree,
6401         tvb, curr_offset, 1,
6402         "%s :  Progress Description: %s (%d)",
6403         a_bigbuf,
6404         str,
6405         oct & 0x7f);
6406
6407     sprintf(add_string, " - %d", oct & 0x7f);
6408
6409     curr_offset++;
6410
6411     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
6412
6413     return(curr_offset - offset);
6414 }
6415
6416 /*
6417  * [3] 10.5.4.22
6418  */
6419 static guint8
6420 de_repeat_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
6421 {
6422     guint8      oct;
6423     guint32     curr_offset;
6424     gchar       *str;
6425
6426     len = len;
6427     add_string = add_string;
6428     curr_offset = offset;
6429
6430     oct = tvb_get_guint8(tvb, curr_offset);
6431
6432     switch (oct & 0x0f)
6433     {
6434     case 1: str = "Circular for successive selection 'mode 1 alternate mode 2'"; break;
6435     case 2: str = "Support of fallback  mode 1 preferred, mode 2 selected if setup of mode 1 fails"; break;
6436     case 3: str = "Reserved: was allocated in earlier phases of the protocol"; break;
6437     default:
6438         str = "Reserved";
6439         break;
6440     }
6441
6442     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
6443     proto_tree_add_text(tree,
6444         tvb, curr_offset, 1,
6445         "%s :  %s",
6446         a_bigbuf,
6447         str);
6448
6449     curr_offset++;
6450
6451     /* no length check possible */
6452
6453     return(curr_offset - offset);
6454 }
6455
6456 /*
6457  * [6] 3.7.2
6458  */
6459 static guint8
6460 de_ss_ver_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     add_string = add_string;
6467     curr_offset = offset;
6468
6469     oct = tvb_get_guint8(tvb, curr_offset);
6470
6471     switch (oct)
6472     {
6473     case 0: str = "Phase 2 service, ellipsis notation, and phase 2 error handling is supported"; break;
6474     case 1: str = "SS-Protocol version 3 is supported, and phase 2 error handling is supported"; break;
6475     default:
6476         str = "Reserved";
6477         break;
6478     }
6479
6480     proto_tree_add_text(tree,
6481         tvb, curr_offset, 1,
6482         "%s",
6483         str);
6484
6485     curr_offset++;
6486
6487     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
6488
6489     return(curr_offset - offset);
6490 }
6491
6492 /*
6493  * [5] 8.1.4.1
6494  */
6495 static guint8
6496 de_cp_user_data(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
6497 {
6498     guint32     curr_offset;
6499     tvbuff_t    *rp_tvb;
6500
6501     add_string = add_string;
6502     curr_offset = offset;
6503
6504     proto_tree_add_text(tree, tvb, curr_offset, len,
6505         "RPDU");
6506
6507     /*
6508      * dissect the embedded RP message
6509      */
6510     rp_tvb = tvb_new_subset(tvb, curr_offset, len, len);
6511
6512     call_dissector(rp_handle, rp_tvb, g_pinfo, g_tree);
6513
6514     curr_offset += len;
6515
6516     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
6517
6518     return(curr_offset - offset);
6519 }
6520
6521 /*
6522  * [5] 8.1.4.2
6523  */
6524 static guint8
6525 de_cp_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
6526 {
6527     guint8      oct;
6528     guint32     curr_offset;
6529     gchar       *str;
6530
6531     len = len;
6532     curr_offset = offset;
6533
6534     oct = tvb_get_guint8(tvb, curr_offset);
6535
6536     switch (oct)
6537     {
6538     case 17: str = "Network failure"; break;
6539     case 22: str = "Congestion"; break;
6540     case 81: str = "Invalid Transaction Identifier value"; break;
6541     case 95: str = "Semantically incorrect message"; break;
6542     case 96: str = "Invalid mandatory information"; break;
6543     case 97: str = "Message type non-existent or not implemented"; break;
6544     case 98: str = "Message not compatible with the short message protocol state"; break;
6545     case 99: str = "Information element non-existent or not implemented"; break;
6546     case 111: str = "Protocol error, unspecified"; break;
6547     default:
6548         str = "Reserved, treat as Protocol error, unspecified";
6549         break;
6550     }
6551
6552     proto_tree_add_text(tree,
6553         tvb, curr_offset, 1,
6554         "Cause: (%u) %s",
6555         oct,
6556         str);
6557
6558     curr_offset++;
6559
6560     sprintf(add_string, " - (%u) %s", oct, str);
6561
6562     /* no length check possible */
6563
6564     return(curr_offset - offset);
6565 }
6566
6567 /*
6568  * [5] 8.2.3
6569  */
6570 static guint8
6571 de_rp_message_ref(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
6572 {
6573     guint8      oct;
6574     guint32     curr_offset;
6575
6576     len = len;
6577     add_string = add_string;
6578     curr_offset = offset;
6579
6580     oct = tvb_get_guint8(tvb, curr_offset);
6581
6582     proto_tree_add_text(tree,
6583         tvb, curr_offset, 1,
6584         "RP-Message Reference: 0x%02x (%u)",
6585         oct,
6586         oct);
6587
6588     curr_offset++;
6589
6590     /* no length check possible */
6591
6592     return(curr_offset - offset);
6593 }
6594
6595 /*
6596  * [5] 8.2.5.1
6597  */
6598 static guint8
6599 de_rp_orig_addr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
6600 {
6601     return(de_cld_party_bcd_num(tvb, tree, offset, len, add_string));
6602 }
6603
6604 /*
6605  * [5] 8.2.5.2
6606  */
6607 static guint8
6608 de_rp_dest_addr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
6609 {
6610     return(de_cld_party_bcd_num(tvb, tree, offset, len, add_string));
6611 }
6612
6613 /*
6614  * [5] 8.2.5.3
6615  */
6616 static guint8
6617 de_rp_user_data(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
6618 {
6619     guint32     curr_offset;
6620     tvbuff_t    *tpdu_tvb;
6621
6622     add_string = add_string;
6623     curr_offset = offset;
6624
6625     proto_tree_add_text(tree, tvb, curr_offset, len,
6626         "TPDU");
6627
6628     /*
6629      * dissect the embedded TPDU message
6630      */
6631     tpdu_tvb = tvb_new_subset(tvb, curr_offset, len, len);
6632
6633     dissector_try_port(sms_dissector_table, 0, tpdu_tvb, g_pinfo, g_tree);
6634
6635     curr_offset += len;
6636
6637     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
6638
6639     return(curr_offset - offset);
6640 }
6641
6642 /*
6643  * [5] 8.2.5.4
6644  */
6645 static guint8
6646 de_rp_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
6647 {
6648     guint8      oct;
6649     guint32     curr_offset;
6650     gchar       *str;
6651
6652     curr_offset = offset;
6653
6654     oct = tvb_get_guint8(tvb, curr_offset);
6655
6656     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6657     proto_tree_add_text(tree,
6658         tvb, curr_offset, 1,
6659         "%s :  Extension: %s",
6660         a_bigbuf,
6661         (oct & 0x80) ? "extended" : "not extended");
6662
6663     switch (oct & 0x7f)
6664     {
6665     case 1: str = "Unassigned (unallocated) number"; break;
6666     case 8: str = "Operator determined barring"; break;
6667     case 10: str = "Call barred"; break;
6668     case 11: str = "Reserved"; break;
6669     case 21: str = "Short message transfer rejected"; break;
6670     case 22: str = "Memory capacity exceeded"; break;
6671     case 27: str = "Destination out of order"; break;
6672     case 28: str = "Unidentified subscriber"; break;
6673     case 29: str = "Facility rejected"; break;
6674     case 30: str = "Unknown subscriber"; break;
6675     case 38: str = "Network out of order"; break;
6676     case 41: str = "Temporary failure"; break;
6677     case 42: str = "Congestion"; break;
6678     case 47: str = "Resources unavailable, unspecified"; break;
6679     case 50: str = "Requested facility not subscribed"; break;
6680     case 69: str = "Requested facility not implemented"; break;
6681     case 81: str = "Invalid short message transfer reference value"; break;
6682     case 95: str = "Semantically incorrect message"; break;
6683     case 96: str = "Invalid mandatory information"; break;
6684     case 97: str = "Message type non-existent or not implemented"; break;
6685     case 98: str = "Message not compatible with short message protocol state"; break;
6686     case 99: str = "Information element non-existent or not implemented"; break;
6687     case 111: str = "Protocol error, unspecified"; break;
6688     case 127: str = "Interworking, unspecified"; break;
6689     default:
6690         str = "Reserved";
6691         break;
6692     }
6693
6694     other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
6695     proto_tree_add_text(tree,
6696         tvb, curr_offset, 1,
6697         "%s :  Cause: (%u) %s",
6698         a_bigbuf,
6699         oct & 0x7f,
6700         str);
6701
6702     curr_offset++;
6703
6704     sprintf(add_string, " - (%u) %s", oct & 0x7f, str);
6705
6706     NO_MORE_DATA_CHECK(len);
6707
6708     proto_tree_add_text(tree,
6709         tvb, curr_offset, len - (curr_offset - offset),
6710         "Diagnostic field");
6711
6712     curr_offset += len - (curr_offset - offset);
6713
6714     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
6715
6716     return(curr_offset - offset);
6717 }
6718
6719 static guint8 (*bssmap_elem_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string) = {
6720     be_cic,     /* Circuit Identity Code */
6721     NULL,       /* Reserved */
6722     NULL,       /* Resource Available */
6723     be_cause,   /* Cause */
6724     be_cell_id, /* Cell Identifier */
6725     be_prio,    /* Priority */
6726     be_l3_header_info,  /* Layer 3 Header Information */
6727     de_mid,     /* IMSI */
6728     be_tmsi,    /* TMSI */
6729     be_enc_info,        /* Encryption Information */
6730     be_chan_type,       /* Channel Type */
6731     NULL,       /* Periodicity */
6732     NULL,       /* Extended Resource Indicator */
6733     NULL,       /* Number Of MSs */
6734     NULL,       /* Reserved */
6735     NULL,       /* Reserved */
6736     NULL,       /* Reserved */
6737     de_ms_cm_2, /* Classmark Information Type 2 */
6738     NULL,       /* Classmark Information Type 3 */
6739     NULL,       /* Interference Band To Be Used */
6740     de_rr_cause,        /* RR Cause */
6741     NULL,       /* Reserved */
6742     be_l3_info, /* Layer 3 Information */
6743     be_dlci,    /* DLCI */
6744     be_down_dtx_flag,   /* Downlink DTX Flag */
6745     be_cell_id_list,    /* Cell Identifier List */
6746     NULL /* no associated data */,      /* Response Request */
6747     NULL,       /* Resource Indication Method */
6748     de_ms_cm_1, /* Classmark Information Type 1 */
6749     NULL,       /* Circuit Identity Code List */
6750     NULL,       /* Diagnostic */
6751     be_l3_msg,  /* Layer 3 Message Contents */
6752     be_chosen_chan,     /* Chosen Channel */
6753     NULL,       /* Total Resource Accessible */
6754     be_ciph_resp_mode,  /* Cipher Response Mode */
6755     NULL,       /* Channel Needed */
6756     NULL,       /* Trace Type */
6757     NULL,       /* TriggerID */
6758     NULL,       /* Trace Reference */
6759     NULL,       /* TransactionID */
6760     de_mid,     /* Mobile Identity */
6761     NULL,       /* OMCID */
6762     be_for_ind, /* Forward Indicator */
6763     be_chosen_enc_alg,  /* Chosen Encryption Algorithm */
6764     be_cct_pool,        /* Circuit Pool */
6765     NULL,       /* Circuit Pool List */
6766     NULL,       /* Time Indication */
6767     NULL,       /* Resource Situation */
6768     be_curr_chan_1,     /* Current Channel Type 1 */
6769     be_que_ind, /* Queueing Indicator */
6770     be_speech_ver,      /* Speech Version */
6771     NULL,       /* Assignment Requirement */
6772     NULL /* no associated data */,      /* Talker Flag */
6773     NULL /* no associated data */,      /* Connection Release Requested */
6774     NULL,       /* Group Call Reference */
6775     NULL,       /* eMLPP Priority */
6776     NULL,       /* Configuration Evolution Indication */
6777     NULL /* no decode required */,      /* Old BSS to New BSS Information */
6778     NULL,       /* LSA Identifier */
6779     NULL,       /* LSA Identifier List */
6780     NULL,       /* LSA Information */
6781     NULL,       /* LCS QoS */
6782     NULL,       /* LSA access control suppression */
6783     NULL,       /* LCS Priority */
6784     NULL,       /* Location Type */
6785     NULL,       /* Location Estimate */
6786     NULL,       /* Positioning Data */
6787     NULL,       /* LCS Cause */
6788     NULL,       /* LCS Client Type */
6789     be_apdu,    /* APDU */
6790     NULL,       /* Network Element Identity */
6791     NULL,       /* GPS Assistance Data */
6792     NULL,       /* Deciphering Keys */
6793     NULL,       /* Return Error Request */
6794     NULL,       /* Return Error Cause */
6795     NULL,       /* Segmentation */
6796     NULL,       /* NONE */
6797 };
6798
6799 static guint8 (*dtap_elem_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string) = {
6800     /* Common Information Elements 10.5.1 */
6801     de_cell_id, /* Cell Identity */
6802     NULL /* handled inline */,  /* Ciphering Key Sequence Number */
6803     de_lai,     /* Location Area Identification */
6804     de_mid,     /* Mobile Identity */
6805     de_ms_cm_1, /* Mobile Station Classmark 1 */
6806     de_ms_cm_2, /* Mobile Station Classmark 2 */
6807     NULL,       /* Mobile Station Classmark 3 */
6808     de_d_gb_call_ref,   /* Descriptive group or broadcast call reference */
6809     NULL /* handled inline */,  /* Group Cipher Key Number */
6810     de_pd_sapi, /* PD and SAPI $(CCBS)$ */
6811     de_prio /* handled inline */,       /* Priority Level */
6812     de_plmn_list,       /* PLMN List */
6813     /* Radio Resource Management Information Elements 10.5.2, most are from 10.5.1 */
6814     de_rr_cause,        /* RR Cause */
6815     /* Mobility Management Information Elements 10.5.3 */
6816     de_auth_param_rand, /* Authentication Parameter RAND */
6817     de_auth_param_autn, /* Authentication Parameter AUTN (UMTS authentication challenge only) */
6818     de_auth_resp_param, /* Authentication Response Parameter */
6819     de_auth_resp_param_ext,     /* Authentication Response Parameter (extension) (UMTS authentication challenge only) */
6820     de_auth_fail_param, /* Authentication Failure Parameter (UMTS authentication challenge only) */
6821     NULL /* handled inline */,  /* CM Service Type */
6822     NULL /* handled inline */,  /* Identity Type */
6823     NULL /* handled inline */,  /* Location Updating Type */
6824     de_network_name,    /* Network Name */
6825     de_rej_cause,       /* Reject Cause */
6826     NULL /* no associated data */,      /* Follow-on Proceed */
6827     de_time_zone,       /* Time Zone */
6828     de_time_zone_time,  /* Time Zone and Time */
6829     NULL /* no associated data */,      /* CTS Permission */
6830     de_lsa_id,  /* LSA Identifier */
6831     de_day_saving_time, /* Daylight Saving Time */
6832     /* Call Control Information Elements 10.5.4 */
6833     de_aux_states,      /* Auxiliary States */
6834     de_bearer_cap,      /* Bearer Capability */
6835     de_cc_cap,  /* Call Control Capabilities */
6836     de_call_state,      /* Call State */
6837     de_cld_party_bcd_num,       /* Called Party BCD Number */
6838     de_cld_party_sub_addr,      /* Called Party Subaddress */
6839     de_clg_party_bcd_num,       /* Calling Party BCD Number */
6840     de_clg_party_sub_addr,      /* Calling Party Subaddress */
6841     de_cause,   /* Cause */
6842     NULL /* no associated data */,      /* CLIR Suppression */
6843     NULL /* no associated data */,      /* CLIR Invocation */
6844     NULL /* handled inline */,  /* Congestion Level */
6845     NULL,       /* Connected Number */
6846     NULL,       /* Connected Subaddress */
6847     de_facility,        /* Facility */
6848     NULL,       /* High Layer Compatibility */
6849     de_keypad_facility, /* Keypad Facility */
6850     NULL,       /* Low Layer Compatibility */
6851     NULL,       /* More Data */
6852     NULL,       /* Notification Indicator */
6853     de_prog_ind,        /* Progress Indicator */
6854     NULL,       /* Recall type $(CCBS)$ */
6855     NULL,       /* Redirecting Party BCD Number */
6856     NULL,       /* Redirecting Party Subaddress */
6857     de_repeat_ind,      /* Repeat Indicator */
6858     NULL /* no associated data */,      /* Reverse Call Setup Direction */
6859     NULL,       /* SETUP Container $(CCBS)$ */
6860     NULL,       /* Signal */
6861     de_ss_ver_ind,      /* SS Version Indicator */
6862     NULL,       /* User-user */
6863     NULL,       /* Alerting Pattern $(NIA)$ */
6864     NULL,       /* Allowed Actions $(CCBS)$ */
6865     NULL,       /* Stream Identifier */
6866     NULL,       /* Network Call Control Capabilities */
6867     NULL,       /* Cause of No CLI */
6868     NULL,       /* Immediate Modification Indicator */
6869     NULL,       /* Supported Codec List */
6870     NULL,       /* Service Category */
6871     /* GPRS Mobility Management Information Elements 10.5.5 */
6872     NULL,       /* Attach Result */
6873     NULL,       /* Attach Type */
6874     NULL,       /* TMSI Status */
6875     NULL,       /* Detach Type */
6876     NULL,       /* DRX Parameter */
6877     NULL,       /* Force to Standby */
6878     NULL,       /* P-TMSI Signature */
6879     NULL,       /* P-TMSI Signature 2 */
6880     NULL,       /* Identity Type 2 */
6881     NULL,       /* IMEISV Request */
6882     NULL,       /* Receive N-PDU Numbers List */
6883     NULL,       /* MS Network Capability */
6884     NULL,       /* MS Radio Access Capability */
6885     NULL,       /* GMM Cause */
6886     NULL,       /* Routing Area Identification */
6887     NULL,       /* Update Result */
6888     NULL,       /* A&C Reference Number */
6889     NULL,       /* Service Type */
6890     NULL,       /* Cell Notification */
6891     NULL,       /* Network Feature Support */
6892     /* Short Message Service Information Elements [5] 8.1.4 */
6893     de_cp_user_data,    /* CP-User Data */
6894     de_cp_cause,        /* CP-Cause */
6895     /* Short Message Service Information Elements [5] 8.2 */
6896     de_rp_message_ref,  /* RP-Message Reference */
6897     de_rp_orig_addr,    /* RP-Origination Address */
6898     de_rp_dest_addr,    /* RP-Destination Address */
6899     de_rp_user_data,    /* RP-User Data */
6900     de_rp_cause,        /* RP-Cause */
6901     /* Session Management Information Elements 10.5.6 */
6902     NULL,       /* Access Point Name */
6903     NULL,       /* Network Service Access Point Identifier */
6904     NULL,       /* Protocol Configuration Options */
6905     NULL,       /* Packet Data Protocol Address */
6906     NULL,       /* Quality Of Service */
6907     NULL,       /* SM Cause */
6908     NULL,       /* Linked TI */
6909     NULL,       /* LLC Service Access Point Identifier */
6910     NULL,       /* Tear Down Indicator */
6911     NULL,       /* Packet Flow Identifier */
6912     NULL,       /* Traffic Flow Template */
6913     /* GPRS Common Information Elements 10.5.7 */
6914     NULL,       /* PDP Context Status */
6915     NULL,       /* Radio Priority */
6916     NULL,       /* GPRS Timer */
6917     NULL,       /* GPRS Timer 2 */
6918     NULL,       /* NONE */
6919 };
6920
6921 #define SET_ELEM_VARS(SEV_pdu_type, SEV_elem_names, SEV_elem_ett, SEV_elem_funcs) \
6922     switch (SEV_pdu_type) \
6923     { \
6924     case BSSAP_PDU_TYPE_BSSMAP: \
6925         SEV_elem_names = gsm_bssmap_elem_strings; \
6926         SEV_elem_ett = ett_gsm_bssmap_elem; \
6927         SEV_elem_funcs = bssmap_elem_fcn; \
6928         break; \
6929     case BSSAP_PDU_TYPE_DTAP: \
6930         SEV_elem_names = gsm_dtap_elem_strings; \
6931         SEV_elem_ett = ett_gsm_dtap_elem; \
6932         SEV_elem_funcs = dtap_elem_fcn; \
6933         break; \
6934     default: \
6935         proto_tree_add_text(tree, \
6936             tvb, curr_offset, -1, \
6937             "Unknown PDU type (%u)", SEV_pdu_type); \
6938         return(consumed); \
6939     }
6940
6941 /*
6942  * Type Length Value (TLV) element dissector
6943  */
6944 static guint8
6945 elem_tlv(tvbuff_t *tvb, proto_tree *tree, guint8 iei, gint pdu_type, int idx, guint32 offset, guint len, gchar *name_add)
6946 {
6947     guint8              oct, parm_len;
6948     guint8              consumed;
6949     guint32             curr_offset;
6950     proto_tree          *subtree;
6951     proto_item          *item;
6952     const value_string  *elem_names;
6953     gint                *elem_ett;
6954     guint8 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string);
6955
6956     len = len;
6957     curr_offset = offset;
6958     consumed = 0;
6959
6960     SET_ELEM_VARS(pdu_type, elem_names, elem_ett, elem_funcs);
6961
6962     oct = tvb_get_guint8(tvb, curr_offset);
6963
6964     if (oct == iei)
6965     {
6966         parm_len = tvb_get_guint8(tvb, curr_offset + 1);
6967
6968         item =
6969             proto_tree_add_text(tree,
6970                 tvb, curr_offset, parm_len + 2,
6971                 "%s%s",
6972                 elem_names[idx].strptr,
6973                 (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
6974
6975         subtree = proto_item_add_subtree(item, elem_ett[idx]);
6976
6977         proto_tree_add_uint(subtree,
6978             (BSSAP_PDU_TYPE_BSSMAP == pdu_type) ? hf_gsm_a_bssmap_elem_id : hf_gsm_a_dtap_elem_id, tvb,
6979             curr_offset, 1, oct);
6980
6981         proto_tree_add_uint(subtree, hf_gsm_a_length, tvb,
6982             curr_offset + 1, 1, parm_len);
6983
6984         if (parm_len > 0)
6985         {
6986             if (elem_funcs[idx] == NULL)
6987             {
6988                 proto_tree_add_text(subtree,
6989                     tvb, curr_offset + 2, parm_len,
6990                     "Element Value");
6991
6992                 consumed = parm_len;
6993             }
6994             else
6995             {
6996                 a_add_string[0] = '\0';
6997                 consumed =
6998                     (*elem_funcs[idx])(tvb, subtree, curr_offset + 2,
6999                         parm_len, a_add_string);
7000
7001                 if (a_add_string[0] != '\0')
7002                 {
7003                     proto_item_append_text(item, a_add_string);
7004                     a_add_string[0] = '\0';
7005                 }
7006             }
7007         }
7008
7009         consumed += 2;
7010     }
7011
7012     return(consumed);
7013 }
7014
7015 /*
7016  * Type Value (TV) element dissector
7017  *
7018  * Length cannot be used in these functions, big problem if a element dissector
7019  * is not defined for these.
7020  */
7021 static guint8
7022 elem_tv(tvbuff_t *tvb, proto_tree *tree, guint8 iei, gint pdu_type, int idx, guint32 offset, gchar *name_add)
7023 {
7024     guint8              oct;
7025     guint8              consumed;
7026     guint32             curr_offset;
7027     proto_tree          *subtree;
7028     proto_item          *item;
7029     const value_string  *elem_names;
7030     gint                *elem_ett;
7031     guint8 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string);
7032
7033     curr_offset = offset;
7034     consumed = 0;
7035
7036     SET_ELEM_VARS(pdu_type, elem_names, elem_ett, elem_funcs);
7037
7038     oct = tvb_get_guint8(tvb, curr_offset);
7039
7040     if (oct == iei)
7041     {
7042         item =
7043             proto_tree_add_text(tree,
7044                 tvb, curr_offset, -1,
7045                 "%s%s",
7046                 elem_names[idx].strptr,
7047                 (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
7048
7049         subtree = proto_item_add_subtree(item, elem_ett[idx]);
7050
7051         proto_tree_add_uint(subtree,
7052             (BSSAP_PDU_TYPE_BSSMAP == pdu_type) ? hf_gsm_a_bssmap_elem_id : hf_gsm_a_dtap_elem_id, tvb,
7053             curr_offset, 1, oct);
7054
7055         if (elem_funcs[idx] == NULL)
7056         {
7057             /* BAD THING, CANNOT DETERMINE LENGTH */
7058
7059             proto_tree_add_text(subtree,
7060                 tvb, curr_offset + 1, 1,
7061                 "No element dissector, rest of dissection may be incorrect");
7062
7063             consumed = 1;
7064         }
7065         else
7066         {
7067             a_add_string[0] = '\0';
7068             consumed = (*elem_funcs[idx])(tvb, subtree, curr_offset + 1, -1, a_add_string);
7069
7070             if (a_add_string[0] != '\0')
7071             {
7072                 proto_item_append_text(item, a_add_string);
7073                 a_add_string[0] = '\0';
7074             }
7075         }
7076
7077         consumed++;
7078
7079         proto_item_set_len(item, consumed);
7080     }
7081
7082     return(consumed);
7083 }
7084
7085 /*
7086  * Type Value (TV) element dissector
7087  * Where top half nibble is IEI and bottom half nibble is value.
7088  *
7089  * Length cannot be used in these functions, big problem if a element dissector
7090  * is not defined for these.
7091  */
7092 static guint8
7093 elem_tv_short(tvbuff_t *tvb, proto_tree *tree, guint8 iei, gint pdu_type, int idx, guint32 offset, gchar *name_add)
7094 {
7095     guint8              oct;
7096     guint8              consumed;
7097     guint32             curr_offset;
7098     proto_tree          *subtree;
7099     proto_item          *item;
7100     const value_string  *elem_names;
7101     gint                *elem_ett;
7102     guint8 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string);
7103
7104     curr_offset = offset;
7105     consumed = 0;
7106
7107     SET_ELEM_VARS(pdu_type, elem_names, elem_ett, elem_funcs);
7108
7109     oct = tvb_get_guint8(tvb, curr_offset);
7110
7111     if ((oct & 0xf0) == (iei & 0xf0))
7112     {
7113         item =
7114             proto_tree_add_text(tree,
7115                 tvb, curr_offset, -1,
7116                 "%s%s",
7117                 elem_names[idx].strptr,
7118                 (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
7119
7120         subtree = proto_item_add_subtree(item, elem_ett[idx]);
7121
7122         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
7123         proto_tree_add_text(subtree,
7124             tvb, curr_offset, 1,
7125             "%s :  Element ID",
7126             a_bigbuf);
7127
7128         if (elem_funcs[idx] == NULL)
7129         {
7130             /* BAD THING, CANNOT DETERMINE LENGTH */
7131
7132             proto_tree_add_text(subtree,
7133                 tvb, curr_offset, 1,
7134                 "No element dissector, rest of dissection may be incorrect");
7135
7136             consumed++;
7137         }
7138         else
7139         {
7140             a_add_string[0] = '\0';
7141             consumed = (*elem_funcs[idx])(tvb, subtree, curr_offset, -1, a_add_string);
7142
7143             if (a_add_string[0] != '\0')
7144             {
7145                 proto_item_append_text(item, a_add_string);
7146                 a_add_string[0] = '\0';
7147             }
7148         }
7149
7150         proto_item_set_len(item, consumed);
7151     }
7152
7153     return(consumed);
7154 }
7155
7156 /*
7157  * Type (T) element dissector
7158  */
7159 static guint8
7160 elem_t(tvbuff_t *tvb, proto_tree *tree, guint8 iei, gint pdu_type, int idx, guint32 offset, gchar *name_add)
7161 {
7162     guint8              oct;
7163     guint32             curr_offset;
7164     guint8              consumed;
7165     const value_string  *elem_names;
7166     gint                *elem_ett;
7167     guint8 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string);
7168
7169     curr_offset = offset;
7170     consumed = 0;
7171
7172     SET_ELEM_VARS(pdu_type, elem_names, elem_ett, elem_funcs);
7173
7174     oct = tvb_get_guint8(tvb, curr_offset);
7175
7176     if (oct == iei)
7177     {
7178         proto_tree_add_uint_format(tree,
7179             (BSSAP_PDU_TYPE_BSSMAP == pdu_type) ? hf_gsm_a_bssmap_elem_id : hf_gsm_a_dtap_elem_id, tvb,
7180             curr_offset, 1, oct,
7181             "%s%s",
7182             elem_names[idx].strptr,
7183             (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
7184
7185         consumed = 1;
7186     }
7187
7188     return(consumed);
7189 }
7190
7191 /*
7192  * Length Value (LV) element dissector
7193  */
7194 static guint8
7195 elem_lv(tvbuff_t *tvb, proto_tree *tree, gint pdu_type, int idx, guint32 offset, guint len, gchar *name_add)
7196 {
7197     guint8              parm_len;
7198     guint8              consumed;
7199     guint32             curr_offset;
7200     proto_tree          *subtree;
7201     proto_item          *item;
7202     const value_string  *elem_names;
7203     gint                *elem_ett;
7204     guint8 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string);
7205
7206     len = len;
7207     curr_offset = offset;
7208     consumed = 0;
7209
7210     SET_ELEM_VARS(pdu_type, elem_names, elem_ett, elem_funcs);
7211
7212     parm_len = tvb_get_guint8(tvb, curr_offset);
7213
7214     item =
7215         proto_tree_add_text(tree,
7216             tvb, curr_offset, parm_len + 1,
7217             "%s%s",
7218             elem_names[idx].strptr,
7219             (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
7220
7221     subtree = proto_item_add_subtree(item, elem_ett[idx]);
7222
7223     proto_tree_add_uint(subtree, hf_gsm_a_length, tvb,
7224         curr_offset, 1, parm_len);
7225
7226     if (parm_len > 0)
7227     {
7228         if (elem_funcs[idx] == NULL)
7229         {
7230             proto_tree_add_text(subtree,
7231                 tvb, curr_offset + 1, parm_len,
7232                 "Element Value");
7233
7234             consumed = parm_len;
7235         }
7236         else
7237         {
7238             a_add_string[0] = '\0';
7239             consumed =
7240                 (*elem_funcs[idx])(tvb, subtree, curr_offset + 1,
7241                     parm_len, a_add_string);
7242
7243             if (a_add_string[0] != '\0')
7244             {
7245                 proto_item_append_text(item, a_add_string);
7246                 a_add_string[0] = '\0';
7247             }
7248         }
7249     }
7250
7251     return(consumed + 1);
7252 }
7253
7254 /*
7255  * Value (V) element dissector
7256  *
7257  * Length cannot be used in these functions, big problem if a element dissector
7258  * is not defined for these.
7259  */
7260 static guint8
7261 elem_v(tvbuff_t *tvb, proto_tree *tree, gint pdu_type, int idx, guint32 offset)
7262 {
7263     guint8              consumed;
7264     guint32             curr_offset;
7265     const value_string  *elem_names;
7266     gint                *elem_ett;
7267     guint8 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string);
7268
7269     curr_offset = offset;
7270     consumed = 0;
7271
7272     SET_ELEM_VARS(pdu_type, elem_names, elem_ett, elem_funcs);
7273
7274     if (elem_funcs[idx] == NULL)
7275     {
7276         /* BAD THING, CANNOT DETERMINE LENGTH */
7277
7278         proto_tree_add_text(tree,
7279             tvb, curr_offset, 1,
7280             "No element dissector, rest of dissection may be incorrect");
7281
7282         consumed = 1;
7283     }
7284     else
7285     {
7286         a_add_string[0] = '\0';
7287         consumed = (*elem_funcs[idx])(tvb, tree, curr_offset, -1, a_add_string);
7288         a_add_string[0] = '\0';
7289     }
7290
7291     return(consumed);
7292 }
7293
7294 #define ELEM_MAND_TLV(EMT_iei, EMT_pdu_type, EMT_elem_idx, EMT_elem_name_addition) \
7295 {\
7296     if ((consumed = elem_tlv(tvb, tree, (guint8) EMT_iei, EMT_pdu_type, EMT_elem_idx, curr_offset, curr_len, EMT_elem_name_addition)) > 0) \
7297     { \
7298         curr_offset += consumed; \
7299         curr_len -= consumed; \
7300     } \
7301     else \
7302     { \
7303         proto_tree_add_text(tree, \
7304             tvb, curr_offset, 0, \
7305             "Missing Mandatory element (0x%02x) %s%s, rest of dissection is suspect", \
7306                 EMT_iei, \
7307                 (EMT_pdu_type == BSSAP_PDU_TYPE_BSSMAP) ? \
7308                     gsm_bssmap_elem_strings[EMT_elem_idx].strptr : gsm_dtap_elem_strings[EMT_elem_idx].strptr, \
7309                 (EMT_elem_name_addition == NULL) || (EMT_elem_name_addition[0] == '\0') ? "" : EMT_elem_name_addition \
7310             ); \
7311     } \
7312     if (curr_len <= 0) return; \
7313 }
7314
7315 #define ELEM_OPT_TLV(EOT_iei, EOT_pdu_type, EOT_elem_idx, EOT_elem_name_addition) \
7316 {\
7317     if ((consumed = elem_tlv(tvb, tree, (guint8) EOT_iei, EOT_pdu_type, EOT_elem_idx, curr_offset, curr_len, EOT_elem_name_addition)) > 0) \
7318     { \
7319         curr_offset += consumed; \
7320         curr_len -= consumed; \
7321     } \
7322     if (curr_len <= 0) return; \
7323 }
7324
7325 #define ELEM_MAND_TV(EMT_iei, EMT_pdu_type, EMT_elem_idx, EMT_elem_name_addition) \
7326 {\
7327     if ((consumed = elem_tv(tvb, tree, (guint8) EMT_iei, EMT_pdu_type, EMT_elem_idx, curr_offset, EMT_elem_name_addition)) > 0) \
7328     { \
7329         curr_offset += consumed; \
7330         curr_len -= consumed; \
7331     } \
7332     else \
7333     { \
7334         proto_tree_add_text(tree, \
7335             tvb, curr_offset, 0, \
7336             "Missing Mandatory element (0x%02x) %s%s, rest of dissection is suspect", \
7337                 EMT_iei, \
7338                 (EMT_pdu_type == BSSAP_PDU_TYPE_BSSMAP) ? \
7339                     gsm_bssmap_elem_strings[EMT_elem_idx].strptr : gsm_dtap_elem_strings[EMT_elem_idx].strptr, \
7340                 (EMT_elem_name_addition == NULL) || (EMT_elem_name_addition[0] == '\0') ? "" : EMT_elem_name_addition \
7341             ); \
7342     } \
7343     if (curr_len <= 0) return; \
7344 }
7345
7346 #define ELEM_OPT_TV(EOT_iei, EOT_pdu_type, EOT_elem_idx, EOT_elem_name_addition) \
7347 {\
7348     if ((consumed = elem_tv(tvb, tree, (guint8) EOT_iei, EOT_pdu_type, EOT_elem_idx, curr_offset, EOT_elem_name_addition)) > 0) \
7349     { \
7350         curr_offset += consumed; \
7351         curr_len -= consumed; \
7352     } \
7353     if (curr_len <= 0) return; \
7354 }
7355
7356 #define ELEM_OPT_TV_SHORT(EOT_iei, EOT_pdu_type, EOT_elem_idx, EOT_elem_name_addition) \
7357 {\
7358     if ((consumed = elem_tv_short(tvb, tree, EOT_iei, EOT_pdu_type, EOT_elem_idx, curr_offset, EOT_elem_name_addition)) > 0) \
7359     { \
7360         curr_offset += consumed; \
7361         curr_len -= consumed; \
7362     } \
7363     if (curr_len <= 0) return; \
7364 }
7365
7366 #define ELEM_OPT_T(EOT_iei, EOT_pdu_type, EOT_elem_idx, EOT_elem_name_addition) \
7367 {\
7368     if ((consumed = elem_t(tvb, tree, (guint8) EOT_iei, EOT_pdu_type, EOT_elem_idx, curr_offset, EOT_elem_name_addition)) > 0) \
7369     { \
7370         curr_offset += consumed; \
7371         curr_len -= consumed; \
7372     } \
7373     if (curr_len <= 0) return; \
7374 }
7375
7376 #define ELEM_MAND_LV(EML_pdu_type, EML_elem_idx, EML_elem_name_addition) \
7377 {\
7378     if ((consumed = elem_lv(tvb, tree, EML_pdu_type, EML_elem_idx, curr_offset, curr_len, EML_elem_name_addition)) > 0) \
7379     { \
7380         curr_offset += consumed; \
7381         curr_len -= consumed; \
7382     } \
7383     else \
7384     { \
7385         /* Mandatory, but nothing we can do */ \
7386     } \
7387     if (curr_len <= 0) return; \
7388 }
7389
7390 #define ELEM_MAND_V(EMV_pdu_type, EMV_elem_idx) \
7391 {\
7392     if ((consumed = elem_v(tvb, tree, EMV_pdu_type, EMV_elem_idx, curr_offset)) > 0) \
7393     { \
7394         curr_offset += consumed; \
7395         curr_len -= consumed; \
7396     } \
7397     else \
7398     { \
7399         /* Mandatory, but nothing we can do */ \
7400     } \
7401     if (curr_len <= 0) return; \
7402 }
7403
7404
7405 /* MESSAGE FUNCTIONS */
7406
7407 /*
7408  *  [2] 3.2.1.1
7409  */
7410 static void
7411 bssmap_ass_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7412 {
7413     guint32     curr_offset;
7414     guint32     consumed;
7415     guint       curr_len;
7416
7417     curr_offset = offset;
7418     curr_len = len;
7419
7420     is_uplink = IS_UPLINK_FALSE;
7421
7422     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CHAN_TYPE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHAN_TYPE, "");
7423
7424     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_L3_HEADER_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_L3_HEADER_INFO, "");
7425
7426     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_PRIO].value, BSSAP_PDU_TYPE_BSSMAP, BE_PRIO, "");
7427
7428     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
7429
7430     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_DOWN_DTX_FLAG].value, BSSAP_PDU_TYPE_BSSMAP, BE_DOWN_DTX_FLAG, "");
7431
7432     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_INT_BAND].value, BSSAP_PDU_TYPE_BSSMAP, BE_INT_BAND, "");
7433
7434     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CM_INFO_2].value, BSSAP_PDU_TYPE_BSSMAP, BE_CM_INFO_2, "");
7435
7436     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_GROUP_CALL_REF].value, BSSAP_PDU_TYPE_BSSMAP, BE_GROUP_CALL_REF, "");
7437
7438     ELEM_OPT_T(gsm_bssmap_elem_strings[BE_TALKER_FLAG].value, BSSAP_PDU_TYPE_BSSMAP, BE_TALKER_FLAG, "");
7439
7440     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_LSA_ACC_CTRL].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_ACC_CTRL, "");
7441
7442     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7443 }
7444
7445 /*
7446  *  [2] 3.2.1.2
7447  */
7448 static void
7449 bssmap_ass_complete(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7450 {
7451     guint32     curr_offset;
7452     guint32     consumed;
7453     guint       curr_len;
7454
7455     curr_offset = offset;
7456     curr_len = len;
7457
7458     is_uplink = IS_UPLINK_TRUE;
7459
7460     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_RR_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_RR_CAUSE, "");
7461
7462     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
7463
7464     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
7465
7466     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_CHAN].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_CHAN, "");
7467
7468     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_ENC_ALG].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_ENC_ALG, "");
7469
7470     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CCT_POOL].value, BSSAP_PDU_TYPE_BSSMAP, BE_CCT_POOL, "");
7471
7472     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_SPEECH_VER].value, BSSAP_PDU_TYPE_BSSMAP, BE_SPEECH_VER, " (Chosen)");
7473
7474     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_LSA_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_ID, "");
7475
7476     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7477 }
7478
7479 /*
7480  *  [2] 3.2.1.3
7481  */
7482 static void
7483 bssmap_ass_failure(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7484 {
7485     guint32     curr_offset;
7486     guint32     consumed;
7487     guint       curr_len;
7488
7489     curr_offset = offset;
7490     curr_len = len;
7491
7492     is_uplink = IS_UPLINK_TRUE;
7493
7494     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
7495
7496     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_RR_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_RR_CAUSE, "");
7497
7498     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CCT_POOL].value, BSSAP_PDU_TYPE_BSSMAP, BE_CCT_POOL, "");
7499
7500     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CCT_POOL_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CCT_POOL_LIST, "");
7501
7502     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7503 }
7504
7505 /*
7506  *  [2] 3.2.1.4
7507  */
7508 static void
7509 bssmap_block(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7510 {
7511     guint32     curr_offset;
7512     guint32     consumed;
7513     guint       curr_len;
7514
7515     curr_offset = offset;
7516     curr_len = len;
7517
7518     is_uplink = IS_UPLINK_TRUE;
7519
7520     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
7521
7522     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
7523
7524     ELEM_OPT_T(gsm_bssmap_elem_strings[BE_CONN_REL_REQ].value, BSSAP_PDU_TYPE_BSSMAP, BE_CONN_REL_REQ, "");
7525
7526     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7527 }
7528
7529 /*
7530  *  [2] 3.2.1.5
7531  */
7532 static void
7533 bssmap_block_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7534 {
7535     guint32     curr_offset;
7536     guint32     consumed;
7537     guint       curr_len;
7538
7539     curr_offset = offset;
7540     curr_len = len;
7541
7542     is_uplink = IS_UPLINK_TRUE;
7543
7544     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
7545
7546     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7547 }
7548
7549 /*
7550  *  [2] 3.2.1.6
7551  */
7552 static void
7553 bssmap_unblock(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7554 {
7555     guint32     curr_offset;
7556     guint32     consumed;
7557     guint       curr_len;
7558
7559     curr_offset = offset;
7560     curr_len = len;
7561
7562     is_uplink = IS_UPLINK_TRUE;
7563
7564     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
7565
7566     ELEM_OPT_T(gsm_bssmap_elem_strings[BE_CONN_REL_REQ].value, BSSAP_PDU_TYPE_BSSMAP, BE_CONN_REL_REQ, "");
7567
7568     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7569 }
7570
7571 /*
7572  *  [2] 3.2.1.7
7573  */
7574 static void
7575 bssmap_unblock_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7576 {
7577     guint32     curr_offset;
7578     guint32     consumed;
7579     guint       curr_len;
7580
7581     curr_offset = offset;
7582     curr_len = len;
7583
7584     is_uplink = IS_UPLINK_TRUE;
7585
7586     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
7587
7588     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7589 }
7590
7591 /*
7592  *  [2] 3.2.1.8
7593  */
7594 static void
7595 bssmap_ho_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7596 {
7597     guint32     curr_offset;
7598     guint32     consumed;
7599     guint       curr_len;
7600
7601     curr_offset = offset;
7602     curr_len = len;
7603
7604     is_uplink = IS_UPLINK_FALSE;
7605
7606     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CHAN_TYPE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHAN_TYPE, "");
7607
7608     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_ENC_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_ENC_INFO, "");
7609
7610     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CM_INFO_1].value, BSSAP_PDU_TYPE_BSSMAP, BE_CM_INFO_1, "");
7611
7612     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CM_INFO_2].value, BSSAP_PDU_TYPE_BSSMAP, BE_CM_INFO_2, "");
7613
7614     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, " (Serving)");
7615
7616     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_PRIO].value, BSSAP_PDU_TYPE_BSSMAP, BE_PRIO, "");
7617
7618     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
7619
7620     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_DOWN_DTX_FLAG].value, BSSAP_PDU_TYPE_BSSMAP, BE_DOWN_DTX_FLAG, "");
7621
7622     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, " (Target)");
7623
7624     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_INT_BAND].value, BSSAP_PDU_TYPE_BSSMAP, BE_INT_BAND, "");
7625
7626     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
7627
7628     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CM_INFO_3].value, BSSAP_PDU_TYPE_BSSMAP, BE_CM_INFO_3, "");
7629
7630     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CURR_CHAN_1].value, BSSAP_PDU_TYPE_BSSMAP, BE_CURR_CHAN_1, "");
7631
7632     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_SPEECH_VER].value, BSSAP_PDU_TYPE_BSSMAP, BE_SPEECH_VER, " (Used)");
7633
7634     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_GROUP_CALL_REF].value, BSSAP_PDU_TYPE_BSSMAP, BE_GROUP_CALL_REF, "");
7635
7636     ELEM_OPT_T(gsm_bssmap_elem_strings[BE_TALKER_FLAG].value, BSSAP_PDU_TYPE_BSSMAP, BE_TALKER_FLAG, "");
7637
7638     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CONF_EVO_IND].value, BSSAP_PDU_TYPE_BSSMAP, BE_CONF_EVO_IND, "");
7639
7640     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_ENC_ALG].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_ENC_ALG, " (Serving)");
7641
7642     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_OLD2NEW_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_OLD2NEW_INFO, "");
7643
7644     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_LSA_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_INFO, "");
7645
7646     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_LSA_ACC_CTRL].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_ACC_CTRL, "");
7647
7648     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7649 }
7650
7651 /*
7652  *  [2] 3.2.1.9
7653  */
7654 static void
7655 bssmap_ho_reqd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7656 {
7657     guint32     curr_offset;
7658     guint32     consumed;
7659     guint       curr_len;
7660
7661     curr_offset = offset;
7662     curr_len = len;
7663
7664     is_uplink = IS_UPLINK_TRUE;
7665
7666     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
7667
7668     ELEM_OPT_T(gsm_bssmap_elem_strings[BE_RESP_REQ].value, BSSAP_PDU_TYPE_BSSMAP, BE_RESP_REQ, "");
7669
7670     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID_LIST, " (Preferred)");
7671
7672     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CCT_POOL_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CCT_POOL_LIST, "");
7673
7674     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CURR_CHAN_1].value, BSSAP_PDU_TYPE_BSSMAP, BE_CURR_CHAN_1, "");
7675
7676     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_SPEECH_VER].value, BSSAP_PDU_TYPE_BSSMAP, BE_SPEECH_VER, " (Used)");
7677
7678     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_QUE_IND].value, BSSAP_PDU_TYPE_BSSMAP, BE_QUE_IND, "");
7679
7680     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_OLD2NEW_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_OLD2NEW_INFO, "");
7681
7682     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7683 }
7684
7685 /*
7686  *  [2] 3.2.1.10
7687  */
7688 static void
7689 bssmap_ho_req_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7690 {
7691     guint32     curr_offset;
7692     guint32     consumed;
7693     guint       curr_len;
7694
7695     curr_offset = offset;
7696     curr_len = len;
7697
7698     is_uplink = IS_UPLINK_TRUE;
7699
7700     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_L3_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_L3_INFO, "");
7701
7702     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_CHAN].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_CHAN, "");
7703
7704     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_ENC_ALG].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_ENC_ALG, "");
7705
7706     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CCT_POOL].value, BSSAP_PDU_TYPE_BSSMAP, BE_CCT_POOL, "");
7707
7708     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_SPEECH_VER].value, BSSAP_PDU_TYPE_BSSMAP, BE_SPEECH_VER, " (Chosen)");
7709
7710     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
7711
7712     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_LSA_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_ID, "");
7713
7714     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7715 }
7716
7717 /*
7718  *  [2] 3.2.1.11
7719  */
7720 static void
7721 bssmap_ho_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7722 {
7723     guint32     curr_offset;
7724     guint32     consumed;
7725     guint       curr_len;
7726
7727     curr_offset = offset;
7728     curr_len = len;
7729
7730     is_uplink = IS_UPLINK_FALSE;
7731
7732     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_L3_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_L3_INFO, "");
7733
7734     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
7735
7736     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7737 }
7738
7739 /*
7740  *  [2] 3.2.1.12
7741  */
7742 static void
7743 bssmap_ho_complete(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7744 {
7745     guint32     curr_offset;
7746     guint32     consumed;
7747     guint       curr_len;
7748
7749     curr_offset = offset;
7750     curr_len = len;
7751
7752     is_uplink = IS_UPLINK_TRUE;
7753
7754     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_RR_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_RR_CAUSE, "");
7755
7756     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7757 }
7758
7759 /*
7760  *  [2] 3.2.1.14
7761  */
7762 static void
7763 bssmap_ho_cand_enq(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7764 {
7765     guint32     curr_offset;
7766     guint32     consumed;
7767     guint       curr_len;
7768
7769     curr_offset = offset;
7770     curr_len = len;
7771
7772     is_uplink = IS_UPLINK_FALSE;
7773
7774     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_NUM_MS].value, BSSAP_PDU_TYPE_BSSMAP, BE_NUM_MS, "");
7775
7776     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID_LIST, "");
7777
7778     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
7779
7780     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7781 }
7782
7783 /*
7784  *  [2] 3.2.1.15
7785  */
7786 static void
7787 bssmap_ho_cand_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7788 {
7789     guint32     curr_offset;
7790     guint32     consumed;
7791     guint       curr_len;
7792
7793     curr_offset = offset;
7794     curr_len = len;
7795
7796     is_uplink = IS_UPLINK_TRUE;
7797
7798     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_NUM_MS].value, BSSAP_PDU_TYPE_BSSMAP, BE_NUM_MS, "");
7799
7800     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
7801
7802     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7803 }
7804
7805 /*
7806  *  [2] 3.2.1.16
7807  */
7808 static void
7809 bssmap_ho_failure(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7810 {
7811     guint32     curr_offset;
7812     guint32     consumed;
7813     guint       curr_len;
7814
7815     curr_offset = offset;
7816     curr_len = len;
7817
7818     is_uplink = IS_UPLINK_TRUE;
7819
7820     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
7821
7822     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_RR_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_RR_CAUSE, "");
7823
7824     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CCT_POOL].value, BSSAP_PDU_TYPE_BSSMAP, BE_CCT_POOL, "");
7825
7826     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CCT_POOL_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CCT_POOL_LIST, "");
7827
7828     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7829 }
7830
7831 /*
7832  *  [2] 3.2.1.19
7833  */
7834 static void
7835 bssmap_paging(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7836 {
7837     guint32     curr_offset;
7838     guint32     consumed;
7839     guint       curr_len;
7840
7841     curr_offset = offset;
7842     curr_len = len;
7843
7844     is_uplink = IS_UPLINK_FALSE;
7845
7846     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_IMSI].value, BSSAP_PDU_TYPE_BSSMAP, BE_IMSI, "");
7847
7848     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_TMSI].value, BSSAP_PDU_TYPE_BSSMAP, BE_TMSI, "");
7849
7850     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID_LIST, "");
7851
7852     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CHAN_NEEDED].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHAN_NEEDED, "");
7853
7854     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_EMLPP_PRIO].value, BSSAP_PDU_TYPE_BSSMAP, BE_EMLPP_PRIO, "");
7855
7856     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7857 }
7858
7859 /*
7860  *  [2] 3.2.1.20
7861  */
7862 static void
7863 bssmap_clear_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7864 {
7865     guint32     curr_offset;
7866     guint32     consumed;
7867     guint       curr_len;
7868
7869     curr_offset = offset;
7870     curr_len = len;
7871
7872     is_uplink = IS_UPLINK_TRUE;
7873
7874     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
7875
7876     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7877 }
7878
7879 /*
7880  *  [2] 3.2.1.21
7881  */
7882 static void
7883 bssmap_clear_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7884 {
7885     guint32     curr_offset;
7886     guint32     consumed;
7887     guint       curr_len;
7888
7889     curr_offset = offset;
7890     curr_len = len;
7891
7892     is_uplink = IS_UPLINK_FALSE;
7893
7894     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_L3_HEADER_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_L3_HEADER_INFO, "");
7895
7896     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
7897
7898     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7899 }
7900
7901 /*
7902  *  [2] 3.2.1.23
7903  */
7904 static void
7905 bssmap_reset(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7906 {
7907     guint32     curr_offset;
7908     guint32     consumed;
7909     guint       curr_len;
7910
7911     curr_offset = offset;
7912     curr_len = len;
7913
7914     is_uplink = IS_UPLINK_UNKNOWN;
7915
7916     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
7917
7918     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7919 }
7920
7921 /*
7922  *  [2] 3.2.1.25
7923  */
7924 static void
7925 bssmap_ho_performed(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7926 {
7927     guint32     curr_offset;
7928     guint32     consumed;
7929     guint       curr_len;
7930
7931     curr_offset = offset;
7932     curr_len = len;
7933
7934     is_uplink = IS_UPLINK_TRUE;
7935
7936     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
7937
7938     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
7939
7940     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_CHAN].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_CHAN, "");
7941
7942     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_ENC_ALG].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_ENC_ALG, "");
7943
7944     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_SPEECH_VER].value, BSSAP_PDU_TYPE_BSSMAP, BE_SPEECH_VER, " (Chosen)");
7945
7946     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_LSA_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_ID, "");
7947
7948     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7949 }
7950
7951 /*
7952  *  [2] 3.2.1.26
7953  */
7954 static void
7955 bssmap_overload(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7956 {
7957     guint32     curr_offset;
7958     guint32     consumed;
7959     guint       curr_len;
7960
7961     curr_offset = offset;
7962     curr_len = len;
7963
7964     is_uplink = IS_UPLINK_TRUE;
7965
7966     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
7967
7968     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
7969
7970     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7971 }
7972
7973 /*
7974  *  [2] 3.2.1.29
7975  */
7976 static void
7977 bssmap_cm_upd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7978 {
7979     guint32     curr_offset;
7980     guint32     consumed;
7981     guint       curr_len;
7982
7983     curr_offset = offset;
7984     curr_len = len;
7985
7986     is_uplink = IS_UPLINK_FALSE;
7987
7988     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CM_INFO_2].value, BSSAP_PDU_TYPE_BSSMAP, BE_CM_INFO_2, "");
7989
7990     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CM_INFO_3].value, BSSAP_PDU_TYPE_BSSMAP, BE_CM_INFO_3, "");
7991
7992     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7993 }
7994
7995 /*
7996  *  [2] 3.2.1.30
7997  */
7998 static void
7999 bssmap_ciph_mode_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8000 {
8001     guint32     curr_offset;
8002     guint32     consumed;
8003     guint       curr_len;
8004
8005     curr_offset = offset;
8006     curr_len = len;
8007
8008     is_uplink = IS_UPLINK_FALSE;
8009
8010     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_L3_HEADER_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_L3_HEADER_INFO, "");
8011
8012     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_ENC_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_ENC_INFO, "");
8013
8014     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CIPH_RESP_MODE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIPH_RESP_MODE, "");
8015
8016     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8017 }
8018
8019 /*
8020  *  [2] 3.2.1.31
8021  */
8022 static void
8023 bssmap_ciph_mode_complete(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8024 {
8025     guint32     curr_offset;
8026     guint32     consumed;
8027     guint       curr_len;
8028
8029     curr_offset = offset;
8030     curr_len = len;
8031
8032     is_uplink = IS_UPLINK_TRUE;
8033
8034     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_L3_MSG].value, BSSAP_PDU_TYPE_BSSMAP, BE_L3_MSG, "");
8035
8036     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_ENC_ALG].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_ENC_ALG, "");
8037
8038     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8039 }
8040
8041 /*
8042  * [2] 3.2.1.32
8043  */
8044 static void
8045 bssmap_cl3_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8046 {
8047     guint8      consumed;
8048     guint32     curr_offset;
8049     guint       curr_len;
8050
8051     curr_offset = offset;
8052     curr_len = len;
8053
8054     is_uplink = IS_UPLINK_TRUE;
8055
8056     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
8057
8058     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_L3_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_L3_INFO, "");
8059
8060     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_CHAN].value, BSSAP_PDU_TYPE_BSSMAP, BE_CHOSEN_CHAN, "");
8061
8062     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_LSA_ID_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_ID_LIST, "");
8063
8064     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_APDU].value, BSSAP_PDU_TYPE_BSSMAP, BE_APDU, "");
8065
8066     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8067 }
8068
8069 /*
8070  * [2] 3.2.1.34
8071  */
8072 static void
8073 bssmap_sapi_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8074 {
8075     guint8      consumed;
8076     guint32     curr_offset;
8077     guint       curr_len;
8078
8079     curr_offset = offset;
8080     curr_len = len;
8081
8082     is_uplink = IS_UPLINK_TRUE;
8083
8084     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_DLCI].value, BSSAP_PDU_TYPE_BSSMAP, BE_DLCI, "");
8085
8086     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
8087
8088     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8089 }
8090
8091 /*
8092  *  [2] 3.2.1.37
8093  */
8094 static void
8095 bssmap_ho_reqd_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8096 {
8097     guint32     curr_offset;
8098     guint32     consumed;
8099     guint       curr_len;
8100
8101     curr_offset = offset;
8102     curr_len = len;
8103
8104     is_uplink = IS_UPLINK_FALSE;
8105
8106     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
8107
8108     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8109 }
8110
8111 /*
8112  *  [2] 3.2.1.38
8113  */
8114 static void
8115 bssmap_reset_cct(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8116 {
8117     guint32     curr_offset;
8118     guint32     consumed;
8119     guint       curr_len;
8120
8121     curr_offset = offset;
8122     curr_len = len;
8123
8124     is_uplink = IS_UPLINK_TRUE;
8125
8126     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
8127
8128     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
8129
8130     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8131 }
8132
8133 /*
8134  *  [2] 3.2.1.39
8135  */
8136 static void
8137 bssmap_reset_cct_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8138 {
8139     guint32     curr_offset;
8140     guint32     consumed;
8141     guint       curr_len;
8142
8143     curr_offset = offset;
8144     curr_len = len;
8145
8146     is_uplink = IS_UPLINK_TRUE;
8147
8148     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
8149
8150     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8151 }
8152
8153 /*
8154  *  [2] 3.2.1.41
8155  */
8156 static void
8157 bssmap_cct_group_block(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8158 {
8159     guint32     curr_offset;
8160     guint32     consumed;
8161     guint       curr_len;
8162
8163     curr_offset = offset;
8164     curr_len = len;
8165
8166     is_uplink = IS_UPLINK_TRUE;
8167
8168     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
8169
8170     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
8171
8172     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC_LIST, "");
8173
8174     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8175 }
8176
8177 /*
8178  *  [2] 3.2.1.42
8179  */
8180 static void
8181 bssmap_cct_group_block_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8182 {
8183     guint32     curr_offset;
8184     guint32     consumed;
8185     guint       curr_len;
8186
8187     curr_offset = offset;
8188     curr_len = len;
8189
8190     is_uplink = IS_UPLINK_TRUE;
8191
8192     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
8193
8194     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC_LIST, "");
8195
8196     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8197 }
8198
8199 /*
8200  *  [2] 3.2.1.43
8201  */
8202 static void
8203 bssmap_cct_group_unblock(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8204 {
8205     guint32     curr_offset;
8206     guint32     consumed;
8207     guint       curr_len;
8208
8209     curr_offset = offset;
8210     curr_len = len;
8211
8212     is_uplink = IS_UPLINK_TRUE;
8213
8214     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
8215
8216     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC_LIST, "");
8217
8218     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8219 }
8220
8221 /*
8222  *  [2] 3.2.1.44
8223  */
8224 static void
8225 bssmap_cct_group_unblock_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8226 {
8227     guint32     curr_offset;
8228     guint32     consumed;
8229     guint       curr_len;
8230
8231     curr_offset = offset;
8232     curr_len = len;
8233
8234     is_uplink = IS_UPLINK_TRUE;
8235
8236     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
8237
8238     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC_LIST, "");
8239
8240     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8241 }
8242
8243 /*
8244  *  [2] 3.2.1.45
8245  */
8246 static void
8247 bssmap_confusion(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8248 {
8249     guint32     curr_offset;
8250     guint32     consumed;
8251     guint       curr_len;
8252
8253     curr_offset = offset;
8254     curr_len = len;
8255
8256     is_uplink = IS_UPLINK_TRUE;
8257
8258     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
8259
8260     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_DIAG].value, BSSAP_PDU_TYPE_BSSMAP, BE_DIAG, "");
8261
8262     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8263 }
8264
8265 /*
8266  *  [2] 3.2.1.47
8267  */
8268 static void
8269 bssmap_unequipped_cct(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8270 {
8271     guint32     curr_offset;
8272     guint32     consumed;
8273     guint       curr_len;
8274
8275     curr_offset = offset;
8276     curr_len = len;
8277
8278     is_uplink = IS_UPLINK_TRUE;
8279
8280     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
8281
8282     ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CIC_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC_LIST, "");
8283
8284     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8285 }
8286
8287 /*
8288  *  [2] 3.2.1.48
8289  */
8290 static void
8291 bssmap_ciph_mode_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8292 {
8293     guint32     curr_offset;
8294     guint32     consumed;
8295     guint       curr_len;
8296
8297     curr_offset = offset;
8298     curr_len = len;
8299
8300     is_uplink = IS_UPLINK_TRUE;
8301
8302     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
8303
8304     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8305 }
8306
8307 /*
8308  *  [2] 3.2.1.49
8309  */
8310 static void
8311 bssmap_load_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8312 {
8313     guint32     curr_offset;
8314     guint32     consumed;
8315     guint       curr_len;
8316
8317     curr_offset = offset;
8318     curr_len = len;
8319
8320     is_uplink = IS_UPLINK_TRUE;
8321
8322     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_TIME_IND].value, BSSAP_PDU_TYPE_BSSMAP, BE_TIME_IND, "");
8323
8324     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID, "");
8325
8326     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID_LIST].value, BSSAP_PDU_TYPE_BSSMAP, BE_CELL_ID_LIST, " (Target)");
8327
8328     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_RES_SIT].value, BSSAP_PDU_TYPE_BSSMAP, BE_RES_SIT, "");
8329
8330     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
8331
8332     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8333 }
8334
8335 /*
8336  *  [2] 3.2.1.66
8337  */
8338 static void
8339 bssmap_change_cct(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8340 {
8341     guint32     curr_offset;
8342     guint32     consumed;
8343     guint       curr_len;
8344
8345     curr_offset = offset;
8346     curr_len = len;
8347
8348     is_uplink = IS_UPLINK_FALSE;
8349
8350     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CAUSE].value, BSSAP_PDU_TYPE_BSSMAP, BE_CAUSE, "");
8351
8352     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8353 }
8354
8355 /*
8356  *  [2] 3.2.1.67
8357  */
8358 static void
8359 bssmap_change_cct_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8360 {
8361     guint32     curr_offset;
8362     guint32     consumed;
8363     guint       curr_len;
8364
8365     curr_offset = offset;
8366     curr_len = len;
8367
8368     is_uplink = IS_UPLINK_TRUE;
8369
8370     ELEM_MAND_TV(gsm_bssmap_elem_strings[BE_CIC].value, BSSAP_PDU_TYPE_BSSMAP, BE_CIC, "");
8371
8372     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8373 }
8374
8375 /*
8376  *  [2] 3.2.1.69
8377  */
8378 static void
8379 bssmap_lsa_info(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_LSA_INFO].value, BSSAP_PDU_TYPE_BSSMAP, BE_LSA_INFO, "");
8391
8392     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8393 }
8394
8395 /*
8396  *  [2] 3.2.1.70
8397  */
8398 static void
8399 bssmap_conn_oriented(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_FALSE;
8409
8410     ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_APDU].value, BSSAP_PDU_TYPE_BSSMAP, BE_APDU, "");
8411
8412     ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_SEG].value, BSSAP_PDU_TYPE_BSSMAP, BE_SEG, "");
8413
8414     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8415 }
8416
8417 #define NUM_GSM_BSSMAP_MSG (sizeof(gsm_a_bssmap_msg_strings)/sizeof(value_string))
8418 static gint ett_gsm_bssmap_msg[NUM_GSM_BSSMAP_MSG];
8419 static void (*bssmap_msg_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
8420     bssmap_ass_req,     /* Assignment Request */
8421     bssmap_ass_complete,        /* Assignment Complete */
8422     bssmap_ass_failure, /* Assignment Failure */
8423     bssmap_ho_req,      /* Handover Request */
8424     bssmap_ho_reqd,     /* Handover Required */
8425     bssmap_ho_req_ack,  /* Handover Request Acknowledge */
8426     bssmap_ho_cmd,      /* Handover Command */
8427     bssmap_ho_complete, /* Handover Complete */
8428     NULL /* no associated data */,      /* Handover Succeeded */
8429     bssmap_ho_failure,  /* Handover Failure */
8430     bssmap_ho_performed,        /* Handover Performed */
8431     bssmap_ho_cand_enq, /* Handover Candidate Enquire */
8432     bssmap_ho_cand_resp,        /* Handover Candidate Response */
8433     bssmap_ho_reqd_rej, /* Handover Required Reject */
8434     NULL /* no associated data */,      /* Handover Detect */
8435     bssmap_clear_cmd,   /* Clear Command */
8436     NULL /* no associated data */,      /* Clear Complete */
8437     bssmap_clear_req,   /* Clear Request */
8438     NULL,       /* Reserved */
8439     NULL,       /* Reserved */
8440     bssmap_sapi_rej,    /* SAPI 'n' Reject */
8441     bssmap_confusion,   /* Confusion */
8442     NULL,       /* Suspend */
8443     NULL,       /* Resume */
8444     bssmap_conn_oriented,       /* Connection Oriented Information */
8445     NULL,       /* Perform Location Request */
8446     bssmap_lsa_info,    /* LSA Information */
8447     NULL,       /* Perform Location Response */
8448     NULL,       /* Perform Location Abort */
8449     bssmap_reset,       /* Reset */
8450     NULL /* no associated data */,      /* Reset Acknowledge */
8451     bssmap_overload,    /* Overload */
8452     NULL,       /* Reserved */
8453     bssmap_reset_cct,   /* Reset Circuit */
8454     bssmap_reset_cct_ack,       /* Reset Circuit Acknowledge */
8455     NULL,       /* MSC Invoke Trace */
8456     NULL,       /* BSS Invoke Trace */
8457     NULL,       /* Connectionless Information */
8458     bssmap_block,       /* Block */
8459     bssmap_block_ack,   /* Blocking Acknowledge */
8460     bssmap_unblock,     /* Unblock */
8461     bssmap_unblock_ack, /* Unblocking Acknowledge */
8462     bssmap_cct_group_block,     /* Circuit Group Block */
8463     bssmap_cct_group_block_ack, /* Circuit Group Blocking Acknowledge */
8464     bssmap_cct_group_unblock,   /* Circuit Group Unblock */
8465     bssmap_cct_group_unblock_ack,       /* Circuit Group Unblocking Acknowledge */
8466     bssmap_unequipped_cct,      /* Unequipped Circuit */
8467     bssmap_change_cct,  /* Change Circuit */
8468     bssmap_change_cct_ack,      /* Change Circuit Acknowledge */
8469     NULL,       /* Resource Request */
8470     NULL,       /* Resource Indication */
8471     bssmap_paging,      /* Paging */
8472     bssmap_ciph_mode_cmd,       /* Cipher Mode Command */
8473     bssmap_cm_upd,      /* Classmark Update */
8474     bssmap_ciph_mode_complete,  /* Cipher Mode Complete */
8475     NULL /* no associated data */,      /* Queuing Indication */
8476     bssmap_cl3_info,    /* Complete Layer 3 Information */
8477     NULL /* no associated data */,      /* Classmark Request */
8478     bssmap_ciph_mode_rej,       /* Cipher Mode Reject */
8479     bssmap_load_ind,    /* Load Indication */
8480     NULL,       /* VGCS/VBS Setup */
8481     NULL,       /* VGCS/VBS Setup Ack */
8482     NULL,       /* VGCS/VBS Setup Refuse */
8483     NULL,       /* VGCS/VBS Assignment Request */
8484     NULL,       /* VGCS/VBS Assignment Result */
8485     NULL,       /* VGCS/VBS Assignment Failure */
8486     NULL,       /* VGCS/VBS Queuing Indication */
8487     NULL,       /* Uplink Request */
8488     NULL,       /* Uplink Request Acknowledge */
8489     NULL,       /* Uplink Request Confirmation */
8490     NULL,       /* Uplink Release Indication */
8491     NULL,       /* Uplink Reject Command */
8492     NULL,       /* Uplink Release Command */
8493     NULL,       /* Uplink Seized Command */
8494     NULL,       /* NONE */
8495 };
8496
8497 /*
8498  * [4] 9.2.2
8499  */
8500 static void
8501 dtap_mm_auth_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8502 {
8503     guint32     curr_offset;
8504     guint32     consumed;
8505     guint       curr_len;
8506     guint8      oct;
8507     proto_tree  *subtree;
8508     proto_item  *item;
8509
8510     curr_offset = offset;
8511     curr_len = len;
8512
8513     is_uplink = IS_UPLINK_FALSE;
8514
8515     /*
8516      * special dissection for Cipher Key Sequence Number
8517      */
8518     oct = tvb_get_guint8(tvb, curr_offset);
8519
8520     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
8521     proto_tree_add_text(tree,
8522         tvb, curr_offset, 1,
8523         "%s :  Spare",
8524         a_bigbuf);
8525
8526     item =
8527         proto_tree_add_text(tree,
8528             tvb, curr_offset, 1,
8529             gsm_dtap_elem_strings[DE_CIPH_KEY_SEQ_NUM].strptr);
8530
8531     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CIPH_KEY_SEQ_NUM]);
8532
8533     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
8534     proto_tree_add_text(subtree,
8535         tvb, curr_offset, 1,
8536         "%s :  Spare",
8537         a_bigbuf);
8538
8539     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
8540
8541     switch (oct & 0x07)
8542     {
8543     case 0x07:
8544         proto_tree_add_text(subtree,
8545             tvb, curr_offset, 1,
8546             "%s :  Ciphering Key Sequence Number: No key is available",
8547             a_bigbuf);
8548         break;
8549
8550     default:
8551         proto_tree_add_text(subtree,
8552             tvb, curr_offset, 1,
8553             "%s :  Ciphering Key Sequence Number: %u",
8554             a_bigbuf,
8555             oct & 0x07);
8556         break;
8557     }
8558
8559     curr_offset++;
8560     curr_len--;
8561
8562     if (curr_len <= 0) return;
8563
8564     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_AUTH_PARAM_RAND);
8565
8566     ELEM_OPT_TLV(0x20, BSSAP_PDU_TYPE_DTAP, DE_AUTH_PARAM_AUTN, "");
8567
8568     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8569 }
8570
8571 /*
8572  * [4] 9.2.3
8573  */
8574 static void
8575 dtap_mm_auth_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8576 {
8577     guint32     curr_offset;
8578     guint32     consumed;
8579     guint       curr_len;
8580
8581     curr_offset = offset;
8582     curr_len = len;
8583
8584     is_uplink = IS_UPLINK_TRUE;
8585
8586     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_AUTH_RESP_PARAM);
8587
8588     ELEM_OPT_TLV(0x21, BSSAP_PDU_TYPE_DTAP, DE_AUTH_RESP_PARAM_EXT, "");
8589
8590     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8591 }
8592
8593 /*
8594  * [4] 9.2.3a
8595  */
8596 static void
8597 dtap_mm_auth_fail(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8598 {
8599     guint32     curr_offset;
8600     guint32     consumed;
8601     guint       curr_len;
8602
8603     curr_offset = offset;
8604     curr_len = len;
8605
8606     is_uplink = IS_UPLINK_TRUE;
8607
8608     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_REJ_CAUSE);
8609
8610     ELEM_OPT_TLV(0x22, BSSAP_PDU_TYPE_DTAP, DE_AUTH_FAIL_PARAM, "");
8611
8612     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8613 }
8614
8615 /*
8616  * [3] 9.2.4
8617  */
8618 static void
8619 dtap_mm_cm_reestab_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8620 {
8621     guint32     curr_offset;
8622     guint32     consumed;
8623     guint       curr_len;
8624     guint8      oct;
8625     proto_tree  *subtree;
8626     proto_item  *item;
8627
8628     curr_offset = offset;
8629     curr_len = len;
8630
8631     is_uplink = IS_UPLINK_TRUE;
8632
8633     /*
8634      * special dissection for Cipher Key Sequence Number
8635      */
8636     oct = tvb_get_guint8(tvb, curr_offset);
8637
8638     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
8639     proto_tree_add_text(tree,
8640         tvb, curr_offset, 1,
8641         "%s :  Spare",
8642         a_bigbuf);
8643
8644     item =
8645         proto_tree_add_text(tree,
8646             tvb, curr_offset, 1,
8647             gsm_dtap_elem_strings[DE_CIPH_KEY_SEQ_NUM].strptr);
8648
8649     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CIPH_KEY_SEQ_NUM]);
8650
8651     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
8652     proto_tree_add_text(subtree,
8653         tvb, curr_offset, 1,
8654         "%s :  Spare",
8655         a_bigbuf);
8656
8657     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
8658
8659     switch (oct & 0x07)
8660     {
8661     case 0x07:
8662         proto_tree_add_text(subtree,
8663             tvb, curr_offset, 1,
8664             "%s :  Ciphering Key Sequence Number: No key is available",
8665             a_bigbuf);
8666         break;
8667
8668     default:
8669         proto_tree_add_text(subtree,
8670             tvb, curr_offset, 1,
8671             "%s :  Ciphering Key Sequence Number: %u",
8672             a_bigbuf,
8673             oct & 0x07);
8674         break;
8675     }
8676
8677     curr_offset++;
8678     curr_len--;
8679
8680     if (curr_len <= 0) return;
8681
8682     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MS_CM_2, "");
8683
8684     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID, "");
8685
8686     ELEM_OPT_TV(0x13, BSSAP_PDU_TYPE_DTAP, DE_LAI, "");
8687
8688     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8689 }
8690
8691 /*
8692  * [3] 9.2.5a
8693  */
8694 static void
8695 dtap_mm_cm_srvc_prompt(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8696 {
8697     guint32     curr_offset;
8698     guint32     consumed;
8699     guint       curr_len;
8700
8701     curr_offset = offset;
8702     curr_len = len;
8703
8704     is_uplink = IS_UPLINK_FALSE;
8705
8706     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_PD_SAPI);
8707
8708     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8709 }
8710
8711 /*
8712  * [4] 9.2.6
8713  */
8714 static void
8715 dtap_mm_cm_srvc_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8716 {
8717     guint32     curr_offset;
8718     guint32     consumed;
8719     guint       curr_len;
8720
8721     curr_offset = offset;
8722     curr_len = len;
8723
8724     is_uplink = IS_UPLINK_FALSE;
8725
8726     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_REJ_CAUSE);
8727
8728     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8729 }
8730
8731 /*
8732  * [4] 9.2.8
8733  */
8734 static void
8735 dtap_mm_abort(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_REJ_CAUSE);
8747
8748     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8749 }
8750
8751 /*
8752  * [3] 9.2.9
8753  */
8754 static void
8755 dtap_mm_cm_srvc_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8756 {
8757     guint32     curr_offset;
8758     guint32     consumed;
8759     guint       curr_len;
8760     guint8      oct;
8761     proto_tree  *subtree;
8762     proto_item  *item;
8763     gchar       *str;
8764
8765     curr_offset = offset;
8766     curr_len = len;
8767
8768     is_uplink = IS_UPLINK_TRUE;
8769
8770     /*
8771      * special dissection for CM Service Type
8772      */
8773     oct = tvb_get_guint8(tvb, curr_offset);
8774
8775     item =
8776         proto_tree_add_text(tree,
8777             tvb, curr_offset, 1,
8778             gsm_dtap_elem_strings[DE_CIPH_KEY_SEQ_NUM].strptr);
8779
8780     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CIPH_KEY_SEQ_NUM]);
8781
8782     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
8783     proto_tree_add_text(subtree,
8784         tvb, curr_offset, 1,
8785         "%s :  Spare",
8786         a_bigbuf);
8787
8788     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
8789
8790     switch ((oct & 0x70) >> 4)
8791     {
8792     case 0x07:
8793         proto_tree_add_text(subtree,
8794             tvb, curr_offset, 1,
8795             "%s :  Ciphering Key Sequence Number: No key is available",
8796             a_bigbuf);
8797         break;
8798
8799     default:
8800         proto_tree_add_text(subtree,
8801             tvb, curr_offset, 1,
8802             "%s :  Ciphering Key Sequence Number: %u",
8803             a_bigbuf,
8804             (oct & 0x70) >> 4);
8805         break;
8806     }
8807
8808     item =
8809         proto_tree_add_text(tree,
8810             tvb, curr_offset, 1,
8811             gsm_dtap_elem_strings[DE_CM_SRVC_TYPE].strptr);
8812
8813     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CM_SRVC_TYPE]);
8814
8815     switch (oct & 0x0f)
8816     {
8817     case 0x01: str = "Mobile originating call establishment or packet mode connection establishment"; break;
8818     case 0x02: str = "Emergency call establishment"; break;
8819     case 0x04: str = "Short message service"; break;
8820     case 0x08: str = "Supplementary service activation"; break;
8821     case 0x09: str = "Voice group call establishment"; break;
8822     case 0x0a: str = "Voice broadcast call establishment"; break;
8823     case 0x0b: str = "Location Services"; break;
8824     default:
8825         str = "Reserved";
8826         break;
8827     }
8828
8829     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
8830     proto_tree_add_text(subtree,
8831         tvb, curr_offset, 1,
8832         "%s :  Service Type: (%u) %s",
8833         a_bigbuf,
8834         oct & 0x0f,
8835         str);
8836
8837     curr_offset++;
8838     curr_len--;
8839
8840     if (curr_len <= 0) return;
8841
8842     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MS_CM_2, "");
8843
8844     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID, "");
8845
8846     ELEM_OPT_TV_SHORT(0x80, BSSAP_PDU_TYPE_DTAP, DE_PRIO, "");
8847
8848     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8849 }
8850
8851 /*
8852  * [3] 9.2.10
8853  */
8854 static void
8855 dtap_mm_id_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8856 {
8857     guint8      oct;
8858     guint32     curr_offset;
8859     guint       curr_len;
8860     proto_tree  *subtree;
8861     proto_item  *item;
8862     gchar       *str;
8863
8864     curr_offset = offset;
8865     curr_len = len;
8866
8867     is_uplink = IS_UPLINK_FALSE;
8868
8869     /*
8870      * special dissection for Identity Type
8871      */
8872     oct = tvb_get_guint8(tvb, curr_offset);
8873
8874     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
8875     proto_tree_add_text(tree,
8876         tvb, curr_offset, 1,
8877         "%s :  Spare",
8878         a_bigbuf);
8879
8880     item =
8881         proto_tree_add_text(tree,
8882             tvb, curr_offset, 1,
8883             gsm_dtap_elem_strings[DE_ID_TYPE].strptr);
8884
8885     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_ID_TYPE]);
8886
8887     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
8888     proto_tree_add_text(subtree,
8889         tvb, curr_offset, 1,
8890         "%s :  Spare",
8891         a_bigbuf);
8892
8893     switch (oct & 0x07)
8894     {
8895     case 1: str = "IMSI"; break;
8896     case 2: str = "IMEI"; break;
8897     case 3: str = "IMEISV"; break;
8898     case 4: str = "TMSI"; break;
8899     default:
8900         str = "Reserved";
8901         break;
8902     }
8903
8904     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
8905     proto_tree_add_text(subtree,
8906         tvb, curr_offset, 1,
8907         "%s :  Type of identity: %s",
8908         a_bigbuf,
8909         str);
8910
8911     curr_offset++;
8912     curr_len--;
8913
8914     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8915 }
8916
8917 /*
8918  * [3] 9.2.11
8919  */
8920 static void
8921 dtap_mm_id_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8922 {
8923     guint32     curr_offset;
8924     guint32     consumed;
8925     guint       curr_len;
8926
8927     curr_offset = offset;
8928     curr_len = len;
8929
8930     is_uplink = IS_UPLINK_TRUE;
8931
8932     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID, "");
8933
8934     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8935 }
8936
8937 /*
8938  * [3] 9.2.12
8939  */
8940 static void
8941 dtap_mm_imsi_det_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8942 {
8943     guint32     curr_offset;
8944     guint32     consumed;
8945     guint       curr_len;
8946
8947     curr_offset = offset;
8948     curr_len = len;
8949
8950     is_uplink = IS_UPLINK_TRUE;
8951
8952     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_MS_CM_1);
8953
8954     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID, "");
8955
8956     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8957 }
8958
8959 /*
8960  * [3] 9.2.13
8961  */
8962 static void
8963 dtap_mm_loc_upd_acc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8964 {
8965     guint32     curr_offset;
8966     guint32     consumed;
8967     guint       curr_len;
8968
8969     curr_offset = offset;
8970     curr_len = len;
8971
8972     is_uplink = IS_UPLINK_FALSE;
8973
8974     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_LAI);
8975
8976     ELEM_OPT_TLV(0x17, BSSAP_PDU_TYPE_DTAP, DE_MID, "");
8977
8978     ELEM_OPT_T(0xa1, BSSAP_PDU_TYPE_DTAP, DE_FOP, "");
8979
8980     ELEM_OPT_T(0xa2, BSSAP_PDU_TYPE_DTAP, DE_CTS_PERM, "");
8981
8982     ELEM_OPT_TLV(0x4a, BSSAP_PDU_TYPE_DTAP, DE_PLMN_LIST, " Equivalent");
8983
8984     EXTRANEOUS_DATA_CHECK(curr_len, 0);
8985 }
8986
8987 /*
8988  * [3] 9.2.14
8989  */
8990 static void
8991 dtap_mm_loc_upd_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
8992 {
8993     guint32     curr_offset;
8994     guint32     consumed;
8995     guint       curr_len;
8996
8997     curr_offset = offset;
8998     curr_len = len;
8999
9000     is_uplink = IS_UPLINK_FALSE;
9001
9002     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_REJ_CAUSE);
9003
9004     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9005 }
9006
9007 /*
9008  * [3] 9.2.15
9009  */
9010 static void
9011 dtap_mm_loc_upd_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9012 {
9013     guint32     curr_offset;
9014     guint32     consumed;
9015     guint       curr_len;
9016     guint8      oct;
9017     proto_tree  *subtree;
9018     proto_item  *item;
9019     gchar       *str;
9020
9021     curr_offset = offset;
9022     curr_len = len;
9023
9024     is_uplink = IS_UPLINK_TRUE;
9025
9026     /*
9027      * special dissection for Location Updating Type
9028      */
9029     oct = tvb_get_guint8(tvb, curr_offset);
9030
9031     item =
9032         proto_tree_add_text(tree,
9033             tvb, curr_offset, 1,
9034             gsm_dtap_elem_strings[DE_CIPH_KEY_SEQ_NUM].strptr);
9035
9036     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CIPH_KEY_SEQ_NUM]);
9037
9038     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
9039     proto_tree_add_text(subtree,
9040         tvb, curr_offset, 1,
9041         "%s :  Spare",
9042         a_bigbuf);
9043
9044     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
9045
9046     switch ((oct & 0x70) >> 4)
9047     {
9048     case 0x07:
9049         proto_tree_add_text(subtree,
9050             tvb, curr_offset, 1,
9051             "%s :  Ciphering Key Sequence Number: No key is available",
9052             a_bigbuf);
9053         break;
9054
9055     default:
9056         proto_tree_add_text(subtree,
9057             tvb, curr_offset, 1,
9058             "%s :  Ciphering Key Sequence Number: %u",
9059             a_bigbuf,
9060             (oct & 0x70) >> 4);
9061         break;
9062     }
9063
9064     item =
9065         proto_tree_add_text(tree,
9066             tvb, curr_offset, 1,
9067             gsm_dtap_elem_strings[DE_LOC_UPD_TYPE].strptr);
9068
9069     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_LOC_UPD_TYPE]);
9070
9071     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
9072     proto_tree_add_text(subtree,
9073         tvb, curr_offset, 1,
9074         "%s :  Follow-On Request (FOR): %s",
9075         a_bigbuf,
9076         (oct & 0x08) ? "Follow-on request pending" : "No follow-on request pending");
9077
9078     other_decode_bitfield_value(a_bigbuf, oct, 0x04, 8);
9079     proto_tree_add_text(subtree,
9080         tvb, curr_offset, 1,
9081         "%s :  Spare",
9082         a_bigbuf);
9083
9084     switch (oct & 0x03)
9085     {
9086     case 0: str = "Normal"; break;
9087     case 1: str = "Periodic"; break;
9088     case 2: str = "IMSI attach"; break;
9089     default:
9090         str = "Reserved";
9091         break;
9092     }
9093
9094     other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
9095     proto_tree_add_text(subtree,
9096         tvb, curr_offset, 1,
9097         "%s :  Updating Type: %s",
9098         a_bigbuf,
9099         str);
9100
9101     proto_item_append_text(item, " - %s", str);
9102
9103     curr_offset++;
9104     curr_len--;
9105
9106     if (curr_len <= 0) return;
9107
9108     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_LAI);
9109
9110     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_MS_CM_1);
9111
9112     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID, "");
9113
9114     ELEM_OPT_TLV(0x33, BSSAP_PDU_TYPE_DTAP, DE_MS_CM_2, "");
9115
9116     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9117 }
9118
9119 /*
9120  * [4] 9.1.15a
9121  */
9122 static void
9123 dtap_mm_mm_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9124 {
9125     guint32     curr_offset;
9126     guint32     consumed;
9127     guint       curr_len;
9128
9129     curr_offset = offset;
9130     curr_len = len;
9131
9132     is_uplink = IS_UPLINK_TRUE;
9133
9134     ELEM_OPT_TLV(0x43, BSSAP_PDU_TYPE_DTAP, DE_NETWORK_NAME, " - Full Name");
9135
9136     ELEM_OPT_TLV(0x45, BSSAP_PDU_TYPE_DTAP, DE_NETWORK_NAME, " - Short Name");
9137
9138     ELEM_OPT_TV(0x46, BSSAP_PDU_TYPE_DTAP, DE_TIME_ZONE, " - Local");
9139
9140     ELEM_OPT_TV(0x47, BSSAP_PDU_TYPE_DTAP, DE_TIME_ZONE_TIME, " - Universal Time and Local Time Zone");
9141
9142     ELEM_OPT_TLV(0x48, BSSAP_PDU_TYPE_DTAP, DE_LSA_ID, "");
9143
9144     ELEM_OPT_TLV(0x49, BSSAP_PDU_TYPE_DTAP, DE_DAY_SAVING_TIME, "");
9145
9146     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9147 }
9148
9149 /*
9150  * [4] 9.1.16
9151  */
9152 static void
9153 dtap_mm_mm_status(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9154 {
9155     guint32     curr_offset;
9156     guint32     consumed;
9157     guint       curr_len;
9158
9159     curr_offset = offset;
9160     curr_len = len;
9161
9162     is_uplink = IS_UPLINK_TRUE;
9163
9164     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_REJ_CAUSE);
9165
9166     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9167 }
9168
9169 /*
9170  * [3] 9.2.17
9171  */
9172 static void
9173 dtap_mm_tmsi_realloc_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9174 {
9175     guint32     curr_offset;
9176     guint32     consumed;
9177     guint       curr_len;
9178
9179     curr_offset = offset;
9180     curr_len = len;
9181
9182     is_uplink = IS_UPLINK_FALSE;
9183
9184     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_LAI);
9185
9186     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID, "");
9187
9188     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9189 }
9190
9191 /*
9192  * [4] 9.1.25
9193  */
9194 static void
9195 dtap_rr_paging_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9196 {
9197     guint32     curr_offset;
9198     guint32     consumed;
9199     guint       curr_len;
9200     guint8      oct;
9201     proto_tree  *subtree;
9202     proto_item  *item;
9203
9204     curr_offset = offset;
9205     curr_len = len;
9206
9207     is_uplink = IS_UPLINK_TRUE;
9208
9209     /*
9210      * special dissection for Cipher Key Sequence Number
9211      */
9212     oct = tvb_get_guint8(tvb, curr_offset);
9213
9214     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
9215     proto_tree_add_text(tree,
9216         tvb, curr_offset, 1,
9217         "%s :  Spare",
9218         a_bigbuf);
9219
9220     item =
9221         proto_tree_add_text(tree,
9222             tvb, curr_offset, 1,
9223             gsm_dtap_elem_strings[DE_CIPH_KEY_SEQ_NUM].strptr);
9224
9225     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CIPH_KEY_SEQ_NUM]);
9226
9227     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
9228     proto_tree_add_text(subtree,
9229         tvb, curr_offset, 1,
9230         "%s :  Spare",
9231         a_bigbuf);
9232
9233     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
9234
9235     switch (oct & 0x07)
9236     {
9237     case 0x07:
9238         proto_tree_add_text(subtree,
9239             tvb, curr_offset, 1,
9240             "%s :  Ciphering Key Sequence Number: No key is available",
9241             a_bigbuf);
9242         break;
9243
9244     default:
9245         proto_tree_add_text(subtree,
9246             tvb, curr_offset, 1,
9247             "%s :  Ciphering Key Sequence Number: %u",
9248             a_bigbuf,
9249             oct & 0x07);
9250         break;
9251     }
9252
9253     curr_offset++;
9254     curr_len--;
9255
9256     if (curr_len <= 0) return;
9257
9258     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MS_CM_2, "");
9259
9260     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_MID, "");
9261
9262     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9263 }
9264
9265 /*
9266  * [4] 9.1.29
9267  */
9268 static void
9269 dtap_rr_rr_status(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9270 {
9271     guint32     curr_offset;
9272     guint32     consumed;
9273     guint       curr_len;
9274
9275     curr_offset = offset;
9276     curr_len = len;
9277
9278     is_uplink = IS_UPLINK_TRUE;
9279
9280     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RR_CAUSE);
9281
9282     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9283 }
9284
9285 /*
9286  * [4] 9.3.1
9287  */
9288 static void
9289 dtap_cc_alerting(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9290 {
9291     guint32     curr_offset;
9292     guint32     consumed;
9293     guint       curr_len;
9294
9295     curr_offset = offset;
9296     curr_len = len;
9297
9298     is_uplink = IS_UPLINK_TRUE;
9299
9300     ELEM_OPT_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
9301
9302     ELEM_OPT_TLV(0x1e, BSSAP_PDU_TYPE_DTAP, DE_PROG_IND, "");
9303
9304     ELEM_OPT_TLV(0x7e, BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
9305
9306     /* uplink only */
9307
9308     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
9309
9310     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9311 }
9312
9313 /*
9314  * [4] 9.3.2
9315  */
9316 static void
9317 dtap_cc_call_conf(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9318 {
9319     guint32     curr_offset;
9320     guint32     consumed;
9321     guint       curr_len;
9322
9323     curr_offset = offset;
9324     curr_len = len;
9325
9326     is_uplink = IS_UPLINK_TRUE;
9327
9328     ELEM_OPT_TV_SHORT(0xd0, BSSAP_PDU_TYPE_DTAP, DE_REPEAT_IND, " BC repeat indicator");
9329
9330     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 1");
9331
9332     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 2");
9333
9334     ELEM_OPT_TLV(0x08, BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
9335
9336     ELEM_OPT_TLV(0x15, BSSAP_PDU_TYPE_DTAP, DE_CC_CAP, "");
9337
9338     ELEM_OPT_TLV(0x2d, BSSAP_PDU_TYPE_DTAP, DE_SI, "");
9339
9340     ELEM_OPT_TLV(0x40, BSSAP_PDU_TYPE_DTAP, DE_SUP_CODEC_LIST, "");
9341
9342     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9343 }
9344
9345 /*
9346  * [4] 9.3.3
9347  */
9348 static void
9349 dtap_cc_call_proceed(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9350 {
9351     guint32     curr_offset;
9352     guint32     consumed;
9353     guint       curr_len;
9354
9355     curr_offset = offset;
9356     curr_len = len;
9357
9358     is_uplink = IS_UPLINK_FALSE;
9359
9360     ELEM_OPT_TV_SHORT(0xd0, BSSAP_PDU_TYPE_DTAP, DE_REPEAT_IND, " BC repeat indicator");
9361
9362     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 1");
9363
9364     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 2");
9365
9366     ELEM_OPT_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
9367
9368     ELEM_OPT_TLV(0x1e, BSSAP_PDU_TYPE_DTAP, DE_PROG_IND, "");
9369
9370     ELEM_OPT_TV_SHORT(0x80, BSSAP_PDU_TYPE_DTAP, DE_PRIO, "");
9371
9372     ELEM_OPT_TLV(0x2f, BSSAP_PDU_TYPE_DTAP, DE_NET_CC_CAP, "");
9373
9374     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9375 }
9376
9377 /*
9378  * [4] 9.3.4
9379  */
9380 static void
9381 dtap_cc_congestion_control(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9382 {
9383     guint32     curr_offset;
9384     guint32     consumed;
9385     guint       curr_len;
9386     guint8      oct;
9387     proto_tree  *subtree;
9388     proto_item  *item;
9389     gchar       *str;
9390
9391     curr_offset = offset;
9392     curr_len = len;
9393
9394     is_uplink = IS_UPLINK_FALSE;
9395
9396     /*
9397      * special dissection for Congestion Level
9398      */
9399     oct = tvb_get_guint8(tvb, curr_offset);
9400
9401     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
9402     proto_tree_add_text(tree,
9403         tvb, curr_offset, 1,
9404         "%s :  Spare",
9405         a_bigbuf);
9406
9407     item =
9408         proto_tree_add_text(tree,
9409             tvb, curr_offset, 1,
9410             gsm_dtap_elem_strings[DE_CONGESTION].strptr);
9411
9412     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_CONGESTION]);
9413
9414     switch (oct & 0x0f)
9415     {
9416     case 0: str = "Receiver ready"; break;
9417     case 15: str = "Receiver not ready"; break;
9418     default:
9419         str = "Reserved";
9420         break;
9421     }
9422
9423     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
9424     proto_tree_add_text(subtree,
9425         tvb, curr_offset, 1,
9426         "%s :  Congestion level: %s",
9427         a_bigbuf,
9428         str);
9429
9430     curr_offset++;
9431     curr_len--;
9432
9433     if (curr_len <= 0) return;
9434
9435     ELEM_OPT_TLV(0x08, BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
9436
9437     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9438 }
9439
9440 /*
9441  * [4] 9.3.5
9442  */
9443 static void
9444 dtap_cc_connect(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9445 {
9446     guint32     curr_offset;
9447     guint32     consumed;
9448     guint       curr_len;
9449
9450     curr_offset = offset;
9451     curr_len = len;
9452
9453     is_uplink = IS_UPLINK_TRUE;
9454
9455     ELEM_OPT_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
9456
9457     ELEM_OPT_TLV(0x1e, BSSAP_PDU_TYPE_DTAP, DE_PROG_IND, "");
9458
9459     ELEM_OPT_TLV(0x4c, BSSAP_PDU_TYPE_DTAP, DE_CONN_NUM, "");
9460
9461     ELEM_OPT_TLV(0x4d, BSSAP_PDU_TYPE_DTAP, DE_CONN_SUB_ADDR, "");
9462
9463     ELEM_OPT_TLV(0x7e, BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
9464
9465     /* uplink only */
9466
9467     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
9468
9469     ELEM_OPT_TLV(0x2d, BSSAP_PDU_TYPE_DTAP, DE_SI, "");
9470
9471     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9472 }
9473
9474 /*
9475  * [4] 9.3.7
9476  */
9477 static void
9478 dtap_cc_disconnect(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9479 {
9480     guint32     curr_offset;
9481     guint32     consumed;
9482     guint       curr_len;
9483
9484     curr_offset = offset;
9485     curr_len = len;
9486
9487     is_uplink = IS_UPLINK_TRUE;
9488
9489     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
9490
9491     ELEM_OPT_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
9492
9493     ELEM_OPT_TLV(0x1e, BSSAP_PDU_TYPE_DTAP, DE_PROG_IND, "");
9494
9495     ELEM_OPT_TLV(0x7e, BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
9496
9497     ELEM_OPT_TLV(0x7b, BSSAP_PDU_TYPE_DTAP, DE_ALLOWED_ACTIONS, "");
9498
9499     /* uplink only */
9500
9501     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
9502
9503     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9504 }
9505
9506 /*
9507  * [4] 9.3.8
9508  */
9509 static void
9510 dtap_cc_emerg_setup(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9511 {
9512     guint32     curr_offset;
9513     guint32     consumed;
9514     guint       curr_len;
9515
9516     curr_offset = offset;
9517     curr_len = len;
9518
9519     is_uplink = IS_UPLINK_TRUE;
9520
9521     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, "");
9522
9523     ELEM_OPT_TLV(0x2d, BSSAP_PDU_TYPE_DTAP, DE_SI, "");
9524
9525     ELEM_OPT_TLV(0x40, BSSAP_PDU_TYPE_DTAP, DE_SUP_CODEC_LIST, "");
9526
9527     ELEM_OPT_TLV(0x2e, BSSAP_PDU_TYPE_DTAP, DE_SRVC_CAT, " Emergency");
9528
9529     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9530 }
9531
9532 /*
9533  * [4] 9.3.9
9534  */
9535 static void
9536 dtap_cc_facility(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9537 {
9538     guint32     curr_offset;
9539     guint32     consumed;
9540     guint       curr_len;
9541
9542     curr_offset = offset;
9543     curr_len = len;
9544
9545     is_uplink = IS_UPLINK_TRUE;
9546
9547     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
9548
9549     /* uplink only */
9550
9551     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
9552
9553     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9554 }
9555
9556 /*
9557  * [4] 9.3.12
9558  */
9559 static void
9560 dtap_cc_hold_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9561 {
9562     guint32     curr_offset;
9563     guint32     consumed;
9564     guint       curr_len;
9565
9566     curr_offset = offset;
9567     curr_len = len;
9568
9569     is_uplink = IS_UPLINK_FALSE;
9570
9571     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
9572
9573     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9574 }
9575
9576 /*
9577  * [4] 9.3.13
9578  */
9579 static void
9580 dtap_cc_modify(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9581 {
9582     guint32     curr_offset;
9583     guint32     consumed;
9584     guint       curr_len;
9585
9586     curr_offset = offset;
9587     curr_len = len;
9588
9589     is_uplink = IS_UPLINK_TRUE;
9590
9591     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, "");
9592
9593     ELEM_OPT_TLV(0x7c, BSSAP_PDU_TYPE_DTAP, DE_LLC, "");
9594
9595     ELEM_OPT_TLV(0x7d, BSSAP_PDU_TYPE_DTAP, DE_HLC, "");
9596
9597     ELEM_OPT_T(0xa3, BSSAP_PDU_TYPE_DTAP, DE_REV_CALL_SETUP_DIR, "");
9598
9599     ELEM_OPT_T(0xa4, BSSAP_PDU_TYPE_DTAP, DE_IMM_MOD_IND, "");
9600
9601     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9602 }
9603
9604 /*
9605  * [4] 9.3.14
9606  */
9607 static void
9608 dtap_cc_modify_complete(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9609 {
9610     guint32     curr_offset;
9611     guint32     consumed;
9612     guint       curr_len;
9613
9614     curr_offset = offset;
9615     curr_len = len;
9616
9617     is_uplink = IS_UPLINK_TRUE;
9618
9619     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, "");
9620
9621     ELEM_OPT_TLV(0x7c, BSSAP_PDU_TYPE_DTAP, DE_LLC, "");
9622
9623     ELEM_OPT_TLV(0x7d, BSSAP_PDU_TYPE_DTAP, DE_HLC, "");
9624
9625     ELEM_OPT_T(0xa3, BSSAP_PDU_TYPE_DTAP, DE_REV_CALL_SETUP_DIR, "");
9626
9627     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9628 }
9629
9630 /*
9631  * [4] 9.3.15
9632  */
9633 static void
9634 dtap_cc_modify_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9635 {
9636     guint32     curr_offset;
9637     guint32     consumed;
9638     guint       curr_len;
9639
9640     curr_offset = offset;
9641     curr_len = len;
9642
9643     is_uplink = IS_UPLINK_FALSE;
9644
9645     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, "");
9646
9647     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
9648
9649     ELEM_OPT_TLV(0x7c, BSSAP_PDU_TYPE_DTAP, DE_LLC, "");
9650
9651     ELEM_OPT_TLV(0x7d, BSSAP_PDU_TYPE_DTAP, DE_HLC, "");
9652
9653     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9654 }
9655
9656 /*
9657  * [4] 9.3.16
9658  */
9659 static void
9660 dtap_cc_notify(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9661 {
9662     guint32     curr_offset;
9663     guint32     consumed;
9664     guint       curr_len;
9665
9666     curr_offset = offset;
9667     curr_len = len;
9668
9669     is_uplink = IS_UPLINK_FALSE;
9670
9671     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_NOT_IND);
9672
9673     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9674 }
9675
9676 /*
9677  * [4] 9.3.17
9678  */
9679 static void
9680 dtap_cc_progress(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9681 {
9682     guint32     curr_offset;
9683     guint32     consumed;
9684     guint       curr_len;
9685
9686     curr_offset = offset;
9687     curr_len = len;
9688
9689     is_uplink = IS_UPLINK_FALSE;
9690
9691     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_PROG_IND, "");
9692
9693     ELEM_OPT_TLV(0x7e, BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
9694
9695     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9696 }
9697
9698 /*
9699  * [4] 9.3.17a
9700  */
9701 static void
9702 dtap_cc_cc_est(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9703 {
9704     guint32     curr_offset;
9705     guint32     consumed;
9706     guint       curr_len;
9707
9708     curr_offset = offset;
9709     curr_len = len;
9710
9711     is_uplink = IS_UPLINK_FALSE;
9712
9713     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_SETUP_CONTAINER, "");
9714
9715     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9716 }
9717
9718 /*
9719  * [4] 9.3.17b
9720  */
9721 static void
9722 dtap_cc_cc_est_conf(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9723 {
9724     guint32     curr_offset;
9725     guint32     consumed;
9726     guint       curr_len;
9727
9728     curr_offset = offset;
9729     curr_len = len;
9730
9731     is_uplink = IS_UPLINK_TRUE;
9732
9733     ELEM_OPT_TV_SHORT(0xd0, BSSAP_PDU_TYPE_DTAP, DE_REPEAT_IND, " Repeat indicator");
9734
9735     ELEM_MAND_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 1");
9736
9737     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 2");
9738
9739     ELEM_OPT_TLV(0x08, BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
9740
9741     ELEM_OPT_TLV(0x40, BSSAP_PDU_TYPE_DTAP, DE_SUP_CODEC_LIST, "");
9742
9743     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9744 }
9745
9746 /*
9747  * [4] 9.3.18
9748  */
9749 static void
9750 dtap_cc_release(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9751 {
9752     guint32     curr_offset;
9753     guint32     consumed;
9754     guint       curr_len;
9755
9756     curr_offset = offset;
9757     curr_len = len;
9758
9759     is_uplink = IS_UPLINK_TRUE;
9760
9761     ELEM_OPT_TLV(0x08, BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
9762
9763     ELEM_OPT_TLV(0x08, BSSAP_PDU_TYPE_DTAP, DE_CAUSE, " 2");
9764
9765     ELEM_OPT_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
9766
9767     ELEM_OPT_TLV(0x7e, BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
9768
9769     /* uplink only */
9770
9771     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
9772
9773     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9774 }
9775
9776 /*
9777  * [4] 9.3.18a
9778  */
9779 static void
9780 dtap_cc_recall(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9781 {
9782     guint32     curr_offset;
9783     guint32     consumed;
9784     guint       curr_len;
9785
9786     curr_offset = offset;
9787     curr_len = len;
9788
9789     is_uplink = IS_UPLINK_FALSE;
9790
9791     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RECALL_TYPE);
9792
9793     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
9794
9795     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9796 }
9797
9798 /*
9799  * [4] 9.3.19
9800  */
9801 static void
9802 dtap_cc_release_complete(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9803 {
9804     guint32     curr_offset;
9805     guint32     consumed;
9806     guint       curr_len;
9807
9808     curr_offset = offset;
9809     curr_len = len;
9810
9811     is_uplink = IS_UPLINK_FALSE;
9812
9813     ELEM_OPT_TLV(0x08, BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
9814
9815     ELEM_OPT_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
9816
9817     ELEM_OPT_TLV(0x7e, BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
9818
9819     /* uplink only */
9820
9821     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
9822
9823     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9824 }
9825
9826 /*
9827  * [4] 9.3.22
9828  */
9829 static void
9830 dtap_cc_retrieve_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9831 {
9832     guint32     curr_offset;
9833     guint32     consumed;
9834     guint       curr_len;
9835
9836     curr_offset = offset;
9837     curr_len = len;
9838
9839     is_uplink = IS_UPLINK_FALSE;
9840
9841     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
9842
9843     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9844 }
9845
9846 /*
9847  * [4] 9.3.23
9848  */
9849 static void
9850 dtap_cc_setup(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9851 {
9852     guint32     curr_offset;
9853     guint32     consumed;
9854     guint       curr_len;
9855
9856     curr_offset = offset;
9857     curr_len = len;
9858
9859     is_uplink = IS_UPLINK_TRUE;
9860
9861     ELEM_OPT_TV_SHORT(0xd0, BSSAP_PDU_TYPE_DTAP, DE_REPEAT_IND, " BC repeat indicator");
9862
9863     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 1");
9864
9865     ELEM_OPT_TLV(0x04, BSSAP_PDU_TYPE_DTAP, DE_BEARER_CAP, " 2");
9866
9867     ELEM_OPT_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
9868
9869     ELEM_OPT_TLV(0x1e, BSSAP_PDU_TYPE_DTAP, DE_PROG_IND, "");
9870
9871     ELEM_OPT_TV(0x34, BSSAP_PDU_TYPE_DTAP, DE_SIGNAL, "");
9872
9873     ELEM_OPT_TLV(0x5c, BSSAP_PDU_TYPE_DTAP, DE_CLG_PARTY_BCD_NUM, "");
9874
9875     ELEM_OPT_TLV(0x5d, BSSAP_PDU_TYPE_DTAP, DE_CLG_PARTY_SUB_ADDR, "");
9876
9877     ELEM_OPT_TLV(0x5e, BSSAP_PDU_TYPE_DTAP, DE_CLD_PARTY_BCD_NUM, "");
9878
9879     ELEM_OPT_TLV(0x6d, BSSAP_PDU_TYPE_DTAP, DE_CLD_PARTY_SUB_ADDR, "");
9880
9881     ELEM_OPT_TLV(0x74, BSSAP_PDU_TYPE_DTAP, DE_RED_PARTY_BCD_NUM, "");
9882
9883     ELEM_OPT_TLV(0x75, BSSAP_PDU_TYPE_DTAP, DE_RED_PARTY_SUB_ADDR, "");
9884
9885     ELEM_OPT_TV_SHORT(0xd0, BSSAP_PDU_TYPE_DTAP, DE_REPEAT_IND, " LLC repeat indicator");
9886
9887     ELEM_OPT_TLV(0x7c, BSSAP_PDU_TYPE_DTAP, DE_LLC, " 1");
9888
9889     ELEM_OPT_TLV(0x7c, BSSAP_PDU_TYPE_DTAP, DE_LLC, " 2");
9890
9891     ELEM_OPT_TV_SHORT(0xd0, BSSAP_PDU_TYPE_DTAP, DE_REPEAT_IND, " HLC repeat indicator");
9892
9893     ELEM_OPT_TLV(0x7d, BSSAP_PDU_TYPE_DTAP, DE_HLC, " 1");
9894
9895     ELEM_OPT_TLV(0x7d, BSSAP_PDU_TYPE_DTAP, DE_HLC, " 2");
9896
9897     ELEM_OPT_TLV(0x7e, BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
9898
9899     /* downlink only */
9900
9901     ELEM_OPT_TV_SHORT(0x80, BSSAP_PDU_TYPE_DTAP, DE_PRIO, "");
9902
9903     ELEM_OPT_TLV(0x19, BSSAP_PDU_TYPE_DTAP, DE_ALERT_PATTERN, "");
9904
9905     ELEM_OPT_TLV(0x2f, BSSAP_PDU_TYPE_DTAP, DE_NET_CC_CAP, "");
9906
9907     ELEM_OPT_TLV(0x3a, BSSAP_PDU_TYPE_DTAP, DE_CAUSE_NO_CLI, "");
9908
9909     /* uplink only */
9910
9911     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
9912
9913     ELEM_OPT_T(0xa1, BSSAP_PDU_TYPE_DTAP, DE_FOP, "");
9914
9915     ELEM_OPT_T(0xa2, BSSAP_PDU_TYPE_DTAP, DE_CTS_PERM, "");
9916
9917     ELEM_OPT_TLV(0x15, BSSAP_PDU_TYPE_DTAP, DE_CC_CAP, "");
9918
9919     ELEM_OPT_TLV(0x1d, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, " $(CCBS)$ (advanced recall alignment)");
9920
9921     ELEM_OPT_TLV(0x1b, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, " (recall alignment Not essential) $(CCBS)$");
9922
9923     ELEM_OPT_TLV(0x2d, BSSAP_PDU_TYPE_DTAP, DE_SI, "");
9924
9925     ELEM_OPT_TLV(0x40, BSSAP_PDU_TYPE_DTAP, DE_SUP_CODEC_LIST, "");
9926
9927     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9928 }
9929
9930 /*
9931  * [4] 9.3.23a
9932  */
9933 static void
9934 dtap_cc_start_cc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9935 {
9936     guint32     curr_offset;
9937     guint32     consumed;
9938     guint       curr_len;
9939
9940     curr_offset = offset;
9941     curr_len = len;
9942
9943     is_uplink = IS_UPLINK_FALSE;
9944
9945     ELEM_OPT_TLV(0x15, BSSAP_PDU_TYPE_DTAP, DE_CC_CAP, "");
9946
9947     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9948 }
9949
9950 /*
9951  * [4] 9.3.24
9952  */
9953 static void
9954 dtap_cc_start_dtmf(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
9955 {
9956     guint32     curr_offset;
9957     guint32     consumed;
9958     guint       curr_len;
9959
9960     curr_offset = offset;
9961     curr_len = len;
9962
9963     is_uplink = IS_UPLINK_TRUE;
9964
9965     ELEM_MAND_TV(0x2c, BSSAP_PDU_TYPE_DTAP, DE_KEYPAD_FACILITY, "");
9966
9967     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9968 }
9969
9970 /*
9971  * [4] 9.3.25
9972  */
9973 static void
9974 dtap_cc_start_dtmf_ack(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_MAND_TV(0x2c, BSSAP_PDU_TYPE_DTAP, DE_KEYPAD_FACILITY, "");
9986
9987     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9988 }
9989
9990 /*
9991  * [4] 9.3.26
9992  */
9993 static void
9994 dtap_cc_start_dtmf_rej(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_FALSE;
10004
10005     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
10006
10007     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10008 }
10009
10010 /*
10011  * [4] 9.3.27
10012  */
10013 static void
10014 dtap_cc_status(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_LV(BSSAP_PDU_TYPE_DTAP, DE_CAUSE, "");
10026
10027     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_CALL_STATE);
10028
10029     ELEM_OPT_TLV(0x24, BSSAP_PDU_TYPE_DTAP, DE_AUX_STATES, "");
10030
10031     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10032 }
10033
10034 /*
10035  * [4] 9.3.31
10036  */
10037 static void
10038 dtap_cc_user_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10039 {
10040     guint32     curr_offset;
10041     guint32     consumed;
10042     guint       curr_len;
10043
10044     curr_offset = offset;
10045     curr_len = len;
10046
10047     is_uplink = IS_UPLINK_TRUE;
10048
10049     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_USER_USER, "");
10050
10051     ELEM_OPT_T(0xa0, BSSAP_PDU_TYPE_DTAP, DE_MORE_DATA, "");
10052
10053     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10054 }
10055
10056 /*
10057  * [6] 2.4.2
10058  */
10059 static void
10060 dtap_ss_register(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10061 {
10062     guint32     curr_offset;
10063     guint32     consumed;
10064     guint       curr_len;
10065
10066     curr_offset = offset;
10067     curr_len = len;
10068
10069     is_uplink = IS_UPLINK_TRUE;
10070
10071     ELEM_MAND_TLV(0x1c, BSSAP_PDU_TYPE_DTAP, DE_FACILITY, "");
10072
10073     ELEM_OPT_TLV(0x7f, BSSAP_PDU_TYPE_DTAP, DE_SS_VER_IND, "");
10074
10075     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10076 }
10077
10078 /*
10079  * [5] 7.2.1
10080  */
10081 static void
10082 dtap_sms_cp_data(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10083 {
10084     guint32     curr_offset;
10085     guint32     consumed;
10086     guint       curr_len;
10087
10088     curr_offset = offset;
10089     curr_len = len;
10090
10091     is_uplink = IS_UPLINK_TRUE;
10092
10093     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_CP_USER_DATA, "");
10094
10095     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10096 }
10097
10098 /*
10099  * [5] 7.2.3
10100  */
10101 static void
10102 dtap_sms_cp_error(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10103 {
10104     guint32     curr_offset;
10105     guint32     consumed;
10106     guint       curr_len;
10107
10108     curr_offset = offset;
10109     curr_len = len;
10110
10111     is_uplink = IS_UPLINK_TRUE;
10112
10113     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_CP_CAUSE);
10114
10115     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10116 }
10117
10118 /*
10119  * [5] 7.3.1.1
10120  */
10121 static void
10122 rp_data_n_ms(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_FALSE;
10132     g_pinfo->p2p_dir = P2P_DIR_SENT;
10133
10134     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RP_MESSAGE_REF);
10135
10136     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_ORIG_ADDR, "");
10137
10138     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_DEST_ADDR, "");
10139
10140     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_USER_DATA, "");
10141
10142     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10143 }
10144
10145 /*
10146  * [5] 7.3.1.2
10147  */
10148 static void
10149 rp_data_ms_n(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10150 {
10151     guint32     curr_offset;
10152     guint32     consumed;
10153     guint       curr_len;
10154
10155     curr_offset = offset;
10156     curr_len = len;
10157
10158     is_uplink = IS_UPLINK_TRUE;
10159     g_pinfo->p2p_dir = P2P_DIR_RECV;
10160
10161     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RP_MESSAGE_REF);
10162
10163     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_ORIG_ADDR, "");
10164
10165     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_DEST_ADDR, "");
10166
10167     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_USER_DATA, "");
10168
10169     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10170 }
10171
10172 /*
10173  * [5] 7.3.2
10174  */
10175 static void
10176 rp_smma(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10177 {
10178     guint32     curr_offset;
10179     guint32     consumed;
10180     guint       curr_len;
10181
10182     curr_offset = offset;
10183     curr_len = len;
10184
10185     is_uplink = IS_UPLINK_TRUE;
10186
10187     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RP_MESSAGE_REF);
10188
10189     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10190 }
10191
10192 /*
10193  * [5] 7.3.3
10194  */
10195 static void
10196 rp_ack_n_ms(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10197 {
10198     guint32     curr_offset;
10199     guint32     consumed;
10200     guint       curr_len;
10201
10202     curr_offset = offset;
10203     curr_len = len;
10204
10205     is_uplink = IS_UPLINK_FALSE;
10206     g_pinfo->p2p_dir = P2P_DIR_SENT;
10207
10208     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RP_MESSAGE_REF);
10209
10210     ELEM_OPT_TLV(0x41, BSSAP_PDU_TYPE_DTAP, DE_RP_USER_DATA, "");
10211
10212     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10213 }
10214
10215 /*
10216  * [5] 7.3.3
10217  */
10218 static void
10219 rp_ack_ms_n(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10220 {
10221     guint32     curr_offset;
10222     guint32     consumed;
10223     guint       curr_len;
10224
10225     curr_offset = offset;
10226     curr_len = len;
10227
10228     is_uplink = IS_UPLINK_TRUE;
10229     g_pinfo->p2p_dir = P2P_DIR_RECV;
10230
10231     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RP_MESSAGE_REF);
10232
10233     ELEM_OPT_TLV(0x41, BSSAP_PDU_TYPE_DTAP, DE_RP_USER_DATA, "");
10234
10235     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10236 }
10237
10238 /*
10239  * [5] 7.3.4
10240  */
10241 static void
10242 rp_error_n_ms(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10243 {
10244     guint32     curr_offset;
10245     guint32     consumed;
10246     guint       curr_len;
10247
10248     curr_offset = offset;
10249     curr_len = len;
10250
10251     is_uplink = IS_UPLINK_FALSE;
10252     g_pinfo->p2p_dir = P2P_DIR_SENT;
10253
10254     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RP_MESSAGE_REF);
10255
10256     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_CAUSE, "");
10257
10258     ELEM_OPT_TLV(0x41, BSSAP_PDU_TYPE_DTAP, DE_RP_USER_DATA, "");
10259
10260     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10261 }
10262
10263 /*
10264  * [5] 7.3.4
10265  */
10266 static void
10267 rp_error_ms_n(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
10268 {
10269     guint32     curr_offset;
10270     guint32     consumed;
10271     guint       curr_len;
10272
10273     curr_offset = offset;
10274     curr_len = len;
10275
10276     is_uplink = IS_UPLINK_TRUE;
10277     g_pinfo->p2p_dir = P2P_DIR_RECV;
10278
10279     ELEM_MAND_V(BSSAP_PDU_TYPE_DTAP, DE_RP_MESSAGE_REF);
10280
10281     ELEM_MAND_LV(BSSAP_PDU_TYPE_DTAP, DE_RP_CAUSE, "");
10282
10283     ELEM_OPT_TLV(0x41, BSSAP_PDU_TYPE_DTAP, DE_RP_USER_DATA, "");
10284
10285     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10286 }
10287
10288 #define NUM_GSM_DTAP_MSG_MM (sizeof(gsm_a_dtap_msg_mm_strings)/sizeof(value_string))
10289 static gint ett_gsm_dtap_msg_mm[NUM_GSM_DTAP_MSG_MM];
10290 static void (*dtap_msg_mm_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
10291     dtap_mm_imsi_det_ind,       /* IMSI Detach Indication */
10292     dtap_mm_loc_upd_acc,        /* Location Updating Accept */
10293     dtap_mm_loc_upd_rej,        /* Location Updating Reject */
10294     dtap_mm_loc_upd_req,        /* Location Updating Request */
10295     NULL /* no associated data */,      /* Authentication Reject */
10296     dtap_mm_auth_req,   /* Authentication Request */
10297     dtap_mm_auth_resp,  /* Authentication Response */
10298     dtap_mm_auth_fail,  /* Authentication Failure */
10299     dtap_mm_id_req,     /* Identity Request */
10300     dtap_mm_id_resp,    /* Identity Response */
10301     dtap_mm_tmsi_realloc_cmd,   /* TMSI Reallocation Command */
10302     NULL /* no associated data */,      /* TMSI Reallocation Complete */
10303     NULL /* no associated data */,      /* CM Service Accept */
10304     dtap_mm_cm_srvc_rej,        /* CM Service Reject */
10305     NULL /* no associated data */,      /* CM Service Abort */
10306     dtap_mm_cm_srvc_req,        /* CM Service Request */
10307     dtap_mm_cm_srvc_prompt,     /* CM Service Prompt */
10308     NULL,       /* Reserved: was allocated in earlier phases of the protocol */
10309     dtap_mm_cm_reestab_req,     /* CM Re-establishment Request */
10310     dtap_mm_abort,      /* Abort */
10311     NULL /* no associated data */,      /* MM Null */
10312     dtap_mm_mm_status,  /* MM Status */
10313     dtap_mm_mm_info,    /* MM Information */
10314     NULL,       /* NONE */
10315 };
10316
10317 #define NUM_GSM_DTAP_MSG_RR (sizeof(gsm_a_dtap_msg_rr_strings)/sizeof(value_string))
10318 static gint ett_gsm_dtap_msg_rr[NUM_GSM_DTAP_MSG_RR];
10319 static void (*dtap_msg_rr_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
10320     NULL,       /* RR Initialisation Request */
10321     NULL,       /* Additional Assignment */
10322     NULL,       /* Immediate Assignment */
10323     NULL,       /* Immediate Assignment Extended */
10324     NULL,       /* Immediate Assignment Reject */
10325
10326     NULL,       /* DTM Assignment Failure */
10327     NULL,       /* DTM Reject */
10328     NULL,       /* DTM Request */
10329     NULL,       /* Main DCCH Assignment Command */
10330     NULL,       /* Packet Assignment Command */
10331
10332     NULL,       /* Ciphering Mode Command */
10333     NULL,       /* Ciphering Mode Complete */
10334
10335     NULL,       /* Configuration Change Command */
10336     NULL,       /* Configuration Change Ack. */
10337     NULL,       /* Configuration Change Reject */
10338
10339     NULL,       /* Assignment Command */
10340     NULL,       /* Assignment Complete */
10341     NULL,       /* Assignment Failure */
10342     NULL,       /* Handover Command */
10343     NULL,       /* Handover Complete */
10344     NULL,       /* Handover Failure */
10345     NULL,       /* Physical Information */
10346     NULL,       /* DTM Assignment Command */
10347
10348     NULL,       /* RR-cell Change Order */
10349     NULL,       /* PDCH Assignment Command */
10350
10351     NULL,       /* Channel Release */
10352     NULL,       /* Partial Release */
10353     NULL,       /* Partial Release Complete */
10354
10355     NULL,       /* Paging Request Type 1 */
10356     NULL,       /* Paging Request Type 2 */
10357     NULL,       /* Paging Request Type 3 */
10358     dtap_rr_paging_resp,        /* Paging Response */
10359     NULL,       /* Notification/NCH */
10360     NULL,       /* Reserved */
10361     NULL,       /* Notification/Response */
10362
10363     NULL,       /* Reserved */
10364
10365 /*    NULL,     * Utran Classmark Change * CONFLICTS WITH Handover To UTRAN Command */
10366     NULL,       /* UE RAB Preconfiguration */
10367     NULL,       /* cdma2000 Classmark Change */
10368
10369     NULL,       /* System Information Type 8 */
10370     NULL,       /* System Information Type 1 */
10371     NULL,       /* System Information Type 2 */
10372     NULL,       /* System Information Type 3 */
10373     NULL,       /* System Information Type 4 */
10374     NULL,       /* System Information Type 5 */
10375     NULL,       /* System Information Type 6 */
10376     NULL,       /* System Information Type 7 */
10377
10378     NULL,       /* System Information Type 2bis */
10379     NULL,       /* System Information Type 2ter */
10380     NULL,       /* System Information Type 2quater */
10381     NULL,       /* System Information Type 5bis */
10382     NULL,       /* System Information Type 5ter */
10383     NULL,       /* System Information Type 9 */
10384     NULL,       /* System Information Type 13 */
10385
10386     NULL,       /* System Information Type 16 */
10387     NULL,       /* System Information Type 17 */
10388
10389     NULL,       /* System Information Type 18 */
10390     NULL,       /* System Information Type 19 */
10391     NULL,       /* System Information Type 20 */
10392
10393     NULL,       /* Channel Mode Modify */
10394     dtap_rr_rr_status,  /* RR Status */
10395     NULL,       /* Channel Mode Modify Acknowledge */
10396     NULL,       /* Frequency Redefinition */
10397     NULL,       /* Measurement Report */
10398     NULL,       /* Classmark Change */
10399     NULL,       /* Classmark Enquiry */
10400     NULL,       /* Extended Measurement Report */
10401     NULL,       /* Extended Measurement Order */
10402     NULL,       /* GPRS Suspension Request */
10403
10404     NULL,       /* VGCS Uplink Grant */
10405     NULL,       /* Uplink Release */
10406     NULL,       /* Reserved */
10407     NULL,       /* Uplink Busy */
10408     NULL,       /* Talker Indication */
10409
10410     NULL,       /* UTRAN Classmark Change/Handover To UTRAN Command */  /* spec conflict */
10411
10412     NULL,       /* Application Information */
10413
10414     NULL,       /* NONE */
10415 };
10416
10417 #define NUM_GSM_DTAP_MSG_CC (sizeof(gsm_a_dtap_msg_cc_strings)/sizeof(value_string))
10418 static gint ett_gsm_dtap_msg_cc[NUM_GSM_DTAP_MSG_CC];
10419 static void (*dtap_msg_cc_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
10420     dtap_cc_alerting,   /* Alerting */
10421     dtap_cc_call_conf,  /* Call Confirmed */
10422     dtap_cc_call_proceed,       /* Call Proceeding */
10423     dtap_cc_connect,    /* Connect */
10424     NULL /* no associated data */,      /* Connect Acknowledge */
10425     dtap_cc_emerg_setup,        /* Emergency Setup */
10426     dtap_cc_progress,   /* Progress */
10427     dtap_cc_cc_est,     /* CC-Establishment */
10428     dtap_cc_cc_est_conf,        /* CC-Establishment Confirmed */
10429     dtap_cc_recall,     /* Recall */
10430     dtap_cc_start_cc,   /* Start CC */
10431     dtap_cc_setup,      /* Setup */
10432     dtap_cc_modify,     /* Modify */
10433     dtap_cc_modify_complete,    /* Modify Complete */
10434     dtap_cc_modify_rej, /* Modify Reject */
10435     dtap_cc_user_info,  /* User Information */
10436     NULL /* no associated data */,      /* Hold */
10437     NULL /* no associated data */,      /* Hold Acknowledge */
10438     dtap_cc_hold_rej,   /* Hold Reject */
10439     NULL /* no associated data */,      /* Retrieve */
10440     NULL /* no associated data */,      /* Retrieve Acknowledge */
10441     dtap_cc_retrieve_rej,       /* Retrieve Reject */
10442     dtap_cc_disconnect, /* Disconnect */
10443     dtap_cc_release,    /* Release */
10444     dtap_cc_release_complete,   /* Release Complete */
10445     dtap_cc_congestion_control, /* Congestion Control */
10446     dtap_cc_notify,     /* Notify */
10447     dtap_cc_status,     /* Status */
10448     NULL /* no associated data */,      /* Status Enquiry */
10449     dtap_cc_start_dtmf, /* Start DTMF */
10450     NULL /* no associated data */,      /* Stop DTMF */
10451     NULL /* no associated data */,      /* Stop DTMF Acknowledge */
10452     dtap_cc_start_dtmf_ack,     /* Start DTMF Acknowledge */
10453     dtap_cc_start_dtmf_rej,     /* Start DTMF Reject */
10454     dtap_cc_facility,   /* Facility */
10455     NULL,       /* NONE */
10456 };
10457
10458 #define NUM_GSM_DTAP_MSG_GMM (sizeof(gsm_a_dtap_msg_gmm_strings)/sizeof(value_string))
10459 static gint ett_gsm_dtap_msg_gmm[NUM_GSM_DTAP_MSG_GMM];
10460 static void (*dtap_msg_gmm_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
10461     NULL,       /* Attach Request */
10462     NULL,       /* Attach Accept */
10463     NULL,       /* Attach Complete */
10464     NULL,       /* Attach Reject */
10465     NULL,       /* Detach Request */
10466     NULL,       /* Detach Accept */
10467     NULL,       /* Routing Area Update Request */
10468     NULL,       /* Routing Area Update Accept */
10469     NULL,       /* Routing Area Update Complete */
10470     NULL,       /* Routing Area Update Reject */
10471     NULL,       /* Service Request */
10472     NULL,       /* Service Accept */
10473     NULL,       /* Service Reject */
10474     NULL,       /* P-TMSI Reallocation Command */
10475     NULL,       /* P-TMSI Reallocation Complete */
10476     NULL,       /* Authentication and Ciphering Req */
10477     NULL,       /* Authentication and Ciphering Resp */
10478     NULL,       /* Authentication and Ciphering Rej */
10479     NULL,       /* Authentication and Ciphering Failure */
10480     NULL,       /* Identity Request */
10481     NULL,       /* Identity Response */
10482     NULL,       /* GMM Status */
10483     NULL,       /* GMM Information */
10484     NULL,       /* NONE */
10485 };
10486
10487 #define NUM_GSM_DTAP_MSG_SMS (sizeof(gsm_a_dtap_msg_sms_strings)/sizeof(value_string))
10488 static gint ett_gsm_dtap_msg_sms[NUM_GSM_DTAP_MSG_SMS];
10489 static void (*dtap_msg_sms_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
10490     dtap_sms_cp_data,   /* CP-DATA */
10491     NULL /* no associated data */,      /* CP-ACK */
10492     dtap_sms_cp_error,  /* CP-ERROR */
10493     NULL,       /* NONE */
10494 };
10495
10496 #define NUM_GSM_DTAP_MSG_SM (sizeof(gsm_a_dtap_msg_sm_strings)/sizeof(value_string))
10497 static gint ett_gsm_dtap_msg_sm[NUM_GSM_DTAP_MSG_SM];
10498 static void (*dtap_msg_sm_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
10499     NULL,       /* Activate PDP Context Request */
10500     NULL,       /* Activate PDP Context Accept */
10501     NULL,       /* Activate PDP Context Reject */
10502     NULL,       /* Request PDP Context Activation */
10503     NULL,       /* Request PDP Context Activation rej. */
10504     NULL,       /* Deactivate PDP Context Request */
10505     NULL,       /* Deactivate PDP Context Accept */
10506     NULL,       /* Modify PDP Context Request(Network to MS direction) */
10507     NULL,       /* Modify PDP Context Accept (MS to network direction) */
10508     NULL,       /* Modify PDP Context Request(MS to network direction) */
10509     NULL,       /* Modify PDP Context Accept (Network to MS direction) */
10510     NULL,       /* Modify PDP Context Reject */
10511     NULL,       /* Activate Secondary PDP Context Request */
10512     NULL,       /* Activate Secondary PDP Context Accept */
10513     NULL,       /* Activate Secondary PDP Context Reject */
10514     NULL,       /* Reserved: was allocated in earlier phases of the protocol */
10515     NULL,       /* Reserved: was allocated in earlier phases of the protocol */
10516     NULL,       /* Reserved: was allocated in earlier phases of the protocol */
10517     NULL,       /* Reserved: was allocated in earlier phases of the protocol */
10518     NULL,       /* Reserved: was allocated in earlier phases of the protocol */
10519     NULL,       /* SM Status */
10520     NULL,       /* NONE */
10521 };
10522
10523 #define NUM_GSM_DTAP_MSG_SS (sizeof(gsm_a_dtap_msg_ss_strings)/sizeof(value_string))
10524 static gint ett_gsm_dtap_msg_ss[NUM_GSM_DTAP_MSG_SS];
10525 static void (*dtap_msg_ss_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
10526     dtap_cc_release_complete,   /* Release Complete */
10527     dtap_cc_facility,   /* Facility */
10528     dtap_ss_register,   /* Register */
10529     NULL,       /* NONE */
10530 };
10531
10532 #define NUM_GSM_RP_MSG (sizeof(gsm_rp_msg_strings)/sizeof(value_string))
10533 static gint ett_gsm_rp_msg[NUM_GSM_RP_MSG];
10534 static void (*rp_msg_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
10535     rp_data_ms_n,       /* RP-DATA (MS to Network) */
10536     rp_data_n_ms,       /* RP-DATA (Network to MS */
10537     rp_ack_ms_n,        /* RP-ACK (MS to Network) */
10538     rp_ack_n_ms,        /* RP-ACK (Network to MS) */
10539     rp_error_ms_n,      /* RP-ERROR (MS to Network) */
10540     rp_error_n_ms,      /* RP-ERROR (Network to MS) */
10541     rp_smma,    /* RP-SMMA (MS to Network) */
10542     NULL,       /* NONE */
10543 };
10544
10545 /* GENERIC DISSECTOR FUNCTIONS */
10546
10547 static void
10548 dissect_rp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
10549 {
10550     guint8      oct;
10551     guint32     offset, saved_offset;
10552     guint32     len;
10553     gint        idx;
10554     proto_item  *rp_item = NULL;
10555     proto_tree  *rp_tree = NULL;
10556     gchar       *str;
10557
10558
10559     if (check_col(pinfo->cinfo, COL_INFO))
10560     {
10561         col_append_str(pinfo->cinfo, COL_INFO, "(RP) ");
10562     }
10563
10564     /*
10565      * In the interest of speed, if "tree" is NULL, don't do any work
10566      * not necessary to generate protocol tree items.
10567      */
10568     if (!tree)
10569     {
10570         return;
10571     }
10572
10573     offset = 0;
10574     saved_offset = offset;
10575
10576     g_pinfo = pinfo;
10577     g_tree = tree;
10578
10579     len = tvb_length(tvb);
10580
10581     /*
10582      * add RP message name
10583      */
10584     oct = tvb_get_guint8(tvb, offset++);
10585
10586     str = my_match_strval((guint32) oct, gsm_rp_msg_strings, &idx);
10587
10588     /*
10589      * create the protocol tree
10590      */
10591     if (str == NULL)
10592     {
10593         rp_item =
10594             proto_tree_add_protocol_format(tree, proto_a_rp, tvb, 0, len,
10595                 "GSM A-I/F RP - Unknown RP Message Type (0x%02x)",
10596                 oct);
10597
10598         rp_tree = proto_item_add_subtree(rp_item, ett_rp_msg);
10599     }
10600     else
10601     {
10602         rp_item =
10603             proto_tree_add_protocol_format(tree, proto_a_rp, tvb, 0, -1,
10604                 "GSM A-I/F RP - %s",
10605                 str);
10606
10607         rp_tree = proto_item_add_subtree(rp_item, ett_gsm_rp_msg[idx]);
10608
10609         if (check_col(pinfo->cinfo, COL_INFO))
10610         {
10611             col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", str);
10612         }
10613     }
10614
10615     /*
10616      * add RP message name
10617      */
10618     proto_tree_add_uint_format(rp_tree, hf_gsm_a_rp_msg_type,
10619         tvb, saved_offset, 1, oct, "Message Type");
10620
10621     if (str == NULL) return;
10622
10623     if ((len - offset) <= 0) return;
10624
10625     /*
10626      * decode elements
10627      */
10628     if (rp_msg_fcn[idx] == NULL)
10629     {
10630         proto_tree_add_text(rp_tree,
10631             tvb, offset, len - offset,
10632             "Message Elements");
10633     }
10634     else
10635     {
10636         (*rp_msg_fcn[idx])(tvb, rp_tree, offset, len - offset);
10637     }
10638 }
10639
10640
10641 static void
10642 dissect_bssmap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
10643 {
10644     static gsm_a_tap_rec_t      tap_rec[4];
10645     static gsm_a_tap_rec_t      *tap_p;
10646     static int                  tap_current=0;
10647     guint8      oct;
10648     guint32     offset, saved_offset;
10649     guint32     len;
10650     gint        idx;
10651     proto_item  *bssmap_item = NULL;
10652     proto_tree  *bssmap_tree = NULL;
10653     gchar       *str;
10654
10655
10656     if (check_col(pinfo->cinfo, COL_INFO))
10657     {
10658         col_append_str(pinfo->cinfo, COL_INFO, "(BSSMAP) ");
10659     }
10660
10661     /*
10662      * set tap record pointer
10663      */
10664     tap_current++;
10665     if (tap_current == 4)
10666     {
10667         tap_current = 0;
10668     }
10669     tap_p = &tap_rec[tap_current];
10670
10671
10672     offset = 0;
10673     saved_offset = offset;
10674
10675     g_pinfo = pinfo;
10676     g_tree = tree;
10677
10678     len = tvb_length(tvb);
10679
10680     /*
10681      * add BSSMAP message name
10682      */
10683     oct = tvb_get_guint8(tvb, offset++);
10684
10685     str = my_match_strval((guint32) oct, gsm_a_bssmap_msg_strings, &idx);
10686
10687     /*
10688      * create the protocol tree
10689      */
10690     if (str == NULL)
10691     {
10692         bssmap_item =
10693             proto_tree_add_protocol_format(tree, proto_a_bssmap, tvb, 0, len,
10694                 "GSM A-I/F BSSMAP - Unknown BSSMAP Message Type (0x%02x)",
10695                 oct);
10696
10697         bssmap_tree = proto_item_add_subtree(bssmap_item, ett_bssmap_msg);
10698     }
10699     else
10700     {
10701         bssmap_item =
10702             proto_tree_add_protocol_format(tree, proto_a_bssmap, tvb, 0, -1,
10703                 "GSM A-I/F BSSMAP - %s",
10704                 str);
10705
10706         bssmap_tree = proto_item_add_subtree(bssmap_item, ett_gsm_bssmap_msg[idx]);
10707
10708         if (check_col(pinfo->cinfo, COL_INFO))
10709         {
10710             col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", str);
10711         }
10712     }
10713
10714     /*
10715      * add BSSMAP message name
10716      */
10717     proto_tree_add_uint_format(bssmap_tree, hf_gsm_a_bssmap_msg_type,
10718         tvb, saved_offset, 1, oct, "Message Type");
10719
10720     tap_p->pdu_type = BSSAP_PDU_TYPE_BSSMAP;
10721     tap_p->message_type = oct;
10722
10723     tap_queue_packet(gsm_a_tap, pinfo, tap_p);
10724
10725     if (str == NULL) return;
10726
10727     if ((len - offset) <= 0) return;
10728
10729     /*
10730      * decode elements
10731      */
10732     if (bssmap_msg_fcn[idx] == NULL)
10733     {
10734         proto_tree_add_text(bssmap_tree,
10735             tvb, offset, len - offset,
10736             "Message Elements");
10737     }
10738     else
10739     {
10740         (*bssmap_msg_fcn[idx])(tvb, bssmap_tree, offset, len - offset);
10741     }
10742 }
10743
10744
10745 static void
10746 dissect_dtap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
10747 {
10748     static gsm_a_tap_rec_t      tap_rec[4];
10749     static gsm_a_tap_rec_t      *tap_p;
10750     static int                  tap_current=0;
10751     void                        (*msg_fcn)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len);
10752     guint8                      oct;
10753     guint8                      pd;
10754     guint32                     offset;
10755     guint32                     len;
10756     guint32                     oct_1, oct_2;
10757     gint                        idx;
10758     proto_item                  *dtap_item = NULL;
10759     proto_tree                  *dtap_tree = NULL;
10760     proto_item                  *oct_1_item = NULL;
10761     proto_tree                  *pd_tree = NULL;
10762     gchar                       *msg_str;
10763     const gchar                 *str;
10764     gint                        ett_tree;
10765     gint                        ti;
10766     int                         hf_idx;
10767     gboolean                    nsd;
10768
10769
10770     len = tvb_length(tvb);
10771
10772     if (len < 2)
10773     {
10774         /*
10775          * too short to be DTAP
10776          */
10777         call_dissector(data_handle, tvb, pinfo, tree);
10778         return;
10779     }
10780
10781     if (check_col(pinfo->cinfo, COL_INFO))
10782     {
10783         col_append_str(pinfo->cinfo, COL_INFO, "(DTAP) ");
10784     }
10785
10786     /*
10787      * set tap record pointer
10788      */
10789     tap_current++;
10790     if (tap_current == 4)
10791     {
10792         tap_current = 0;
10793     }
10794     tap_p = &tap_rec[tap_current];
10795
10796
10797     offset = 0;
10798     oct_2 = 0;
10799
10800     g_pinfo = pinfo;
10801     g_tree = tree;
10802
10803     /*
10804      * get protocol discriminator
10805      */
10806     oct_1 = tvb_get_guint8(tvb, offset++);
10807
10808     if ((((oct_1 & DTAP_TI_MASK) >> 4) & DTAP_TIE_PRES_MASK) == DTAP_TIE_PRES_MASK)
10809     {
10810         /*
10811          * eventhough we don't know if a TI should be in the message yet
10812          * we rely on the TI/SKIP indicator to be 0 to avoid taking this
10813          * octet
10814          */
10815         oct_2 = tvb_get_guint8(tvb, offset++);
10816     }
10817
10818     oct = tvb_get_guint8(tvb, offset);
10819
10820     pd = oct_1 & DTAP_PD_MASK;
10821     ti = -1;
10822     msg_str = NULL;
10823     ett_tree = -1;
10824     hf_idx = -1;
10825     msg_fcn = NULL;
10826     nsd = FALSE;
10827
10828     /*
10829      * octet 1
10830      */
10831     switch (pd)
10832     {
10833     case 3:
10834         str = gsm_a_pd_str[pd];
10835         msg_str = my_match_strval((guint32) (oct & DTAP_CC_IEI_MASK), gsm_a_dtap_msg_cc_strings, &idx);
10836         ett_tree = ett_gsm_dtap_msg_cc[idx];
10837         hf_idx = hf_gsm_a_dtap_msg_cc_type;
10838         msg_fcn = dtap_msg_cc_fcn[idx];
10839         ti = (oct_1 & DTAP_TI_MASK) >> 4;
10840         nsd = TRUE;
10841         break;
10842
10843     case 5:
10844         str = gsm_a_pd_str[pd];
10845         msg_str = my_match_strval((guint32) (oct & DTAP_MM_IEI_MASK), gsm_a_dtap_msg_mm_strings, &idx);
10846         ett_tree = ett_gsm_dtap_msg_mm[idx];
10847         hf_idx = hf_gsm_a_dtap_msg_mm_type;
10848         msg_fcn = dtap_msg_mm_fcn[idx];
10849         nsd = TRUE;
10850         break;
10851
10852     case 6:
10853         str = gsm_a_pd_str[pd];
10854         msg_str = my_match_strval((guint32) (oct & DTAP_RR_IEI_MASK), gsm_a_dtap_msg_rr_strings, &idx);
10855         ett_tree = ett_gsm_dtap_msg_rr[idx];
10856         hf_idx = hf_gsm_a_dtap_msg_rr_type;
10857         msg_fcn = dtap_msg_rr_fcn[idx];
10858         break;
10859
10860     case 8:
10861         str = gsm_a_pd_str[pd];
10862         msg_str = my_match_strval((guint32) (oct & DTAP_GMM_IEI_MASK), gsm_a_dtap_msg_gmm_strings, &idx);
10863         ett_tree = ett_gsm_dtap_msg_gmm[idx];
10864         hf_idx = hf_gsm_a_dtap_msg_gmm_type;
10865         msg_fcn = dtap_msg_gmm_fcn[idx];
10866         break;
10867
10868     case 9:
10869         str = gsm_a_pd_str[pd];
10870         msg_str = my_match_strval((guint32) (oct & DTAP_SMS_IEI_MASK), gsm_a_dtap_msg_sms_strings, &idx);
10871         ett_tree = ett_gsm_dtap_msg_sms[idx];
10872         hf_idx = hf_gsm_a_dtap_msg_sms_type;
10873         msg_fcn = dtap_msg_sms_fcn[idx];
10874         ti = (oct_1 & DTAP_TI_MASK) >> 4;
10875         break;
10876
10877     case 10:
10878         str = gsm_a_pd_str[pd];
10879         msg_str = my_match_strval((guint32) (oct & DTAP_SM_IEI_MASK), gsm_a_dtap_msg_sm_strings, &idx);
10880         ett_tree = ett_gsm_dtap_msg_sm[idx];
10881         hf_idx = hf_gsm_a_dtap_msg_sm_type;
10882         msg_fcn = dtap_msg_sm_fcn[idx];
10883         ti = (oct_1 & DTAP_TI_MASK) >> 4;
10884         break;
10885
10886     case 11:
10887         str = gsm_a_pd_str[pd];
10888         msg_str = my_match_strval((guint32) (oct & DTAP_SS_IEI_MASK), gsm_a_dtap_msg_ss_strings, &idx);
10889         ett_tree = ett_gsm_dtap_msg_ss[idx];
10890         hf_idx = hf_gsm_a_dtap_msg_ss_type;
10891         msg_fcn = dtap_msg_ss_fcn[idx];
10892         ti = (oct_1 & DTAP_TI_MASK) >> 4;
10893         nsd = TRUE;
10894         break;
10895
10896     default:
10897         str = gsm_a_pd_str[pd];
10898         break;
10899     }
10900
10901     /*
10902      * create the protocol tree
10903      */
10904     if (msg_str == NULL)
10905     {
10906         dtap_item =
10907             proto_tree_add_protocol_format(tree, proto_a_dtap, tvb, 0, len,
10908                 "GSM A-I/F DTAP - Unknown DTAP Message Type (0x%02x)",
10909                 oct);
10910
10911         dtap_tree = proto_item_add_subtree(dtap_item, ett_dtap_msg);
10912     }
10913     else
10914     {
10915         dtap_item =
10916             proto_tree_add_protocol_format(tree, proto_a_dtap, tvb, 0, -1,
10917                 "GSM A-I/F DTAP - %s",
10918                 msg_str);
10919
10920         dtap_tree = proto_item_add_subtree(dtap_item, ett_tree);
10921
10922         if (check_col(pinfo->cinfo, COL_INFO))
10923         {
10924             col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", msg_str);
10925         }
10926     }
10927
10928     oct_1_item =
10929         proto_tree_add_text(dtap_tree,
10930             tvb, 0, 1,
10931             "Protocol Discriminator: %s",
10932             str);
10933
10934     pd_tree = proto_item_add_subtree(oct_1_item, ett_dtap_oct_1);
10935
10936     if (ti == -1)
10937     {
10938         other_decode_bitfield_value(a_bigbuf, oct_1, 0xf0, 8);
10939         proto_tree_add_text(pd_tree,
10940             tvb, 0, 1,
10941             "%s :  Skip Indicator",
10942             a_bigbuf);
10943     }
10944     else
10945     {
10946         other_decode_bitfield_value(a_bigbuf, oct_1, 0x80, 8);
10947         proto_tree_add_text(pd_tree,
10948             tvb, 0, 1,
10949             "%s :  TI flag: %s",
10950             a_bigbuf,
10951             ((oct_1 & 0x80) ?  "allocated by receiver" : "allocated by sender"));
10952
10953         if ((ti & DTAP_TIE_PRES_MASK) == DTAP_TIE_PRES_MASK)
10954         {
10955             /* ti is extended to next octet */
10956
10957             other_decode_bitfield_value(a_bigbuf, oct_1, 0x70, 8);
10958             proto_tree_add_text(pd_tree,
10959                 tvb, 0, 1,
10960                 "%s :  TIO: The TI value is given by the TIE in octet 2",
10961                 a_bigbuf);
10962         }
10963         else
10964         {
10965             other_decode_bitfield_value(a_bigbuf, oct_1, 0x70, 8);
10966             proto_tree_add_text(pd_tree,
10967                 tvb, 0, 1,
10968                 "%s :  TIO: %u",
10969                 a_bigbuf,
10970                 ti & DTAP_TIE_PRES_MASK);
10971         }
10972     }
10973
10974     other_decode_bitfield_value(a_bigbuf, oct_1, DTAP_PD_MASK, 8);
10975     proto_tree_add_text(pd_tree,
10976         tvb, 0, 1,
10977         "%s :  Protocol Discriminator: %u",
10978         a_bigbuf,
10979         pd);
10980
10981     if ((ti != -1) &&
10982         (ti & DTAP_TIE_PRES_MASK) == DTAP_TIE_PRES_MASK)
10983     {
10984         other_decode_bitfield_value(a_bigbuf, oct_2, 0x80, 8);
10985         proto_tree_add_text(pd_tree,
10986             tvb, 1, 1,
10987             "%s :  Extension",
10988             a_bigbuf);
10989
10990         other_decode_bitfield_value(a_bigbuf, oct_2, DTAP_TIE_MASK, 8);
10991         proto_tree_add_text(pd_tree,
10992             tvb, 1, 1,
10993             "%s :  TIE: %u",
10994             a_bigbuf,
10995             oct_2 & DTAP_TIE_MASK);
10996     }
10997
10998     /*
10999      * N(SD)
11000      */
11001     if ((pinfo->p2p_dir == P2P_DIR_RECV) &&
11002         nsd)
11003     {
11004         /* XXX */
11005     }
11006
11007     /*
11008      * add DTAP message name
11009      */
11010     proto_tree_add_uint_format(dtap_tree, hf_idx,
11011         tvb, offset, 1, oct,
11012         "Message Type");
11013
11014     offset++;
11015
11016     tap_p->pdu_type = BSSAP_PDU_TYPE_DTAP;
11017     tap_p->message_type = (nsd ? (oct & 0x3f) : oct);
11018     tap_p->protocol_disc = pd;
11019
11020     tap_queue_packet(gsm_a_tap, pinfo, tap_p);
11021
11022     if (msg_str == NULL) return;
11023
11024     if ((len - offset) <= 0) return;
11025
11026     /*
11027      * decode elements
11028      */
11029     if (msg_fcn == NULL)
11030     {
11031         proto_tree_add_text(dtap_tree,
11032             tvb, offset, len - offset,
11033             "Message Elements");
11034     }
11035     else
11036     {
11037         (*msg_fcn)(tvb, dtap_tree, offset, len - offset);
11038     }
11039 }
11040
11041
11042 /* Register the protocol with Ethereal */
11043 void
11044 proto_register_gsm_a(void)
11045 {
11046     guint               i;
11047     guint               last_offset;
11048
11049     /* Setup list of header fields */
11050
11051     static hf_register_info hf[] =
11052     {
11053         { &hf_gsm_a_bssmap_msg_type,
11054             { "BSSMAP Message Type",    "gsm_a.bssmap_msgtype",
11055             FT_UINT8, BASE_HEX, VALS(gsm_a_bssmap_msg_strings), 0x0,
11056             "", HFILL }
11057         },
11058         { &hf_gsm_a_dtap_msg_mm_type,
11059             { "DTAP Mobility Management Message Type",  "gsm_a.dtap_msg_mm_type",
11060             FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_mm_strings), 0x0,
11061             "", HFILL }
11062         },
11063         { &hf_gsm_a_dtap_msg_rr_type,
11064             { "DTAP Radio Resources Management Message Type",   "gsm_a.dtap_msg_rr_type",
11065             FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_rr_strings), 0x0,
11066             "", HFILL }
11067         },
11068         { &hf_gsm_a_dtap_msg_cc_type,
11069             { "DTAP Call Control Message Type", "gsm_a.dtap_msg_cc_type",
11070             FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_cc_strings), 0x0,
11071             "", HFILL }
11072         },
11073         { &hf_gsm_a_dtap_msg_gmm_type,
11074             { "DTAP GPRS Mobility Management Message Type",     "gsm_a.dtap_msg_gmm_type",
11075             FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_gmm_strings), 0x0,
11076             "", HFILL }
11077         },
11078         { &hf_gsm_a_dtap_msg_sms_type,
11079             { "DTAP Short Message Service Message Type",        "gsm_a.dtap_msg_sms_type",
11080             FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_sms_strings), 0x0,
11081             "", HFILL }
11082         },
11083         { &hf_gsm_a_dtap_msg_sm_type,
11084             { "DTAP GPRS Session Management Message Type",      "gsm_a.dtap_msg_sm_type",
11085             FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_sm_strings), 0x0,
11086             "", HFILL }
11087         },
11088         { &hf_gsm_a_dtap_msg_ss_type,
11089             { "DTAP Non call Supplementary Service Message Type",       "gsm_a.dtap_msg_ss_type",
11090             FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_ss_strings), 0x0,
11091             "", HFILL }
11092         },
11093         { &hf_gsm_a_rp_msg_type,
11094             { "RP Message Type",        "gsm_a.rp_msg_type",
11095             FT_UINT8, BASE_HEX, VALS(gsm_rp_msg_strings), 0x0,
11096             "", HFILL }
11097         },
11098         { &hf_gsm_a_bssmap_elem_id,
11099             { "Element ID",     "gsm_a_bssmap.elem_id",
11100             FT_UINT8, BASE_DEC, NULL, 0,
11101             "", HFILL }
11102         },
11103         { &hf_gsm_a_dtap_elem_id,
11104             { "Element ID",     "gsm_a_dtap.elem_id",
11105             FT_UINT8, BASE_DEC, NULL, 0,
11106             "", HFILL }
11107         },
11108         { &hf_gsm_a_length,
11109             { "Length",         "gsm_a.len",
11110             FT_UINT8, BASE_DEC, NULL, 0,
11111             "", HFILL }
11112         },
11113         { &hf_gsm_a_none,
11114             { "Sub tree",       "gsm_a.none",
11115             FT_NONE, 0, 0, 0,
11116             "", HFILL }
11117         },
11118         { &hf_gsm_a_imsi,
11119             { "IMSI",   "gsm_a.imsi",
11120             FT_STRING, BASE_DEC, 0, 0,
11121             "", HFILL }
11122         },
11123         { &hf_gsm_a_tmsi,
11124             { "TMSI/P-TMSI",    "gsm_a.tmsi",
11125             FT_UINT32, BASE_HEX, 0, 0x0,
11126             "", HFILL }
11127         },
11128         { &hf_gsm_a_imei,
11129             { "IMEI",   "gsm_a.imei",
11130             FT_STRING, BASE_DEC, 0, 0,
11131             "", HFILL }
11132         },
11133         { &hf_gsm_a_imeisv,
11134             { "IMEISV", "gsm_a.imeisv",
11135             FT_STRING, BASE_DEC, 0, 0,
11136             "", HFILL }
11137         },
11138         { &hf_gsm_a_cld_party_bcd_num,
11139             { "Called Party BCD Number",        "gsm_a.cld_party_bcd_num",
11140             FT_STRING, BASE_DEC, 0, 0,
11141             "", HFILL }
11142         },
11143         { &hf_gsm_a_clg_party_bcd_num,
11144             { "Calling Party BCD Number",       "gsm_a.clg_party_bcd_num",
11145             FT_STRING, BASE_DEC, 0, 0,
11146             "", HFILL }
11147         },
11148         { &hf_gsm_a_cell_ci,
11149             { "Cell CI",        "gsm_a.cell_ci",
11150             FT_UINT16, BASE_HEX, 0, 0x0,
11151             "", HFILL }
11152         },
11153         { &hf_gsm_a_cell_lac,
11154             { "Cell LAC",       "gsm_a.cell_lac",
11155             FT_UINT16, BASE_HEX, 0, 0x0,
11156             "", HFILL }
11157         },
11158         { &hf_gsm_a_dlci_cc,
11159             { "Control Channel", "bssap.dlci.cc",
11160             FT_UINT8, BASE_HEX, VALS(bssap_cc_values), 0xc0,
11161             "", HFILL}
11162         },
11163         { &hf_gsm_a_dlci_spare,
11164             { "Spare", "bssap.dlci.spare",
11165             FT_UINT8, BASE_HEX, NULL, 0x38,
11166             "", HFILL}
11167         },
11168         { &hf_gsm_a_dlci_sapi,
11169             { "SAPI", "bssap.dlci.sapi",
11170             FT_UINT8, BASE_HEX, VALS(bssap_sapi_values), 0x07,
11171             "", HFILL}
11172         },
11173         { &hf_gsm_a_bssmap_cause,
11174             { "BSSMAP Cause",   "gsm_a_bssmap.cause",
11175             FT_UINT8, BASE_HEX, 0, 0x0,
11176             "", HFILL }
11177         },
11178         { &hf_gsm_a_dtap_cause,
11179             { "DTAP Cause",     "gsm_a_dtap.cause",
11180             FT_UINT8, BASE_HEX, 0, 0x0,
11181             "", HFILL }
11182         },
11183     };
11184
11185     /* Setup protocol subtree array */
11186 #define NUM_INDIVIDUAL_ELEMS    33
11187     static gint *ett[NUM_INDIVIDUAL_ELEMS + NUM_GSM_BSSMAP_MSG +
11188                         NUM_GSM_DTAP_MSG_MM + NUM_GSM_DTAP_MSG_RR + NUM_GSM_DTAP_MSG_CC +
11189                         NUM_GSM_DTAP_MSG_GMM + NUM_GSM_DTAP_MSG_SMS +
11190                         NUM_GSM_DTAP_MSG_SM + NUM_GSM_DTAP_MSG_SS + NUM_GSM_RP_MSG +
11191                         NUM_GSM_BSSMAP_ELEM + NUM_GSM_DTAP_ELEM];
11192
11193     memset((void *) ett, -1, sizeof(ett));
11194
11195     ett[0] = &ett_bssmap_msg;
11196     ett[1] = &ett_dtap_msg;
11197     ett[2] = &ett_rp_msg;
11198     ett[3] = &ett_elems;
11199     ett[4] = &ett_elem;
11200     ett[5] = &ett_dtap_oct_1;
11201     ett[6] = &ett_cm_srvc_type;
11202     ett[7] = &ett_gsm_enc_info;
11203     ett[8] = &ett_cell_list;
11204     ett[9] = &ett_dlci;
11205     ett[10] = &ett_bc_oct_3a;
11206     ett[11] = &ett_bc_oct_4;
11207     ett[12] = &ett_bc_oct_5;
11208     ett[13] = &ett_bc_oct_5a;
11209     ett[14] = &ett_bc_oct_5b;
11210     ett[15] = &ett_bc_oct_6;
11211     ett[16] = &ett_bc_oct_6a;
11212     ett[17] = &ett_bc_oct_6b;
11213     ett[18] = &ett_bc_oct_6c;
11214     ett[19] = &ett_bc_oct_6d;
11215     ett[20] = &ett_bc_oct_6e;
11216     ett[21] = &ett_bc_oct_6f;
11217     ett[22] = &ett_bc_oct_6g;
11218     ett[23] = &ett_bc_oct_7;
11219
11220     ett[24] = &ett_tc_component;
11221     ett[25] = &ett_tc_invoke_id;
11222     ett[26] = &ett_tc_linked_id;
11223     ett[27] = &ett_tc_opr_code;
11224     ett[28] = &ett_tc_err_code;
11225     ett[29] = &ett_tc_prob_code;
11226     ett[30] = &ett_tc_sequence;
11227     ett[31] = &gsm_ss_ett_sequence;
11228     ett[32] = &gsm_ss_ett_param;
11229
11230     last_offset = NUM_INDIVIDUAL_ELEMS;
11231
11232     for (i=0; i < NUM_GSM_BSSMAP_MSG; i++, last_offset++)
11233     {
11234         ett[last_offset] = &ett_gsm_bssmap_msg[i];
11235     }
11236
11237     for (i=0; i < NUM_GSM_DTAP_MSG_MM; i++, last_offset++)
11238     {
11239         ett[last_offset] = &ett_gsm_dtap_msg_mm[i];
11240     }
11241
11242     for (i=0; i < NUM_GSM_DTAP_MSG_RR; i++, last_offset++)
11243     {
11244         ett[last_offset] = &ett_gsm_dtap_msg_rr[i];
11245     }
11246
11247     for (i=0; i < NUM_GSM_DTAP_MSG_CC; i++, last_offset++)
11248     {
11249         ett[last_offset] = &ett_gsm_dtap_msg_cc[i];
11250     }
11251
11252     for (i=0; i < NUM_GSM_DTAP_MSG_GMM; i++, last_offset++)
11253     {
11254         ett[last_offset] = &ett_gsm_dtap_msg_gmm[i];
11255     }
11256
11257     for (i=0; i < NUM_GSM_DTAP_MSG_SMS; i++, last_offset++)
11258     {
11259         ett[last_offset] = &ett_gsm_dtap_msg_sms[i];
11260     }
11261
11262     for (i=0; i < NUM_GSM_DTAP_MSG_SM; i++, last_offset++)
11263     {
11264         ett[last_offset] = &ett_gsm_dtap_msg_sm[i];
11265     }
11266
11267     for (i=0; i < NUM_GSM_DTAP_MSG_SS; i++, last_offset++)
11268     {
11269         ett[last_offset] = &ett_gsm_dtap_msg_ss[i];
11270     }
11271
11272     for (i=0; i < NUM_GSM_RP_MSG; i++, last_offset++)
11273     {
11274         ett[last_offset] = &ett_gsm_rp_msg[i];
11275     }
11276
11277     for (i=0; i < NUM_GSM_BSSMAP_ELEM; i++, last_offset++)
11278     {
11279         ett[last_offset] = &ett_gsm_bssmap_elem[i];
11280     }
11281
11282     for (i=0; i < NUM_GSM_DTAP_ELEM; i++, last_offset++)
11283     {
11284         ett[last_offset] = &ett_gsm_dtap_elem[i];
11285     }
11286
11287     /* Register the protocol name and description */
11288
11289     proto_a_bssmap =
11290         proto_register_protocol("GSM A-I/F BSSMAP", "GSM BSSMAP", "gsm_a_bssmap");
11291
11292     proto_register_field_array(proto_a_bssmap, hf, array_length(hf));
11293
11294     proto_a_dtap =
11295         proto_register_protocol("GSM A-I/F DTAP", "GSM DTAP", "gsm_a_dtap");
11296
11297     proto_a_rp =
11298         proto_register_protocol("GSM A-I/F RP", "GSM RP", "gsm_a_rp");
11299
11300     sms_dissector_table =
11301         register_dissector_table("gsm_a.sms_tpdu", "GSM SMS TPDU",
11302         FT_UINT8, BASE_DEC);
11303
11304     proto_register_subtree_array(ett, array_length(ett));
11305
11306     gsm_a_tap = register_tap("gsm_a");
11307 }
11308
11309
11310 void
11311 proto_reg_handoff_gsm_a(void)
11312 {
11313
11314     bssmap_handle = create_dissector_handle(dissect_bssmap, proto_a_bssmap);
11315     dtap_handle = create_dissector_handle(dissect_dtap, proto_a_dtap);
11316     rp_handle = create_dissector_handle(dissect_rp, proto_a_rp);
11317
11318     dissector_add("bssap.pdu_type",  BSSAP_PDU_TYPE_BSSMAP, bssmap_handle);
11319     dissector_add("bssap.pdu_type",  BSSAP_PDU_TYPE_DTAP, dtap_handle);
11320     dissector_add("ranap.nas_pdu",  BSSAP_PDU_TYPE_DTAP, dtap_handle);
11321
11322     data_handle = find_dissector("data");
11323 }