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