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